]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch
diff --git a/src/patches/suse-2.6.27.31/patches.suse/ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch b/src/patches/suse-2.6.27.31/patches.suse/ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch
new file mode 100644 (file)
index 0000000..68e7d70
--- /dev/null
@@ -0,0 +1,240 @@
+From: Joel Becker <joel.becker@oracle.com>
+Date: Mon, 27 Oct 2008 15:18:29 -0700
+Subject: ocfs2: Use buckets in ocfs2_xattr_create_index_block().
+Patch-mainline: 2.6.29
+
+Use the ocfs2_xattr_bucket abstraction in
+ocfs2_xattr_create_index_block() and its helpers.  We get more efficient
+reads, a lot less buffer_head munging, and nicer code to boot.  While
+we're at it, ocfs2_xattr_update_xattr_search() becomes void.
+
+Signed-off-by: Joel Becker <joel.becker@oracle.com>
+Signed-off-by: Mark Fasheh <mfasheh@suse.com>
+---
+ fs/ocfs2/xattr.c |  114 +++++++++++++++--------------------------------------
+ 1 files changed, 32 insertions(+), 82 deletions(-)
+
+diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
+index 46986c6..76969b9 100644
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -2649,32 +2649,34 @@ static void swap_xe(void *a, void *b, int size)
+ /*
+  * When the ocfs2_xattr_block is filled up, new bucket will be created
+  * and all the xattr entries will be moved to the new bucket.
++ * The header goes at the start of the bucket, and the names+values are
++ * filled from the end.  This is why *target starts as the last buffer.
+  * Note: we need to sort the entries since they are not saved in order
+  * in the ocfs2_xattr_block.
+  */
+ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
+                                          struct buffer_head *xb_bh,
+-                                         struct buffer_head *xh_bh,
+-                                         struct buffer_head *data_bh)
++                                         struct ocfs2_xattr_bucket *bucket)
+ {
+       int i, blocksize = inode->i_sb->s_blocksize;
++      int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
+       u16 offset, size, off_change;
+       struct ocfs2_xattr_entry *xe;
+       struct ocfs2_xattr_block *xb =
+                               (struct ocfs2_xattr_block *)xb_bh->b_data;
+       struct ocfs2_xattr_header *xb_xh = &xb->xb_attrs.xb_header;
+-      struct ocfs2_xattr_header *xh =
+-                              (struct ocfs2_xattr_header *)xh_bh->b_data;
++      struct ocfs2_xattr_header *xh = bucket_xh(bucket);
+       u16 count = le16_to_cpu(xb_xh->xh_count);
+-      char *target = xh_bh->b_data, *src = xb_bh->b_data;
++      char *src = xb_bh->b_data;
++      char *target = bucket_block(bucket, blks - 1);
+       mlog(0, "cp xattr from block %llu to bucket %llu\n",
+            (unsigned long long)xb_bh->b_blocknr,
+-           (unsigned long long)xh_bh->b_blocknr);
++           (unsigned long long)bucket_blkno(bucket));
++
++      for (i = 0; i < blks; i++)
++              memset(bucket_block(bucket, i), 0, blocksize);
+-      memset(xh_bh->b_data, 0, blocksize);
+-      if (data_bh)
+-              memset(data_bh->b_data, 0, blocksize);
+       /*
+        * Since the xe_name_offset is based on ocfs2_xattr_header,
+        * there is a offset change corresponding to the change of
+@@ -2686,8 +2688,6 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
+       size = blocksize - offset;
+       /* copy all the names and values. */
+-      if (data_bh)
+-              target = data_bh->b_data;
+       memcpy(target + offset, src + offset, size);
+       /* Init new header now. */
+@@ -2697,7 +2697,7 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
+       xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE - size);
+       /* copy all the entries. */
+-      target = xh_bh->b_data;
++      target = bucket_block(bucket, 0);
+       offset = offsetof(struct ocfs2_xattr_header, xh_entries);
+       size = count * sizeof(struct ocfs2_xattr_entry);
+       memcpy(target + offset, (char *)xb_xh + offset, size);
+@@ -2723,42 +2723,24 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
+  * While if the entry is in index b-tree, "bucket" indicates the
+  * real place of the xattr.
+  */
+-static int ocfs2_xattr_update_xattr_search(struct inode *inode,
+-                                         struct ocfs2_xattr_search *xs,
+-                                         struct buffer_head *old_bh,
+-                                         struct buffer_head *new_bh)
++static void ocfs2_xattr_update_xattr_search(struct inode *inode,
++                                          struct ocfs2_xattr_search *xs,
++                                          struct buffer_head *old_bh)
+ {
+-      int ret = 0;
+       char *buf = old_bh->b_data;
+       struct ocfs2_xattr_block *old_xb = (struct ocfs2_xattr_block *)buf;
+       struct ocfs2_xattr_header *old_xh = &old_xb->xb_attrs.xb_header;
+-      int i, blocksize = inode->i_sb->s_blocksize;
+-      u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
++      int i;
+-      xs->bucket->bu_bhs[0] = new_bh;
+-      get_bh(new_bh);
+       xs->header = bucket_xh(xs->bucket);
+-
+-      xs->base = new_bh->b_data;
++      xs->base = bucket_block(xs->bucket, 0);
+       xs->end = xs->base + inode->i_sb->s_blocksize;
+-      if (!xs->not_found) {
+-              if (OCFS2_XATTR_BUCKET_SIZE != blocksize) {
+-                      ret = ocfs2_read_blocks(inode,
+-                                      bucket_blkno(xs->bucket) + 1,
+-                                      blk_per_bucket - 1, &xs->bucket->bu_bhs[1],
+-                                      0);
+-                      if (ret) {
+-                              mlog_errno(ret);
+-                              return ret;
+-                      }
+-
+-              }
+-              i = xs->here - old_xh->xh_entries;
+-              xs->here = &xs->header->xh_entries[i];
+-      }
++      if (xs->not_found)
++              return;
+-      return ret;
++      i = xs->here - old_xh->xh_entries;
++      xs->here = &xs->header->xh_entries[i];
+ }
+ static int ocfs2_xattr_create_index_block(struct inode *inode,
+@@ -2771,18 +2753,17 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+       struct ocfs2_inode_info *oi = OCFS2_I(inode);
+       struct ocfs2_alloc_context *data_ac;
+-      struct buffer_head *xh_bh = NULL, *data_bh = NULL;
+       struct buffer_head *xb_bh = xs->xattr_bh;
+       struct ocfs2_xattr_block *xb =
+                       (struct ocfs2_xattr_block *)xb_bh->b_data;
+       struct ocfs2_xattr_tree_root *xr;
+       u16 xb_flags = le16_to_cpu(xb->xb_flags);
+-      u16 bpb = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
+       mlog(0, "create xattr index block for %llu\n",
+            (unsigned long long)xb_bh->b_blocknr);
+       BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
++      BUG_ON(!xs->bucket);
+       ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
+       if (ret) {
+@@ -2798,10 +2779,10 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
+       down_write(&oi->ip_alloc_sem);
+       /*
+-       * 3 more credits, one for xattr block update, one for the 1st block
+-       * of the new xattr bucket and one for the value/data.
++       * We need more credits.  One for the xattr block update and one
++       * for each block of the new xattr bucket.
+        */
+-      credits += 3;
++      credits += 1 + ocfs2_blocks_per_xattr_bucket(inode->i_sb);
+       handle = ocfs2_start_trans(osb, credits);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+@@ -2832,51 +2813,23 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
+       mlog(0, "allocate 1 cluster from %llu to xattr block\n",
+            (unsigned long long)blkno);
+-      xh_bh = sb_getblk(inode->i_sb, blkno);
+-      if (!xh_bh) {
+-              ret = -EIO;
++      ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
++      if (ret) {
+               mlog_errno(ret);
+               goto out_commit;
+       }
+-      ocfs2_set_new_buffer_uptodate(inode, xh_bh);
+-
+-      ret = ocfs2_journal_access(handle, inode, xh_bh,
+-                                 OCFS2_JOURNAL_ACCESS_CREATE);
++      ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
++                                              OCFS2_JOURNAL_ACCESS_CREATE);
+       if (ret) {
+               mlog_errno(ret);
+               goto out_commit;
+       }
+-      if (bpb > 1) {
+-              data_bh = sb_getblk(inode->i_sb, blkno + bpb - 1);
+-              if (!data_bh) {
+-                      ret = -EIO;
+-                      mlog_errno(ret);
+-                      goto out_commit;
+-              }
+-
+-              ocfs2_set_new_buffer_uptodate(inode, data_bh);
+-
+-              ret = ocfs2_journal_access(handle, inode, data_bh,
+-                                         OCFS2_JOURNAL_ACCESS_CREATE);
+-              if (ret) {
+-                      mlog_errno(ret);
+-                      goto out_commit;
+-              }
+-      }
+-
+-      ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xh_bh, data_bh);
+-
+-      ocfs2_journal_dirty(handle, xh_bh);
+-      if (data_bh)
+-              ocfs2_journal_dirty(handle, data_bh);
++      ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
++      ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
+-      ret = ocfs2_xattr_update_xattr_search(inode, xs, xb_bh, xh_bh);
+-      if (ret) {
+-              mlog_errno(ret);
+-              goto out_commit;
+-      }
++      ocfs2_xattr_update_xattr_search(inode, xs, xb_bh);
+       /* Change from ocfs2_xattr_header to ocfs2_xattr_tree_root */
+       memset(&xb->xb_attrs, 0, inode->i_sb->s_blocksize -
+@@ -2911,9 +2864,6 @@ out:
+       if (data_ac)
+               ocfs2_free_alloc_context(data_ac);
+-      brelse(xh_bh);
+-      brelse(data_bh);
+-
+       return ret;
+ }
+-- 
+1.5.6
+