struct iam_container {
/*
* Underlying flat file. IO against this object is issued to
-@@ -284,7 +423,7 @@ struct iam_path_descr {
+@@ -274,6 +413,10 @@ struct iam_container {
+ * container flavor.
+ */
+ struct iam_descr *ic_descr;
++ /*
++ * read-write lock protecting index consistency.
++ */
++ struct rw_semaphore ic_sem;
+ };
+
+ /*
+@@ -284,7 +427,7 @@ struct iam_path_descr {
/*
* Scratch-pad area for temporary keys.
*/
};
/*
-@@ -316,6 +455,7 @@ struct iam_path {
+@@ -316,6 +459,7 @@ struct iam_path {
* Key searched for.
*/
const struct iam_key *ip_key_target;
/*
* Description-specific data.
*/
-@@ -334,6 +474,7 @@ struct iam_path_compat {
+@@ -334,6 +478,7 @@ struct iam_path_compat {
struct dx_hash_info *ipc_hinfo;
struct dentry *ipc_dentry;
struct iam_path_descr ipc_descr;
};
/*
-@@ -347,7 +488,9 @@ enum iam_it_state {
+@@ -347,7 +492,9 @@ enum iam_it_state {
/* initial state */
IAM_IT_DETACHED,
/* iterator is above particular record in the container */
};
/*
-@@ -355,7 +498,7 @@ enum iam_it_state {
+@@ -355,7 +502,7 @@ enum iam_it_state {
*/
enum iam_it_flags {
/*
*/
IAM_IT_MOVE = (1 << 0),
/*
-@@ -372,15 +515,26 @@ enum iam_it_flags {
+@@ -372,15 +519,26 @@ enum iam_it_flags {
* doesn't point to any particular record in this container.
*
* After successful call to iam_it_get() and until corresponding call to
*
*/
struct iam_iterator {
-@@ -390,7 +544,8 @@ struct iam_iterator {
+@@ -390,7 +548,8 @@ struct iam_iterator {
__u32 ii_flags;
enum iam_it_state ii_state;
/*
*/
struct iam_path ii_path;
};
-@@ -405,133 +560,26 @@ void iam_path_compat_fini(struct iam_pat
+@@ -405,133 +564,26 @@ void iam_path_compat_fini(struct iam_pat
struct iam_path_descr *iam_ipd_alloc(int keysize);
void iam_ipd_free(struct iam_path_descr *ipd);
int iam_it_load(struct iam_iterator *it, iam_pos_t pos);
int iam_lookup(struct iam_container *c, const struct iam_key *k,
-@@ -539,10 +587,10 @@ int iam_lookup(struct iam_container *c,
+@@ -539,10 +591,10 @@ int iam_lookup(struct iam_container *c,
int iam_delete(handle_t *h, struct iam_container *c, const struct iam_key *k,
struct iam_path_descr *pd);
int iam_update(handle_t *h, struct iam_container *c, const struct iam_key *k,
/*
* Initialize container @c.
*/
-@@ -558,10 +606,6 @@ void iam_container_fini(struct iam_conta
+@@ -558,10 +610,6 @@ void iam_container_fini(struct iam_conta
*/
int iam_container_setup(struct iam_container *c);
static inline struct iam_descr *iam_container_descr(struct iam_container *c)
{
return c->ic_descr;
-@@ -577,16 +621,65 @@ static inline struct inode *iam_path_obj
+@@ -577,16 +625,65 @@ static inline struct inode *iam_path_obj
return p->ip_container->ic_object;
}
- struct iam_key *k1, const struct iam_key *k2)
+static inline void iam_ikeycpy(const struct iam_container *c,
+ struct iam_ikey *k1, const struct iam_ikey *k2)
- {
-- memcpy(k1, k2, c->ic_descr->id_key_size);
++{
+ memcpy(k1, k2, c->ic_descr->id_ikey_size);
- }
-
--static inline int iam_keycmp(const struct iam_container *c,
-- const struct iam_key *k1, const struct iam_key *k2)
++}
++
+static inline size_t iam_entry_size(struct iam_path *p)
- {
-- return c->ic_descr->id_ops->id_keycmp(c, k1, k2);
++{
+ return iam_path_descr(p)->id_ikey_size + iam_path_descr(p)->id_ptr_size;
+}
+
+ */
+static inline void iam_ikeycpy0(const struct iam_container *c,
+ struct iam_ikey *k1, const struct iam_ikey *k2)
-+{
+ {
+- memcpy(k1, k2, c->ic_descr->id_key_size);
+ if (k1 != k2)
+ iam_ikeycpy(c, k1, k2);
-+}
-+
+ }
+
+-static inline int iam_keycmp(const struct iam_container *c,
+- const struct iam_key *k1, const struct iam_key *k2)
+static inline int iam_ikeycmp(const struct iam_container *c,
+ const struct iam_ikey *k1,
+ const struct iam_ikey *k2)
-+{
+ {
+- return c->ic_descr->id_ops->id_keycmp(c, k1, k2);
+ return c->ic_descr->id_ops->id_ikeycmp(c, k1, k2);
}
static inline void iam_reccpy(const struct iam_path *p, struct iam_rec *rec_dst,
-@@ -604,7 +697,7 @@ static inline void *iam_entry_off(struct
+@@ -604,7 +701,7 @@ static inline void *iam_entry_off(struct
static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry)
{
return le32_to_cpu(*(u32*)iam_entry_off(entry,
& 0x00ffffff;
}
-@@ -612,21 +705,64 @@ static inline void dx_set_block(struct i
+@@ -612,21 +709,64 @@ static inline void dx_set_block(struct i
struct iam_entry *entry, unsigned value)
{
*(u32*)iam_entry_off(entry,
static inline unsigned dx_get_count(struct iam_entry *entries)
{
return le16_to_cpu(((struct dx_countlimit *) entries)->count);
-@@ -647,9 +783,21 @@ static inline unsigned dx_node_limit(str
+@@ -647,9 +787,21 @@ static inline unsigned dx_node_limit(str
struct iam_descr *param = iam_path_descr(p);
unsigned entry_space = iam_path_obj(p)->i_sb->s_blocksize -
param->id_node_gap;
- return entry_space / (param->id_key_size + param->id_ptr_size);
+ return entry_space / (param->id_ikey_size + param->id_ptr_size);
-+}
-+
+ }
+
+static inline unsigned dx_root_limit(struct iam_path *p)
+{
+ struct iam_descr *param = iam_path_descr(p);
+ if (limit == dx_node_limit(p))
+ limit--;
+ return limit;
- }
-
++}
++
+
static inline struct iam_entry *dx_get_entries(struct iam_path *path,
void *data, int root)
{
-@@ -665,7 +813,8 @@ static inline struct iam_entry *dx_node_
+@@ -665,7 +817,8 @@ static inline struct iam_entry *dx_node_
frame->bh->b_data, frame == path->ip_frames);
}
{
assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch));
return path->ip_data->ipd_key_scratch[nr];
-@@ -674,6 +823,7 @@ static inline struct iam_key *iam_path_k
+@@ -674,6 +827,7 @@ static inline struct iam_key *iam_path_k
int dx_lookup(struct iam_path *path);
void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
u32 hash, u32 block);
int ext3_htree_next_block(struct inode *dir, __u32 hash,
struct iam_path *path, __u32 *start_hash);
-@@ -681,6 +831,20 @@ int ext3_htree_next_block(struct inode *
+@@ -681,6 +835,20 @@ int ext3_htree_next_block(struct inode *
struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
u32 *block, int *err);
int split_index_node(handle_t *handle, struct iam_path *path);
/*
* external
-@@ -698,10 +862,12 @@ int iam_node_read(struct iam_container *
+@@ -698,10 +866,12 @@ int iam_node_read(struct iam_container *
handle_t *handle, struct buffer_head **bh);
void iam_insert_key(struct iam_path *path, struct iam_frame *frame,
struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
struct iam_container *iam_leaf_container(const struct iam_leaf *leaf);
-@@ -709,14 +875,95 @@ struct iam_descr *iam_leaf_descr(const s
+@@ -709,14 +879,95 @@ struct iam_descr *iam_leaf_descr(const s
struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);