From a23090430871c551a88493cb3ebf5f00f2021eca Mon Sep 17 00:00:00 2001 From: nikita Date: Fri, 2 Jun 2006 11:22:20 +0000 Subject: [PATCH] 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 --- .../kernel_patches/patches/ext3-iam-separate.patch | 279 +++++++++++++-------- lustre/kernel_patches/patches/ext3-iam-uapi.patch | 72 ++++-- lustre/tests/iam_ut | Bin 57742 -> 59587 bytes lustre/tests/iam_ut.c | 154 ++++++++---- 4 files changed, 327 insertions(+), 178 deletions(-) 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 b83bf4976e3107b46744b6ade99e1988e9fbaa89..fd54635b2d693ab5f2718c30b11a9fdaba74951e 100755 GIT binary patch delta 26893 zcmaid2Ygh;_W#V?-MjZDljLNxAqlCZK!DJD5kd)FdJq+)BS;kjf`S_eAOV7bi;6r{ z!0v-5icb;niK2ig7NptbDH;@?Se|0#|2;Ds#ozDu`TRGZ-8*OI%$d_>ZaZ_b_JHre zTfXYln4A@Ur?n8`)6?s6$9E|U3Blh0Y6J-(anNpe?O?w1IJWPIbe13ug_3Ev>Tpf3{eb@8qJptl(uNABz38^%`% zugmGIfFA|RTN0m?>C=^e{=}mggRjCjmNDcQ@2JdX&m|)u|+%eidKMI#d z;p?OD<574>6s~3Xe!$DB{f>d-#jlgfY~W=xtfcT$;`=F72h96xWe z*WTAC(j3EB|DQjJcK%5G<>SZ(=MPPt3V*P~O9m8!@Ao@4Ty8iY;UOdW2;@p`3RC__xmGG5c*rd6%c$8AK_Bve1yv^<0IT^B_H7xYxo!|L^U7bAshGz7B=z` zp0k;caK$Zrgi#*gBL*(5JX>+zscC_+Yc}$a4@6!$ATG6uOa#iMf+_fAAubg#k5jmK z?&C}N6fmz-xb57V8V1kK6js2w{TgQ0r=&8xQ^PF6lpKb)XqZKrQpj+%hFPR3tn_o` z3`YuBwkhqoVzx$L8K)F8JXXUj>y$nW57sctJY_J$#TsVWr?4}gYp!9|!IZHK=V+L9 zF@+^MM;d0GOqtEF0Nky`SJzdZsrdB5;Ne53D7fF0eYg9aAtRYPNer0x8!#1)^eJldU^(Tuo?5uX>vCEB5>E=ekSB z{%D%_<-q`>%U2Fm{$LEVbs3hO<@?L(?dCoxq#p9;b6ri*Lhr>uVR8gMvE;z`3?Zs2 z3ctE^snVZcGtj#f$chZmEzQtUIq%oXk_)R#sIuhys*($pJ@cK_C1D)=t4kd2Q1&}m z-d}leUVP<+)uS)22LAcc;GyQd-!5HREh@|M6|iY_NhI-5EclaQ4Q2D z_g6htpBb&%*C4`2EktVN=wEA|htn@Puq~bW9A&!GZr@a=9CQ@3rkUblYMEl2tsWia z1Ozp`J^rcAes)<+^af4zN)W9ap0BDZrbP)ey~zI}_%WpXUj&~GFb}l^>uQ3()dj%; zOz`H*2>vg6)&Cd0%ClFEXz|0ait`b*da*UgOpq_Zn3)5NqE{{rQpYu_g9AVYo0^z zii^_{mOX$~E#dar_^r4&C1F`V4Gz-a#DwKG3LuCTP<$Czefg(&-VSJjDesn3Q;Vw> z9|mcMnXGvNv@u5-18~MwRctoa`-_`?{qv{29_aG z6aUv| z2Na;#*LYB<>A&cBuEk~KOLkWFjPP=FE^6nRxAhQzND#x+OZTk?A~OLRL&5B!l9w=u zsPevLnJRwb&ZX6rC2OEsDBSqFR>(w*2tBh-!4ew6`OH$y0Ms*b$xEvv=&2VlZ6@7% z2~%SAyq9*@z;{-cu4#C|Ah5|X515pm2d9CijZpH35m-wvurvH=gg#hRD;DpTk(5g% zFD+U8(&y}uYlmUdwb*~I@o$$R5b&j{3Spd&#jKeP!e1WyKS)0V(!9!-1uHL{y8uo6 zRX6RSyf4rGAAa!$`kmX)W@exHE4z^-ZhQcZRTYU~;@l!IY%Fqa7@s^YH*TH(ZQQ!t zCl_{tT42d73|;|hkzjGcvKZ#^assLUi$J8Jg%Q2xy&o@KsyPVR&z%LiYOEbR)haGd zO<1;{C3~jg;+(Sdh(ZG<0ve`&dA8!>{CW3XD%pMRUSO;)ePDH{vhi}R~)zJ2H z72K4Of8g>Z2xXkvt{PEsepiE-wlZ`luJ>zN{+A^W!!%W1*qasGH^{dWTg$e2&&M{6 zvl%7khf9}6Ui-=cT)fv=uL?#?oi(9sdSSubh8=SXrZy{>np0RXqhXBb+wICReFyaz z(|6#olA*)@00#^j)W3A_A7Iat0VTsr#G)L07KwrdV*b?W(>l)SIMM5-GG&Z6TQ%=J zwC{+Lp+idtiiJ%I7BpEPX7k}jF>TU9445-@=G;kh$|g;W5rex8DCyOAXbG;9XU?2e zmZPth%O>UE!g$u4g)!bgRCBL5uGq_o%MS55NXT?wC%)8U9Z&bF;u^^I-aq3yMV#e+ zhi`-iM=#f>Eb%*hr!}$y*SR=4OZ^TLcpYC{XzJ@_zIoyguk~Yb`NQT}fG^(^@%>5) zzSYb84wq-+$hQZ1Z`Zs%3UyTke34fXod7994% zcLctZ@tu$F3ViRx_aS_r#`hq;C-MCZ-yiU`aR*rk-&z{wpy%D2(8Oz)@MP`KGkcz-x5;OxT0NCA!dx5I#buz;(1Lewf_*bvfSvz5{SiX{SFg; z0ZJN!>zfZyC#@kUSts}s+1E7(s6p!o@Z`(w&NXG|C>?97w~jI*Cvhq2E4Y#CI~vTf zP@Au?f@|h8rfr3wU|&P-YdwRjD_^56+;|u_6;{BSnS*lU;oNu^k5Tj-ihkTz34g%q zi(5@!6XwGjQy;~a@1p3N1$mu-bq@rK_*$Lksx~>O3R*{*n@)^morFNX&fI8Sz(~Hz z-?{iCe8RU%6I=g& z6{5UVW4r(d_dU=FZs7W@0Wh`iVU4~Rdi8DB#V!db?$9DlVUz9D%q{kw2sMseYKV%x zQ<(9q8lkxF@1PXp*T_$D#dG^~#f$j$Ee0A~z|XAi*Q57jLmtoq)WuBnKeq~amJI~| z`B%8u3kd%2j-wcR8zThLRaY=6)OHv|st8}ZSZWDVR107Yzxoi22h;%|*{WqGo`|SI ztObrb10QhJ%~%g&)KicsR;@)Zr6$1&af+`COu7w{J~MT zp_{Aj2E`b)93#c5r!^lnuuq)I)_kmpVLlqcRY~oDw2A6aHuLc{ESseIfTys!1bLDp z>N=39qcXv4ips@csj4m-($uRUR9AhB*_N(ugU}i316+G&s9ykhp{T2&{BeW1y{0$^q-0RTe0BR(a@qg*t}%E-IVv_qwX*ppgAS%_SjT5Q>+@ z7lqo1kq!uT2!p>Q)NWM1EEGY>2Zd?^Z5|S;0`eag>Kr(GMW|#@IU>|xDDG9Ec0tvz z3FTt6qe8XCEO}k18$s+1q58wo-V`do4($JyQ2QYFF`>Rj|F?yjfX3rO&4Cq82z5V( zI4M*Iw4D;_N=R^8sH;Hq9ic{{@?D`ONg>`7s&#!K-WO^H9Qp&Hdcr6l3iWp|`jJpM z(8b3>twV=1=m$CfEmR}8P~;QP#_?03rUUh?P-o%7p9ysn6!W=I_kdcBP@Q17b3#1< z^?o5#NfK^vgn9=uofm2wZ1cpr~w%F5*P(axl~gj_7bVS2bHB#jR7+iQhf!KWl{}A+j6P4!mcZ%N<-UiGNOJ2 z(UnrQ1H+Y4t%ZG8N%aWywOXnrP}CZ!!kCp+fIw!gR6jvow@W2+aFUcN1(@rkssxqw zQXK?Oo>WKR`5UBK4$M116C>Rz)k%2CT~hUe3v2{UkiHx1Pd#wDNvciI(BHrt8aGRI zH|%?lRQn<5y;4* z!SBOTO@co@BGn$~_fe@X!Jv;}T=e_9R0|{Ed%IM#A>j_GN-=N$A=O^U^f-9J%CHkS z82$;V)`QHGQoRSa-X+y<81N~n{so8lr&MnM^J%G8q3s!|o=1n>QauPiepad`;CGKy zIk5I#sdi%ceNsJy+4r1O`_jBOQ|m^?VZ0Zm+Klc8&<{(+OH$$bPP{BtI*fJ@qeFRz zq`C##`Vv+K*XN~(s{*{;)J7C0XpfZ?cnZ|qgtZhX-5sh;T=bn zpzU2pjjJQ-iT50JAC&gKqdozd4;=L#Jm*74@zdCk9Cf4T)=iK62;+Y0sO3=WSx23Q zUOscw^U%cSj_LZGt!8E}>#awI;-wIyYpNmg{zu?d?7fYbT z;5GWHgD=d3V|4Kicvo=ZTt@hwyG=dK#V&BmV3~h3bMX{2H17#6u7n1Ix76ig2pG*#Jw*x;`b6yu9A-GY`J#^neL=aY;Q|2m`iCF58%(5}j7NfPIQ?R?cZ^eF08Lxw^d zyeBf#BX40PQH@8SBJdS{QdMXBYOZRnbp=^ohEJ(BTAz7-`!u{*wKZ*yy(J9+QK3+1&T^lT|-Bhc;{+nfO&D$72E=5hGlh-8@#Hl^oXC?E@_GC zz*+nhsS$>yfrgl{Pr) zFUMwctKo)9zC90GR;3Ji4YK1>G@B!)GizF9S0zB-;Ie;qy4>eopPd=mfC_aT+gMmx z%+Q!dsIjhLIukV2f%Q{N^Ec=YvN|C~%Y)tj2r)UwIDJEup}r=XaSiqaI}i3}!6zQur(hO^=6p->cb z!gIZtdYO?17&nw0tqh01hg*m0M8VYXx0qC+lqi@H{(_C48U=I0=b3)pD3~992j&bx z$$GfL@Hy}u%7}tR;c7XZ7czy92p5<0$X{l!z-b@P;Qj<_Tjr3yM7ex z94_V7LODWDx8iUtR2wRi!`Xs)J;QTYuqLuXgT2CUFqchbb4|H-_!{_5sHH5{V4v{S zOsbRAOJd%DNH~KT=_ZYD4G-rr*gXo446o@4uxFHyQQ`PcK5;BYygk23u5;B>X#_t6Dgsi2Ee+oa8kZ17g8Bu}n zQC_`atI#IYHJN-d@d2OH)Hy87K2-{x`c+E@-BmHp54O4wZXZ1>g;FKaQG?ZbV0uGfA9jL(^ zI|J6HWoC$c`$HzP+(3nPHEc^O3{+(If~a(xftuSD46QOyYx{_IZ+>cIFqX4?Dz>v= zJMu1pGK;hqu1OmVJY2tATx^I}OejPEP^ zeb|#`8ZHQ2%mr5ZV)%l@a)fe>pZO)e6Fdhea%hLWoE7{JoG?HsF08kf+U(s}*j|=-j};ckjozF1{mJ{GuyN)!aGlV6`5DBm z^8_Tm2iyYf(yV7^x(^$1#wV{{x0f z?yfH>ag7t0&sPb_{q46fQ^kTm_`E_;GZdP~n(C2-0Ybx|+~oeO zn4B?l%0%)o7C$r>&Xqj+Q7#@~+zHHn$dXCkp~hJSn^0Ar+}e&|owTXd(EAKUue|*B zG%uzoBl04;B~RakF=HFSas0_k)d_IdQz;nsX0;6EThvHcY?0y@8H?2x2zaad2F8jg zKMW_-=7#)CK*Uba{Wq!a0ZY{g*YK9=1Ll2dKjyq&jfGPL)Tf!er1MEIsNRzis7J(Z z);%9rItPjY)dKalDu8G~)fEnmj!)>0FR6C00Uirrep({- zHC=gBE!CADK&h5`8I1Zw>>1s3TAdCs{?##fFoX{AV9B3+Mm>yW3+EyXV5zrYX`lKR z&rh`nVg^)m)Yu}nlSckl&4GTTdRX(i4t)F69O%lg;xP*XY6tkUMZF0?c9QdCcrSF9 zTu;sd%$H34*}Zdda`*0UlAEUOo+kN5F7Ivj=}gJ)m)FGmut`p=tS>}ya!7__(>=Fo z2DRY6$Dq#zFt^t$vWkUnf8Gymw2}o|zwm#X9+o zSwc*!L>Qq?5#NaLg1pvyziF$!ufkN}wvwkVGg=JE!tJ7i`NK)v+M#xALD^{T+6s$c zO31zkETklH4by(q8`&(kcoojsl#*iFQvYa!ol?^Dl8VdiHefWRuDO_u5wrvZ#zEDT zl4-x=?P-=PtGy4Jb%_LEoRkK9CxVMs`$6b4rO-fOdo*TpN<#ysCXAU|CQ=$L&0)+8 z`*zSuG4Cq!rrY;%zalgAOuHA>tQ1;i}vKEWwcF$_rcK9@?IHj*?>0%EJ1L|iaE4H77I#c=^sAs}lkQiVP``D*p z%UY=M0sMU z;HV8JEzAB8{+X7IDxeAbq01mY&ZeIO-wI%IrR8#w_*At74&&7AVDklM-HwJ?VgKS) zw91PptT6t%qtp?73f%-uscy40-}j^I0Z2`Cr`sKT=sJ_{w|UUdK)LR01A)^sK&)#n z2VVjEPG?@z>yJU#vKgYtS!Oqa^EuJWH(^IyK+(&$h~FN8vqOhFt__bE*uKW1qt!?dbPcR$jjS8bj;MrEH=1 zK5Tctsk4H6r~gKHbnUjB+#7sWRHyePFJPc3Q(w!U8BEqrEXD zlrRNSWpsFy^>qcwqqgq979 zF^E-C;MKJ0BF}jZ+P0Akz0qxRGWRhbPt3rY!?*08Vgbl_($G})kKU%XIjxt~L)}w3 zz{tFUNqrYz1$|`r^qo=MR@D155~P}s0Z1hM3vj~}?>}uDM81YzGGBQI73m3B1|{Xg z#m+#5PFAKp0wZN*nOP_7$01o(wt+0W29rN4$3TAjkPWDwfoxp-gGeW!hqCJ1H$b;p z4Qh#;fhbvpwL~stV(MiztfjIUQe-uXQn7p2^PXteD$*Tv@OT!!WvS6X@T1u5?sisHL1#3FIx$5wR9b;m;ngw!ssn zpa}pI!DwnuJDVVNPJ44tBy4X&`;5p`EF(FcYHykf;cz*fjTy-v2MRe?M2#w}o3S?4 zYnA|oT8FTL)oZ>Gq|;YobZK1;m(2BR`C@>O8(YE4M{Ep=syi1S!_c|$Te#>zq}&9J zTipXn%T3fnG{)@B4K-(sb5KKW^1EDo0{YIabDoQ_z|G6$B5i;`+wi%3o+7mAEsz z*~~>@Hv?w=Ee7)2UF&(&F?(DA{5>_l+`b#~<}Wcy5%xWhFn{TNV297W@4;~S6-Jq1 zK|O)`9F!K$UtvEAt>oWUJHo5bM*hlZH$jy^Jm*z+OdkIj+_>NcGynYd?Wiw!(aZ^%yBQ+X~~q% zSY7-DP4T(|2AAsJ78+GYsL-!2LIy{jKnYAD8?HG)a9tp zptg=8eg@W-f+2cB#@9ei1w&0aP~ctYl-X?toF!GZvRnBvR%@1mnItG#wlR=p4`-;Y zf&6w|5RvT+WZM_Kft_(PY+aA%_-#du!cn(XbSw@eLwmGIomNxz<6HT`=HH^}D4ZG8=Z)0jn zJxsZ2=-Ffr47J3J2@8}7xl{v#i`ucPRv5J6qAM z-Nw@T);$$zqFteq*8mKrrCr5<1KT%G$wFRtI$ z9`&);>H3NIwP%2m40gjP8@;|=^CEY22Bk&}V;y!s0R>-U11a}WQ1TTSh}?(4hp&l& z!tU6CfSMX8)otG&P_tf|N``wMe9_n3KsoNST>!N(nECD{jPGk{ph7nx(g|Q|0~Wc@ zv;fp*q9)Vat?CY_{ZtKgcKbuozK#a7k6XoTcbci&2DsO>0d&P&4UKeXF*98a=0x{h zX0&*vZkyu1QVghjm4;@!v4dbHUr&R&z_kVeDp{`^7rE_Nir#kt;`Zum$PU?47^>s zJDAo`1MZaWcb@9j*y@_&b?DYD@-Im0_Z{?82YVafxK$+Q%cs17Z{Zwjr0zopVrpr(n$=it99K|jOys2v)BI^Scq@dpta zI2hpHqo6-D8@}w@9tE9HA4c901y!gYBmW}`QYbQ=u^*4Z;ZO>zYG)Ko6-kBt0Y72) z!te=hJc17Tvbqu-QV>nh7vNpeC{$YX;{c%23HR!O1;zz@?244h0I zfmw&fcV~4CL`^E~x&rE=7}V6Iu3#damO{V`YK6I$NeA(pMR^19IFFWsS`J0-?tu$A zIttb1(#_C#9<}U)OA~qsaum=in5#au0l5a$0%k9yt*B{8-GSMN{s9t==}RzIM85*3 z2|Ww}n$mf&)r=kl>&+YsgSF2D{RBZj7jzKDs1ei#syqkMS8^B@ zO~1lhkM+>We*|>~__d(95cGneKH&5lyh=gkw|F=NX1)`&7dHQ1P#8r2E9eXi@q?h2 z=K)l3u{M zX|<#iXj>!c2so^g6bBoumGm^sbi1T3aMo%`*+5w*>CUcLuGdRC2bnxcw`0H!l5E)i z4oNQTbf=^*LG&(3AHfMXO4t*xm8j>h`UWvI-vU{UELMWEgz6{7K(aM(p9K^NK#*D?_o)wK&D4f3GF>9 zDF!xpOwvhM`|pz81Q**Sy$rT@NSX>}{vqjoSn_d6-{P=S(s@YugrpEKpOh2}t?iQZ z8FcZKq|;b`{we8qR7Rebv=_C{NXmj`c1vmnbw4Yq9{ApaN=Uy~l7quONzcJAo|7~M zhkr@>6qwIT8Un5Dm!tr_AZhUc4o;#8I2@340Q|lrDFrHdS<+C@JSgc6U>=fm1H?TX zk@Ns2!YdFIN;o3v7|i@CJOMbbNt%VjQArbl@;Vd@?Y#jr0p(3eo1oygBz+9&k4b7X z7}F4#@b2T1UV$l2NXo%HI0@yU@|2|3s5~v{Nvs#|NNNby-jxyRf+_Q!r0=2U_a*%U z&iO8YSDke;Wn_{3iI!Ni@wM3 z4_K50q7OnebbQF7o6zxLiw5BE2!;nUk6QE{H2auEZ(yXqTeJy>?G`-^N8Dl20v!GU zJ%Pi=EehbU)1ukX+7lM-ME55x`X{>YvS<_zPg%4Zaz_4XQ5lX;TXYINp0Vgx*l@Q+ zHv@XsqH(a(9*Z7>wf9d8VH|o-gCu@m$2htU>`F=iDmNsv&p}8~Bj`p_H5dlJ5YR{I@IOBt215anz)$-| z!Lj_lQE~JQ2Eb!bFa~0u^Dxks-?u7`jt=COY#xS6LB$dQj#Dh(z6#&O7CwutYTgZ5y6Bklaz--3RCUrPrX@=yVexeK(+0eXP<$=D|b zpcvoPbm4t6!QAV(rc8nfC$QBk9%%N-1PgeK0B?{97H(ve`HW%*c!Nx^A$JP!2AN=^ ze{!SQAQPAg!okL~xsf->1dCXb0PlYb&+?*1lMS`d1p+pO5^g*nBZEC zz&m4tx9cMBj0slH0xxE~cx&~vZ$W(~@U1X(C= z4fDWTVuBl(Lf{~j9K1shyk4MqryiKM#02lsqw$uQ;6{zhTVjHD>ssCt6WpY0c}q-i zvsM;wi3#4LYk5md@LpZZJ7R)clXUroM3f)sj^AW|V1SoBI60*Y6cogz4Vd9AFu|Rg znZ;iJ!HxT0YKV%x^SO<;zy$X_iJm^cM&>Or!RI)X)aQQ%zwu@ZOn|q*1o!LFcneJM zfM)m>?}fo8#v$;^XTT2f6XIwXr)$DEzrZkXQ`dxXvK0J!E%h28>R<>rH;scK+&re8 z#=#J7K1(7391P(WFvT!ONI7l~mxCDGZcCyhIT*t2o*RkM3_k}f<@R?u8p7?v^myPQ z@FBOaf&4CqI=KCKbbd1zzM#7dGlU2Kh47GEL)UZ}`bU?p@UO5t+H@I-E_ic}VKg&W z*Y@G?2=^K@sN-^YgnKQ&Lbvjiy9B0nM;VAjcm(MA-3czoOSt1%bdVF_TTtz|H@F-x z;Z8AngB%P^jS3^`z6GSR-tIL0;@s`bU>XNZxIHF8urv;saQn0J(m7zl9mX0;7mMG0i^0p4mis*O=x3wF?T5D6Q!}l3#TdTuq5X5a?E1U;CyVICm2qyv@ zM&VB9H#r$MVqx&ROG$@OkPf3D9Y#STVc$ih!zf6HQIHO!Ab$ilN4ORov|Nge$25UW zq~j<^$5D`uqaYneK{}3tKE*7zNykypdsvbjk@1P{_&Dh>3esT|q{Apkhf$CYqaYnd zK?OXg$b?a3f=m=e-F0wYe@uSb^ImDGiK2+fpMyG{0vtsV zQ^cnhOmTOu_jIX=q6oB=yf`rP97Pdm_s7_**g%Kcu|;rlN;HZhHso>?MQjq+FzrXZ zmLqcO>nMuY6w{XaM;lx@HjU3Q{J<3P2RDzX=jzCb*i82w?|~5S7#3PQ+ee0Ofw|%^b;*6X!>^&E&|5*uJKvi_4J{vHgr> z#qP6S*Q@Jha*#yq0E5xb>1hal=@*#R$Q7IRrm$xFM78atMB0seuYbT?@)+ z9(T17V#FBcTnlj(H$aHDuH{htudX$r_;J^1Q34!_A2%iwC;<+|kDI{s0vw7TcRh0- z_!QT>@!7g)^+B;sm99T9Akg(Y>h zw|dkS9XQA-ew=YyGgafq8^}!6_z4CwQ#F1fx4_g5V<8NW-XT!~J4!y=Nx=W81cHila#>Hl7obF!q-W;9WW>zoMML5PF zFslhpVRx|}lX&x#T_V{40gkOrXxttHn2WK1jPvSVm!mfogjICe6d~SJ5KfeQ(FR6B z*;r)4p(yBt=6X}EGn)#+$qNoS(6@ZWkrD+nLcFOUoEimlLcFOUTsI2l zhu#4{;q)k27~)L@;fyF)6yi+<;Vk(qR&Oh>dC0~ET^O4Rc;6T{6@++GK{z+cdixM> zDhSt)f}KOWsUTb^Cqj5DuQ2kk$mrA<@E~jrh;%&`Guz3JH(p` z!Y$>`8tfC|aGG!@$yd2p)FL6?R1oea%~CWx#G4Aj-J{^h5N|37_l)u}D#V)#!o8$` z(_49CMSwRIP?zBlJn1M_KzqF8nNT+qGr^xYER8o6Bo6r&Eos-|Cvj*`OfZl~vy(WS zS0c|ETX!gLA4nX|ox*eQqe59OZyyL{7Foogw-1osK0tc=0O{=mq_+={-abHP`#?qztoxJNliof+X8Sj5KvLva4Q05zeIThkbD$m~$K~wB&{$|k;~f$l5R6lbGL$_RR(J99`Sx1mpWZ8vtXqpk9W0e#R^g!sVR+;oW9w@Vf%^ z!uz6%2e(Vn&*$e!SD)v&-XRcvmGlk)(mMo5?+~EP-oGaC4uKyh@eYB^$-G0L$K=NH z8gJI*^pq}eCmP8UE^rYpk(@V-*}UJ|IypJQdqb1!FXf6ixY$7QvU@rf#X^0{?sAWY zySSG3h9)=Nj72t3#JDZnb1m-&P41GyMcxmZ+@lE>c|T}!pMhND{h-NLUd=_`51Krb zZxI8$A2fMngeQK0cY!8Pl=*6uSCSOVm1_LYoD7M2H&%16)3~$)HVT#_cSve(J-rzktB{Rai zhf^mS*ANcx9!{NPAS{!qm=md!KgGb|4p5JiI@8to)A<~V`EBrL7zp^hc{p`u7^sPR z@uRmArXG_a-b$GIw&XhW3h`FL)Z-ewmQSm^moW82wAl&qUc%Iq(KCh$@m|8zQ&EsY zyp=HZbQBDS?!tPL`cAZOD!lq<5KF9!>xcKfEmKqEdT;ks-Z*%2Y8G!C{9$TQgj0&7 zoqv<{(+l38_T76ZW}HPAf8BJ_DMd)96rn@VyG1&q2^dS@)Ae~W!bVd;>3_vlY zGm4PTC_*};2q%(?;&L~3Pg4F~{`XE`RGTSQbbTD zc*W}#%nH2Fz(_vQ8AV8E6d|2ag!Y1`AnA-EbQ^lPbT@n{hL&TXSb7>16zPm2q%(>{ zNT(Dbol=B$V3b7CDMd)96d|2bgmg*~(iufaXB44awi@Y-BBV2lkj^MVx7qv>UuP5{ zol%5zMiHumIgvv;qX=DuW8{*~C_)jPQiOC$5z;9|=w>Wu4M?XHp?D0_kWyp#CBDum zLOP=e-3aGtLOP=e?Selwqnm-#oJw(0X+b)p2^fXra)}%9vkj^MVI->|}arqto zvk^$#fpkg{8UuB8BArr%bV?D@DMd)96d|mSc$IH5ijc`DLMEdK?ZoPZSNSHR2s}Fe-jjgSNZpV8eZj_j3Q(*icksGYP`xf z8AWJYzJ8T&GK!GSD1xwtW$2Gr`Sal+c$IHbicnWLIbP*g!>V|duTzQ$G8sk4WE3Hj zQG`rJ5i%J?$Yc~DlTn0T15LcjKLszst9+ADgiJ;eG8si8WKxQdNhv}mr3jgnB4kpE zP#R9(w@ES?MF?-m_*K5iC_*Nq2=QqJukuYs5i%J?=qIQPukvLM-XY@MGEO>p%w369 z25<6BMiGke<GAKyvgUcIS)$O5y5jGyvjEzMaZNSp*_$#UgevVB4kpE z&_eKySNSHR2$_r`WHO4-CM+&^mA??fKY>^WEJ1jcZ!(II$tXhq!hFN4{5OD!H~FjJ z&Ulmmd=91@UgevVB4kpEP!601ukuYw5qbzHc$L4;+dnHkno)#IMiDX@MaX0nA(K&r zOhyqh8AWI+xJE{ioU)d@kmBvK&L~31aFUdijM-$-A|J1$J~&)WkW5AqdQ;%tTaZjf z5i%J?D4J1(OhyqJ2#5bVNG78QnT#UD8{}Vi$Yc~DlTn0BMiDX@MaX0nA(K&rOhyqh z8AZrs6d{vQgiJ;eG8siEno)%AgO=ZS=o5I{2M(ExB4jd((2d^Dv(v|$j3Q(*iqL5+ z$)7pImw%r-WHO47$tXf5qX|}i@4n`Bo>Lg%%{R`rc-S0wPq;kA z+rNya`s!;$e-sDvoo=9%i$nB<*uWwbhw|&Sz?EDarmxBNbwY6jj}zF-#jEt?nUA|& zqlsBuyjEYSH64uN)r(n%W$JwQccj*0e29!DFl8DAaB4^(*_AobI{v8aJ7O zMML^^_-+Rd-=($eI8t`t@Ljsy03FAV2U0?-UE}5@SdoD6#dnPD6x%n+g4K#z{{?IU z(D}2qX;Uea40;2VC_}OsU7Gp1(us{_Jem;P>YG%H*WypoT~%kC>V-^{wCk&z zc35)juD{*zwjNMNQwbio;GvtBAhM8txQX4gNfiEOc`E zPHa@}6wS{1xbNJrRFXTjgGkg0|JNRZ!@TnUwI9JUdGk5O4og!bz zY9M{CQ`*UStdFmi^Rll_sc%mt;*>|0^=;p$VaJX|R`am4*16|<=b-b=J@;&L$`4zG zbl7=pbGg+b$vJ-5$#%+}KF%CxH`sBO9P}-~5MR&qjdCV96B`vZneDW39`-G;T1ww+ ztD*GGac;DV5=Z#vPMG6l&+*OqTc>Nv$CO(ESccaj3jsT9rCpyc{!&`V@%UEcTCZ_= zrgdS3*RQ;8gf{~$g}%DQJIk%^ae-bH{vj){?%~9yKODE;`!DUjKiYIeer;QC?)zuk zV1(J$Htr_mn{rC(wCd5@PTCvwpHmAGovJoJnU^z}}ZXWO3wqk8SGpUYpj<7+dG znp~p04&4@S1qTftGrVNjaPN3!zHPGSdp}k#aZzm&knXx^)lC1cuh(w$`zOwtHG9_z z?+$5CoHTt>*(9&-9qob$avy_!y9VF!V1RoW+TQn@N`nY_*G+x?w%Fn(li+mMOZP<7 zu6~bADD-w7n<%$<$!}-7oG6qtfe!Yr0L1A-M?!nAdy@chZqNESukVAXCOYm88InQfZ$m@>cA`};e zyc5K+bnBgEJgURG5Cnx+kA)!{*N7|f|nc&03#R}*HZYfQ4EZWDty>12F4i#AGVEw zVL5!*KnBK=iVs`Kz&JzU!=^GYY=K>l`k#H63g{Uhwwi%)>w^#5&A_;Zj)8O3AHz$LBuW7DzXiZSNTj~)i=+OZ z02)per8v%xs>i~=0+|MQ=L)a>ds*EVM5W+imZ6%n)Zzd#A+Zj}*-@=XLE=8ZwNmr2 ze+QgX?X7q(OE2g+!DEF}2x&%jbR}c>1mN10i{bYH*REC!e*&;}g<|*%z_qIq!{0N0 z^y3%bT>2g5+T^^6A}oRu)@SRo<0XoC5syWdKfG+Rt?B`;RVP{BTxtn;dsJPCR*L8f znEzJ;J8B364vO}FGTMK96vk5wO^;K)@|l}o9fvH1z+t{W#i#b4r))$+t-ppu46gZ2 zyJ3(o!v6}t7=;T_%?uw0TS*qLBG!2DSPLQJp=;L8aP0$l5!IdG_JqWDdK%lOj)*UqmH{)tUw&i^2=BHE#G zw8N$-?8kb{1hxadoWWgyd8-wgv`UWvuAMK5RvpCY;SS_7fzATvPe*(~FM?<}4Qp5D z0UQj(pU3fKI34ii5;l#t*P5gl@a6w5W>B=<{JR*W9spdc5rRf$M%#Ie9Lxo=6cv{b zu+i)G;YVqFvJ)m{wwOL^*0g!EMf9xK)q=CT^^nUDLYnSW1nS*?iv l{~GUykFyiaIr_3zFMQ_egfU~TpD}AD-u921Q#NLd_()(GT|Is4?ygUKD|h); zr&Xgxey6DrV#$Fu`QzH{PZWax0;mxrgv3SHJ?MA#U^Lg(+`8icU>_zKb=@D8bK_PUY_yzw$Z^P&pZ$-`yoHH+usZmy34bn|Zrj z#4MC@@yyA~_!KcKrQCLAzlNEmSSbs7W{0j|-b&LL-lAdVu{4k2M>Nc=mKHO-TEon8 zX+wq=XqZ_qZOQNq4YLTP9T>h&!z@Z^cZU0G7$OaJO4(J;bU+2J`qSw9(M!K7|K@!E z!2?S-EJv5#_!=;@bjDqNr}8Es{<3;Cv@mEuC8Lj6xa-z*A(nf8qGi#6If2Se-dHzZ*|tUM<=&r^Yt! zgF@O~e<9aZw!PImU>8U0!G;TWy$5Yol=uJs^5v!e!pg;7axf=$307XXYaLpa&i!*~ z*YnG}($cQKRCGPRv`eA0%~$5^K*7JftHWKE{RO6XEZs9#Ej_<{)WzlKacgw*ZfQdj!?Y3t6DnhV&x(|Xg&sw#fJo?!G-?+jvOB_ zpV;Ng zt^T^LPDS|~)=Jm&M(fLmILR;jt9LV^pJ&vWpp5RP%HL5VMvob_>k10m0;cWU*-aHM z)?^F7D%T9f@KcuG=2YH~`Lu9X3k(l0sn~iG4>YIHVO6v(jPVea|Ase|Uo1_&a|Cdc zSB=JZ`NeU`i&9bOF!#Xn@{3xftuD@QcSXHj3e`5A4Xpibm|0x#SCropx9(3MS$PVK z>9&fAzr?v#%bVV@4P-U?(x$P($|v>UmzVBMzVklN0aF!S_bu)Eh9O**)7GTuYI&0vDQJwb zy;p%#QNEKghrGz_EbY2Qcen(umd5_u<0yPhbN}LUU@#(+{fx2pR5r)pN0&Je8B$b~zt01L>#68?W?r0h*KHL;b}SvT`3m*ZF-`so z*Tb0dkj=01y0^49XhjMun?kTgJI-9iG~hQC<&_|PW+A{>utV~lU!&PD^BU$8^I=$5 ze{+i8;>>(?2~Kg4?ey%@U&}Avn0#loN74Q4j^$Z}ySA=MY9~XZ!&s!>gTGajr$L1k zUYhr1a*rV2)Hm*b&}%^T6Fu%EW17 zr%ue9S~h$3#0k~BKPWpS`giQzwOfyYUB$p2L%R+fIHa$ap3*Rh?{URNvun4`D=wN^ z+gqK|u%i%V)5p)5Qrx3spD{i9bsp2B@1U*&2Lq$1Oe0nMKkdEy_3JgH|KHlZ%PD!@ zTPYnAWu~tUPY|}wBVMCWEjh)zHq@qe!#n*BZx~Kuo#s1n=|aE5n~FE?z`c;KfO&KA zg7;=9wf8oxv^-sg;V*(e-Y#G&i$mpphs!%~jByAO1(| zn6Jq>t~!me zvFC{~ej7%zo`pcZw%lm#!$`iRe{pdce8RU(6P(CgE!V|kpyXS@LRbTfP^{3nQwmXB zsS$pHK76YTAGq=RR*!{bzBztTz+6_sg?wv%=I-0EG4kEbA_VRMisSR_THfO7IkC7J zFLJwgJDRLpc%-#V$a;vkd-v$^??zYOy?Xp-nX7er&=XM<*K6DZu)gm;UHf%Diudc< zYSmHPz~fr|xZ8uewq*{A4{>cbt9~)c8#Tsb%S_DK@=12VuV1Z`Xd7ztI<%uRC^gmH7NiU)eWlms}tZd zpkiR#R^LF@pehbP)9O_i+*P+?^2e&Fd%=H#>VR%a4TW1Js!iyYq&DT@)~t5bz-C*m z#K27N(Ea*>Iq=hRNXb9)>Sbbs%v)RR;X}Y9Tzbff@)_8mfADRA{6QfI?%XfFEn3R)SDdMLr># zsZLN)b5#q=LJM^>h_+O(LgH5H0cg9mN`W%lsLx^AwrW3W+NwW5?kcq$_3adtBHF9v z(8ms;hL8|%3w1lxyi=%+7-^SK4+Hxhp`JwLZlQL9xjiwVzJ#v#3N;aKuurI0!0fw1 zeGTQlCscoE?tP&a0{TFxuh9QPq0%rXJ`$=2ppS)02Rr+P`U(9$5o#{vJ|NVa;NnxE z8lml=P(5Lt&xBfp5k40xh_)|;x(ophiI{2t@ed1C2en7Qg%skbP~Sr7$Ap>+k3KF` z7Z~M)P@^E>mqHzbSxyQy1|7Z+k@p?ZPJzl9o);eQqC2~_?j)C%bNqEJU++24iY=Z;H4-GhPt z5Xu7PpF%ww1JVD08`%9Xp$eg>%U}vP3#2Nuv5%JO6v*5mRXs3MF4bcSU`D;P6mJs(yH4!xC=W^19u|36s!QPa5vks(h55Hps+&OcQK{Yq z!;gVs^w@+|1a^8{s(C>Dhg2=W@Dox^gg^chVne}CN_80)eM+iE;Qnc;>VoafQq6#b z&qx)72R#eYkp4NTdShkS0u&7YJi3F*3s4ulI<{4+FEQYYQr!!WcuA^-Kz&)NVQ72> z?4!pvsb<5GUj-(V@S0Tr!Tfw(sx27)4XMUp_Pr_9GN5diDjk(?NtF+4?|`5f>20a9 z!NpFgZUD_)Acoohj#ODM!5vJ$&n^nUMUnqtc*`N=FTa6P|I@d|-a(s2|}4XC0B03=XZXl5f9( ztDzyso@6I^b#k*J2f>OxDIax#n{>l8Gz`zpiharr(|8fKzQUvl7Vs>whF}d07WUwx zi{XPsBe=MXYimy8;zBOg`k9McFnF-|FD_n!k%F~1V|eQ|*dkc}9$4Kv0aFB;!c>y}xGUhQ%n3 zEaK|NK^Q*~aq$`Ec->5v?mV-$elQms=c8zLP+h#2^YVsuFUdM@}ouhm@h#~ z4uYzZ8nG}wS;pm$FbRWx8AI86&+C<+EpPP7@-s&~jA^Fo4uu?n@9~wU+S(1cs;Sli zxW5UGrJ89y75MG7Z~@iav^n-fu&r7dNZEbhxvI6nBzte6_ho)Gbv+YnyBefJPhxC! zRVs88y3tE0XcfB=ys9oNstArn^-dsYq3~nsx0sHqYh%;~PT{LW4K;lAt>Wu(xSi@( z#n)7*NcBI*b}Mk~Q_RT#1Cg!ZQfi=q((Lz`p+US+9%&Wi*shAoS7J;-C{5 z0*4QU#AGi31+jtY^X_J9cc)^3pJJ< zG}t|oz_i*(y;c_Vj{L=Zbd>CtR>9y%083V=Qyd%?>DmQgmpC6IBd;>$Zari-P3t=h)9<{YcI-;tIPHI8M&yPI}2o!!05?=MKjI0$-F|VDM`gk$~^* zt5svr6tv-aEt|IkFY!%HJ%Du;&wcP&zbb&(0re*q6=P?whAKlU%0W*?FpD|RzaFw8%$BGk%qGD7lA_y25KnJ{+*#a%^WMVH#3z* z1}e5oVJ=#1pc1=93{ufu25e~0VQ86wn%caS&X8iSKU>R|7O`;vDV zHJJFe2M?sR2J+j>8Cq{hIrh&irTKlJK-smhlF%c%&3mmD{NwSRF&$qrbpZqwR)ROZPG>pC+ghio^>&eWrcMX> zuve#U@1X?KM5vQJ4^Buoa2MwDYaV^_Rt@>>4KOH88LExq7?GzMk(IrY`I@%JtW6ks zHcFYTybtPTXAfefK8u^NCfN#$I6cSQz~Aiko?X(s(fim+BsV@0w>IlCxe03!i@r#? z1#`M2xmidfHDILBtKQU-l408!uhn3tyAJM{Z0=D9pv;uIucK2nKQG_0K3!*`ph=C_-Ao$42l*7y(n5B`S#!GG`yKKwlVkbx9#B!C{) zTeX6Sunx0c%C_(V`7x$yq;@(gtWn;+`dP7YP*LRFePA+|_tIGoWRK>Dwq@g2jRN+) z&~{9PXdxS0SeM}x(W3Lf4s-^#6YXr@jvHFEqZv!sAHj#Bo%AjeyP&|0to3Lwdnfb} z?QYy$*uFeKJv0=9Bcx-@XipxUjUISX_Zege_x~Tl1LA~Dmw{KhTtt^hbd>2b?0>pk zTh*lA6{rojR}n~tz5LPfcJAE`tC!V)YNMrm z%jap)nxQg7#xGKq0dr1ta%dSA)@WOXLbX6M+BpXUgaWlt?8TbO8#8N;hz??Xgo@yT z(NQdBXg=ePXZAy1hP+tAoLFzvEQmI>-+-$`n^kFSC2K6cN%Px%;Gof#Rib#XOmuQn z3=K(ybvuYfr`!)Pp$_JjKYEAS1D?C6Barb{H5cW1Y8Z?;U(JTY-lnEuj^3``f=y%U zx&iesn8y|gZ8Y*v zsspBiR53lLJA*}^8V|Mj)wie#s4=)V*`mgHAUn|l8CefCMQh0EfO+Ruj~zbW8`iie zU0Xd}K8BWpci6?VB|Be1vUhLeyo9Y_qeC<#BYQKvw;N|sm^((}_k1VP$@{)>Vg6xW z9Mwo@MXKxJ7?#SY16D*zPl)2LUKpzInl$N>{R#N1URamKgA;xU{;QYpLkcgXF>h^? zCOz(hMIy~5&t&HEC!j`J#0T?7zT#=#s%mUOxsdu|V=R=ZA-f+eni}RBroGssruiLs zXH2Q7rY-GC8_bcKJ{TPHp8N+GF*U<%Gph+&2m)b9L#f&J^WLnc`Lc(1Pt$hU$6cV+ z(vNoqWZwa0rWPA0V)ymVH_eQ7M6Xoya-m>~J)bd3%plY32)s76!QFX0j%s@uR@?6|9!__8I`2ykJ1fu-kN}0evFKG=GJb9B)~(Ue!Zz zv0Ha86(wZOfLMq2~4T(vNWHMq3c`-MHy4v)r_$*)|(~g@Ll{6Htm%VW2$wacJMs?~bg3LVF2AYr;^GRZ#4W zY?W2U;y90v)xtrXzK}I@$Q)iwmf$OMs4lj|WY4^Y?;3Ofl6A+7RawpLOBgq+1*@7B zQwP_qmd2c*)DsM6wR)0ucoAOCzOIY=o*E%=& zFlt~ezWiBhZGMTA{8YFM zFBcy=fL<_sD4V6s+G_5qBr+IDrg9_pZezJebIjhX7xPfe{!jA2NG*#&>A z?){@pt=LBBFZ9jSW3FD;b}1iva{_SBDHj#PF8##E>B@PjShl)%LnNc9u^ZGoja^2M)CW2ISu zpGTqR1*Cohg#~#c!GaO}x#QGeSV#&Q4{#U$((+o^5`^r$!k;f z>{Jbonb+1>knAuh=e60i!~Y~L!s7_xC7K^cnip8cEsq?N`U9(`?Y*;z!Lch ziX!7&<@c5iY)#hhnnEo!S{n%TLim9EZK~Lk$_@6{sOUdW4JPq3`_a z=eSr2MHS?8k=8=#+d9MGVq6pgj{S7!}@Pe<<;kcB`4+!cGB&!g&Vr+ZXb@eeH5% zUtsA-D_md?gdPeP8f6K4ZZ$x6JPcBN6W$6v6qXw$M+9{N>T)PEQn=V20d*GMRW-sJ z&{E-&csD^yfw%`6qN2Bwr%#$BiguV8BJ7b+a?#tE;n(T`x&yIjr)hNTQ4phOmw^=S z5olZnDv_c+c1Ji>(cTNF;U%UwtX8zoKz`e;2I$??x<-XBdvCR07>i)h@)y;Y>S}m~ zRR6*Zx70c4&ad`EC`WyU8od96Ez(po)MtoVt3crr@2`qFNYw>(dFor}v9(B=iq)`a zfc~{2>3+=dqJgIT3YW)7R)4}y^!CdV)eIIP@2w7Y$9{0OG}**%;s*;&p9T{1{u73j z%?xDO&0!kZ+(3T&1K32iFpzC;_w0`Ou}2|^Biqk8ju?4!R&ZG%K_GT}U{p(Dgcng4=peg{fCXT-X)V+`E^lzVXXvy>$XfFau zYt0N%yH`ED`sDR&gr?18&;OUSeuk+cJ^XK^V{$l4Df=7RBQ*<#_UJ0w^*9b?2+2-e3rc`km^d-v?}lIhrvJyX4RmIi$gw zY&<^5*``y2b}+V_{V5#STBAy4LF&1NMhWZYMuP>R=LmU|2KqPrj2BA1DQMV&o!}O( zZ}=;Fz^%I2n#Y}|i?f;k`CP2K9j+p8=V>R0#!9q;W6Y+trbEfxu|h6nU$fS9$Eyw0 zUim#YC>k|^No(qdP$@Grm`o<`on@mYxHlxO&E#m&pqGO>j3dnfLqxag&vIRD_AStUaYBJ z23#-QvrMtNNQck%5~IxwrzaX3f+1*TE=(s;6QPwDI7&ZX#p=rJ z#Oey7CXJ?`CY^SHS_WP0i%k%VqFhL0AV(2(#*j7X2au~p-@(YmG#oXx=?|E$4qXotb!iirE1{RbL_N9=^3|uu zAwUBf4MrQ%cHlRncHQy2GDYhN(S$~UPE+~?`e;T6Vvw>q1)=2@B*9%vDg{HW$Ok!E z(;HA-8#>p9e_=lawyvU2(b|r>LYnsU5PWZkpmpHxZ9xxUh@FC>K-(qg0@!~?&@&*v z8?OYQgFS+pV}QMa-h#{T6Ep&C@5Th3!u35t-LQ_lkDsw|`9RQ02=bwze6)RpS%J!r zvFX9E`|+DS#QsE3G1xjFXfKrZsi4M??VzBoxO^t4D=weo=XG4Zz~&#AhXl32yg4lB zNr-ktkOL(h6)`%8Idx1>A87Qrpv!?t@SOK|kSg7Qcq$a!$}m2>3lPdqF2Z z2>Lg`9|e^_HRlCMaC$*d6HMiw1RVlTKMR@zL4OhSA&CB4(EX_VRnS>z<~KnVu<1qo zmV)lT3#tPSFJWs42meFRr>Oi>&?sE~Bj_Gn{t`3;B3;G?Fa`-1NV*#uS}3UlNxk48OC?>?mjid`R!pDel2)Q^g`{$D zSRrW-thG|oboj+8Nxz|OwWLF!xkggI_E@g(mh>pR%9GR`1Fn_y7RcNqX(#Ro_e$CX zXq}|>fYwWz4SDaAq~O)}OX>ryJs{~bKpP~jgJB<(v_Mpx{p=-3RFpNcsUIeF{u?_d!W_ zz!aZJI*g^^b0`nYd?D$380L_q$*4Rm>0i+A5gDW3Fz!)F&p^+|BwY_h9hcM*{ZB|r zg717ODGho)DXA`8=qpLzU~c|P(r|S6TG9b<@eOF#!8DY#8MME}^E~>UmedF~sFZXZ z&>2ZK)cqZdj_zk61Y|iUDRvsJ@V%tlAjJ=o8erTXp-YT(UQ!0yE?@$H@1NlLu+Ptu zwqm4TFfLT`Z+JdB{0d(MGrviy4@NIadJXFSUD67u`w~0>&>xci37UVxFyQGwlDdJ> zza({yL2Z{YWiZkLi@t}M7g{t1&>a?ygYwHQdI8qH)1u?JEV3vK9Tr>U1Ik?%rDOOd z7G1{Du+*adSQ?gDG!?$O+@j7<>Vo;V#-ahx z(A^eI1deCXw^$<9TJ!~Ey2qlXu+zO3<>9igpSp_wNw+6+@XWziCh^t45TaM^6pbhyAX7B#}! zZ!GExAx>Ge5W|0Kkq5h;1~YJvN{dP`;2AK3?%!E-4s4&bD0T@r=PVkI+3`K3hk}0q zDwz4vqCHp`&s%gaP%mIW5d8_v^usi?C>zrM0(ArB-|z&W{A$rPK>5w0KOy!-_!Fku z@9;-pUb3hN-2Y*bfb@S_)Ek%oSRy%gbrLL8pEs4oiPR335wsCzk`x5j7Hxt7eDoC* z@2548F+dMPH8%Z>`k+YWV5LGR(C=%VNU0zrX&>|g!t>D50fYE`of9bw1wl7sK1-4O z3|bms2*0maBE=rT#1Ql~h5{maFS()v`RSrY=vBVoODAea% zE^2}S4rlY{{sf8ve%~9Y&BOyWQ5$H?M+O3XaK!$sH;PH-#6y4&js){ZbIlxyVV%Gr z@3leZ;7G72ojdV~kznz9M!Atu>;Rt_3D)LL0X{Jjtn(5#niC^|ygby@oxzQKVkB6? zya)KGNU$D{9N?oO!N!%`#T*q0@KKRqlS^DGM&-{lQI6=>?<((Ov6XP=?L2m`~z-L5)YneiT&xi!?(F5NN8wT&y z1M?Y?;5t1TpAiYJ*SLH}BzT{${W>4T`*kg!5eaV4%HlI3!3T9MpAiW@q-*(zNN{6& zUFI_)!A+g;9rXwJj7abajm~F8f}3@b4Iaei2F&ppk>D21Tmx_S5OYQ(`1+09#%Dx= zZ@d6XKEFnu>?ICOP31Ep!5w-mJ|hy`rP&?jwHazc2LkVY%Ph2jZ^T0-T@xz#9f-m$ z-9{Nu+AYip#~7sz2cnKKaP!kS#=tFL+UXo);1;qRBET^QZV^+AEW?-Mc6K?&!0os& zPLg8`+)nx4=R+yRfdy`Nron^x;B#&d1NmK!D{y=Ai2On00{|~VN`G!B! zW#E-A?cq@oca-Te?0>pktGkRW@VgvX;0`x~IxYtmxFfb}ddlUv0(Yc=NJNH$p5Gns z=3?f$<5*m9Eh6(!?YK9%9BJT|8eIvuwfFWl)w}R3X1DDpz)0u70=M%-h>^~L1#T}^ zPbLQzxP#v0S`I95N3opg^BH$M^Pi5ug3Mt#MLMv+ZR&Dhf!nM~V=Gx>&8sxl#~VE? zE5;E7?v$_4H*02u8NP#b1Oe#?0@4u#Gz_MiPdb8tbOZtE2m*Q;))N#DAjo=3_rITX z00HR$0@48lqyq>@2N2M`a0Hul00AA9q1VPqC-SHjL0R&_M2(rSMb$<6l(g6gt${TTQRRBTO5Z&|@=>P)K0R*H22@2M~}BARrw;Kqi17`zathZh;JO0D)UWz6==l4sig1 zoA3Q{ZIQ8Vy8I3;xg0>?W=r<6++-}+=*h$3_y)e&LW!gBr9?^>IF*hqa6>YL*n&~R zO>BW1m2oc&b@G-DkH;2}jx8V^TR22)$s%g+3xdR&Pa|Y=s42E6C~8)RSdB@ zF2@rj6dNew_VqT5%q;DQ8JVDOJyyXKm*WW%N(|v?F2@rjG&q9^h2f?lLgU|o%kcy*#}gzpadEod7mx`r z2sXi8VJih=i1M3zV_WX>~6L9H;c zZu*n#ueBLUztMYsOlFLu(i7|UKt<#vzS0ugx*V0B*wk<*T#ialY{s`2_B)PBPmHfi zjyn;9CAKn{%H^o^#MTCr+`U*J6Wf@!h{&jhduCc<`*e;ZOl(`u3@|TF;#J%NW(Hl? z3W4$!*JZ{yAU&~b5vn7H@KusH)UedIiX{$6PwZF45(lIw_UHWvJ17UFCk`+Wxg3z5 zIM6_8E(fG14l-)Yb2%P8aj>CM=+?r@oj8Ocuh!T^9Za7%bPThmRd$U9HGs=rV>9J5 z-t}X%TXRf$;%L4phyX{NCyvPmN`NEI6UQ^1fPh~nUe8Pi9>m5oDOVR?zuMbAHoMNx zjWL~*hU&?dbj{xg zf3-aZD(jDaKL2L$6IqAiu%tO|8FMhL6jeOoXEXyevn$$+tA0E#D>kAd>gEhZU48&6 zJ<$(w`!eZfcNcc~Nw=86guA9Lpj#P%-JyLGK=asDS@#VZ0-DbwBH-7(yAz<>%z`z= zeV+T>&Mf%~aEi(2e-vne;%=yo>0+JYdbr!HV;zP0Fpu3;>U|Oik0#e`i2;57cj4=S z!^&GbK2OKQM^t=u6CsX?kEF<5dMWgWI3_+4ii1vwW8x#>IH*D#6Ca7hK?-q9d?XqN zBO#87k5rF?X(5h@kEF)ItPsb9uOnf9G-dq^snD|I$94roTOnf9O4wi&C zCO(oQU&ZQc6*LTSOnf9yzNNvYA&!ZU+29A&!ZU zlt|+&T|yiaAE_t#IlwCD7J7o&tS`UQq^}NfOnjuVhK7yEd0Z+FIt`h-{iKlkFDurWM*z9qV-9IB6 z?(a_-l+H2nDFc2&OL{uKQU-RxtO9*BJ1K+Ro4i{mnwa>M!Q3S>3tuXf<8n-VD9eb8 zeI+;!WpgLquLd|KK9tjk@gKz(g$fLQ4I>ipy~>I4n0Ul<@B^EUi6G zY_N4qJn5Kt(lPO5V&b!cVB8;WNjfH;OiX;>X>a7Dcuah_y~{E2;kgfDndVuAnE1CR znV9(St;Ro;%Q5lcc?KevW8%ZNF=d`291|bD{d4FKG4U?P#D`;lYADO)nE3F5Y$yST zXIzen58ug?1F=so$Ha#h8K~IhnE3Ew1C_WsCO&+Z0UNp;6CYk?pr$UbzTp+d&Mh&a znq#owR($E0_;3f8W8%Z!dzuH_F5!XUwFdIL91|a2Z%8>V$Ha&A^AN&YU5<$lKcd^b z!`GXb`0!)KTxl+1;xApVW8zCnIVOHUsfmdX_bY~cK7W0DS8t6knc54g5rG76RVl~B ze_EE_i;b+Z_RJa@yAAXLx;dO4kSMvrF6CY~)WZc@U%TN>6AV0=r zbivdr2{lXSnD|fwMoNFxtGJ=$YL1Bywc=?SScjD*r0b*Ic zBjC?W&Wv#cJPqTC72uPO(SkwD4WD$37V;tQ0H1V>7Tv@}KIs^(c?TEyq+_&}#3B*c zl7M2derV>Cj?vm%xt32lM(c0jRhdsZMjN-}+V|j((RQg^2YP2l7K(fR8suhw+3D?BFpb@RmEU#oI9@I)RTfM&~5(NK^4d9G$z3 zi+r3hI zo7#6VY68o+^AK(f#88Z$?#Cpvz*c7T>_jf#=R@_6^H7YqP?nQ6$xZS)PBTYg(lC&g{)|l0 zi7{w2j4x@g1&OE$RP7_37=v_T4AO})=o@G|NW}r@j&x!Sx)l?o8r=);Ng$mUgLGaD z(s?mx6NE{oT^yuOq!VM1PK-f1F$S5$7+I|wF&{nYG}I2=sQNIEeFb%51e(s?mR=fxnM7lZDHUK1%7m`O3xi7`kg#-L{~N($-37^D+p zkWP$2Ixz<6#2BO#W6(ji1^rYF8l(3?D1&rj4AO})NGHaiPOw4_>AV=E^I}kAsH6tH zh^d@UIxhyr%AoW@(upxhC&r-eSmtVxPK-f2FidUIi81JUhu^I0#2BO#V~|daK{_!8 z@tN#~q!VM1PK-gE7^4ZT#H!zvbY2YNdrNcTqjoJw=f$8`W01HN>BJbM6JwB0j6pgv z2I<5Yv>a+|N0@AQzitv^kV%X|CNTz?#291}W6+cEX}n+GiIouV*G*mwGI=q`sf73ICNTz?#291}V~|OVLF-@~ zykEZwioyH!2SE+**G*y!GKn!LAB#EOubaFWWb$H=$%{ccFGd?2+e3f6UpI*{$Rx%f zlNf_cVhl2gF~}swpeJBzykB48^`9MynM@dDGGWlOm~D8Wz7&SW3w4tSgG?d}GKnzA zB*Gw*2!l)_3>pZ>T!dHda2dQ$H;FLFB*LH;;1BQ9O(G1MfO(Gh=_U~dMPitS6_QLQ z40;+XDqg6YL>TlbG>M;{+u-(q_vtr-C%jKLi7?0{!XT3fgG?d}GKnzgR|tXk=_U~d znM4?55@C=@gh3_|2DQ(F|2{0qWWpe1!r&L`CJ_diL>OceVNh*M#>XX@L>OceVUS6L zL3cx;c%N<(VUS6LK_(FfnM4?55@C=@gh9QrXySc(-8=-eJ`c5F0l*7&&V+#%>Lw8e z-RtTX>I;F2_vt1P2F--a;C;GDgh3_|2AM<{v;_`?_vvFW+weYpnb&%5X3V6#Ad~Wf zOv($=DK8|Mj2Cnr?l*XIZZcj_CX|h5#k@IUY+rRbjAzP882u)ZgoB~882uM zY;-0_`(fknf@CsYkjZ#K&!j`U-v{X|#QPygeZk+4K{6RI=sT=ZA39_*V35gxK_&wR zS%rB0=a9*OK_&wRnG6_YGGLI&fI%h$2AK>P#E0MxJ7h9o5HeuIkOG4SKxfAgT!mZz zafd2k;}Z^<3>efN!k=_#qr_x&r~x?qmqTB}C%<;c)9-Klq37 z+B2F|9sF?3!4HEeTyyZFs-HRcVITzILOy4Sfs|{`eHe&bbMC`H5!amiFi@In&V6(% zgwR$&mTL}vn8rNU9Q-i9zZbeoyq9k(j+w(ANm%}Q_Z@h?FK+bp^|md!7mEG)IXIBS z#Q}N;7c4<>AioF;*jyZ>H*<5_pg5Gr3C!W*HF{t7Mo$!nYhtf+afIIDo$iO?q+nCr zXkTbL03PWNY-@?C>(jZaMIQ+64|H#jnj7kJO=Hw3f1p(Z)ab{tlrmKJ1*1+@U0G|& z^qT~(`=MptT0P-CdvpDQoDM*4E*Y`z4b8Ao8Q%q8c|LgoXdJ}aYq@v%<|4Zjic^<) zb#A#MZ3l{b@YkSzbD;LeZE`RQpEmH`xn;X7^2%?mTTe&P`gIg-D~_V2mHb#CWh;)N zrBw!KJ#L(k{(X(N9=$c$n%GqMl3FLUN$3$~+m`@z{tMQtFJ;)Y*HS4G5s1L4&z0>} zRdtVWRYQZo|Ik8|M-}O<18&=G$<|v_7rbEUG=9Flc*EKH;ODEGf4;`qP^YB+OU}22 zzFUS2YySCl9Xem-!HOZMIn@N&Hzziu@PJLmUVg|yF^wPAtPDC}(5=d|%%JJaXRbY@y5 zDMPK~t=q~kNh@!e_u`@v9xcwYPA>B5FV5)7q2x0JqBN77MOLT8K(})LfW=sTpiuqc zaPTYbS0@H~l=}z&y`96lZ}HwBv2pO$$2ZQm zw$|NryRuCV<*onRGNIUW4__|_dovH`x}4JS4J<9fyN@9xdgSQr7reItabm`45GBt$ z1BlZ$t_IZ5OF5G3a&pHVfYQ8HfH>vjAwa{tv4A*@WJ4^dsh&I<_BI?*Zg`%O$6E&@7pLpF))J*Ju$Y=W)8bKEC>p^MOBXK)(8PDsdc#y8`2R z9~(+-HG=>H;lpM#FjUVUwjDk`B>3hJTaT|k0hQsyCgiIRL8AO&1M=0!&%yYx75VDZ zImbc&3XILB=mPy+sfaM1U~}@-CvdmKhYiYCALn4fht0`XpTM3MpFbb+8lU_q))d~y zpv5ohxDfyN#RcA6U*SulwGQAaz9jgtE+%PQQ z+kmS+EZ}<>U+@_j?8dYP_TyT$oN;E#m zA2261#~wiAp9HM)l>;Vd1lv?mwXCxM7Xb5TA+Deo6G>QX|E_^tz*WAQ2Pdinm_POK z#|*RuTs7H3NbcV$-o7i|J{a)d>6HThJ44d}^BEwZi;xvlh-v)qWJ$5ABajd+4;uuQ zU?ao$w8kGZ@B-k!53n2X-_!YX&QbpKH4-8m?Y{yM1o}DN&N%#>FLW;bxL30eWaBo% zpDL3y@DfjbnOHV$_C!QZOqo7?^4u9-;M;A!iL+*T-+cR2k@;r;9XedyyGN(aV;a|Q zgyg(4W=$-cRyJqM*jcm2-ZEz5vC?t&lrdw({{yLqV|D-l 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; } -- 1.8.3.1