X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_iam.h;h=afeb8be75d46da786d1f006c67da67928379b30a;hb=f07508d17b49574c7ea47a855c6e8af2b23c3add;hp=fe2f66d61ea7bc394934797157f4a8fe0d7cbde6;hpb=e992a95314f9d6721144d5521ebe795a72bb140a;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_iam.h b/lustre/osd-ldiskfs/osd_iam.h index fe2f66d..afeb8be 100644 --- a/lustre/osd-ldiskfs/osd_iam.h +++ b/lustre/osd-ldiskfs/osd_iam.h @@ -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. @@ -16,18 +14,16 @@ * 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 (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/ @@ -45,13 +41,12 @@ #include #include -#include + +#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. */ }; /* @@ -374,6 +371,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 +400,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 +442,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 +464,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 +810,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 +842,8 @@ struct fake_dirent { }; struct dx_countlimit { - __le16 limit; - __le16 count; + __le16 limit; + __le16 count; }; /* @@ -900,22 +929,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 +949,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 +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, @@ -992,8 +1014,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 +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 @@ -1021,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 } @@ -1065,7 +1086,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 +1110,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 +1124,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