X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_iam.c;h=e7b5ae64939c00412775eaee8a7f11bcecf1e689;hb=a1f7493109cc995f43204d9a0f19a229ec5edef6;hp=2d3e80e1d4886bbbb40e8a8d5aef55ad656f9766;hpb=7cbd1b0c7409b4bfb44dc6869afc4ff9c90a7dce;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_iam.c b/lustre/osd-ldiskfs/osd_iam.c index 2d3e80e..e7b5ae6 100644 --- a/lustre/osd-ldiskfs/osd_iam.c +++ b/lustre/osd-ldiskfs/osd_iam.c @@ -27,7 +27,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, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -157,11 +157,11 @@ * * No locking. Callers synchronize. */ -static CFS_LIST_HEAD(iam_formats); +static struct list_head iam_formats = LIST_HEAD_INIT(iam_formats); void iam_format_register(struct iam_format *fmt) { - cfs_list_add(&fmt->if_linkage, &iam_formats); + list_add(&fmt->if_linkage, &iam_formats); } EXPORT_SYMBOL(iam_format_register); @@ -173,7 +173,7 @@ iam_load_idle_blocks(struct iam_container *c, iam_ptr_t blk) struct buffer_head *bh; int err; - LASSERT_SEM_LOCKED(&c->ic_idle_sem); + LASSERT(mutex_is_locked(&c->ic_idle_mutex)); if (blk == 0) return NULL; @@ -222,7 +222,7 @@ static int iam_format_guess(struct iam_container *c) } result = -ENOENT; - cfs_list_for_each_entry(fmt, &iam_formats, if_linkage) { + list_for_each_entry(fmt, &iam_formats, if_linkage) { result = fmt->if_guess(c); if (result == 0) break; @@ -237,13 +237,13 @@ static int iam_format_guess(struct iam_container *c) idle_blocks = (__u32 *)(c->ic_root_bh->b_data + c->ic_descr->id_root_gap + sizeof(struct dx_countlimit)); - cfs_down(&c->ic_idle_sem); + mutex_lock(&c->ic_idle_mutex); bh = iam_load_idle_blocks(c, le32_to_cpu(*idle_blocks)); if (bh != NULL && IS_ERR(bh)) result = PTR_ERR(bh); else c->ic_idle_bh = bh; - cfs_up(&c->ic_idle_sem); + mutex_unlock(&c->ic_idle_mutex); } return result; @@ -258,9 +258,9 @@ int iam_container_init(struct iam_container *c, memset(c, 0, sizeof *c); c->ic_descr = descr; c->ic_object = inode; - cfs_init_rwsem(&c->ic_sem); + init_rwsem(&c->ic_sem); dynlock_init(&c->ic_tree_lock); - cfs_sema_init(&c->ic_idle_sem, 1); + mutex_init(&c->ic_idle_mutex); return 0; } EXPORT_SYMBOL(iam_container_init); @@ -304,6 +304,7 @@ void iam_path_release(struct iam_path *path) for (i = 0; i < ARRAY_SIZE(path->ip_frames); i++) { if (path->ip_frames[i].bh != NULL) { + path->ip_frames[i].at_shifted = 0; brelse(path->ip_frames[i].bh); path->ip_frames[i].bh = NULL; } @@ -455,33 +456,33 @@ static int iam_path_check(struct iam_path *p) static int iam_leaf_load(struct iam_path *path) { - iam_ptr_t block; - int err; - struct iam_container *c; - struct buffer_head *bh; - struct iam_leaf *leaf; - struct iam_descr *descr; - - c = path->ip_container; - leaf = &path->ip_leaf; - descr = iam_path_descr(path); - block = path->ip_frame->leaf; - if (block == 0) { - /* XXX bug 11027 */ - printk(CFS_KERN_EMERG "wrong leaf: %lu %d [%p %p %p]\n", - (long unsigned)path->ip_frame->leaf, - dx_get_count(dx_node_get_entries(path, path->ip_frame)), - path->ip_frames[0].bh, path->ip_frames[1].bh, - path->ip_frames[2].bh); - } - err = descr->id_ops->id_node_read(c, block, NULL, &bh); - if (err == 0) { - leaf->il_bh = bh; - leaf->il_curidx = block; - err = iam_leaf_ops(leaf)->init(leaf); - assert_inv(ergo(err == 0, iam_leaf_check(leaf))); - } - return err; + iam_ptr_t block; + int err; + struct iam_container *c; + struct buffer_head *bh; + struct iam_leaf *leaf; + struct iam_descr *descr; + + c = path->ip_container; + leaf = &path->ip_leaf; + descr = iam_path_descr(path); + block = path->ip_frame->leaf; + if (block == 0) { + /* XXX bug 11027 */ + printk(KERN_EMERG "wrong leaf: %lu %d [%p %p %p]\n", + (long unsigned)path->ip_frame->leaf, + dx_get_count(dx_node_get_entries(path, path->ip_frame)), + path->ip_frames[0].bh, path->ip_frames[1].bh, + path->ip_frames[2].bh); + } + err = descr->id_ops->id_node_read(c, block, NULL, &bh); + if (err == 0) { + leaf->il_bh = bh; + leaf->il_curidx = block; + err = iam_leaf_ops(leaf)->init(leaf); + assert_inv(ergo(err == 0, iam_leaf_check(leaf))); + } + return err; } static void iam_unlock_htree(struct iam_container *ic, @@ -691,22 +692,22 @@ static int iam_it_get_exact(struct iam_iterator *it, const struct iam_key *k) void iam_container_write_lock(struct iam_container *ic) { - cfs_down_write(&ic->ic_sem); + down_write(&ic->ic_sem); } void iam_container_write_unlock(struct iam_container *ic) { - cfs_up_write(&ic->ic_sem); + up_write(&ic->ic_sem); } void iam_container_read_lock(struct iam_container *ic) { - cfs_down_read(&ic->ic_sem); + down_read(&ic->ic_sem); } void iam_container_read_unlock(struct iam_container *ic) { - cfs_up_read(&ic->ic_sem); + up_read(&ic->ic_sem); } /* @@ -1039,9 +1040,7 @@ int iam_lookup_lock(struct iam_path *path, struct dynlock_handle **dl, enum dynlock_type lt) { int result; - struct inode *dir; - dir = iam_path_obj(path); while ((result = __iam_path_lookup(path)) == 0) { do_corr(schedule()); *dl = iam_lock_htree(path->ip_container, path->ip_frame->leaf, @@ -1071,13 +1070,11 @@ int iam_lookup_lock(struct iam_path *path, static int iam_path_lookup(struct iam_path *path, int index) { struct iam_container *c; - struct iam_descr *descr; struct iam_leaf *leaf; int result; c = path->ip_container; leaf = &path->ip_leaf; - descr = iam_path_descr(path); result = iam_lookup_lock(path, &leaf->il_lock, DLT_WRITE); assert_inv(iam_path_check(path)); do_corr(schedule()); @@ -1499,7 +1496,6 @@ int iam_it_next(struct iam_iterator *it) int result; struct iam_path *path; struct iam_leaf *leaf; - struct inode *obj; do_corr(struct iam_ikey *ik_orig); /* assert_corr(it->ii_flags&IAM_IT_MOVE); */ @@ -1508,7 +1504,6 @@ int iam_it_next(struct iam_iterator *it) path = &it->ii_path; leaf = &path->ip_leaf; - obj = iam_path_obj(path); assert_corr(iam_leaf_is_locked(leaf)); @@ -1670,9 +1665,9 @@ iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e) if (c->ic_idle_bh == NULL) goto newblock; - cfs_down(&c->ic_idle_sem); - if (unlikely(c->ic_idle_failed || c->ic_idle_bh == NULL)) { - cfs_up(&c->ic_idle_sem); + mutex_lock(&c->ic_idle_mutex); + if (unlikely(c->ic_idle_bh == NULL)) { + mutex_unlock(&c->ic_idle_mutex); goto newblock; } @@ -1690,7 +1685,7 @@ iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e) if (*e != 0) goto fail; - cfs_up(&c->ic_idle_sem); + mutex_unlock(&c->ic_idle_mutex); bh = ldiskfs_bread(NULL, inode, *b, 0, e); if (bh == NULL) return NULL; @@ -1728,7 +1723,7 @@ iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e) } c->ic_idle_bh = idle; - cfs_up(&c->ic_idle_sem); + mutex_unlock(&c->ic_idle_mutex); got: /* get write access for the found buffer head */ @@ -1737,15 +1732,19 @@ got: brelse(bh); bh = NULL; ldiskfs_std_error(inode->i_sb, *e); + } else { + /* Clear the reused node as new node does. */ + memset(bh->b_data, 0, inode->i_sb->s_blocksize); + set_buffer_uptodate(bh); } return bh; newblock: - bh = ldiskfs_append(h, inode, b, e); + bh = osd_ldiskfs_append(h, inode, b, e); return bh; fail: - cfs_up(&c->ic_idle_sem); + mutex_unlock(&c->ic_idle_mutex); ldiskfs_std_error(inode->i_sb, *e); return NULL; } @@ -2068,7 +2067,7 @@ int split_index_node(handle_t *handle, struct iam_path *path, ++ frame; assert_inv(dx_node_check(path, frame)); bh_new[0] = NULL; /* buffer head is "consumed" */ - err = ldiskfs_journal_get_write_access(handle, bh2); + err = ldiskfs_journal_dirty_metadata(handle, bh2); if (err) goto journal_error; do_corr(schedule()); @@ -2260,6 +2259,7 @@ static iam_ptr_t iam_index_shrink(handle_t *h, struct iam_path *p, struct inode *inode = c->ic_object; struct iam_frame *frame = p->ip_frame; struct iam_entry *entries; + struct iam_entry *pos; struct dynlock_handle *lh; int count; int rc; @@ -2289,6 +2289,27 @@ static iam_ptr_t iam_index_shrink(handle_t *h, struct iam_path *p, iam_lock_bh(frame->bh); entries = frame->entries; count = dx_get_count(entries); + /* NOT shrink the last entry in the index node, which can be reused + * directly by next new node. */ + if (count == 2) { + iam_unlock_bh(frame->bh); + iam_unlock_htree(c, lh); + return 0; + } + + pos = iam_find_position(p, frame); + /* There may be some new leaf nodes have been added or empty leaf nodes + * have been shrinked during my delete operation. + * + * If the empty leaf is not under current index node because the index + * node has been split, then just skip the empty leaf, which is rare. */ + if (unlikely(frame->leaf != dx_get_block(p, pos))) { + iam_unlock_bh(frame->bh); + iam_unlock_htree(c, lh); + return 0; + } + + frame->at = pos; if (frame->at < iam_entry_shift(p, entries, count - 1)) { struct iam_entry *n = iam_entry_shift(p, frame->at, 1); @@ -2297,8 +2318,8 @@ static iam_ptr_t iam_index_shrink(handle_t *h, struct iam_path *p, frame->at_shifted = 1; } dx_set_count(entries, count - 1); - rc = iam_txn_dirty(h, p, frame->bh); iam_unlock_bh(frame->bh); + rc = iam_txn_dirty(h, p, frame->bh); iam_unlock_htree(c, lh); if (rc != 0) return 0; @@ -2317,14 +2338,11 @@ iam_install_idle_blocks(handle_t *h, struct iam_path *p, struct buffer_head *bh, struct iam_idle_head *head; int rc; - rc = iam_txn_add(h, p, bh); - if (rc != 0) - return rc; - head = (struct iam_idle_head *)(bh->b_data); head->iih_magic = cpu_to_le16(IAM_IDLE_HEADER_MAGIC); head->iih_count = 0; head->iih_next = *idle_blocks; + /* The bh already get_write_accessed. */ rc = iam_txn_dirty(h, p, bh); if (rc != 0) return rc; @@ -2364,7 +2382,7 @@ static void iam_recycle_leaf(handle_t *h, struct iam_path *p, int count; int rc; - cfs_down(&c->ic_idle_sem); + mutex_lock(&c->ic_idle_mutex); if (unlikely(c->ic_idle_failed)) { rc = -EFAULT; goto unlock; @@ -2397,7 +2415,7 @@ static void iam_recycle_leaf(handle_t *h, struct iam_path *p, rc = iam_txn_dirty(h, p, c->ic_idle_bh); unlock: - cfs_up(&c->ic_idle_sem); + mutex_unlock(&c->ic_idle_mutex); if (rc != 0) CWARN("%.16s: idle blocks failed, will lose the blk %u\n", LDISKFS_SB(inode->i_sb)->s_es->s_volume_name, blk);