Whamcloud - gitweb
LU-1548 osd: move i_htree_lock to iam container
authorwangdi <di.wang@whamcloud.com>
Tue, 7 Aug 2012 21:40:45 +0000 (14:40 -0700)
committerOleg Drokin <green@whamcloud.com>
Mon, 13 Aug 2012 05:06:17 +0000 (01:06 -0400)
Move i_tree_lock from ldiskfs_inode to iam_container,
so to reduce ldiskfs_inode_info size.

Signed-off-by: wang di <di.wang@whamcloud.com>
Change-Id: I4277e73347380bcb3fd34e3d76f66b1d6ec881f5
Reviewed-on: http://review.whamcloud.com/3561
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
ldiskfs/kernel_patches/patches/ext4-pdir-fix-rhel6.patch
lustre/osd-ldiskfs/osd_iam.c
lustre/osd-ldiskfs/osd_iam.h

index fc7c791..419f386 100644 (file)
@@ -1,8 +1,8 @@
-Index: linux-2.6.32.i386/fs/ext4/ext4.h
+Index: linux-stage/fs/ext4/ext4.h
 ===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/ext4.h      2010-04-16 03:39:11.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/ext4.h   2010-04-16 04:27:41.000000000 +0530
-@@ -29,6 +29,7 @@
+--- linux-stage.orig/fs/ext4/ext4.h    2012-08-07 11:52:38.994200699 -0700
++++ linux-stage/fs/ext4/ext4.h 2012-08-07 12:28:19.497442862 -0700
+@@ -16,6 +16,7 @@
  #ifndef _EXT4_H
  #define _EXT4_H
  
@@ -10,22 +10,21 @@ Index: linux-2.6.32.i386/fs/ext4/ext4.h
  #include <linux/types.h>
  #include <linux/blkdev.h>
  #include <linux/magic.h>
-@@ -621,6 +622,10 @@
-       ext4_fsblk_t    i_file_acl;
+@@ -706,6 +707,9 @@
        __u32   i_dtime;
+       ext4_fsblk_t    i_file_acl;
  
 +      /* following fields for parallel directory operations -bzzz */
-+      struct dynlock   i_htree_lock;
 +      struct semaphore i_append_sem;
 +
        /*
         * i_block_group is the number of the block group which contains
         * this file's inode.  Constant across the lifetime of the inode,
-Index: linux-2.6.32.i386/fs/ext4/namei.c
+Index: linux-stage/fs/ext4/namei.c
 ===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/namei.c     2010-04-15 07:42:15.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/namei.c  2010-04-16 04:26:03.000000000 +0530
-@@ -54,6 +54,11 @@
+--- linux-stage.orig/fs/ext4/namei.c   2012-08-07 11:52:38.992199430 -0700
++++ linux-stage/fs/ext4/namei.c        2012-08-07 12:27:24.845281099 -0700
+@@ -53,6 +53,11 @@
                                        ext4_lblk_t *block, int *err)
  {
        struct buffer_head *bh;
@@ -37,7 +36,7 @@ Index: linux-2.6.32.i386/fs/ext4/namei.c
  
        *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
  
-@@ -66,7 +71,9 @@
+@@ -65,7 +70,9 @@
                        brelse(bh);
                        bh = NULL;
                }
@@ -47,15 +46,14 @@ Index: linux-2.6.32.i386/fs/ext4/namei.c
        return bh;
  }
  
-Index: linux-2.6.32.i386/fs/ext4/super.c
+Index: linux-stage/fs/ext4/super.c
 ===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/super.c     2010-04-16 03:39:11.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/super.c  2010-04-16 04:26:03.000000000 +0530
-@@ -700,6 +700,8 @@
+--- linux-stage.orig/fs/ext4/super.c   2012-08-07 11:52:39.009197356 -0700
++++ linux-stage/fs/ext4/super.c        2012-08-07 12:28:29.499112997 -0700
+@@ -749,6 +749,7 @@
  
        ei->vfs_inode.i_version = 1;
        ei->vfs_inode.i_data.writeback_index = 0;
-+      dynlock_init(&ei->i_htree_lock);
 +      sema_init(&ei->i_append_sem, 1);
        memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
        INIT_LIST_HEAD(&ei->i_prealloc_list);
index 49f56de..802f4f9 100644 (file)
@@ -171,6 +171,7 @@ int iam_container_init(struct iam_container *c,
         c->ic_descr  = descr;
         c->ic_object = inode;
         cfs_init_rwsem(&c->ic_sem);
+       dynlock_init(&c->ic_tree_lock);
         return 0;
 }
 EXPORT_SYMBOL(iam_container_init);
@@ -392,20 +393,21 @@ static int iam_leaf_load(struct iam_path *path)
         return err;
 }
 
-static void iam_unlock_htree(struct inode *dir, struct dynlock_handle *lh)
+static void iam_unlock_htree(struct iam_container *ic,
+                            struct dynlock_handle *lh)
 {
-        if (lh != NULL)
-                dynlock_unlock(&LDISKFS_I(dir)->i_htree_lock, lh);
+       if (lh != NULL)
+               dynlock_unlock(&ic->ic_tree_lock, lh);
 }
 
 
 static void iam_leaf_unlock(struct iam_leaf *leaf)
 {
         if (leaf->il_lock != NULL) {
-                iam_unlock_htree(iam_leaf_container(leaf)->ic_object,
-                                leaf->il_lock);
-                do_corr(schedule());
-                leaf->il_lock = NULL;
+               iam_unlock_htree(iam_leaf_container(leaf),
+                                leaf->il_lock);
+               do_corr(schedule());
+               leaf->il_lock = NULL;
         }
 }
 
@@ -643,25 +645,24 @@ EXPORT_SYMBOL(iam_it_fini);
  * this locking primitives are used to protect parts
  * of dir's htree. protection unit is block: leaf or index
  */
-struct dynlock_handle *iam_lock_htree(struct inode *dir, unsigned long value,
-                                     enum dynlock_type lt)
+static struct dynlock_handle *iam_lock_htree(struct iam_container *ic,
+                                            unsigned long value,
+                                            enum dynlock_type lt)
 {
-        return dynlock_lock(&LDISKFS_I(dir)->i_htree_lock, value, lt, GFP_NOFS);
+       return dynlock_lock(&ic->ic_tree_lock, value, lt, GFP_NOFS);
 }
 
-
-
 int iam_index_lock(struct iam_path *path, struct dynlock_handle **lh)
 {
         struct iam_frame *f;
 
-        for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
-                do_corr(schedule());
-                *lh = iam_lock_htree(iam_path_obj(path), f->curidx, DLT_READ);
-                if (*lh == NULL)
-                        return -ENOMEM;
-        }
-        return 0;
+       for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
+               do_corr(schedule());
+               *lh = iam_lock_htree(path->ip_container, f->curidx, DLT_READ);
+               if (*lh == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
 }
 
 /*
@@ -947,12 +948,13 @@ int iam_lookup_lock(struct iam_path *path,
         dir = iam_path_obj(path);
         while ((result = __iam_path_lookup(path)) == 0) {
                 do_corr(schedule());
-                *dl = iam_lock_htree(dir, path->ip_frame->leaf, lt);
-                if (*dl == NULL) {
-                        iam_path_fini(path);
-                        result = -ENOMEM;
-                        break;
-                }
+               *dl = iam_lock_htree(path->ip_container, path->ip_frame->leaf,
+                                    lt);
+               if (*dl == NULL) {
+                       iam_path_fini(path);
+                       result = -ENOMEM;
+                       break;
+               }
                 do_corr(schedule());
                 /*
                  * while locking leaf we just found may get split so we need
@@ -960,7 +962,7 @@ int iam_lookup_lock(struct iam_path *path,
                  */
                 if (iam_check_full_path(path, 1) == 0)
                         break;
-                iam_unlock_htree(dir, *dl);
+               iam_unlock_htree(path->ip_container, *dl);
                 *dl = NULL;
                 iam_path_fini(path);
         }
@@ -1294,15 +1296,16 @@ static inline int iam_index_advance(struct iam_path *path)
         return iam_htree_advance(iam_path_obj(path), 0, path, NULL, 0);
 }
 
-static void iam_unlock_array(struct inode *dir, struct dynlock_handle **lh)
+static void iam_unlock_array(struct iam_container *ic,
+                            struct dynlock_handle **lh)
 {
         int i;
 
         for (i = 0; i < DX_MAX_TREE_HEIGHT; ++i, ++lh) {
-                if (*lh != NULL) {
-                        iam_unlock_htree(dir, *lh);
-                        *lh = NULL;
-                }
+               if (*lh != NULL) {
+                       iam_unlock_htree(ic, *lh);
+                       *lh = NULL;
+               }
         }
 }
 /*
@@ -1338,7 +1341,7 @@ int iam_index_next(struct iam_container *c, struct iam_path *path)
                         break;
                 }
                 do {
-                        iam_unlock_array(object, lh);
+                       iam_unlock_array(c, lh);
 
                         iam_path_release(path);
                         do_corr(schedule());
@@ -1370,13 +1373,13 @@ int iam_index_next(struct iam_container *c, struct iam_path *path)
                                 result = iam_check_full_path(path, 0);
                                 if (result != 0)
                                         break;
-                                iam_unlock_array(object, lh);
+                               iam_unlock_array(c, lh);
                         }
                 } while (result == -EAGAIN);
                 if (result < 0)
                         break;
         }
-        iam_unlock_array(object, lh);
+       iam_unlock_array(c, lh);
         return result;
 }
 
@@ -1429,9 +1432,10 @@ int iam_it_next(struct iam_iterator *it)
                         result = iam_index_next(iam_it_container(it), path);
                         assert_corr(iam_leaf_is_locked(leaf));
                         if (result == 1) {
-                                struct dynlock_handle *lh;
-                                lh = iam_lock_htree(obj, path->ip_frame->leaf,
-                                                   DLT_WRITE);
+                               struct dynlock_handle *lh;
+                               lh = iam_lock_htree(iam_it_container(it),
+                                                   path->ip_frame->leaf,
+                                                   DLT_WRITE);
                                 if (lh != NULL) {
                                         iam_leaf_fini(leaf);
                                         leaf->il_lock = lh;
@@ -1601,7 +1605,7 @@ static int iam_new_leaf(handle_t *handle, struct iam_leaf *leaf)
         if (new_leaf != NULL) {
                 struct dynlock_handle *lh;
 
-                lh = iam_lock_htree(obj, blknr, DLT_WRITE);
+               lh = iam_lock_htree(c, blknr, DLT_WRITE);
                 do_corr(schedule());
                 if (lh != NULL) {
                         iam_leaf_ops(leaf)->init_new(c, new_leaf);
@@ -1616,7 +1620,7 @@ static int iam_new_leaf(handle_t *handle, struct iam_leaf *leaf)
                                 leaf->il_lock = lh;
                                 path->ip_frame->leaf = blknr;
                         } else
-                                iam_unlock_htree(obj, lh);
+                               iam_unlock_htree(path->ip_container, lh);
                         do_corr(schedule());
                         err = iam_txn_dirty(handle, path, new_leaf);
                         brelse(new_leaf);
@@ -1756,12 +1760,13 @@ int split_index_node(handle_t *handle, struct iam_path *path,
          * Lock all nodes, bottom to top.
          */
         for (frame = path->ip_frame, i = nr_splet; i >= 0; --i, --frame) {
-                do_corr(schedule());
-                lock[i] = iam_lock_htree(dir, frame->curidx, DLT_WRITE);
-                if (lock[i] == NULL) {
-                        err = -ENOMEM;
-                        goto cleanup;
-                }
+               do_corr(schedule());
+               lock[i] = iam_lock_htree(path->ip_container, frame->curidx,
+                                        DLT_WRITE);
+               if (lock[i] == NULL) {
+                       err = -ENOMEM;
+                       goto cleanup;
+               }
         }
 
         /*
@@ -1792,11 +1797,12 @@ int split_index_node(handle_t *handle, struct iam_path *path,
                     descr->id_ops->id_node_init(path->ip_container,
                                                 bh_new[i], 0) != 0)
                         goto cleanup;
-                new_lock[i] = iam_lock_htree(dir, newblock[i], DLT_WRITE);
-                if (new_lock[i] == NULL) {
-                        err = -ENOMEM;
-                        goto cleanup;
-                }
+               new_lock[i] = iam_lock_htree(path->ip_container, newblock[i],
+                                            DLT_WRITE);
+               if (new_lock[i] == NULL) {
+                       err = -ENOMEM;
+                       goto cleanup;
+               }
                 do_corr(schedule());
                 BUFFER_TRACE(frame->bh, "get_write_access");
                 err = ldiskfs_journal_get_write_access(handle, frame->bh);
@@ -1936,8 +1942,8 @@ journal_error:
         ldiskfs_std_error(dir->i_sb, err);
 
 cleanup:
-        iam_unlock_array(dir, lock);
-        iam_unlock_array(dir, new_lock);
+       iam_unlock_array(path->ip_container, lock);
+       iam_unlock_array(path->ip_container, new_lock);
 
         assert_corr(err || iam_frame_is_locked(path, path->ip_frame));
 
@@ -1992,7 +1998,7 @@ static int iam_add_rec(handle_t *handle, struct iam_iterator *it,
                                         err = iam_txn_dirty(handle, path,
                                                             path->ip_frame->bh);
                         }
-                        iam_unlock_htree(iam_path_obj(path), lh);
+                       iam_unlock_htree(path->ip_container, lh);
                         do_corr(schedule());
                 }
                 if (err == 0) {
index 98da250..293f2e3 100644 (file)
@@ -462,6 +462,7 @@ struct iam_container {
          * read-write lock protecting index consistency.
          */
         cfs_rw_semaphore_t   ic_sem;
+       struct dynlock       ic_tree_lock;
 };
 
 /*
@@ -910,18 +911,12 @@ static inline struct iam_ikey *iam_path_ikey(const struct iam_path *path,
         return path->ip_data->ipd_key_scratch[nr];
 }
 
-
-static inline struct dynlock *path_dynlock(struct iam_path *path)
-{
-        return &LDISKFS_I(iam_path_obj(path))->i_htree_lock;
-}
-
 static inline int iam_leaf_is_locked(const struct iam_leaf *leaf)
 {
         int result;
 
-        result = dynlock_is_locked(path_dynlock(leaf->il_path),
-                                   leaf->il_curidx);
+       result = dynlock_is_locked(&iam_leaf_container(leaf)->ic_tree_lock,
+                                  leaf->il_curidx);
         if (!result)
                 dump_stack();
         return result;
@@ -932,7 +927,8 @@ static inline int iam_frame_is_locked(struct iam_path *path,
 {
         int result;
 
-        result = dynlock_is_locked(path_dynlock(path), frame->curidx);
+       result = dynlock_is_locked(&path->ip_container->ic_tree_lock,
+                                  frame->curidx);
         if (!result)
                 dump_stack();
         return result;