1. 14 Oct, 2008 17 commits
  2. 13 Oct, 2008 23 commits
    • Joel Becker's avatar
      ocfs2: Add the 'inode64' mount option. · 12462f1d
      Joel Becker authored
      Now that ocfs2 limits inode numbers to 32bits, add a mount option to
      disable the limit.  This parallels XFS.  64bit systems can handle the
      larger inode numbers.
      
      [ Added description of inode64 mount option in ocfs2.txt. --Mark ]
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      12462f1d
    • Joel Becker's avatar
      ocfs2: Limit inode allocation to 32bits. · 1187c968
      Joel Becker authored
      ocfs2 inode numbers are block numbers.  For any filesystem with less
      than 2^32 blocks, this is not a problem.  However, when ocfs2 starts
      using JDB2, it will be able to support filesystems with more than 2^32
      blocks.  This would result in inode numbers higher than 2^32.
      
      The problem is that stat(2) can't handle those numbers on 32bit
      machines.  The simple solution is to have ocfs2 allocate all inodes
      below that boundary.
      
      The suballoc code is changed to honor an optional block limit.  Only the
      inode suballocator sets that limit - all other allocations stay unlimited.
      
      The biggest trick is to grow the inode suballocator beneath that limit.
      There's no point in allocating block groups that are above the limit,
      then rejecting their elements later on.  We want to prevent the inode
      allocator from ever having block groups above the limit.  This involves
      a little gyration with the local alloc code.  If the local alloc window
      is above the limit, it signals the caller to try the global bitmap but
      does not disable the local alloc file (which can be used for other
      allocations).
      
      [ Minor cleanup - removed an ML_NOTICE comment. --Mark ]
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      1187c968
    • Tao Ma's avatar
      ocfs2: Resolve deadlock in ocfs2_xattr_free_block. · 08413899
      Tao Ma authored
      In ocfs2_xattr_free_block, we take a cluster lock on xb_alloc_inode while we
      have a transaction open. This will deadlock the downconvert thread, so fix
      it.
      
      We can clean up how xattr blocks are removed while here - this patch also
      moves the mechanism of releasing xattr block (including both value, xattr
      tree and xattr block) into this function.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      08413899
    • Tao Ma's avatar
      ocfs2: bug-fix for journal extend in xattr. · 28b8ca0b
      Tao Ma authored
      In ocfs2_extend_trans, when we can't extend the current
      transaction, it will commit current transaction and restart
      a new one. So if the previous credits we have allocated aren't
      used(the block isn't dirtied before our extend), we will not
      have enough credits for any future operation(it will cause jbd
      complain and bug out). So check this and re-extend it.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      28b8ca0b
    • Joel Becker's avatar
      ocfs2: Change ocfs2_get_*_extent_tree() to ocfs2_init_*_extent_tree() · 8d6220d6
      Joel Becker authored
      The original get/put_extent_tree() functions held a reference on
      et_root_bh.  However, every single caller already has a safe reference,
      making the get/put cycle irrelevant.
      
      We change ocfs2_get_*_extent_tree() to ocfs2_init_*_extent_tree().  It
      no longer gets a reference on et_root_bh.  ocfs2_put_extent_tree() is
      removed.  Callers now have a simpler init+use pattern.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      8d6220d6
    • Joel Becker's avatar
      ocfs2: Comment struct ocfs2_extent_tree_operations. · 1625f8ac
      Joel Becker authored
      struct ocfs2_extent_tree_operations provides methods for the different
      on-disk btrees in ocfs2.  Describing what those methods do is probably a
      good idea.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      1625f8ac
    • Joel Becker's avatar
      ocfs2: Make ocfs2_extent_tree the first-class representation of a tree. · f99b9b7c
      Joel Becker authored
      We now have three different kinds of extent trees in ocfs2: inode data
      (dinode), extended attributes (xattr_tree), and extended attribute
      values (xattr_value).  There is a nice abstraction for them,
      ocfs2_extent_tree, but it is hidden in alloc.c.  All the calling
      functions have to pick amongst a varied API and pass in type bits and
      often extraneous pointers.
      
      A better way is to make ocfs2_extent_tree a first-class object.
      Everyone converts their object to an ocfs2_extent_tree() via the
      ocfs2_get_*_extent_tree() calls, then uses the ocfs2_extent_tree for all
      tree calls to alloc.c.
      
      This simplifies a lot of callers, making for readability.  It also
      provides an easy way to add additional extent tree types, as they only
      need to be defined in alloc.c with a ocfs2_get_<new>_extent_tree()
      function.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      f99b9b7c
    • Joel Becker's avatar
      ocfs2: Add an insertion check to ocfs2_extent_tree_operations. · 1e61ee79
      Joel Becker authored
      A couple places check an extent_tree for a valid inode.  We move that
      out to add an eo_insert_check() operation.  It can be called from
      ocfs2_insert_extent() and elsewhere.
      
      We also have the wrapper calls ocfs2_et_insert_check() and
      ocfs2_et_sanity_check() ignore NULL ops.  That way we don't have to
      provide useless operations for xattr types.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      1e61ee79
    • Joel Becker's avatar
      ocfs2: Create specific get_extent_tree functions. · 1a09f556
      Joel Becker authored
      A caller knows what kind of extent tree they have.  There's no reason
      they have to call ocfs2_get_extent_tree() with a NULL when they could
      just as easily call a specific function to their type of extent tree.
      
      Introduce ocfs2_dinode_get_extent_tree(),
      ocfs2_xattr_tree_get_extent_tree(), and
      ocfs2_xattr_value_get_extent_tree().  They only take the necessary
      arguments, calling into the underlying __ocfs2_get_extent_tree() to do
      the real work.
      
      __ocfs2_get_extent_tree() is the old ocfs2_get_extent_tree(), but
      without needing any switch-by-type logic.
      
      ocfs2_get_extent_tree() is now a wrapper around the specific calls.  It
      exists because a couple alloc.c functions can take et_type.  This will
      go later.
      
      Another benefit is that ocfs2_xattr_value_get_extent_tree() can take a
      struct ocfs2_xattr_value_root* instead of void*.  This gives us
      typechecking where we didn't have it before.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      1a09f556
    • Joel Becker's avatar
      ocfs2: Determine an extent tree's max_leaf_clusters in an et_op. · 943cced3
      Joel Becker authored
      Provide an optional extent_tree_operation to specify the
      max_leaf_clusters of an ocfs2_extent_tree.  If not provided, the value
      is 0 (unlimited).
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      943cced3
    • Joel Becker's avatar
      ocfs2: Use struct ocfs2_extent_tree in ocfs2_num_free_extents(). · 1c25d93a
      Joel Becker authored
      ocfs2_num_free_extents() re-implements the logic of
      ocfs2_get_extent_tree().  Now that ocfs2_get_extent_tree() does not
      allocate, let's use it in ocfs2_num_free_extents() to simplify the code.
      
      The inode validation code in ocfs2_num_free_extents() is not needed.
      All callers are passing in pre-validated inodes.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      1c25d93a
    • Joel Becker's avatar
      ocfs2: Provide the get_root_el() method to ocfs2_extent_tree_operations. · 0ce1010f
      Joel Becker authored
      The root_el of an ocfs2_extent_tree needs to be calculated from
      et->et_object.  Make it an operation on et->et_ops.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      0ce1010f
    • Joel Becker's avatar
      ocfs2: Make 'private' into 'object' on ocfs2_extent_tree. · ea5efa15
      Joel Becker authored
      The 'private' pointer was a way to store off xattr values, which don't
      live at a set place in the bh.  But the concept of "the object
      containing the extent tree" is much more generic.  For an inode it's the
      struct ocfs2_dinode, for an xattr value its the value.  Let's save off
      the 'object' at all times.  If NULL is passed to
      ocfs2_get_extent_tree(), 'object' is set to bh->b_data;
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      ea5efa15
    • Joel Becker's avatar
      ocfs2: Make ocfs2_extent_tree get/put instead of alloc. · dc0ce61a
      Joel Becker authored
      Rather than allocating a struct ocfs2_extent_tree, just put it on the
      stack.  Fill it with ocfs2_get_extent_tree() and drop it with
      ocfs2_put_extent_tree().  Now the callers don't have to ENOMEM, yet
      still safely ref the root_bh.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      dc0ce61a
    • Joel Becker's avatar
      ocfs2: Prefix the ocfs2_extent_tree structure. · ce1d9ea6
      Joel Becker authored
      The members of the ocfs2_extent_tree structure gain a prefix of 'et_'.
      All users are updated.
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      ce1d9ea6
    • Joel Becker's avatar
      ocfs2: Prefix the extent tree operations structure. · 35dc0aa3
      Joel Becker authored
      The ocfs2_extent_tree_operations structure gains a field prefix on its
      members.  The ->eo_sanity_check() operation gains a wrapper function for
      completeness.  All of the extent tree operation wrappers gain a
      consistent name (ocfs2_et_*()).
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      35dc0aa3
    • Mark Fasheh's avatar
      ocfs2: fix printk format warnings · ff1ec20e
      Mark Fasheh authored
      This patch fixes the following build warnings:
      
      fs/ocfs2/xattr.c: In function 'ocfs2_half_xattr_bucket':
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 7 has type 'long int'
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 8 has type 'long int'
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 7 has type 'long int'
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 8 has type 'long int'
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 7 has type 'long int'
      fs/ocfs2/xattr.c:3282: warning: format '%d' expects type 'int', but argument 8 has type 'long int'
      fs/ocfs2/xattr.c: In function 'ocfs2_xattr_set_entry_in_bucket':
      fs/ocfs2/xattr.c:4092: warning: format '%d' expects type 'int', but argument 6 has type 'size_t'
      fs/ocfs2/xattr.c:4092: warning: format '%d' expects type 'int', but argument 6 has type 'size_t'
      fs/ocfs2/xattr.c:4092: warning: format '%d' expects type 'int', but argument 6 has type 'size_t'
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      ff1ec20e
    • Tiger Yang's avatar
      ocfs2: Add incompatible flag for extended attribute · 8154da3d
      Tiger Yang authored
      This patch adds the s_incompat flag for extended attribute support. This
      helps us ensure that older versions of Ocfs2 or ocfs2-tools will not be able
      to mount a volume with xattr support.
      Signed-off-by: default avatarTiger Yang <tiger.yang@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      8154da3d
    • Tao Ma's avatar
      ocfs2: Delete all xattr buckets during inode removal · a3944256
      Tao Ma authored
      In inode removal, we need to iterate all the buckets, remove any
      externally-stored EA values and delete the xattr buckets.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      a3944256
    • Tao Ma's avatar
      ocfs2: Enable xattr set in index btree · 01225596
      Tao Ma authored
      Where the previous patches added the ability of list/get xattr in buckets
      for ocfs2, this patch enables ocfs2 to store large numbers of EAs.
      
      The original design doc is written by Mark Fasheh, and it can be found in
      http://oss.oracle.com/osswiki/OCFS2/DesignDocs/IndexedEATrees. I only had to
      make small modifications to it.
      
      First, because the bucket size is 4K, a new field named xh_free_start is added
      in ocfs2_xattr_header to indicate the next valid name/value offset in a bucket.
      It is used when we store new EA name/value. With this field, we can find the
      place more quickly and what's more, we don't need to sort the name/value every
      time to let the last entry indicate the next unused space. This makes the
      insert operation more efficient for blocksizes smaller than 4k.
      
      Because of the new xh_free_start, another field named as xh_name_value_len is
      also added in ocfs2_xattr_header. It records the total length of all the
      name/values in the bucket. We need this so that we can check it and defragment
      the bucket if there is not enough contiguous free space.
      
      An xattr insertion looks like this:
      1. xattr_index_block_find: find the right bucket by the name_hash, say bucketA.
      2. check whether there is enough space in bucketA. If yes, insert it directly
         and modify xh_free_start and xh_name_value_len accordingly. If not, check
         xh_name_value_len to see whether we can store this by defragment the bucket.
         If yes, defragment it and go on insertion.
      3. If defragement doesn't work, check whether there is new empty bucket in
         the clusters within this extent record. If yes, init the new bucket and move
         all the buckets after bucketA one by one to the next bucket. Move half of the
         entries in bucketA to the next bucket and go on insertion.
      4. If there is no new bucket, grow the extent tree.
      
      As for xattr deletion, we will delete an xattr bucket when all it's xattrs
      are removed and move all the buckets after it to the previous one. When all
      the xattr buckets in an extend record are freed, free this extend records
      from ocfs2_xattr_tree.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      01225596
    • Tao Ma's avatar
      ocfs2: Optionally limit extent size in ocfs2_insert_extent() · ca12b7c4
      Tao Ma authored
      In xattr bucket, we want to limit the maximum size of a btree leaf,
      otherwise we'll lose the benefits of hashing because we'll have to search
      large leaves.
      
      So add a new field in ocfs2_extent_tree which indicates the maximum leaf cluster
      size we want so that we can prevent ocfs2_insert_extent() from merging the leaf
      record even if it is contiguous with an adjacent record.
      
      Other btree types are not affected by this change.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      ca12b7c4
    • Tao Ma's avatar
      ocfs2: Add xattr lookup code xattr btrees · 589dc260
      Tao Ma authored
      Add code to lookup a given extended attribute in the xattr btree. Lookup
      follows this general scheme:
      
      1. Use ocfs2_xattr_get_rec to find the xattr extent record
      
      2. Find the xattr bucket within the extent which may contain this xattr
      
      3. Iterate the bucket to find the xattr. In ocfs2_xattr_block_get(), we need
         to recalcuate the block offset and name offset for the right position of
         name/value.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      589dc260
    • Tao Ma's avatar
      ocfs2: Add xattr bucket iteration for large numbers of EAs · 0c044f0b
      Tao Ma authored
      Ocfs2 breaks up xattr index tree leaves into 4k regions, called buckets.
      Attributes are stored within a given bucket, depending on hash value.
      
      After a discussion with Mark, we decided that the per-bucket index
      (xe_entry[]) would only exist in the 1st block of a bucket. Likewise,
      name/value pairs will not straddle more than one block. This allows the
      majority of operations to work directly on the buffer heads in a leaf block.
      
      This patch adds code to iterate the buckets in an EA. A new abstration of
      ocfs2_xattr_bucket is added. It records the bhs in this bucket and
      ocfs2_xattr_header. This keeps the code neat, improving readibility.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      0c044f0b