Whamcloud - gitweb
LU-4423 lustre: don't declare extern variables in C files.
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_iam.h
index 2c71983..23cd286 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  * in the LICENSE file that accompanied this code).
  *
  * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see [sun.com URL with a
- * copy of GPLv2].
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 
 #include <linux/module.h>
 #include <asm/unaligned.h>
-#include <linux/dynlocks.h>
+
+#include "osd_dynlocks.h"
 /*
- *  linux/include/linux/osd_iam.h
+ *  osd_iam.h
  */
 #ifndef CLASSERT
 #define CLASSERT(cond) do {switch(42) {case (cond): case 0: break;}} while (0)
@@ -91,7 +88,6 @@ enum {
         DX_FMT_NAME_LEN    = 16,
 };
 
-#ifdef __KERNEL__
 
 /*
  * Debugging.
@@ -219,6 +215,9 @@ struct iam_frame {
         iam_ptr_t         curidx;  /* (logical) offset of this node. Used to
                                     * per-node locking to detect concurrent
                                     * splits. */
+       unsigned int      at_shifted:1; /* The "at" entry has moved to next
+                                        * because of shrinking index node
+                                        * for recycling empty leaf node. */
 };
 
 /*
@@ -374,6 +373,8 @@ struct iam_leaf_operations {
         int (*key_cmp)(const struct iam_leaf *l, const struct iam_key *k);
         int (*key_eq)(const struct iam_leaf *l, const struct iam_key *k);
 
+       int (*rec_eq)(const struct iam_leaf *l, const struct iam_rec *r);
+
         int (*key_size)(const struct iam_leaf *l);
         /*
          * Search leaf @l for a record with key @k or for a place
@@ -401,6 +402,10 @@ struct iam_leaf_operations {
          */
         void (*split)(struct iam_leaf *l, struct buffer_head **bh,
                       iam_ptr_t newblknr);
+       /*
+        * the leaf is empty?
+        */
+       int (*leaf_empty)(struct iam_leaf *l);
 };
 
 /*
@@ -439,6 +444,20 @@ struct iam_descr {
         struct iam_leaf_operations      *id_leaf_ops;
 };
 
+enum {
+       IAM_IDLE_HEADER_MAGIC = 0x7903,
+};
+
+/*
+ * Header structure to record idle blocks.
+ */
+struct iam_idle_head {
+       __le16 iih_magic;
+       __le16 iih_count; /* how many idle blocks in this head */
+       __le32 iih_next; /* next head for idle blocks */
+       __le32 iih_blks[0];
+};
+
 /*
  * An instance of iam container.
  */
@@ -447,15 +466,27 @@ struct iam_container {
          * Underlying flat file. IO against this object is issued to
          * read/write nodes.
          */
-        struct inode      *ic_object;
+        struct inode        *ic_object;
+        /*
+         * BH of root block
+         */
+        struct buffer_head  *ic_root_bh;
         /*
          * container flavor.
          */
-        struct iam_descr  *ic_descr;
+        struct iam_descr    *ic_descr;
         /*
          * read-write lock protecting index consistency.
          */
-        cfs_rw_semaphore_t ic_sem;
+       struct rw_semaphore     ic_sem;
+       struct dynlock       ic_tree_lock;
+       /* Protect ic_idle_bh */
+       struct mutex         ic_idle_mutex;
+       /*
+        * BH for idle blocks
+        */
+       struct buffer_head  *ic_idle_bh;
+       unsigned int         ic_idle_failed:1; /* Idle block mechanism failed */
 };
 
 /*
@@ -781,7 +812,7 @@ static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry)
         u32 *addr;
 
         addr = iam_entry_off(entry, iam_path_descr(p)->id_ikey_size);
-        return le32_to_cpu(get_unaligned(addr)) & 0x00ffffff;
+        return le32_to_cpu(get_unaligned(addr));
 }
 
 static inline void dx_set_block(struct iam_path *p,
@@ -813,8 +844,8 @@ struct fake_dirent {
 };
 
 struct dx_countlimit {
-        __le16 limit;
-        __le16 count;
+       __le16 limit;
+       __le16 count;
 };
 
 /*
@@ -900,22 +931,16 @@ static inline struct iam_entry *dx_node_get_entries(struct iam_path *path,
 static inline struct iam_ikey *iam_path_ikey(const struct iam_path *path,
                                              int nr)
 {
-        assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch));
+       LASSERT(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch));
         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;
@@ -926,7 +951,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;
@@ -942,8 +968,6 @@ int dx_index_is_compat(struct iam_path *path);
 int ldiskfs_htree_next_block(struct inode *dir, __u32 hash,
                           struct iam_path *path, __u32 *start_hash);
 
-struct buffer_head *ldiskfs_append(handle_t *handle, struct inode *inode,
-                                u32 *block, int *err);
 int split_index_node(handle_t *handle, struct iam_path *path,
                      struct dynlock_handle **lh);
 struct ldiskfs_dir_entry_2 *split_entry(struct inode *dir,
@@ -992,8 +1016,8 @@ int iam_lvar_create(struct inode *obj,
 #define dxtrace(command) 
 #endif
 
-#define BH_DXLock        25
-#define DX_DEBUG (1)
+#define BH_DXLock        (BH_BITMAP_UPTODATE + 1)
+#define DX_DEBUG (0)
 #if DX_DEBUG
 static struct iam_lock_stats {
         unsigned dls_bh_lock;
@@ -1010,9 +1034,9 @@ static inline void iam_lock_bh(struct buffer_head volatile *bh)
 {
         DX_DEVAL(iam_lock_stats.dls_bh_lock++);
 #ifdef CONFIG_SMP
-        while (cfs_test_and_set_bit(BH_DXLock, &bh->b_state)) {
-                DX_DEVAL(iam_lock_stats.dls_bh_busy++);
-                while (cfs_test_bit(BH_DXLock, &bh->b_state))
+       while (test_and_set_bit_lock(BH_DXLock, &bh->b_state)) {
+               DX_DEVAL(iam_lock_stats.dls_bh_busy++);
+               while (test_bit(BH_DXLock, &bh->b_state))
                         cpu_relax();
         }
 #endif
@@ -1021,8 +1045,7 @@ static inline void iam_lock_bh(struct buffer_head volatile *bh)
 static inline void iam_unlock_bh(struct buffer_head *bh)
 {
 #ifdef CONFIG_SMP
-        smp_mb__before_clear_bit();
-        clear_bit(BH_DXLock, &bh->b_state);
+       clear_bit_unlock(BH_DXLock, &bh->b_state);
 #endif
 }
 
@@ -1065,7 +1088,7 @@ struct iam_format {
         /*
          * Linkage into global list of container formats.
          */
-        cfs_list_t if_linkage;
+       struct list_head if_linkage;
 };
 
 void iam_format_register(struct iam_format *fmt);
@@ -1089,6 +1112,7 @@ int iam_uapi_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
 extern int ldiskfs_check_dir_entry(const char *, struct inode *,
                                 struct ldiskfs_dir_entry_2 *,
                                 struct buffer_head *, unsigned long);
+extern int dx_node_check(struct iam_path *p, struct iam_frame *f);
 #else
 static inline int ldiskfs_check_dir_entry(const char * function,
                                        struct inode * dir,
@@ -1102,7 +1126,6 @@ static inline int ldiskfs_check_dir_entry(const char * function,
 */
 
 /* __KERNEL__ */
-#endif
 
 /*
  * User level API. Copy exists in lustre/lustre/tests/iam_ut.c