Whamcloud - gitweb
0. iam: pub r5 hash back.
authornikita <nikita>
Sat, 4 Nov 2006 21:14:11 +0000 (21:14 +0000)
committernikita <nikita>
Sat, 4 Nov 2006 21:14:11 +0000 (21:14 +0000)
1. iam/osd: fix a race that caused 11150.

lustre/kernel_patches/patches/ext3-iam-separate.patch
lustre/kernel_patches/patches/ext3-iam-uapi.patch
lustre/kernel_patches/patches/ext3-pdirops-2.6.9.patch
lustre/obdclass/mea.c
lustre/osd/osd_handler.c

index a4903b0..d11300c 100644 (file)
@@ -15,7 +15,7 @@ Index: iam/fs/ext3/iam.c
 ===================================================================
 --- iam.orig/fs/ext3/iam.c
 +++ iam/fs/ext3/iam.c
-@@ -0,0 +1,1407 @@
+@@ -0,0 +1,1402 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -1110,11 +1110,6 @@ Index: iam/fs/ext3/iam.c
 +                                assert_corr(lh != NULL);
 +                                do_corr(schedule());
 +                                err = iam_new_leaf(handle, leaf);
-+                                /*
-+                                 * refresh @leaf, as split may retarget path
-+                                 * to the new leaf node.
-+                                 */
-+                                leaf = &path->ip_leaf;
 +                                if (err == 0)
 +                                        err = iam_txn_dirty(handle, path,
 +                                                            path->ip_frame->bh);
@@ -1427,7 +1422,7 @@ Index: iam/fs/ext3/iam_htree.c
 ===================================================================
 --- iam.orig/fs/ext3/iam_htree.c
 +++ iam/fs/ext3/iam_htree.c
-@@ -0,0 +1,683 @@
+@@ -0,0 +1,682 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -2044,8 +2039,7 @@ Index: iam/fs/ext3/iam_htree.c
 +              return NULL;
 +}
 +
-+static void iam_htree_ipd_free(const struct iam_container *c,
-+                         struct iam_path_descr *ipd)
++static void iam_htree_ipd_free(struct iam_path_descr *ipd)
 +{
 +      struct iam_path_compat *ipc;
 +
@@ -2115,7 +2109,7 @@ Index: iam/fs/ext3/iam_lfix.c
 ===================================================================
 --- iam.orig/fs/ext3/iam_lfix.c
 +++ iam/fs/ext3/iam_lfix.c
-@@ -0,0 +1,682 @@
+@@ -0,0 +1,676 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -2700,12 +2694,6 @@ Index: iam/fs/ext3/iam_lfix.c
 +        return iam_ipd_alloc(c->ic_descr->id_ikey_size);
 +}
 +
-+static void iam_lfix_ipd_free(const struct iam_container *c,
-+                              struct iam_path_descr *ipd)
-+{
-+        iam_ipd_free(ipd);
-+}
-+
 +static struct iam_operations iam_lfix_ops = {
 +        .id_root_ptr    = iam_lfix_root_ptr,
 +        .id_node_read   = iam_node_read,
@@ -2715,7 +2703,7 @@ Index: iam/fs/ext3/iam_lfix.c
 +        .id_ikeycmp     = iam_lfix_ikeycmp,
 +        .id_root_inc    = iam_lfix_root_inc,
 +        .id_ipd_alloc   = iam_lfix_ipd_alloc,
-+        .id_ipd_free    = iam_lfix_ipd_free,
++        .id_ipd_free    = iam_ipd_free,
 +        .id_name        = "lfix"
 +};
 +
@@ -2802,7 +2790,7 @@ Index: iam/fs/ext3/iam_lvar.c
 ===================================================================
 --- iam.orig/fs/ext3/iam_lvar.c
 +++ iam/fs/ext3/iam_lvar.c
-@@ -0,0 +1,1006 @@
+@@ -0,0 +1,1011 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -2974,8 +2962,8 @@ Index: iam/fs/ext3/iam_lvar.c
 +        return ((void *)ent) + e_size(leaf, ent);
 +}
 +
-+#define LVAR_HASH_TEA    (1)
-+#define LVAR_HASH_R5     (0)
++#define LVAR_HASH_TEA    (0)
++#define LVAR_HASH_R5     (1)
 +#define LVAR_HASH_PREFIX (0)
 +
 +static inline lvar_hash_t get_hash(const struct iam_container *bag,
@@ -3079,17 +3067,21 @@ Index: iam/fs/ext3/iam_lvar.c
 +#if EXT3_INVARIANT_ON
 +static int n_invariant(const struct iam_leaf *leaf)
 +{
++        struct iam_path        *path;
 +        struct lvar_leaf_entry *scan;
 +        struct lvar_leaf_entry *end;
 +        lvar_hash_t             hash;
 +        lvar_hash_t             nexthash;
++        lvar_hash_t             starthash;
 +
-+        end = n_end(leaf);
++        end  = n_end(leaf);
 +        hash = 0;
++        path = leaf->il_path;
 +
 +        if (h_used(n_head(leaf)) > blocksize(leaf))
 +                return 0;
 +
++        starthash = *(lvar_hash_t *)iam_ikey_at(path, path->ip_frame->at);
 +        for (scan = n_start(leaf); scan < end; scan = e_next(leaf, scan)) {
 +                nexthash = e_hash(scan);
 +                if (nexthash != get_hash(iam_leaf_container(leaf),
@@ -3097,6 +3089,13 @@ Index: iam/fs/ext3/iam_lvar.c
 +                        BREAKPOINT();
 +                        return 0;
 +                }
++                if (nexthash < starthash) {
++                        n_print(leaf);
++                        printk("%#x < %#x\n", nexthash, starthash);
++                        dump_stack();
++                        BREAKPOINT();
++                        return 0;
++                }
 +                if (nexthash < hash) {
 +                        BREAKPOINT();
 +                        return 0;
@@ -3624,12 +3623,6 @@ Index: iam/fs/ext3/iam_lvar.c
 +        return iam_ipd_alloc(c->ic_descr->id_ikey_size);
 +}
 +
-+static void lvar_ipd_free(const struct iam_container *c,
-+                          struct iam_path_descr *ipd)
-+{
-+        iam_ipd_free(ipd);
-+}
-+
 +static int root_limit(int rootgap, int blocksize, int size)
 +{
 +        int limit;
@@ -3766,7 +3759,7 @@ Index: iam/fs/ext3/iam_lvar.c
 +        .id_ikeycmp     = lvar_ikeycmp,
 +        .id_root_inc    = lvar_root_inc,
 +        .id_ipd_alloc   = lvar_ipd_alloc,
-+        .id_ipd_free    = lvar_ipd_free,
++        .id_ipd_free    = iam_ipd_free,
 +        .id_name        = "lvar"
 +};
 +
index 75e775f..082658a 100644 (file)
@@ -100,7 +100,7 @@ Index: iam/fs/ext3/iam-uapi.c
 ===================================================================
 --- iam.orig/fs/ext3/iam-uapi.c
 +++ iam/fs/ext3/iam-uapi.c
-@@ -0,0 +1,368 @@
+@@ -0,0 +1,367 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -243,8 +243,7 @@ Index: iam/fs/ext3/iam-uapi.c
 +        iam_it_put(&info->ipi_it);
 +        iam_it_fini(&info->ipi_it);
 +        if (info->ipi_ipd != NULL)
-+                info->ipi_bag.ic_descr->id_ops->id_ipd_free(&info->ipi_bag,
-+                                                            info->ipi_ipd);
++                info->ipi_bag.ic_descr->id_ops->id_ipd_free(info->ipi_ipd);
 +        iam_container_fini(&info->ipi_bag);
 +}
 +
index 2f7db65..5702631 100644 (file)
@@ -918,7 +918,17 @@ Index: iam/include/linux/lustre_iam.h
  };
  
  /*
-@@ -331,6 +349,7 @@ struct iam_leaf_operations {
+@@ -271,8 +289,7 @@ struct iam_operations {
+                                          struct iam_frame *frame);
+         struct iam_path_descr *(*id_ipd_alloc)(const struct iam_container *c);
+-        void (*id_ipd_free)(const struct iam_container *c,
+-                            struct iam_path_descr *ipd);
++        void (*id_ipd_free)(struct iam_path_descr *ipd);
+         /*
+          * Format name.
+          */
+@@ -331,6 +348,7 @@ struct iam_leaf_operations {
          void (*rec_set)(struct iam_leaf *l, const struct iam_rec *r);
  
        int (*key_cmp)(const struct iam_leaf *l, const struct iam_key *k);
@@ -926,7 +936,7 @@ Index: iam/include/linux/lustre_iam.h
  
          int (*key_size)(const struct iam_leaf *l);
          /*
-@@ -473,7 +492,7 @@ struct iam_path_compat {
+@@ -473,7 +491,7 @@ struct iam_path_compat {
        struct iam_container ipc_container;
        __u32                 ipc_scratch[DX_SCRATCH_KEYS];
        struct dx_hash_info  *ipc_hinfo;
@@ -935,7 +945,7 @@ Index: iam/include/linux/lustre_iam.h
        struct iam_path_descr ipc_descr;
          struct dx_hash_info   ipc_hinfo_area;
  };
-@@ -848,7 +867,9 @@ static inline struct iam_ikey *iam_path_
+@@ -848,7 +866,9 @@ static inline struct iam_ikey *iam_path_
        return path->ip_data->ipd_key_scratch[nr];
  }
  
@@ -946,7 +956,7 @@ Index: iam/include/linux/lustre_iam.h
  void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
                     u32 hash, u32 block);
  int dx_index_is_compat(struct iam_path *path);
-@@ -858,7 +879,8 @@ int ext3_htree_next_block(struct inode *
+@@ -858,7 +878,8 @@ int ext3_htree_next_block(struct inode *
  
  struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
                                u32 *block, int *err);
@@ -956,7 +966,7 @@ Index: iam/include/linux/lustre_iam.h
  struct ext3_dir_entry_2 *split_entry(struct inode *dir,
                                     struct ext3_dir_entry_2 *de,
                                     unsigned long ino, mode_t mode,
-@@ -874,6 +896,10 @@ struct ext3_dir_entry_2 *move_entries(st
+@@ -874,6 +895,10 @@ struct ext3_dir_entry_2 *move_entries(st
  
  extern struct iam_descr iam_htree_compat_param;
  
index 030cf61..2d68aa7 100644 (file)
@@ -64,8 +64,8 @@ static int mea_all_chars_hash(int count, char *name, int namelen)
 #ifdef __KERNEL__
 /* This hash calculate method must be same as the lvar hash method */
 
-#define LVAR_HASH_TEA    (1)
-#define LVAR_HASH_R5     (0)
+#define LVAR_HASH_TEA    (0)
+#define LVAR_HASH_R5     (1)
 #define LVAR_HASH_PREFIX (0)
 
 static __u32 hash_build(char *name, int namelen)
index c145091..1f643e3 100644 (file)
@@ -74,9 +74,6 @@
 #include "osd_igif.h"
 
 struct osd_object {
-        /*
-         * Mutable fields (like ->do_index_ops) are protected by ->oo_guard.
-         */
         struct dt_object       oo_dt;
         /*
          * Inode for file system object represented by this osd_object. This
@@ -89,11 +86,6 @@ struct osd_object {
         struct rw_semaphore    oo_sem;
         struct iam_container   oo_container;
         struct iam_descr       oo_descr;
-        /*
-         * Protected by ->oo_guard.
-         */
-        struct iam_path_descr *oo_ipd;
-        spinlock_t             oo_guard;
         const struct lu_env   *oo_owner;
 };
 
@@ -343,7 +335,6 @@ static struct lu_object *osd_object_alloc(const struct lu_env *env,
                 mo->oo_dt.do_ops = &osd_obj_ops;
                 l->lo_ops = &osd_lu_obj_ops;
                 init_rwsem(&mo->oo_sem);
-                spin_lock_init(&mo->oo_guard);
                 return l;
         } else
                 return NULL;
@@ -394,6 +385,19 @@ static void osd_object_free(const struct lu_env *env, struct lu_object *l)
         OBD_FREE_PTR(obj);
 }
 
+static struct iam_path_descr *osd_ipd_get(const struct lu_env *env,
+                                          const struct iam_container *bag)
+{
+        return bag->ic_descr->id_ops->id_ipd_alloc(bag);
+}
+
+static void osd_ipd_put(const struct lu_env *env,
+                        const struct iam_container *bag,
+                        struct iam_path_descr *ipd)
+{
+        bag->ic_descr->id_ops->id_ipd_free(ipd);
+}
+
 /*
  * Concurrency: no concurrent access is possible that late in object
  * life-cycle.
@@ -403,14 +407,9 @@ static void osd_index_fini(struct osd_object *o)
         struct iam_container *bag;
 
         bag = &o->oo_container;
-        if (o->oo_ipd != NULL) {
-                LASSERT(bag->ic_descr->id_ops->id_ipd_free != NULL);
-                bag->ic_descr->id_ops->id_ipd_free(&o->oo_container, o->oo_ipd);
-                o->oo_ipd = NULL;
-        }
         if (o->oo_inode != NULL) {
-                if (o->oo_container.ic_object == o->oo_inode)
-                        iam_container_fini(&o->oo_container);
+                if (bag->ic_object == o->oo_inode)
+                        iam_container_fini(bag);
         }
 }
 
@@ -1525,33 +1524,6 @@ static int osd_index_probe(const struct lu_env *env, struct osd_object *o,
                                 * writable */);
 }
 
-static int osd_index_setup(const struct lu_env *env, struct osd_object *obj,
-                           struct iam_container *bag)
-{
-        struct iam_path_descr *ipd;
-        int result;
-
-        ipd = bag->ic_descr->id_ops->id_ipd_alloc(bag);
-        if (ipd != NULL) {
-                spin_lock(&obj->oo_guard);
-                if (obj->oo_ipd == NULL) {
-                        obj->oo_ipd = ipd;
-                        obj->oo_dt.do_index_ops = &osd_index_ops;
-                } else {
-                        /*
-                         * Oops, index was setup concurrently.
-                         */
-                        LASSERT(obj->oo_dt.do_index_ops == &osd_index_ops);
-                        LASSERT(bag->ic_descr->id_ops->id_ipd_free != NULL);
-                        bag->ic_descr->id_ops->id_ipd_free(bag, ipd);
-                }
-                spin_unlock(&obj->oo_guard);
-                result = 0;
-        } else
-                result = -ENOMEM;
-        return result;
-}
-
 /*
  * Concurrency: no external locking is necessary.
  */
@@ -1575,7 +1547,7 @@ static int osd_index_try(const struct lu_env *env, struct dt_object *dt,
                 if (result == 0) {
                         result = iam_container_setup(bag);
                         if (result == 0)
-                                result = osd_index_setup(env, obj, bag);
+                                obj->oo_dt.do_index_ops = &osd_index_ops;
                 }
         } else
                 result = 0;
@@ -1597,25 +1569,29 @@ static int osd_index_delete(const struct lu_env *env, struct dt_object *dt,
 {
         struct osd_object     *obj = osd_dt_obj(dt);
         struct osd_thandle    *oh;
+        struct iam_path_descr *ipd;
+        struct iam_container  *bag = &obj->oo_container;
         int rc;
 
         ENTRY;
 
         LASSERT(osd_invariant(obj));
         LASSERT(dt_object_exists(dt));
-        LASSERT(obj->oo_container.ic_object == obj->oo_inode);
-        LASSERT(obj->oo_ipd != NULL);
+        LASSERT(bag->ic_object == obj->oo_inode);
         LASSERT(handle != NULL);
 
         if (osd_object_auth(env, dt, capa, CAPA_OPC_INDEX_DELETE))
                 RETURN(-EACCES);
 
+        ipd = osd_ipd_get(env, bag);
+        if (ipd == NULL)
+                RETURN(-ENOMEM);
+
         oh = container_of0(handle, struct osd_thandle, ot_super);
         LASSERT(oh->ot_handle != NULL);
 
-        rc = iam_delete(oh->ot_handle, &obj->oo_container,
-                        (const struct iam_key *)key, obj->oo_ipd);
-
+        rc = iam_delete(oh->ot_handle, bag, (const struct iam_key *)key, ipd);
+        osd_ipd_put(env, bag, ipd);
         LASSERT(osd_invariant(obj));
         RETURN(rc);
 }
@@ -1624,22 +1600,27 @@ static int osd_index_lookup(const struct lu_env *env, struct dt_object *dt,
                             struct dt_rec *rec, const struct dt_key *key,
                             struct lustre_capa *capa)
 {
-        struct osd_object *obj = osd_dt_obj(dt);
+        struct osd_object     *obj = osd_dt_obj(dt);
+        struct iam_path_descr *ipd;
+        struct iam_container  *bag = &obj->oo_container;
         int rc;
 
         ENTRY;
 
         LASSERT(osd_invariant(obj));
         LASSERT(dt_object_exists(dt));
-        LASSERT(obj->oo_container.ic_object == obj->oo_inode);
-        LASSERT(obj->oo_ipd != NULL);
+        LASSERT(bag->ic_object == obj->oo_inode);
 
         if (osd_object_auth(env, dt, capa, CAPA_OPC_INDEX_LOOKUP))
                 return -EACCES;
 
-        rc = iam_lookup(&obj->oo_container, (const struct iam_key *)key,
-                        (struct iam_rec *)rec, obj->oo_ipd);
+        ipd = osd_ipd_get(env, bag);
+        if (ipd == NULL)
+                RETURN(-ENOMEM);
 
+        rc = iam_lookup(bag, (const struct iam_key *)key,
+                        (struct iam_rec *)rec, ipd);
+        osd_ipd_put(env, bag, ipd);
         LASSERT(osd_invariant(obj));
 
         RETURN(rc);
@@ -1650,27 +1631,30 @@ static int osd_index_insert(const struct lu_env *env, struct dt_object *dt,
                             struct thandle *th, struct lustre_capa *capa)
 {
         struct osd_object     *obj = osd_dt_obj(dt);
-
+        struct iam_path_descr *ipd;
         struct osd_thandle    *oh;
+        struct iam_container  *bag = &obj->oo_container;
         int rc;
 
         ENTRY;
 
         LASSERT(osd_invariant(obj));
         LASSERT(dt_object_exists(dt));
-        LASSERT(obj->oo_container.ic_object == obj->oo_inode);
-        LASSERT(obj->oo_ipd != NULL);
+        LASSERT(bag->ic_object == obj->oo_inode);
         LASSERT(th != NULL);
 
         if (osd_object_auth(env, dt, capa, CAPA_OPC_INDEX_INSERT))
                 return -EACCES;
 
+        ipd = osd_ipd_get(env, bag);
+        if (ipd == NULL)
+                RETURN(-ENOMEM);
+
         oh = container_of0(th, struct osd_thandle, ot_super);
         LASSERT(oh->ot_handle != NULL);
-        rc = iam_insert(oh->ot_handle, &obj->oo_container,
-                        (const struct iam_key *)key,
-                        (struct iam_rec *)rec, obj->oo_ipd);
-
+        rc = iam_insert(oh->ot_handle, bag, (const struct iam_key *)key,
+                        (struct iam_rec *)rec, ipd);
+        osd_ipd_put(env, bag, ipd);
         LASSERT(osd_invariant(obj));
         RETURN(rc);
 }
@@ -1687,25 +1671,31 @@ static struct dt_it *osd_it_init(const struct lu_env *env,
                                  struct dt_object *dt, int writable,
                                  struct lustre_capa *capa)
 {
-        struct osd_it     *it;
-        struct osd_object *obj = osd_dt_obj(dt);
-        struct lu_object  *lo  = &dt->do_lu;
-        __u32              flags;
+        struct osd_it         *it;
+        struct osd_object     *obj = osd_dt_obj(dt);
+        struct lu_object      *lo  = &dt->do_lu;
+        struct iam_path_descr *ipd;
+        struct iam_container  *bag = &obj->oo_container;
+        __u32                  flags;
 
         LASSERT(lu_object_exists(lo));
-        LASSERT(obj->oo_ipd != NULL);
 
         if (osd_object_auth(env, dt, capa, writable ? CAPA_OPC_BODY_WRITE :
                             CAPA_OPC_BODY_READ))
                 return ERR_PTR(-EACCES);
 
+        ipd = osd_ipd_get(env, bag);
+        if (ipd == NULL)
+                return ERR_PTR(-ENOMEM);
+
         flags = writable ? IAM_IT_MOVE|IAM_IT_WRITE : IAM_IT_MOVE;
         OBD_ALLOC_PTR(it);
         if (it != NULL) {
                 it->oi_obj = obj;
                 lu_object_get(lo);
-                iam_it_init(&it->oi_it, &obj->oo_container, flags, obj->oo_ipd);
+                iam_it_init(&it->oi_it, bag, flags, ipd);
         }
+        osd_ipd_put(env, bag, ipd);
         return (struct dt_it *)it;
 }