Whamcloud - gitweb
LU-6142 libcfs: discard cfs_strrstr()
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_iam.h
index 293f2e3..bd1fcd5 100644 (file)
  * 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
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * 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)
-#endif
+
 /* implication */
 #define ergo(a, b) (!(a) || (b))
 /* logical equivalence */
@@ -91,7 +86,6 @@ enum {
         DX_FMT_NAME_LEN    = 16,
 };
 
-#ifdef __KERNEL__
 
 /*
  * Debugging.
@@ -219,6 +213,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. */
 };
 
 /*
@@ -403,42 +400,60 @@ 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);
 };
 
 /*
  * Parameters, describing a flavor of iam container.
  */
 struct iam_descr {
-        /*
-         * Size of a key in this container, in bytes.
-         */
-         size_t       id_key_size;
-        /*
-         * Size of a key in index nodes, in bytes.
-         */
-         size_t       id_ikey_size;
-        /*
-         * Size of a pointer to the next level (stored in index nodes), in
-         * bytes.
-         */
-        size_t       id_ptr_size;
-        /*
-         * Size of a record (stored in leaf nodes), in bytes.
-         */
-        size_t       id_rec_size;
-        /*
-         * Size of unused (by iam) space at the beginning of every non-root
-         * node, in bytes. Used for compatibility with ldiskfs.
-         */
-        size_t       id_node_gap;
-        /*
-         * Size of unused (by iam) space at the beginning of root node, in
-         * bytes. Used for compatibility with ldiskfs.
-         */
-        size_t       id_root_gap;
+       /*
+        * Size of a key in this container, in bytes.
+        */
+       size_t       id_key_size;
+       /*
+        * Size of a key in index nodes, in bytes.
+        */
+       size_t       id_ikey_size;
+       /*
+        * Size of a pointer to the next level (stored in index nodes), in
+        * bytes.
+        */
+       size_t       id_ptr_size;
+       /*
+        * Size of a record (stored in leaf nodes), in bytes.
+        */
+       size_t       id_rec_size;
+       /*
+        * Size of unused (by iam) space at the beginning of every non-root
+        * node, in bytes. Used for compatibility with ldiskfs.
+        */
+       size_t       id_node_gap;
+       /*
+        * Size of unused (by iam) space at the beginning of root node, in
+        * bytes. Used for compatibility with ldiskfs.
+        */
+       size_t       id_root_gap;
+
+       const struct iam_operations           *id_ops;
+       const struct iam_leaf_operations      *id_leaf_ops;
+};
+
+enum {
+       IAM_IDLE_HEADER_MAGIC = 0x7903,
+};
 
-        struct iam_operations           *id_ops;
-        struct iam_leaf_operations      *id_leaf_ops;
+/*
+ * 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];
 };
 
 /*
@@ -461,8 +476,15 @@ struct iam_container {
         /*
          * 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 */
 };
 
 /*
@@ -562,11 +584,11 @@ enum iam_it_flags {
         /*
          * this iterator will move (iam_it_next() will be called on it)
          */
-        IAM_IT_MOVE  = (1 << 0),
+        IAM_IT_MOVE  = BIT(0),
         /*
          * tree can be updated through this iterator.
          */
-        IAM_IT_WRITE = (1 << 1)
+        IAM_IT_WRITE = BIT(1)
 };
 
 /*
@@ -770,10 +792,10 @@ static inline struct iam_descr *iam_leaf_descr(const struct iam_leaf *leaf)
         return iam_leaf_container(leaf)->ic_descr;
 }
 
-static inline struct iam_leaf_operations *
+static inline const struct iam_leaf_operations *
 iam_leaf_ops(const struct iam_leaf *leaf)
 {
-        return iam_leaf_descr(leaf)->id_leaf_ops;
+       return iam_leaf_descr(leaf)->id_leaf_ops;
 }
 
 static inline void iam_reccpy(const struct iam_leaf *leaf,
@@ -820,8 +842,8 @@ struct fake_dirent {
 };
 
 struct dx_countlimit {
-        __le16 limit;
-        __le16 count;
+       __le16 limit;
+       __le16 count;
 };
 
 /*
@@ -907,7 +929,7 @@ 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];
 }
 
@@ -944,8 +966,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,
@@ -994,7 +1014,7 @@ int iam_lvar_create(struct inode *obj,
 #define dxtrace(command) 
 #endif
 
-#define BH_DXLock        25
+#define BH_DXLock        (BH_BITMAP_UPTODATE + 1)
 #define DX_DEBUG (0)
 #if DX_DEBUG
 static struct iam_lock_stats {
@@ -1012,9 +1032,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
@@ -1023,8 +1043,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
 }
 
@@ -1044,37 +1063,18 @@ int iam_leaf_can_add(const struct iam_leaf *l,
 struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
 struct iam_container *iam_leaf_container(const struct iam_leaf *leaf);
 struct iam_descr *iam_leaf_descr(const struct iam_leaf *leaf);
-struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);
+const struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);
 
 
 int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
                   handle_t *h, struct buffer_head **bh);
 
-/*
- * Container format.
- */
-struct iam_format {
-        /*
-         * Method called to recognize container format. Should return true iff
-         * container @c conforms to this format. This method may do IO to read
-         * container pages.
-         *
-         * If container is recognized, this method sets operation vectors
-         * ->id_ops and ->id_leaf_ops in container description (c->ic_descr),
-         * and fills other description fields.
-         */
-        int (*if_guess)(struct iam_container *c);
-        /*
-         * Linkage into global list of container formats.
-         */
-        cfs_list_t if_linkage;
-};
-
-void iam_format_register(struct iam_format *fmt);
 int iam_root_limit(int rootgap, int blocksize, int size);
 
 void iam_lfix_format_init(void);
 void iam_lvar_format_init(void);
+int iam_lfix_guess(struct iam_container *c);
+int iam_lvar_guess(struct iam_container *c);
 void iam_htree_format_init(void);
 
 int iam_lfix_create(struct inode *obj,
@@ -1091,6 +1091,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,
@@ -1104,7 +1105,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