Whamcloud - gitweb
LU-6698 kernel: kernel update RHEL 6.6 [2.6.32-504.23.4.el6]
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_iam_lvar.c
index 4d1fa30..0092a8e 100644 (file)
@@ -26,6 +26,8 @@
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -198,14 +200,14 @@ static __u32 hash_build0(const char *name, int namelen)
                 struct ldiskfs_dx_hash_info hinfo;
 
                 hinfo.hash_version = LDISKFS_DX_HASH_TEA;
-                hinfo.seed = 0;
+               hinfo.seed = NULL;
                 ldiskfsfs_dirhash(name, namelen, &hinfo);
                 result = hinfo.hash;
                 if (LVAR_HASH_SANDWICH) {
                         __u32 result2;
 
                         hinfo.hash_version = LDISKFS_DX_HASH_TEA;
-                        hinfo.seed = 0;
+                       hinfo.seed = NULL;
                         ldiskfsfs_dirhash(name, namelen, &hinfo);
                         result2 = hinfo.hash;
                         result = (0xfc000000 & result2) | (0x03ffffff & result);
@@ -287,11 +289,11 @@ static struct lvar_leaf_entry *n_cur(const struct iam_leaf *l)
 
 void n_print(const struct iam_leaf *l)
 {
-        struct lvar_leaf_entry *scan;
+       struct lvar_leaf_entry *scan;
 
-        printk(CFS_KERN_EMERG "used: %d\n", h_used(n_head(l)));
-        for (scan = n_start(l); scan < n_end(l); scan = e_next(l, scan))
-                e_print(scan);
+       printk(KERN_EMERG "used: %d\n", h_used(n_head(l)));
+       for (scan = n_start(l); scan < n_end(l); scan = e_next(l, scan))
+               e_print(scan);
 }
 
 #if LDISKFS_CORRECTNESS_ON
@@ -397,7 +399,7 @@ static int lvar_init(struct iam_leaf *l)
 
         head = n_head(l);
         used = h_used(head);
-        if (head->vlh_magic == le16_to_cpu(IAM_LVAR_LEAF_MAGIC) &&
+       if (le16_to_cpu(head->vlh_magic) == IAM_LVAR_LEAF_MAGIC &&
             used <= blocksize(l)) {
                 l->il_at = l->il_entries = lvar_lentry(n_start(l));
                 result = 0;
@@ -405,12 +407,12 @@ static int lvar_init(struct iam_leaf *l)
                 struct inode *obj;
 
                 obj = iam_leaf_container(l)->ic_object;
-                CERROR("Wrong magic in node %llu (#%lu): %#x != %#x or "
-                       "wrong used: %d",
-                       (unsigned long long)l->il_bh->b_blocknr, obj->i_ino,
-                       head->vlh_magic, le16_to_cpu(IAM_LVAR_LEAF_MAGIC),
-                       used);
-                result = -EIO;
+               CERROR("Wrong magic in node %llu (#%lu): %#x != %#x or "
+                      "wrong used: %d\n",
+                      (unsigned long long)l->il_bh->b_blocknr, obj->i_ino,
+                      le16_to_cpu(head->vlh_magic), IAM_LVAR_LEAF_MAGIC,
+                      used);
+               result = -EIO;
         }
         return result;
 }
@@ -420,7 +422,7 @@ static void lvar_fini(struct iam_leaf *l)
         l->il_entries = l->il_at = NULL;
 }
 
-struct iam_rec *lvar_rec(const struct iam_leaf *l)
+static struct iam_rec *lvar_rec(const struct iam_leaf *l)
 {
         assert_corr(n_at_rec(l));
         return e_rec(n_cur(l));
@@ -571,6 +573,15 @@ static void lvar_rec_set(struct iam_leaf *l, const struct iam_rec *r)
         assert_inv(n_invariant(l));
 }
 
+static int lvar_rec_eq(const struct iam_leaf *l, const struct iam_rec *r)
+{
+       struct iam_rec *rec = e_rec(n_cur(l));
+
+       if (rec_size(rec) != rec_size(r))
+               return 0;
+       return !memcmp(rec, r, rec_size(r));
+}
+
 static void lvar_rec_get(const struct iam_leaf *l, struct iam_rec *r)
 {
         struct iam_rec *rec;
@@ -754,6 +765,11 @@ static void lvar_split(struct iam_leaf *leaf, struct buffer_head **bh,
         assert_inv(n_invariant(leaf));
 }
 
+static int lvar_leaf_empty(struct iam_leaf *leaf)
+{
+       return h_used(n_head(leaf)) == sizeof(struct lvar_leaf_header);
+}
+
 static struct iam_leaf_operations lvar_leaf_ops = {
         .init           = lvar_init,
         .init_new       = lvar_init_new,
@@ -768,6 +784,7 @@ static struct iam_leaf_operations lvar_leaf_ops = {
         .key_eq         = lvar_key_eq,
         .key_size       = lvar_key_size,
         .rec_set        = lvar_rec_set,
+       .rec_eq         = lvar_rec_eq,
         .rec_get        = lvar_rec_get,
         .lookup         = lvar_lookup,
         .ilookup        = lvar_ilookup,
@@ -775,7 +792,8 @@ static struct iam_leaf_operations lvar_leaf_ops = {
         .rec_add        = lvar_rec_add,
         .rec_del        = lvar_rec_del,
         .can_add        = lvar_can_add,
-        .split          = lvar_split
+       .split          = lvar_split,
+       .leaf_empty     = lvar_leaf_empty,
 };
 
 /*
@@ -844,7 +862,7 @@ static int lvar_node_check(struct iam_path *path, struct iam_frame *frame)
                 struct lvar_root *root;
 
                 root = (void *)frame->bh->b_data;
-                if (le64_to_cpu(root->vr_magic) != IAM_LVAR_ROOT_MAGIC)
+               if (le32_to_cpu(root->vr_magic) != IAM_LVAR_ROOT_MAGIC)
                         return -EIO;
                 limit_correct = dx_root_limit(path);
         } else
@@ -926,11 +944,22 @@ static void lvar_root(void *buf,
                                         sizeof (lvar_hash_t) + ptrsize)
         };
 
-        entry = root + 1;
-        /*
-         * Skip over @limit.
-         */
-        entry += isize;
+       /* To guarantee that the padding "keysize + ptrsize"
+        * covers the "dx_countlimit" and the "idle_blocks". */
+       LASSERT((keysize + ptrsize) >=
+               (sizeof(struct dx_countlimit) + sizeof(__u32)));
+
+       entry = (void *)(limit + 1);
+       /* Put "idle_blocks" just after the limit. There was padding after
+        * the limit, the "idle_blocks" re-uses part of the padding, so no
+        * compatibility issues with old layout.
+        */
+       *(__u32 *)entry = 0;
+
+       /*
+        * Skip over @limit.
+        */
+       entry = (void *)(root + 1) + isize;
 
         /*
          * Entry format is <key> followed by <ptr>. In the minimal tree
@@ -981,22 +1010,23 @@ int iam_lvar_create(struct inode *obj,
         struct super_block *sb;
 
         u32 blknr;
-        int result;
+        int result = 0;
         unsigned long bsize;
 
         assert_corr(obj->i_size == 0);
 
         sb = obj->i_sb;
         bsize = sb->s_blocksize;
-        root_node = ldiskfs_append(handle, obj, &blknr, &result);
-        leaf_node = ldiskfs_append(handle, obj, &blknr, &result);
+        root_node = osd_ldiskfs_append(handle, obj, &blknr, &result);
+        leaf_node = osd_ldiskfs_append(handle, obj, &blknr, &result);
         if (root_node != NULL && leaf_node != NULL) {
                 lvar_root(root_node->b_data, bsize, keysize, ptrsize, recsize);
                 lvar_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize);
                 ldiskfs_mark_inode_dirty(handle, obj);
-                result = ldiskfs_journal_dirty_metadata(handle, root_node);
-                if (result == 0)
-                        result = ldiskfs_journal_dirty_metadata(handle, leaf_node);
+               result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node);
+               if (result == 0)
+                       result = ldiskfs_handle_dirty_metadata(handle, NULL,
+                                                              leaf_node);
                 if (result != 0)
                         ldiskfs_std_error(sb, result);
         }
@@ -1004,7 +1034,6 @@ int iam_lvar_create(struct inode *obj,
         brelse(root_node);
         return result;
 }
-EXPORT_SYMBOL(iam_lvar_create);
 
 static struct iam_operations lvar_ops = {
         .id_root_ptr    = lvar_root_ptr,
@@ -1030,7 +1059,7 @@ static int lvar_guess(struct iam_container *c)
         result = iam_node_read(c, lvar_root_ptr(c), NULL, &bh);
         if (result == 0) {
                 root = (void *)bh->b_data;
-                if (le64_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC) {
+               if (le32_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC) {
                         struct iam_descr *descr;
 
                         descr = c->ic_descr;
@@ -1042,11 +1071,14 @@ static int lvar_guess(struct iam_container *c)
                         descr->id_node_gap  = 0;
                         descr->id_ops       = &lvar_ops;
                         descr->id_leaf_ops  = &lvar_leaf_ops;
-                } else
-                        result = -EBADF;
-                brelse(bh);
-        }
-        return result;
+
+                       c->ic_root_bh = bh;
+               } else {
+                       result = -EBADF;
+                       brelse(bh);
+               }
+       }
+       return result;
 }
 
 static struct iam_format lvar_format = {