X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_iam_lvar.c;h=0092a8eb6bb57b57df2db4fd666d49002ebe29f7;hp=4d1fa30145f6cf91051530e20a1aea22011fa9f6;hb=473bc6473eb8d6d78069a561dbe035e795d8b7e2;hpb=e3a7c58aebafce40323db54bf6056029e5af4a70 diff --git a/lustre/osd-ldiskfs/osd_iam_lvar.c b/lustre/osd-ldiskfs/osd_iam_lvar.c index 4d1fa30..0092a8e 100644 --- a/lustre/osd-ldiskfs/osd_iam_lvar.c +++ b/lustre/osd-ldiskfs/osd_iam_lvar.c @@ -26,6 +26,8 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -198,14 +200,14 @@ static __u32 hash_build0(const char *name, int namelen) struct ldiskfs_dx_hash_info hinfo; hinfo.hash_version = LDISKFS_DX_HASH_TEA; - hinfo.seed = 0; + hinfo.seed = NULL; ldiskfsfs_dirhash(name, namelen, &hinfo); result = hinfo.hash; if (LVAR_HASH_SANDWICH) { __u32 result2; hinfo.hash_version = LDISKFS_DX_HASH_TEA; - hinfo.seed = 0; + hinfo.seed = NULL; ldiskfsfs_dirhash(name, namelen, &hinfo); result2 = hinfo.hash; result = (0xfc000000 & result2) | (0x03ffffff & result); @@ -287,11 +289,11 @@ static struct lvar_leaf_entry *n_cur(const struct iam_leaf *l) void n_print(const struct iam_leaf *l) { - struct lvar_leaf_entry *scan; + struct lvar_leaf_entry *scan; - printk(CFS_KERN_EMERG "used: %d\n", h_used(n_head(l))); - for (scan = n_start(l); scan < n_end(l); scan = e_next(l, scan)) - e_print(scan); + printk(KERN_EMERG "used: %d\n", h_used(n_head(l))); + for (scan = n_start(l); scan < n_end(l); scan = e_next(l, scan)) + e_print(scan); } #if LDISKFS_CORRECTNESS_ON @@ -397,7 +399,7 @@ static int lvar_init(struct iam_leaf *l) head = n_head(l); used = h_used(head); - if (head->vlh_magic == le16_to_cpu(IAM_LVAR_LEAF_MAGIC) && + if (le16_to_cpu(head->vlh_magic) == IAM_LVAR_LEAF_MAGIC && used <= blocksize(l)) { l->il_at = l->il_entries = lvar_lentry(n_start(l)); result = 0; @@ -405,12 +407,12 @@ static int lvar_init(struct iam_leaf *l) struct inode *obj; obj = iam_leaf_container(l)->ic_object; - CERROR("Wrong magic in node %llu (#%lu): %#x != %#x or " - "wrong used: %d", - (unsigned long long)l->il_bh->b_blocknr, obj->i_ino, - head->vlh_magic, le16_to_cpu(IAM_LVAR_LEAF_MAGIC), - used); - result = -EIO; + CERROR("Wrong magic in node %llu (#%lu): %#x != %#x or " + "wrong used: %d\n", + (unsigned long long)l->il_bh->b_blocknr, obj->i_ino, + le16_to_cpu(head->vlh_magic), IAM_LVAR_LEAF_MAGIC, + used); + result = -EIO; } return result; } @@ -420,7 +422,7 @@ static void lvar_fini(struct iam_leaf *l) l->il_entries = l->il_at = NULL; } -struct iam_rec *lvar_rec(const struct iam_leaf *l) +static struct iam_rec *lvar_rec(const struct iam_leaf *l) { assert_corr(n_at_rec(l)); return e_rec(n_cur(l)); @@ -571,6 +573,15 @@ static void lvar_rec_set(struct iam_leaf *l, const struct iam_rec *r) assert_inv(n_invariant(l)); } +static int lvar_rec_eq(const struct iam_leaf *l, const struct iam_rec *r) +{ + struct iam_rec *rec = e_rec(n_cur(l)); + + if (rec_size(rec) != rec_size(r)) + return 0; + return !memcmp(rec, r, rec_size(r)); +} + static void lvar_rec_get(const struct iam_leaf *l, struct iam_rec *r) { struct iam_rec *rec; @@ -754,6 +765,11 @@ static void lvar_split(struct iam_leaf *leaf, struct buffer_head **bh, assert_inv(n_invariant(leaf)); } +static int lvar_leaf_empty(struct iam_leaf *leaf) +{ + return h_used(n_head(leaf)) == sizeof(struct lvar_leaf_header); +} + static struct iam_leaf_operations lvar_leaf_ops = { .init = lvar_init, .init_new = lvar_init_new, @@ -768,6 +784,7 @@ static struct iam_leaf_operations lvar_leaf_ops = { .key_eq = lvar_key_eq, .key_size = lvar_key_size, .rec_set = lvar_rec_set, + .rec_eq = lvar_rec_eq, .rec_get = lvar_rec_get, .lookup = lvar_lookup, .ilookup = lvar_ilookup, @@ -775,7 +792,8 @@ static struct iam_leaf_operations lvar_leaf_ops = { .rec_add = lvar_rec_add, .rec_del = lvar_rec_del, .can_add = lvar_can_add, - .split = lvar_split + .split = lvar_split, + .leaf_empty = lvar_leaf_empty, }; /* @@ -844,7 +862,7 @@ static int lvar_node_check(struct iam_path *path, struct iam_frame *frame) struct lvar_root *root; root = (void *)frame->bh->b_data; - if (le64_to_cpu(root->vr_magic) != IAM_LVAR_ROOT_MAGIC) + if (le32_to_cpu(root->vr_magic) != IAM_LVAR_ROOT_MAGIC) return -EIO; limit_correct = dx_root_limit(path); } else @@ -926,11 +944,22 @@ static void lvar_root(void *buf, sizeof (lvar_hash_t) + ptrsize) }; - entry = root + 1; - /* - * Skip over @limit. - */ - entry += isize; + /* To guarantee that the padding "keysize + ptrsize" + * covers the "dx_countlimit" and the "idle_blocks". */ + LASSERT((keysize + ptrsize) >= + (sizeof(struct dx_countlimit) + sizeof(__u32))); + + entry = (void *)(limit + 1); + /* Put "idle_blocks" just after the limit. There was padding after + * the limit, the "idle_blocks" re-uses part of the padding, so no + * compatibility issues with old layout. + */ + *(__u32 *)entry = 0; + + /* + * Skip over @limit. + */ + entry = (void *)(root + 1) + isize; /* * Entry format is followed by . In the minimal tree @@ -981,22 +1010,23 @@ int iam_lvar_create(struct inode *obj, struct super_block *sb; u32 blknr; - int result; + int result = 0; unsigned long bsize; assert_corr(obj->i_size == 0); sb = obj->i_sb; bsize = sb->s_blocksize; - root_node = ldiskfs_append(handle, obj, &blknr, &result); - leaf_node = ldiskfs_append(handle, obj, &blknr, &result); + root_node = osd_ldiskfs_append(handle, obj, &blknr, &result); + leaf_node = osd_ldiskfs_append(handle, obj, &blknr, &result); if (root_node != NULL && leaf_node != NULL) { lvar_root(root_node->b_data, bsize, keysize, ptrsize, recsize); lvar_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize); ldiskfs_mark_inode_dirty(handle, obj); - result = ldiskfs_journal_dirty_metadata(handle, root_node); - if (result == 0) - result = ldiskfs_journal_dirty_metadata(handle, leaf_node); + result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node); + if (result == 0) + result = ldiskfs_handle_dirty_metadata(handle, NULL, + leaf_node); if (result != 0) ldiskfs_std_error(sb, result); } @@ -1004,7 +1034,6 @@ int iam_lvar_create(struct inode *obj, brelse(root_node); return result; } -EXPORT_SYMBOL(iam_lvar_create); static struct iam_operations lvar_ops = { .id_root_ptr = lvar_root_ptr, @@ -1030,7 +1059,7 @@ static int lvar_guess(struct iam_container *c) result = iam_node_read(c, lvar_root_ptr(c), NULL, &bh); if (result == 0) { root = (void *)bh->b_data; - if (le64_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC) { + if (le32_to_cpu(root->vr_magic) == IAM_LVAR_ROOT_MAGIC) { struct iam_descr *descr; descr = c->ic_descr; @@ -1042,11 +1071,14 @@ static int lvar_guess(struct iam_container *c) descr->id_node_gap = 0; descr->id_ops = &lvar_ops; descr->id_leaf_ops = &lvar_leaf_ops; - } else - result = -EBADF; - brelse(bh); - } - return result; + + c->ic_root_bh = bh; + } else { + result = -EBADF; + brelse(bh); + } + } + return result; } static struct iam_format lvar_format = {