I've been unable to test rigorously today so I analyzed the affected code.
If the "nocrc" flag is supplied, the ceph_options->flags field gets the
CEPH_OPT_NOCRC set. (And conversely if "crc" is supplied, that flag is
cleared.)
The CEPH_OPT_NOCRC flag is checked in two places:
- In ceph_show_options(), "nocrc" is added to the options shown if it's set.
- And in ceph_create_client(), "nocrc" flag on the newly-created client's
messenger gets assigned (via ceph_test_opt()) either true or false based
on whether CEPH_OPT_NOCRC is set or cleared, respectively.
A messenger's "nocrc" flag is used in two places:
- write_partial_msg_pages()
- read_partial_message()
In both of these the value is assigned to a local variable, and that
variable is used to determine whether to compute a CRC on the data
portion of the message and either send or verify it.
That's it. These last two uses of the "nocrc" flag is where the logic
is inverted. The fix is to logically negate the assigned value.
In write_partial_msg_pages(), the assigned flag is used consistently
to determine whether to map a page to a memory address, with the result
passed to crc32c(). It is later used to determine whether to unmap
the mapped page address, and finally, it is used to decide whether the
CEPH_MSG_FOOTER_NOCRC should be set in the message footer flags. This
all appears to be correct.
In read_partial_message() the assigned flag is passed to either
read_partial_message_pages() or read_partial_message_bio(), and
later if it's used--if the CEPH_MSG_FOOTER_NOCRC flag is not set in
the message footer--to determine whether to check the data CRC
received in the message footer matches the CRC calculated for the
data portion of the message. Assuming the two called functions
use the values correctly, this looks correct.
read_partial_message_pages() receives no more than one page from
the socket, and if the "do_datacrc" flag indicates to, updates
the computed data CRC based on the data received. This looks
right.
The logic in read_partial_message_bio() matches the above, using
the length of the current bio segment rather than the current page
as the limit to the size of the data received.
So in summary, I have confidence that simply inverting the
"nocrc" values as described above will produce the desired,
correct behavior.
Now it just has to be tested...