-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
/*
* 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/
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);
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
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;
struct inode *obj;
obj = iam_leaf_container(l)->ic_object;
- CERROR("Wrong magic in node %llu (#%lu): %#x != %#x or "
- "wrong used: %i",
- (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;
}
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));
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;
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,
.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,
.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,
};
/*
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
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 <key> followed by <ptr>. In the minimal tree
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);
}
brelse(root_node);
return result;
}
-EXPORT_SYMBOL(iam_lvar_create);
static struct iam_operations lvar_ops = {
.id_root_ptr = lvar_root_ptr,
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;
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 = {