libceph: fix inverted crc option logic

CRC's are computed for all messages between ceph entities.  The CRC
computation for the data portion of message can optionally be
disabled using the "nocrc" (common) ceph option.  The default is
for CRC computation for the data portion to be enabled.

Unfortunately, the code that implements this feature interprets the
feature flag wrong, meaning that by default the CRC's have *not*
been computed (or checked) for the data portion of messages unless
the "nocrc" option was supplied.

Fix this, in write_partial_msg_pages() and read_partial_message().
Also change the flag variable in write_partial_msg_pages() to be
"no_datacrc" to match the usage elsewhere in the file.

This fixes http://tracker.newdream.net/issues/2064

Signed-off-by: Alex Elder <elder@dreamhost.com>
libceph: use kernel_sendpage() for sending zeroes

If a message queued for send gets revoked, zeroes are sent over the
wire instead of any unsent data.  This is done by constructing a
message and passing it to kernel_sendmsg() via ceph_tcp_sendmsg().

Since we are already working with a page in this case we can use
the sendpage interface instead.  Create a new ceph_tcp_sendpage()
helper that sets up flags to match the way ceph_tcp_sendmsg()
does now.

Signed-off-by: Alex Elder <elder@dreamhost.com>
libceph: only call kernel_sendpage() via helper

Make ceph_tcp_sendpage() be the only place kernel_sendpage() is
used, by using this helper in write_partial_msg_pages().

Signed-off-by: Alex Elder <elder@dreamhost.com>
libceph: get rid of zero_page_address

There's not a lot of benefit to zero_page_address, which basically
holds a mapping of the zero page through the life of the messenger
module.  Even with our own mapping, the sendpage interface where
it's used may need to kmap() it again.  It's almost certain to
be in low memory anyway.

So stop treating the zero page specially in write_partial_msg_pages()
and just get rid of zero_page_address entirely.

Signed-off-by: Alex Elder <elder@dreamhost.com>
libceph: rename "page_shift" variable to something sensible

In write_partial_msg_pages() there is a local variable used to
track the starting offset within a bio segment to use.  Its name,
"page_shift" defies the Linux convention of using that name for
log-base-2(page size).

Since it's only used in the bio case rename it "bio_offset".  Use it
along with the page_pos field to compute the memory offset when
computing CRC's in that function.  This makes the bio case match the
others more closely.

Signed-off-by: Alex Elder <elder@dreamhost.com>
libceph: isolate kmap() call in write_partial_msg_pages()

In write_partial_msg_pages(), every case now does an identical call
to kmap(page).  Instead, just call it once inside the CRC-computing
block where it's needed.  Move the definition of kaddr inside that
block, and make it a (char *) to ensure portable pointer arithmetic.

We still don't kunmap() it until after the sendpage() call, in case
that also ends up needing to use the mapping.

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: fix three bugs, two in ceph_vxattrcb_file_layout()

In ceph_vxattrcb_file_layout(), there is a check to determine
whether a preferred PG should be formatted into the output buffer.
That check assumes that a preferred PG number of 0 indicates "no
preference," but that is wrong.  No preference is indicated by a
negative (specifically, -1) PG number.

In addition, if that condition yields true, the preferred value
is formatted into a sized buffer, but the size consumed by the
earlier snprintf() call is not accounted for, opening up the
possibilty of a buffer overrun.

Finally, in ceph_vxattrcb_dir_rctime() where the nanoseconds part of
the time displayed did not include leading 0's, which led to
erroneous (sub-second portion of) time values being shown.

This fixes these three issues:
    http://tracker.newdream.net/issues/2155
    http://tracker.newdream.net/issues/2156
    http://tracker.newdream.net/issues/2157

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: move file layout helpers to ceph_fs.h

The helper macros for accessing fields from struct ceph_file_layout
(which is defined in "include/linux/ceph/ceph_fs.h") are defined
instead in "include/linux/ceph/osdmap.h".

Move them, so they are defined in the same place as the structure
they apply to.

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: make ceph file layout helpers take a pointer

Make the helpers for accessing the fields of an on-disk ceph file
layout structure take the address of a layout structure rather than
the structure itself.  It's more useful (and to my eye a bit more
normal).

Use the result in ceph_file_layout_stripe_width() and
ceph_file_layout_period(), since it's now possible.

Rename ceph_file_layout_su() to be ceph_file_layout_stripe_unit().

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: make use of ceph file layout helpers

There are helpers defined in "include/linux/ceph/osdmap.h" for
accessing the fields of an on-disk ceph file layout structure.
Use them--consistently--throughout the code.

Also define CEPH_FILE_LAYOUT_PG_PREFERRED_NONE, to represent
symbolically the explicit "no preferred PG" value.

Make a few casts explicit too (to make it more obvious it's
occuring).  This produces some long lines, but they go away in an
upcoming patch.

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: use 64-bit math in ceph_calc_file_object_mapping()

Convert ceph_calc_file_object_mapping() so it uses 64-bit variables
and divide operators.  This is in anticipation of the next patch,
to keep the the changes it incurs more focused.

I made most of the variable names more verbose, and because it now
uses do_div() some of the calculations get done in a different
order.  Net result is that the code does what it did before, but it
looks quite a bit different...

Signed-off-by: Alex Elder <elder@dreamhost.com>
ceph: fix up the types of the file layout helpers

The helper macros for accessing file layout fields of an on-disk
ceph file layout structure cast their results to type (__s32).  This
is a bit strange, since (with one exception--fl_pg_preferred):
    - there is no need for negative values; and
    - all users of these macros are assigning their result to
      64-bit variables.
So just make these macros return a 64-bit unsigned type.

The exception is the preferred placement group, which remains a
signed 32-bit value.  A placement group id encodes the preferred
primary OSD in a 16-bit value, and there's no sense at this point
getting too far away from that.

Signed-off-by: Alex Elder <elder@dreamhost.com>