From: nikita Date: Fri, 2 Jun 2006 11:22:20 +0000 (+0000) Subject: iam: fixes of fects found by UT: X-Git-Tag: v1_8_0_110~486^2~1675 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=a23090430871c551a88493cb3ebf5f00f2021eca;p=fs%2Flustre-release.git iam: fixes of fects found by UT: - defect: iam_new_leaf(): fix typo in previous ext3_append() fix. - defect: iam_add_rec(): leaf node has to be added to transaction. 5 min. - defect: iam_lfix_split(): erroneously inserts physical block number instead of offset into parent node. 10 min. - defect: mark index node as dirty, when inserting new entry into it. - defect: LDISKFS_INDEX_FL flag cleared in iam_release_file() is not written to disk. - defect: iam_lfix_lookup(): wrong key comparison. - defect: iam_add_rec(): @leaf variable has to be refreshed as split may retarget path to the new leaf node. - defect: iam_lfix_lookup(): wrong return code (this made it impossible to remove last record in a node). 90 min. iam-ut: - new IAM_IOC_DELETE ioctl command, - new functionality for lustre/tests/iam_ut --- diff --git a/lustre/kernel_patches/patches/ext3-iam-separate.patch b/lustre/kernel_patches/patches/ext3-iam-separate.patch index 92bdc58..795ac5e 100644 --- a/lustre/kernel_patches/patches/ext3-iam-separate.patch +++ b/lustre/kernel_patches/patches/ext3-iam-separate.patch @@ -1,7 +1,7 @@ Index: iam/fs/ext3/Makefile =================================================================== --- iam.orig/fs/ext3/Makefile 2006-05-31 20:24:32.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-05-31 23:32:29.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-06-02 15:15:24.000000000 +0400 @@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ @@ -14,8 +14,8 @@ Index: iam/fs/ext3/Makefile Index: iam/fs/ext3/iam.c =================================================================== --- iam.orig/fs/ext3/iam.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam.c 2006-05-31 22:34:57.000000000 +0400 -@@ -0,0 +1,1016 @@ ++++ iam/fs/ext3/iam.c 2006-06-01 23:33:54.000000000 +0400 +@@ -0,0 +1,1056 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -343,6 +343,7 @@ Index: iam/fs/ext3/iam.c + leaf->il_bh = bh; + leaf->il_path = path; + err = iam_leaf_ops(leaf)->init(leaf); ++ assert(ergo(err == 0, iam_leaf_check(leaf))); + } + return err; +} @@ -350,6 +351,7 @@ Index: iam/fs/ext3/iam.c +static void iam_leaf_fini(struct iam_leaf *leaf) +{ + if (leaf->il_path != NULL) { ++ assert(ergo(leaf->il_bh != NULL, iam_leaf_check(leaf))); + iam_leaf_ops(leaf)->fini(leaf); + if (leaf->il_bh) { + brelse(leaf->il_bh); @@ -368,8 +370,8 @@ Index: iam/fs/ext3/iam.c + iam_leaf_ops(folio)->next(folio); +} + -+static void iam_rec_add(struct iam_leaf *leaf, struct iam_key *key, -+ struct iam_rec *rec) ++static void iam_leaf_rec_add(struct iam_leaf *leaf, const struct iam_key *key, ++ const struct iam_rec *rec) +{ + iam_leaf_ops(leaf)->rec_add(leaf, key, rec); +} @@ -384,17 +386,72 @@ Index: iam/fs/ext3/iam.c + return iam_leaf_ops(leaf)->at_end(leaf); +} + -+void iam_leaf_split(struct iam_leaf *l, struct buffer_head *bh) ++void iam_leaf_split(struct iam_leaf *l, struct buffer_head **bh, iam_ptr_t nr) +{ -+ iam_leaf_ops(l)->split(l, bh); ++ iam_leaf_ops(l)->split(l, bh, nr); +} + -+static int iam_leaf_can_add(const struct iam_leaf *l, -+ const struct iam_key *k, const struct iam_rec *r) ++int iam_leaf_can_add(const struct iam_leaf *l, ++ const struct iam_key *k, const struct iam_rec *r) +{ + return iam_leaf_ops(l)->can_add(l, k, r); +} + ++static int iam_leaf_check(struct iam_leaf *leaf) ++{ ++ struct iam_lentry *orig; ++ struct iam_path *path; ++ struct iam_container *bag; ++ struct iam_key *k0; ++ struct iam_key *k1; ++ int result; ++ int first; ++ ++ orig = leaf->il_at; ++ path = iam_leaf_path(leaf); ++ bag = iam_leaf_container(leaf); ++ ++ result = iam_leaf_ops(leaf)->init(leaf); ++ if (result != 0) ++ return result; ++ ++ first = 1; ++ k0 = iam_path_key(path, 0); ++ k1 = iam_path_key(path, 1); ++ while (!iam_leaf_at_end(leaf)) { ++ iam_keycpy(bag, k0, k1); ++ iam_keycpy(bag, k1, iam_leaf_key(leaf, k1)); ++ if (!first && iam_keycmp(bag, k0, k1) > 0) ++ return 0; ++ first = 0; ++ iam_leaf_next(leaf); ++ } ++ leaf->il_at = orig; ++ return 1; ++} ++ ++static int iam_txn_dirty(handle_t *handle, ++ struct iam_path *path, struct buffer_head *bh) ++{ ++ int result; ++ ++ result = ext3_journal_dirty_metadata(handle, bh); ++ if (result != 0) ++ ext3_std_error(iam_path_obj(path)->i_sb, result); ++ return result; ++} ++ ++static int iam_txn_add(handle_t *handle, ++ struct iam_path *path, struct buffer_head *bh) ++{ ++ int result; ++ ++ result = ext3_journal_get_write_access(handle, bh); ++ if (result != 0) ++ ext3_std_error(iam_path_obj(path)->i_sb, result); ++ return result; ++} ++ +/***********************************************************************/ +/* iterator interface */ +/***********************************************************************/ @@ -520,6 +577,7 @@ Index: iam/fs/ext3/iam.c + result = dx_lookup(path); + if (result == 0) { + result = iam_leaf_load(path); ++ assert(ergo(result == 0, iam_leaf_check(leaf))); + if (result == 0) + result = iam_leaf_ops(leaf)->lookup(leaf, + path->ip_key_target); @@ -685,7 +743,7 @@ Index: iam/fs/ext3/iam.c + + assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE); + -+ result = ext3_journal_get_write_access(h, it->ii_path.ip_leaf.il_bh); ++ result = iam_txn_add(h, &it->ii_path, it->ii_path.ip_leaf.il_bh); + if (result == 0) + iam_it_reccpy(it, r); + return result; @@ -703,47 +761,28 @@ Index: iam/fs/ext3/iam.c + return iam_leaf_key(&it->ii_path.ip_leaf, k); +} + -+static int iam_leaf_rec_add(handle_t *handle, struct iam_path *path) -+{ -+ int err; -+ -+ err = ext3_journal_get_write_access(handle, path->ip_leaf.il_bh); -+ if (err) -+ goto journal_error; -+ iam_rec_add(&path->ip_leaf, NULL, NULL); -+ err = ext3_journal_dirty_metadata(handle, path->ip_leaf.il_bh); -+journal_error: -+ if (err) -+ ext3_std_error(iam_path_obj(path)->i_sb, err); -+ return err; -+} -+ +static int iam_new_leaf(handle_t *handle, struct iam_leaf *leaf) +{ + int err; -+ int err2; + u32 blknr; /* XXX 32bit block size */ + struct buffer_head *new_leaf; + struct iam_container *c; ++ struct inode *obj; ++ ++ assert(iam_leaf_check(leaf)); + + c = iam_leaf_container(leaf); -+ err = ext3_journal_get_write_access(handle, leaf->il_bh); -+ if (err == 0) { -+ struct inode *obj; + -+ obj = c->ic_object; -+ new_leaf = ext3_append(handle, c->ic_object, &blknr, &err); -+ if (new_leaf != NULL) { -+ iam_leaf_ops(leaf)->init_new(c, new_leaf); -+ iam_leaf_ops(leaf)->split(leaf, new_leaf); -+ err = ext3_journal_dirty_metadata(handle, new_leaf); -+ err2 = ext3_journal_dirty_metadata(handle, leaf->il_bh); -+ err = err ? : err2; -+ if (err) -+ ext3_std_error(obj->i_sb, err); -+ brelse(new_leaf); -+ } ++ obj = c->ic_object; ++ new_leaf = ext3_append(handle, c->ic_object, &blknr, &err); ++ if (new_leaf != NULL) { ++ iam_leaf_ops(leaf)->init_new(c, new_leaf); ++ iam_leaf_split(leaf, &new_leaf, blknr); ++ err = iam_txn_dirty(handle, iam_leaf_path(leaf), new_leaf); ++ brelse(new_leaf); + } ++ assert(iam_leaf_check(leaf)); ++ assert(iam_leaf_check(&iam_leaf_path(leaf)->ip_leaf)); + return err; +} + @@ -751,21 +790,35 @@ Index: iam/fs/ext3/iam.c + const struct iam_key *k, const struct iam_rec *r) +{ + int err; ++ struct iam_leaf *leaf; + -+ if (iam_leaf_can_add(&path->ip_leaf, k, r)) { -+ err = iam_leaf_rec_add(handle, path); -+ } else { -+ err = split_index_node(handle, path); -+ if (err == 0) { -+ err = iam_new_leaf(handle, &path->ip_leaf); -+ /* -+ * XXX: if insertion point moved into new leaf, path -+ * and path->ip_leaf have to be updated. -+ */ -+ if (err == 0) -+ err = iam_leaf_rec_add(handle, path); -+ } -+ } ++ leaf = &path->ip_leaf; ++ assert(iam_leaf_check(leaf)); ++ err = iam_txn_add(handle, path, leaf->il_bh); ++ if (err == 0) { ++ if (!iam_leaf_can_add(leaf, k, r)) { ++ err = split_index_node(handle, path); ++ if (err == 0) { ++ err = iam_new_leaf(handle, leaf); ++ /* ++ * refresh @leaf, as split may retarget path ++ * to the new leaf node. ++ */ ++ leaf = &path->ip_leaf; ++ if (err == 0) ++ err = iam_txn_dirty(handle, path, ++ path->ip_frame->bh); ++ } ++ } else ++ err = 0; ++ ++ if (err == 0) { ++ iam_leaf_rec_add(leaf, k, r); ++ err = iam_txn_dirty(handle, path, leaf->il_bh); ++ } ++ } ++ assert(iam_leaf_check(leaf)); ++ assert(iam_leaf_check(&path->ip_leaf)); + return err; +} + @@ -789,16 +842,6 @@ Index: iam/fs/ext3/iam.c + assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE); + assert(it_keycmp(it, iam_it_key_get(it, it_scratch_key(it, 0)), k) < 0); + result = iam_add_rec(h, &it->ii_path, k, r); -+ if (result == 0) { -+ /* place record and key info freed space. Leaf node is already -+ * in transaction. */ -+ iam_it_reccpy(it, r); -+ iam_it_keycpy(it, k); -+ iam_keycpy(it->ii_path.ip_container, it_scratch_key(it, 0), k); -+ /* -+ * XXX TBD. -+ */ -+ } + assert(it_state(it) == IAM_IT_ATTACHED); + assert(ergo(result == 0, + it_keycmp(it, @@ -811,13 +854,10 @@ Index: iam/fs/ext3/iam.c + +static int iam_leaf_rec_remove(handle_t *handle, struct iam_leaf *leaf) +{ -+ int err; -+ ++ assert(iam_leaf_check(leaf)); + iam_rec_del(leaf); -+ err = ext3_journal_dirty_metadata(handle, leaf->il_bh); -+ if (err) -+ ext3_std_error(iam_path_obj(iam_leaf_path(leaf))->i_sb, err); -+ return err; ++ assert(iam_leaf_check(leaf)); ++ return iam_txn_dirty(handle, iam_leaf_path(leaf), leaf->il_bh); +} + +/* @@ -832,7 +872,7 @@ Index: iam/fs/ext3/iam.c + + assert(it_state(it) == IAM_IT_ATTACHED && it->ii_flags&IAM_IT_WRITE); + -+ result = ext3_journal_get_write_access(h, it->ii_path.ip_leaf.il_bh); ++ result = iam_txn_add(h, &it->ii_path, it->ii_path.ip_leaf.il_bh); + /* + * no compaction for now. + */ @@ -1035,8 +1075,8 @@ Index: iam/fs/ext3/iam.c Index: iam/fs/ext3/iam_lfix.c =================================================================== --- iam.orig/fs/ext3/iam_lfix.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam_lfix.c 2006-05-31 23:32:16.000000000 +0400 -@@ -0,0 +1,451 @@ ++++ iam/fs/ext3/iam_lfix.c 2006-06-01 23:51:13.000000000 +0400 +@@ -0,0 +1,470 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -1230,35 +1270,45 @@ Index: iam/fs/ext3/iam_lfix.c + p = iam_lfix_shift(l, m, +1); + } + l->il_at = iam_lfix_shift(l, p, -1); -+ iam_keycpy(c, iam_path_key(iam_leaf_path(l), 0), iam_leaf_key_at(q)); + -+ if (l->il_at == l->il_entries || -+ iam_keycmp(c, iam_leaf_key_at(q), k) != 0) -+ return -ENOENT; -+ else -+ return 0; ++ assert(!iam_leaf_at_end(l)); ++ ++ return iam_keycmp(c, iam_leaf_key_at(l->il_at), k) != 0 ? -ENOENT : 0; ++} ++ ++static void iam_lfix_key_set(struct iam_leaf *l, const struct iam_key *k) ++{ ++ iam_keycpy(iam_leaf_container(l), iam_leaf_key_at(l->il_at), k); ++} ++ ++static void iam_lfix_rec_set(struct iam_leaf *l, const struct iam_rec *r) ++{ ++ iam_reccpy(iam_leaf_path(l), iam_lfix_rec(l), r); +} + +static void iam_lfix_rec_add(struct iam_leaf *leaf, + const struct iam_key *k, const struct iam_rec *r) +{ -+ struct iam_lentry *end, *next, *cur, *nnext; ++ struct iam_lentry *end; ++ struct iam_lentry *cur; ++ struct iam_lentry *next; + ptrdiff_t diff; + int count; + ++ assert(!iam_leaf_at_end(leaf)); ++ assert(iam_leaf_can_add(leaf, k, r)); ++ + count = lentry_count_get(leaf); -+ end = iam_lfix_get_end(leaf); -+ cur = leaf->il_at; -+ if (cur != end) { -+ next = iam_lfix_shift(leaf, cur, 1); -+ if (next != end) { -+ nnext = iam_lfix_shift(leaf, next, 1); -+ diff = (void *)end - (void *)next; -+ memmove(nnext, next, diff); -+ } -+ iam_lfix_next(leaf); -+ } ++ end = iam_lfix_get_end(leaf); ++ cur = leaf->il_at; ++ next = iam_lfix_shift(leaf, cur, 1); ++ diff = (void *)end - (void *)next; ++ memmove(iam_lfix_shift(leaf, next, 1), next, diff); ++ iam_lfix_next(leaf); ++ iam_lfix_key_set(leaf, k); ++ iam_lfix_rec_set(leaf, r); + lentry_count_set(leaf, count + 1); ++ assert(!iam_leaf_at_end(leaf)); +} + +static void iam_lfix_rec_del(struct iam_leaf *leaf) @@ -1299,9 +1349,7 @@ Index: iam/fs/ext3/iam_lfix.c + +static int iam_lfix_at_end(const struct iam_leaf *folio) +{ -+ struct iam_lentry *ile = iam_lfix_get_end(folio); -+ -+ return (folio->il_at == ile); ++ return folio->il_at == iam_lfix_get_end(folio); +} + +static void iam_lfix_init_new(struct iam_container *c, struct buffer_head *bh) @@ -1313,11 +1361,13 @@ Index: iam/fs/ext3/iam_lfix.c + hdr->ill_count = cpu_to_le16(0); +} + -+static void iam_lfix_split(struct iam_leaf *l, struct buffer_head *bh) ++static void iam_lfix_split(struct iam_leaf *l, struct buffer_head **bh, ++ iam_ptr_t new_blknr) +{ + struct iam_path *path; + struct iam_leaf_head *hdr; + const struct iam_key *pivot; ++ struct buffer_head *new_leaf; + + unsigned count; + unsigned split; @@ -1325,9 +1375,10 @@ Index: iam/fs/ext3/iam_lfix.c + void *start; + void *finis; + ++ new_leaf = *bh; + path = iam_leaf_path(l); + -+ hdr = (void *)bh->b_data; ++ hdr = (void *)new_leaf->b_data; + + count = lentry_count_get(l); + split = count / 2; @@ -1337,24 +1388,32 @@ Index: iam/fs/ext3/iam_lfix.c + + pivot = iam_leaf_key_at(start); + -+ memmove(iam_entries(bh), start, finis - start); ++ memmove(iam_entries(new_leaf), start, finis - start); + hdr->ill_count = count - split; + lentry_count_set(l, split); + /* + * Insert pointer to the new node (together with the smallest key in + * the node) into index node. + */ -+ iam_insert_key(path, path->ip_frame, pivot, bh->b_blocknr); -+} ++ iam_insert_key(path, path->ip_frame, pivot, new_blknr); ++ if ((void *)l->il_at >= start) { ++ /* ++ * insertion point moves into new leaf. ++ */ ++ int shift; ++ int result; + -+static void iam_lfix_key_set(struct iam_leaf *l, const struct iam_key *k) -+{ -+ iam_keycpy(iam_leaf_container(l), iam_leaf_key_at(l->il_at), k); -+} ++ shift = iam_lfix_diff(l, l->il_at, start); ++ *bh = l->il_bh; ++ l->il_bh = new_leaf; ++ result = iam_lfix_init(l); ++ /* ++ * init cannot fail, as node was just initialized. ++ */ ++ assert(result == 0); ++ l->il_at = iam_lfix_shift(l, iam_get_lentries(l), shift); ++ } + -+static void iam_lfix_rec_set(struct iam_leaf *l, const struct iam_rec *r) -+{ -+ iam_reccpy(iam_leaf_path(l), iam_lfix_rec(l), r); +} + +static struct iam_leaf_operations iam_lfix_leaf_ops = { @@ -1491,7 +1550,7 @@ Index: iam/fs/ext3/iam_lfix.c Index: iam/fs/ext3/namei.c =================================================================== --- iam.orig/fs/ext3/namei.c 2006-05-31 20:24:32.000000000 +0400 -+++ iam/fs/ext3/namei.c 2006-05-31 20:26:49.000000000 +0400 ++++ iam/fs/ext3/namei.c 2006-06-01 19:56:08.000000000 +0400 @@ -24,81 +24,6 @@ * Theodore Ts'o, 2002 */ @@ -1605,7 +1664,7 @@ Index: iam/fs/ext3/namei.c EXT3_I(inode)->i_disksize = inode->i_size; - ext3_journal_get_write_access(handle,bh); + *err = ext3_journal_get_write_access(handle, bh); -+ if (err != 0) { ++ if (*err != 0) { + brelse(bh); + bh = NULL; + } @@ -3001,7 +3060,7 @@ Index: iam/fs/ext3/namei.c Index: iam/include/linux/lustre_iam.h =================================================================== --- iam.orig/include/linux/lustre_iam.h 2006-05-31 20:24:32.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-05-31 23:32:29.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-06-02 15:15:24.000000000 +0400 @@ -1,9 +1,68 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: diff --git a/lustre/kernel_patches/patches/ext3-iam-uapi.patch b/lustre/kernel_patches/patches/ext3-iam-uapi.patch index 5175757..56686db 100644 --- a/lustre/kernel_patches/patches/ext3-iam-uapi.patch +++ b/lustre/kernel_patches/patches/ext3-iam-uapi.patch @@ -1,7 +1,7 @@ Index: iam/fs/ext3/Makefile =================================================================== ---- iam.orig/fs/ext3/Makefile 2006-05-31 23:32:29.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-05-31 23:32:36.000000000 +0400 +--- iam.orig/fs/ext3/Makefile 2006-06-02 15:15:24.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-06-02 15:15:25.000000000 +0400 @@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ @@ -13,8 +13,8 @@ Index: iam/fs/ext3/Makefile ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o Index: iam/fs/ext3/file.c =================================================================== ---- iam.orig/fs/ext3/file.c 2006-05-31 23:32:29.000000000 +0400 -+++ iam/fs/ext3/file.c 2006-05-31 23:32:36.000000000 +0400 +--- iam.orig/fs/ext3/file.c 2006-06-02 15:15:24.000000000 +0400 ++++ iam/fs/ext3/file.c 2006-06-02 15:15:25.000000000 +0400 @@ -23,6 +23,7 @@ #include #include @@ -33,7 +33,7 @@ Index: iam/fs/ext3/file.c + if (S_ISDIR(inode->i_mode)) + ext3_htree_free_dir_info(filp->private_data); + else -+ ext3_iam_free_info(filp->private_data); ++ ext3_iam_release(filp, inode); + } return 0; @@ -50,8 +50,8 @@ Index: iam/fs/ext3/file.c Index: iam/fs/ext3/iam-uapi.c =================================================================== --- iam.orig/fs/ext3/iam-uapi.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam-uapi.c 2006-05-31 23:32:36.000000000 +0400 -@@ -0,0 +1,246 @@ ++++ iam/fs/ext3/iam-uapi.c 2006-06-02 15:15:25.000000000 +0400 +@@ -0,0 +1,256 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -113,13 +113,18 @@ Index: iam/fs/ext3/iam-uapi.c + struct iam_private_info *ipi; + + ipi = get_ipi(filp); -+ if (cmd == IAM_IOC_INSERT) { ++ if (cmd == IAM_IOC_INSERT || cmd == IAM_IOC_DELETE) { + handle_t *h; + + h = ext3_journal_start(inode, IAM_INSERT_CREDITS); + if (!IS_ERR(h)) { -+ result = iam_insert(h, &ipi->ipi_bag, op->iul_key, -+ op->iul_rec, ipi->ipi_ipd); ++ if (cmd == IAM_IOC_INSERT) ++ result = iam_insert(h, &ipi->ipi_bag, ++ op->iul_key, ++ op->iul_rec, ipi->ipi_ipd); ++ else ++ result = iam_delete(h, &ipi->ipi_bag, ++ op->iul_key, ipi->ipi_ipd); + ext3_journal_stop(h); + } else { + result = PTR_ERR(h); @@ -141,13 +146,17 @@ Index: iam/fs/ext3/iam-uapi.c + return info; +} + -+void ext3_iam_free_info(struct iam_private_info *info) ++void ext3_iam_release(struct file *filp, struct inode *inode) +{ ++ struct iam_private_info *info; ++ ++ info = filp->private_data; + iam_container_fini(&info->ipi_bag); + if (info->ipi_ipd != NULL) + iam_ipd_free(info->ipi_ipd); + + kfree(info); ++ EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; +} + +static int iam_uapi_init(struct inode *inode, @@ -262,13 +271,13 @@ Index: iam/fs/ext3/iam-uapi.c + else if (!S_ISREG(inode->i_mode)) + result = -EBADF; + else if (cmd == IAM_IOC_INIT) { -+ if (!is_dx(inode)) { ++ if (filp->private_data == NULL) { + result = getua(&u.ua, arg); + if (result == 0) + result = iam_uapi_init(inode, filp, &u.ua); + } else + result = -EBUSY; -+ } else if (is_dx(inode)) { ++ } else if (is_dx(inode) && filp->private_data != NULL) { + struct iam_descr *des; + + des = &get_ipi(filp)->ipi_descr; @@ -280,14 +289,15 @@ Index: iam/fs/ext3/iam-uapi.c + memcpy(u.ua.iui_fmt_name, des->id_ops->id_name, + ARRAY_SIZE(u.ua.iui_fmt_name)); + result = putua(&u.ua, arg); -+ } else if (cmd == IAM_IOC_INSERT || cmd == IAM_IOC_LOOKUP) { ++ } else if (cmd == IAM_IOC_INSERT || cmd == IAM_IOC_LOOKUP || ++ cmd == IAM_IOC_DELETE) { + result = getop(&u.op, &uop, des, arg); + if (result == 0) { + result = iam_uapi_op(cmd, inode, filp, &u.op); + if (cmd == IAM_IOC_LOOKUP) { + int res2; + -+ res2 = outop(&u.op, &uop, des, KEY); ++ res2 = outop(&u.op, &uop, des, REC); + result = result ? : res2; + } + putop(&u.op); @@ -300,8 +310,8 @@ Index: iam/fs/ext3/iam-uapi.c +} Index: iam/include/linux/lustre_iam.h =================================================================== ---- iam.orig/include/linux/lustre_iam.h 2006-05-31 23:32:29.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-05-31 23:32:36.000000000 +0400 +--- iam.orig/include/linux/lustre_iam.h 2006-06-02 15:15:24.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-06-02 15:15:25.000000000 +0400 @@ -30,9 +30,6 @@ #ifndef __LINUX_LUSTRE_IAM_H__ #define __LINUX_LUSTRE_IAM_H__ @@ -323,13 +333,32 @@ Index: iam/include/linux/lustre_iam.h /* * Entry within index tree node. Consists of a key immediately followed * (without padding) by a pointer to the child node. -@@ -718,5 +719,39 @@ void iam_format_register(struct iam_form +@@ -226,7 +227,8 @@ struct iam_leaf_operations { + * split leaf node, moving some entries into @bh (the latter currently + * is assumed to be empty). + */ +- void (*split)(struct iam_leaf *l, struct buffer_head *bh); ++ void (*split)(struct iam_leaf *l, struct buffer_head **bh, ++ iam_ptr_t newblknr); + }; + + struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); +@@ -702,6 +704,8 @@ void iam_insert_key(struct iam_path *pat + + int iam_leaf_at_end(const struct iam_leaf *l); + void iam_leaf_next(struct iam_leaf *folio); ++int iam_leaf_can_add(const struct iam_leaf *l, ++ const struct iam_key *k, const struct iam_rec *r); + + struct iam_path *iam_leaf_path(const struct iam_leaf *leaf); + struct iam_container *iam_leaf_container(const struct iam_leaf *leaf); +@@ -718,5 +722,40 @@ void iam_format_register(struct iam_form void iam_lfix_format_init(void); +struct iam_private_info; + -+void ext3_iam_free_info(struct iam_private_info *info); ++void ext3_iam_release(struct file *filp, struct inode *inode); + +int iam_uapi_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, + unsigned long arg); @@ -357,8 +386,9 @@ Index: iam/include/linux/lustre_iam.h +enum iam_ioctl_cmd { + IAM_IOC_INIT = _IOW('i', 1, struct iam_uapi_info), + IAM_IOC_GETINFO = _IOR('i', 2, struct iam_uapi_info), -+ IAM_IOC_INSERT = _IOWR('i', 3, struct iam_uapi_op), -+ IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op) ++ IAM_IOC_INSERT = _IOR('i', 3, struct iam_uapi_op), ++ IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op), ++ IAM_IOC_DELETE = _IOR('i', 5, struct iam_uapi_op) +}; + /* __LINUX_LUSTRE_IAM_H__ */ diff --git a/lustre/tests/iam_ut b/lustre/tests/iam_ut index b83bf49..fd54635 100755 Binary files a/lustre/tests/iam_ut and b/lustre/tests/iam_ut differ diff --git a/lustre/tests/iam_ut.c b/lustre/tests/iam_ut.c index 867e020..5320c8d 100644 --- a/lustre/tests/iam_ut.c +++ b/lustre/tests/iam_ut.c @@ -64,8 +64,9 @@ struct iam_uapi_op { enum iam_ioctl_cmd { IAM_IOC_INIT = _IOW('i', 1, struct iam_uapi_info), IAM_IOC_GETINFO = _IOR('i', 2, struct iam_uapi_info), - IAM_IOC_INSERT = _IOWR('i', 3, struct iam_uapi_op), - IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op) + IAM_IOC_INSERT = _IOR('i', 3, struct iam_uapi_op), + IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op), + IAM_IOC_DELETE = _IOR('i', 5, struct iam_uapi_op) }; static void usage(void) @@ -73,7 +74,8 @@ static void usage(void) printf("usage: iam_ut [-v] [-h] file\n"); } -static int insert(int fd, const void *key, const void *rec) +static int doop(int fd, const void *key, const void *rec, + int cmd, const char *name) { int result; @@ -81,24 +83,25 @@ static int insert(int fd, const void *key, const void *rec) .iul_key = key, .iul_rec = rec }; - result = ioctl(fd, IAM_IOC_INSERT, &op); + result = ioctl(fd, cmd, &op); if (result != 0) - fprintf(stderr, "ioctl(IAM_IOC_INSERT): %i (%m)\n", result); + fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno); return result; } +static int insert(int fd, const void *key, const void *rec) +{ + return doop(fd, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT"); +} + static int lookup(int fd, const void *key, void *rec) { - int result; + return doop(fd, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP"); +} - struct iam_uapi_op op = { - .iul_key = key, - .iul_rec = rec - }; - result = ioctl(fd, IAM_IOC_LOOKUP, &op); - if (result != 0) - fprintf(stderr, "ioctl(IAM_IOC_LOOKUP): %i (%m)\n", result); - return result; +static int delete(int fd, const void *key, void *rec) +{ + return doop(fd, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE"); } static void print_rec(const unsigned char *rec, int nr) @@ -113,31 +116,61 @@ static void print_rec(const unsigned char *rec, int nr) printf("\n"); } +enum op { + OP_TEST, + OP_INSERT, + OP_LOOKUP, + OP_DELETE +}; + int main(int argc, char **argv) { + int i; int rc; - int fd; int opt; - int blocksize = 4096; - int keysize = 8; - int recsize = 8; - int ptrsize = 4; - int verbose = 0; + int keysize; + int recsize; + int verbose = 0; + + enum op op; + + char *key; + char *rec; - char *name; - char rec[8]; + char *key_opt; + char *rec_opt; struct iam_uapi_info ua; + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + key_opt = NULL; + rec_opt = NULL; + + op = OP_TEST; + do { - opt = getopt(argc, argv, "v"); + opt = getopt(argc, argv, "vilk:r:d"); switch (opt) { case 'v': verbose++; case -1: break; - case 'b': - /* blocksize = atoi(optarg); */ + case 'k': + key_opt = optarg; + break; + case 'r': + rec_opt = optarg; + break; + case 'i': + op = OP_INSERT; + break; + case 'l': + op = OP_LOOKUP; + break; + case 'd': + op = OP_DELETE; break; case '?': default: @@ -148,52 +181,79 @@ int main(int argc, char **argv) } } while (opt != -1); - if (optind >= argc) { - fprintf(stderr, "filename missed\n"); - usage(); - return 1; - } - name = argv[optind]; - fd = open(name, O_RDWR); - if (fd == -1) { - fprintf(stderr, "open(%s): (%m)", name); + rc = ioctl(0, IAM_IOC_INIT, &ua); + if (rc != 0) { + fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)\n", rc); return 1; } - rc = ioctl(fd, IAM_IOC_INIT, &ua); + rc = ioctl(0, IAM_IOC_GETINFO, &ua); if (rc != 0) { - fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)", rc); + fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)\n", rc); return 1; } - rc = ioctl(fd, IAM_IOC_GETINFO, &ua); - if (rc != 0) { - fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)", rc); + + keysize = ua.iui_keysize; + recsize = ua.iui_recsize; + if (verbose > 0) + printf("keysize: %i, recsize: %i, ptrsize: %i, " + "height: %i, name: %s\n", + keysize, recsize, ua.iui_ptrsize, + ua.iui_height, ua.iui_fmt_name); + + key = calloc(keysize + 1, sizeof key[0]); + rec = calloc(recsize + 1, sizeof rec[0]); + + if (key == NULL || rec == NULL) { + fprintf(stderr, "cannot allocte memory\n"); return 1; } - printf("keysize: %i, recsize: %i, ptrsize: %i, height: %i, name: %s\n", - ua.iui_keysize, ua.iui_recsize, ua.iui_ptrsize, - ua.iui_height, ua.iui_fmt_name); + strncpy(key, key_opt ? : "RIVERRUN", keysize + 1); + strncpy(rec, rec_opt ? : "PALEFIRE", recsize + 1); - rc = insert(fd, "RIVERRUN", "PALEFIRE"); + if (op == OP_INSERT) + return insert(0, key, rec); + else if (op == OP_DELETE) + return delete(0, key, rec); + else if (op == OP_LOOKUP) { + rc = lookup(0, key, rec); + if (rc == 0) + print_rec(rec, recsize); + return rc; + } + + rc = insert(0, key, rec); if (rc != 0) return 1; - rc = insert(fd, "DAEDALUS", "FINNEGAN"); + rc = insert(0, "DAEDALUS", "FINNEGAN"); if (rc != 0) return 1; - rc = insert(fd, "DAEDALUS", "FINNEGAN"); + rc = insert(0, "DAEDALUS", "FINNEGAN"); if (errno != EEXIST) { if (rc == 0) fprintf(stderr, "Duplicate key not detected!\n"); return 1; } - rc = lookup(fd, "RIVERRUN", rec); + rc = lookup(0, "RIVERRUN", rec); if (rc != 0) return 1; - print_rec(rec, 8); + print_rec(rec, recsize); + + for (i = 0; i < 1000; ++i) { + memset(key, 0, keysize + 1); + memset(rec, 0, recsize + 1); + snprintf(key, keysize, "y-%x-x", i); + snprintf(rec, recsize, "p-%x-q", 1000 - i); + rc = insert(0, key, rec); + if (rc != 0) + return 1; + if (verbose > 1) + printf("key %i inserted\n", i); + } return 0; }