1. 02 5月, 2013 40 次提交
    • Y
      ceph: fix race between writepages and truncate · 1ac0fc8a
      Yan, Zheng 提交于
      ceph_writepages_start() reads inode->i_size in two places. It can get
      different values between successive read, because truncate can change
      inode->i_size at any time. The race can lead to mismatch between data
      length of osd request and pages marked as writeback. When osd request
      finishes, it clear writeback page according to its data length. So
      some pages can be left in writeback state forever. The fix is only
      read inode->i_size once, save its value to a local variable and use
      the local variable when i_size is needed.
      Signed-off-by: NYan, Zheng <zheng.z.yan@intel.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      1ac0fc8a
    • Y
      ceph: apply write checks in ceph_aio_write · 03d254ed
      Yan, Zheng 提交于
      copy write checks in __generic_file_aio_write to ceph_aio_write.
      To make these checks cover sync write path.
      Signed-off-by: NYan, Zheng <zheng.z.yan@intel.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      03d254ed
    • Y
      ceph: take i_mutex before getting Fw cap · 37505d57
      Yan, Zheng 提交于
      There is deadlock as illustrated bellow. The fix is taking i_mutex
      before getting Fw cap reference.
      
            write                    truncate                 MDS
      ---------------------     --------------------      --------------
      get Fw cap
                                lock i_mutex
      lock i_mutex (blocked)
                                request setattr.size  ->
                                                      <-   revoke Fw cap
      Signed-off-by: NYan, Zheng <zheng.z.yan@intel.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NSage Weil <sage@inktank.com>
      37505d57
    • A
      libceph: change how "safe" callback is used · 26be8808
      Alex Elder 提交于
      An osd request currently has two callbacks.  They inform the
      initiator of the request when we've received confirmation for the
      target osd that a request was received, and when the osd indicates
      all changes described by the request are durable.
      
      The only time the second callback is used is in the ceph file system
      for a synchronous write.  There's a race that makes some handling of
      this case unsafe.  This patch addresses this problem.  The error
      handling for this callback is also kind of gross, and this patch
      changes that as well.
      
      In ceph_sync_write(), if a safe callback is requested we want to add
      the request on the ceph inode's unsafe items list.  Because items on
      this list must have their tid set (by ceph_osd_start_request()), the
      request added *after* the call to that function returns.  The
      problem with this is that there's a race between starting the
      request and adding it to the unsafe items list; the request may
      already be complete before ceph_sync_write() even begins to put it
      on the list.
      
      To address this, we change the way the "safe" callback is used.
      Rather than just calling it when the request is "safe", we use it to
      notify the initiator the bounds (start and end) of the period during
      which the request is *unsafe*.  So the initiator gets notified just
      before the request gets sent to the osd (when it is "unsafe"), and
      again when it's known the results are durable (it's no longer
      unsafe).  The first call will get made in __send_request(), just
      before the request message gets sent to the messenger for the first
      time.  That function is only called by __send_queued(), which is
      always called with the osd client's request mutex held.
      
      We then have this callback function insert the request on the ceph
      inode's unsafe list when we're told the request is unsafe.  This
      will avoid the race because this call will be made under protection
      of the osd client's request mutex.  It also nicely groups the setup
      and cleanup of the state associated with managing unsafe requests.
      
      The name of the "safe" callback field is changed to "unsafe" to
      better reflect its new purpose.  It has a Boolean "unsafe" parameter
      to indicate whether the request is becoming unsafe or is now safe.
      Because the "msg" parameter wasn't used, we drop that.
      
      This resolves the original problem reportedin:
          http://tracker.ceph.com/issues/4706Reported-by: NYan, Zheng <zheng.z.yan@intel.com>
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYan, Zheng <zheng.z.yan@intel.com>
      Reviewed-by: NSage Weil <sage@inktank.com>
      26be8808
    • A
      ceph: let osd client clean up for interrupted request · 7d7d51ce
      Alex Elder 提交于
      In ceph_sync_write(), if a safe callback is supplied with a request,
      and an error is returned by ceph_osdc_wait_request(), a block of
      code is executed to remove the request from the unsafe writes list
      and drop references to capabilities acquired just prior to a call to
      ceph_osdc_wait_request().
      
      The only function used for this callback is sync_write_commit(),
      and it does *exactly* what that block of error handling code does.
      
      Now in ceph_osdc_wait_request(), if an error occurs (due to an
      interupt during a wait_for_completion_interruptible() call),
      complete_request() gets called, and that calls the request's
      safe_callback method if it's defined.
      
      So this means that this cleanup activity gets called twice in this
      case, which is erroneous (and in fact leads to a crash).
      
      Fix this by just letting the osd client handle the cleanup in
      the event of an interrupt.
      
      This resolves one problem mentioned in:
          http://tracker.ceph.com/issues/4706Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYan, Zheng <zheng.z.yan@intel.com>
      7d7d51ce
    • Y
      ceph: fix symlink inode operations · 0b932672
      Yan, Zheng 提交于
      add getattr/setattr and xattrs related methods.
      Signed-off-by: NYan, Zheng <zheng.z.yan@intel.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      0b932672
    • S
      ceph: Use pseudo-random numbers to choose mds · a84cd293
      Sam Lang 提交于
      We don't need to use up entropy to choose an mds,
      so use prandom_u32() to get a pseudo-random number.
      
      Also, we don't need to choose a random mds if only
      one mds is available, so add special casing for the
      common case.
      
      Fixes http://tracker.ceph.com/issues/3579Signed-off-by: NSam Lang <sam.lang@inktank.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      a84cd293
    • A
      libceph: add, don't set data for a message · 90af3602
      Alex Elder 提交于
      Change the names of the functions that put data on a pagelist to
      reflect that we're adding to whatever's already there rather than
      just setting it to the one thing.  Currently only one data item is
      ever added to a message, but that's about to change.
      
      This resolves:
          http://tracker.ceph.com/issues/2770Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      90af3602
    • A
      libceph: combine initializing and setting osd data · a4ce40a9
      Alex Elder 提交于
      This ends up being a rather large patch but what it's doing is
      somewhat straightforward.
      
      Basically, this is replacing two calls with one.  The first of the
      two calls is initializing a struct ceph_osd_data with data (either a
      page array, a page list, or a bio list); the second is setting an
      osd request op so it associates that data with one of the op's
      parameters.  In place of those two will be a single function that
      initializes the op directly.
      
      That means we sort of fan out a set of the needed functions:
          - extent ops with pages data
          - extent ops with pagelist data
          - extent ops with bio list data
      and
          - class ops with page data for receiving a response
      
      We also have define another one, but it's only used internally:
          - class ops with pagelist data for request parameters
      
      Note that we *still* haven't gotten rid of the osd request's
      r_data_in and r_data_out fields.  All the osd ops refer to them for
      their data.  For now, these data fields are pointers assigned to the
      appropriate r_data_* field when these new functions are called.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      a4ce40a9
    • A
      libceph: specify osd op by index in request · c99d2d4a
      Alex Elder 提交于
      An osd request now holds all of its source op structures, and every
      place that initializes one of these is in fact initializing one
      of the entries in the the osd request's array.
      
      So rather than supplying the address of the op to initialize, have
      caller specify the osd request and an indication of which op it
      would like to initialize.  This better hides the details the
      op structure (and faciltates moving the data pointers they use).
      
      Since osd_req_op_init() is a common routine, and it's not used
      outside the osd client code, give it static scope.  Also make
      it return the address of the specified op (so all the other
      init routines don't have to repeat that code).
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      c99d2d4a
    • A
      libceph: add data pointers in osd op structures · 8c042b0d
      Alex Elder 提交于
      An extent type osd operation currently implies that there will
      be corresponding data supplied in the data portion of the request
      (for write) or response (for read) message.  Similarly, an osd class
      method operation implies a data item will be supplied to receive
      the response data from the operation.
      
      Add a ceph_osd_data pointer to each of those structures, and assign
      it to point to eithre the incoming or the outgoing data structure in
      the osd message.  The data is not always available when an op is
      initially set up, so add two new functions to allow setting them
      after the op has been initialized.
      
      Begin to make use of the data item pointer available in the osd
      operation rather than the request data in or out structure in
      places where it's convenient.  Add some assertions to verify
      pointers are always set the way they're expected to be.
      
      This is a sort of stepping stone toward really moving the data
      into the osd request ops, to allow for some validation before
      making that jump.
      
      This is the first in a series of patches that resolve:
          http://tracker.ceph.com/issues/4657Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      8c042b0d
    • A
      libceph: keep source rather than message osd op array · 79528734
      Alex Elder 提交于
      An osd request keeps a pointer to the osd operations (ops) array
      that it builds in its request message.
      
      In order to allow each op in the array to have its own distinct
      data, we will need to keep track of each op's data, and that
      information does not go over the wire.
      
      As long as we're tracking the data we might as well just track the
      entire (source) op definition for each of the ops.  And if we're
      doing that, we'll have no more need to keep a pointer to the
      wire-encoded version.
      
      This patch makes the array of source ops be kept with the osd
      request structure, and uses that instead of the version encoded in
      the message in places where that was previously used.  The array
      will be embedded in the request structure, and the maximum number of
      ops we ever actually use is currently 2.  So reduce CEPH_OSD_MAX_OP
      to 2 to reduce the size of the structure.
      
      The result of doing this sort of ripples back up, and as a result
      various function parameters and local variables become unnecessary.
      
      Make r_num_ops be unsigned, and move the definition of struct
      ceph_osd_req_op earlier to ensure it's defined where needed.
      
      It does not yet add per-op data, that's coming soon.
      
      This resolves:
          http://tracker.ceph.com/issues/4656Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      79528734
    • A
      libceph: a few more osd data cleanups · 87060c10
      Alex Elder 提交于
      These are very small changes that make use osd_data local pointers
      as shorthands for structures being operated on.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      87060c10
    • A
      libceph: define osd data initialization helpers · 43bfe5de
      Alex Elder 提交于
      Define and use functions that encapsulate the initializion of a
      ceph_osd_data structure.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      43bfe5de
    • A
      ceph: build osd request message later for writepages · e5975c7c
      Alex Elder 提交于
      Hold off building the osd request message in ceph_writepages_start()
      until just before it will be submitted to the osd client for
      execution.
      
      We'll still create the request and allocate the page pointer array
      after we learn we have at least one page to write.  A local variable
      will be used to keep track of the allocated array of pages.  Wait
      until just before submitting the request for assigning that page
      array pointer to the request message.
      
      Create ands use a new function osd_req_op_extent_update() whose
      purpose is to serve this one spot where the length value supplied
      when an osd request's op was initially formatted might need to get
      changed (reduced, never increased) before submitting the request.
      
      Previously, ceph_writepages_start() assigned the message header's
      data length because of this update.  That's no longer necessary,
      because ceph_osdc_build_request() will recalculate the right
      value to use based on the content of the ops in the request.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      e5975c7c
    • A
      libceph: hold off building osd request · 02ee07d3
      Alex Elder 提交于
      Defer building the osd request until just before submitting it in
      all callers except ceph_writepages_start().  (That caller will be
      handed in the next patch.)
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      02ee07d3
    • A
      ceph: kill ceph alloc_page_vec() · 88486957
      Alex Elder 提交于
      There is a helper function alloc_page_vec() that, despite its
      generic sounding name depends heavily on an osd request structure
      being populated with certain information.
      
      There is only one place this function is used, and it ends up
      being a bit simpler to just open code what it does, so get
      rid of the helper.
      
      The real motivation for this is deferring building the of the osd
      request message, and this is a step in that direction.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      88486957
    • A
      ceph: define ceph_writepages_osd_request() · 94fe8420
      Alex Elder 提交于
      Mostly for readability, define ceph_writepages_osd_request() and
      use it to allocate the osd request for ceph_writepages_start().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      94fe8420
    • A
      libceph: don't build request in ceph_osdc_new_request() · acead002
      Alex Elder 提交于
      This patch moves the call to ceph_osdc_build_request() out of
      ceph_osdc_new_request() and into its caller.
      
      This is in order to defer formatting osd operation information into
      the request message until just before request is started.
      
      The only unusual (ab)user of ceph_osdc_build_request() is
      ceph_writepages_start(), where the final length of write request may
      change (downward) based on the current inode size or the oldest
      snapshot context with dirty data for the inode.
      
      The remaining callers don't change anything in the request after has
      been built.
      
      This means the ops array is now supplied by the caller.  It also
      means there is no need to pass the mtime to ceph_osdc_new_request()
      (it gets provided to ceph_osdc_build_request()).  And rather than
      passing a do_sync flag, have the number of ops in the ops array
      supplied imply adding a second STARTSYNC operation after the READ or
      WRITE requested.
      
      This and some of the patches that follow are related to having the
      messenger (only) be responsible for filling the content of the
      message header, as described here:
          http://tracker.ceph.com/issues/4589Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      acead002
    • A
      ceph: use page_offset() in ceph_writepages_start() · 25d71cb9
      Alex Elder 提交于
      There's one spot in ceph_writepages_start() that open-codes what
      page_offset() does safely.  Use the macro so we don't have to worry
      about wrapping.
      
      This resolves:
          http://tracker.ceph.com/issues/4648Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      25d71cb9
    • A
      ceph: set up page array mempool with correct size · 3bf53337
      Alex Elder 提交于
      In create_fs_client() a memory pool is set up be used for arrays of
      pages that might be needed in ceph_writepages_start() if memory is
      tight.  There are two problems with the way it's initialized:
          - The size provided is the number of pages we want in the
            array, but it should be the number of bytes required for
            that many page pointers.
          - The number of pages computed can end up being 0, while we
            will always need at least one page.
      
      This patch fixes both of these problems.
      
      This resolves the two simple problems defined in:
          http://tracker.ceph.com/issues/4603Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3bf53337
    • S
      libceph: wrap auth ops in wrapper functions · 27859f97
      Sage Weil 提交于
      Use wrapper functions that check whether the auth op exists so that callers
      do not need a bunch of conditional checks.  Simplifies the external
      interface.
      Signed-off-by: NSage Weil <sage@inktank.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      27859f97
    • S
      libceph: add update_authorizer auth method · 0bed9b5c
      Sage Weil 提交于
      Currently the messenger calls out to a get_authorizer con op, which will
      create a new authorizer if it doesn't yet have one.  In the meantime, when
      we rotate our service keys, the authorizer doesn't get updated.  Eventually
      it will be rejected by the server on a new connection attempt and get
      invalidated, and we will then rebuild a new authorizer, but this is not
      ideal.
      
      Instead, if we do have an authorizer, call a new update_authorizer op that
      will verify that the current authorizer is using the latest secret.  If it
      is not, we will build a new one that does.  This avoids the transient
      failure.
      
      This fixes one of the sorry sequence of events for bug
      
      	http://tracker.ceph.com/issues/4282Signed-off-by: NSage Weil <sage@inktank.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      0bed9b5c
    • H
      ceph: fix buffer pointer advance in ceph_sync_write · 022f3e2e
      Henry C Chang 提交于
      We should advance the user data pointer by _len_ instead of _written_.
      _len_ is the data length written in each iteration while _written_ is the
      accumulated data length we have writtent out.
      Signed-off-by: NHenry C Chang <henry.cy.chang@gmail.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      Tested-by: NSage Weil <sage@inktank.com>
      022f3e2e
    • Y
      ceph: use i_release_count to indicate dir's completeness · 2f276c51
      Yan, Zheng 提交于
      Current ceph code tracks directory's completeness in two places.
      ceph_readdir() checks i_release_count to decide if it can set the
      I_COMPLETE flag in i_ceph_flags. All other places check the I_COMPLETE
      flag. This indirection introduces locking complexity.
      
      This patch adds a new variable i_complete_count to ceph_inode_info.
      Set i_release_count's value to it when marking a directory complete.
      By comparing the two variables, we know if a directory is complete
      Signed-off-by: NYan, Zheng <zheng.z.yan@intel.com>
      2f276c51
    • A
      ceph: only set message data pointers if non-empty · ebf18f47
      Alex Elder 提交于
      Change it so we only assign outgoing data information for messages
      if there is outgoing data to send.
      
      This then allows us to add a few more (currently commented-out)
      assertions.
      
      This is related to:
          http://tracker.ceph.com/issues/4284Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      ebf18f47
    • A
      libceph: isolate other message data fields · 27fa8385
      Alex Elder 提交于
      Define ceph_msg_data_set_pagelist(), ceph_msg_data_set_bio(), and
      ceph_msg_data_set_trail() to clearly abstract the assignment of the
      remaining data-related fields in a ceph message structure.  Use the
      new functions in the osd client and mds client.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4263Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      27fa8385
    • A
      libceph: set page info with byte length · f1baeb2b
      Alex Elder 提交于
      When setting page array information for message data, provide the
      byte length rather than the page count ceph_msg_data_set_pages().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      f1baeb2b
    • A
      libceph: isolate message page field manipulation · 02afca6c
      Alex Elder 提交于
      Define a function ceph_msg_data_set_pages(), which more clearly
      abstracts the assignment page-related fields for data in a ceph
      message structure.  Use this new function in the osd client and mds
      client.
      
      Ideally, these fields would never be set more than once (with
      BUG_ON() calls to guarantee that).  At the moment though the osd
      client sets these every time it receives a message, and in the event
      of a communication problem this can happen more than once.  (This
      will be resolved shortly, but setting up these helpers first makes
      it all a bit easier to work with.)
      
      Rearrange the field order in a ceph_msg structure to group those
      that are used to define the possible data payloads.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4263Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      02afca6c
    • A
      libceph: record byte count not page count · e0c59487
      Alex Elder 提交于
      Record the byte count for an osd request rather than the page count.
      The number of pages can always be derived from the byte count (and
      alignment/offset) but the reverse is not true.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      e0c59487
    • A
      libceph: separate read and write data · 0fff87ec
      Alex Elder 提交于
      An osd request defines information about where data to be read
      should be placed as well as where data to write comes from.
      Currently these are represented by common fields.
      
      Keep information about data for writing separate from data to be
      read by splitting these into data_in and data_out fields.
      
      This is the key patch in this whole series, in that it actually
      identifies which osd requests generate outgoing data and which
      generate incoming data.  It's less obvious (currently) that an osd
      CALL op generates both outgoing and incoming data; that's the focus
      of some upcoming work.
      
      This resolves:
          http://tracker.ceph.com/issues/4127Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      0fff87ec
    • A
      libceph: distinguish page and bio requests · 2ac2b7a6
      Alex Elder 提交于
      An osd request uses either pages or a bio list for its data.  Use a
      union to record information about the two, and add a data type
      tag to select between them.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      2ac2b7a6
    • A
      libceph: separate osd request data info · 2794a82a
      Alex Elder 提交于
      Pull the fields in an osd request structure that define the data for
      the request out into a separate structure.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      2794a82a
    • A
      libceph: don't assign page info in ceph_osdc_new_request() · 153e5167
      Alex Elder 提交于
      Currently ceph_osdc_new_request() assigns an osd request's
      r_num_pages and r_alignment fields.  The only thing it does
      after that is call ceph_osdc_build_request(), and that doesn't
      need those fields to be assigned.
      
      Move the assignment of those fields out of ceph_osdc_new_request()
      and into its caller.  As a result, the page_align parameter is no
      longer used, so get rid of it.
      
      Note that in ceph_sync_write(), the value for req->r_num_pages had
      already been calculated earlier (as num_pages, and fortunately
      it was computed the same way).  So don't bother recomputing it,
      but because it's not needed earlier, move that calculation after the
      call to ceph_osdc_new_request().  Hold off making the assignment to
      r_alignment, doing it instead r_pages and r_num_pages are
      getting set.
      
      Similarly, in start_read(), nr_pages already holds the number of
      pages in the array (and is calculated the same way), so there's no
      need to recompute it.  Move the assignment of the page alignment
      down with the others there as well.
      
      This and the next few patches are preparation work for:
          http://tracker.ceph.com/issues/4127Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      153e5167
    • A
      ceph: simplify ceph_sync_write() page_align calculation · 3a42b6c4
      Alex Elder 提交于
      (This is being reposted.  The first one had a problem because it
      erroneously added a similar change elsewhere; that change has been
      dropped.)
      
      The next patch in this series points out that the calculation for
      the number of pages in an osd request is getting done twice.  It
      is not obvious, but the result of both calculations is identical.
      This patch simplifies one of them--as a separate step--to make
      it clear that the transformation in the next patch is valid.
      
      In ceph_sync_write() there is some magic that computes page_align
      for an osd request.  But a little analysis shows it can be
      simplified.
      
      First, we have:
       	io_align = pos & ~PAGE_MASK;
      which is used here:
      	page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
      
      Note (pos - io_align) simply rounds "pos" down to the nearest multiple
      of the page size.
      
      We also have:
       	buf_align = (unsigned long)data & ~PAGE_MASK;
      
      Adding buf_align to that rounded-down "pos" value will stay within
      the same page; the result will just be offset by the page offset for
      the "data" pointer.  The final mask therefore leaves just the value
      of "buf_align".
      
      One more simplification.  Note that the result of calc_pages_for()
      is invariant of which page the offset starts in--the only thing that
      matters is the offset within the starting page.  We will have
      put the proper page offset to use into "page_align", so just use
      that in calculating num_pages.
      
      This resolves:
          http://tracker.ceph.com/issues/4166Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3a42b6c4
    • A
      ceph: use calc_pages_for() in start_read() · cf7b7e14
      Alex Elder 提交于
      There's a spot that computes the number of pages to allocate for a
      page-aligned length by just shifting it.  Use calc_pages_for()
      instead, to be consistent with usage everywhere else.  The result
      is the same.
      
      The reason for this is to make it clearer in an upcoming patch that
      this calculation is duplicated.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      cf7b7e14
    • A
      libceph: no need for alignment for mds message · 54ae0756
      Alex Elder 提交于
      Currently, incoming mds messages never use page data, which means
      there is no need to set the page_alignment field in the message.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      54ae0756
    • A
      libceph: define mds_alloc_msg() method · 53ded495
      Alex Elder 提交于
      The only user of the ceph messenger that doesn't define an alloc_msg
      method is the mds client.  Define one, such that it works just like
      it did before, and simplify ceph_con_in_msg_alloc() by assuming the
      alloc_msg method is always present.
      
      This and the next patch resolve:
          http://tracker.ceph.com/issues/4322Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      53ded495
    • A
      libceph: rename ceph_calc_object_layout() · 41766f87
      Alex Elder 提交于
      The purpose of ceph_calc_object_layout() is to fill in the pool
      number and seed for a ceph_pg structure provided, based on a given
      osd map and target object id.
      
      Currently that function takes a file layout parameter, but the only
      thing used out of that is its pool number.
      
      Change the function so it takes a pool number rather than the full
      file layout structure.  Only update the ceph_pg if the pool is found
      in the osd map.  Get rid of few useless lines of code from the
      function while there.
      
      Since the function now very clearly just fills in the ceph_pg
      structure it's provided, rename it ceph_calc_ceph_pg().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      41766f87
    • A
      libceph: kill ceph_msg->pagelist_count · ec02a2f2
      Alex Elder 提交于
      The pagelist_count field is never actually used, so get rid of it.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      ec02a2f2