-Index: linux-2.6.32.i386/fs/ext4/ext4.h
+Index: linux-stage/fs/ext4/ext4.h
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/ext4.h 2010-04-16 03:39:11.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/ext4.h 2010-04-16 04:27:41.000000000 +0530
-@@ -29,6 +29,7 @@
+--- linux-stage.orig/fs/ext4/ext4.h 2012-08-07 11:52:38.994200699 -0700
++++ linux-stage/fs/ext4/ext4.h 2012-08-07 12:28:19.497442862 -0700
+@@ -16,6 +16,7 @@
#ifndef _EXT4_H
#define _EXT4_H
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/magic.h>
-@@ -621,6 +622,10 @@
- ext4_fsblk_t i_file_acl;
+@@ -706,6 +707,9 @@
__u32 i_dtime;
+ ext4_fsblk_t i_file_acl;
+ /* following fields for parallel directory operations -bzzz */
-+ struct dynlock i_htree_lock;
+ struct semaphore i_append_sem;
+
/*
* i_block_group is the number of the block group which contains
* this file's inode. Constant across the lifetime of the inode,
-Index: linux-2.6.32.i386/fs/ext4/namei.c
+Index: linux-stage/fs/ext4/namei.c
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/namei.c 2010-04-15 07:42:15.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/namei.c 2010-04-16 04:26:03.000000000 +0530
-@@ -54,6 +54,11 @@
+--- linux-stage.orig/fs/ext4/namei.c 2012-08-07 11:52:38.992199430 -0700
++++ linux-stage/fs/ext4/namei.c 2012-08-07 12:27:24.845281099 -0700
+@@ -53,6 +53,11 @@
ext4_lblk_t *block, int *err)
{
struct buffer_head *bh;
*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
-@@ -66,7 +71,9 @@
+@@ -65,7 +70,9 @@
brelse(bh);
bh = NULL;
}
return bh;
}
-Index: linux-2.6.32.i386/fs/ext4/super.c
+Index: linux-stage/fs/ext4/super.c
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/super.c 2010-04-16 03:39:11.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/super.c 2010-04-16 04:26:03.000000000 +0530
-@@ -700,6 +700,8 @@
+--- linux-stage.orig/fs/ext4/super.c 2012-08-07 11:52:39.009197356 -0700
++++ linux-stage/fs/ext4/super.c 2012-08-07 12:28:29.499112997 -0700
+@@ -749,6 +749,7 @@
ei->vfs_inode.i_version = 1;
ei->vfs_inode.i_data.writeback_index = 0;
-+ dynlock_init(&ei->i_htree_lock);
+ sema_init(&ei->i_append_sem, 1);
memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
INIT_LIST_HEAD(&ei->i_prealloc_list);
c->ic_descr = descr;
c->ic_object = inode;
cfs_init_rwsem(&c->ic_sem);
+ dynlock_init(&c->ic_tree_lock);
return 0;
}
EXPORT_SYMBOL(iam_container_init);
return err;
}
-static void iam_unlock_htree(struct inode *dir, struct dynlock_handle *lh)
+static void iam_unlock_htree(struct iam_container *ic,
+ struct dynlock_handle *lh)
{
- if (lh != NULL)
- dynlock_unlock(&LDISKFS_I(dir)->i_htree_lock, lh);
+ if (lh != NULL)
+ dynlock_unlock(&ic->ic_tree_lock, lh);
}
static void iam_leaf_unlock(struct iam_leaf *leaf)
{
if (leaf->il_lock != NULL) {
- iam_unlock_htree(iam_leaf_container(leaf)->ic_object,
- leaf->il_lock);
- do_corr(schedule());
- leaf->il_lock = NULL;
+ iam_unlock_htree(iam_leaf_container(leaf),
+ leaf->il_lock);
+ do_corr(schedule());
+ leaf->il_lock = NULL;
}
}
* this locking primitives are used to protect parts
* of dir's htree. protection unit is block: leaf or index
*/
-struct dynlock_handle *iam_lock_htree(struct inode *dir, unsigned long value,
- enum dynlock_type lt)
+static struct dynlock_handle *iam_lock_htree(struct iam_container *ic,
+ unsigned long value,
+ enum dynlock_type lt)
{
- return dynlock_lock(&LDISKFS_I(dir)->i_htree_lock, value, lt, GFP_NOFS);
+ return dynlock_lock(&ic->ic_tree_lock, value, lt, GFP_NOFS);
}
-
-
int iam_index_lock(struct iam_path *path, struct dynlock_handle **lh)
{
struct iam_frame *f;
- for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
- do_corr(schedule());
- *lh = iam_lock_htree(iam_path_obj(path), f->curidx, DLT_READ);
- if (*lh == NULL)
- return -ENOMEM;
- }
- return 0;
+ for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
+ do_corr(schedule());
+ *lh = iam_lock_htree(path->ip_container, f->curidx, DLT_READ);
+ if (*lh == NULL)
+ return -ENOMEM;
+ }
+ return 0;
}
/*
dir = iam_path_obj(path);
while ((result = __iam_path_lookup(path)) == 0) {
do_corr(schedule());
- *dl = iam_lock_htree(dir, path->ip_frame->leaf, lt);
- if (*dl == NULL) {
- iam_path_fini(path);
- result = -ENOMEM;
- break;
- }
+ *dl = iam_lock_htree(path->ip_container, path->ip_frame->leaf,
+ lt);
+ if (*dl == NULL) {
+ iam_path_fini(path);
+ result = -ENOMEM;
+ break;
+ }
do_corr(schedule());
/*
* while locking leaf we just found may get split so we need
*/
if (iam_check_full_path(path, 1) == 0)
break;
- iam_unlock_htree(dir, *dl);
+ iam_unlock_htree(path->ip_container, *dl);
*dl = NULL;
iam_path_fini(path);
}
return iam_htree_advance(iam_path_obj(path), 0, path, NULL, 0);
}
-static void iam_unlock_array(struct inode *dir, struct dynlock_handle **lh)
+static void iam_unlock_array(struct iam_container *ic,
+ struct dynlock_handle **lh)
{
int i;
for (i = 0; i < DX_MAX_TREE_HEIGHT; ++i, ++lh) {
- if (*lh != NULL) {
- iam_unlock_htree(dir, *lh);
- *lh = NULL;
- }
+ if (*lh != NULL) {
+ iam_unlock_htree(ic, *lh);
+ *lh = NULL;
+ }
}
}
/*
break;
}
do {
- iam_unlock_array(object, lh);
+ iam_unlock_array(c, lh);
iam_path_release(path);
do_corr(schedule());
result = iam_check_full_path(path, 0);
if (result != 0)
break;
- iam_unlock_array(object, lh);
+ iam_unlock_array(c, lh);
}
} while (result == -EAGAIN);
if (result < 0)
break;
}
- iam_unlock_array(object, lh);
+ iam_unlock_array(c, lh);
return result;
}
result = iam_index_next(iam_it_container(it), path);
assert_corr(iam_leaf_is_locked(leaf));
if (result == 1) {
- struct dynlock_handle *lh;
- lh = iam_lock_htree(obj, path->ip_frame->leaf,
- DLT_WRITE);
+ struct dynlock_handle *lh;
+ lh = iam_lock_htree(iam_it_container(it),
+ path->ip_frame->leaf,
+ DLT_WRITE);
if (lh != NULL) {
iam_leaf_fini(leaf);
leaf->il_lock = lh;
if (new_leaf != NULL) {
struct dynlock_handle *lh;
- lh = iam_lock_htree(obj, blknr, DLT_WRITE);
+ lh = iam_lock_htree(c, blknr, DLT_WRITE);
do_corr(schedule());
if (lh != NULL) {
iam_leaf_ops(leaf)->init_new(c, new_leaf);
leaf->il_lock = lh;
path->ip_frame->leaf = blknr;
} else
- iam_unlock_htree(obj, lh);
+ iam_unlock_htree(path->ip_container, lh);
do_corr(schedule());
err = iam_txn_dirty(handle, path, new_leaf);
brelse(new_leaf);
* Lock all nodes, bottom to top.
*/
for (frame = path->ip_frame, i = nr_splet; i >= 0; --i, --frame) {
- do_corr(schedule());
- lock[i] = iam_lock_htree(dir, frame->curidx, DLT_WRITE);
- if (lock[i] == NULL) {
- err = -ENOMEM;
- goto cleanup;
- }
+ do_corr(schedule());
+ lock[i] = iam_lock_htree(path->ip_container, frame->curidx,
+ DLT_WRITE);
+ if (lock[i] == NULL) {
+ err = -ENOMEM;
+ goto cleanup;
+ }
}
/*
descr->id_ops->id_node_init(path->ip_container,
bh_new[i], 0) != 0)
goto cleanup;
- new_lock[i] = iam_lock_htree(dir, newblock[i], DLT_WRITE);
- if (new_lock[i] == NULL) {
- err = -ENOMEM;
- goto cleanup;
- }
+ new_lock[i] = iam_lock_htree(path->ip_container, newblock[i],
+ DLT_WRITE);
+ if (new_lock[i] == NULL) {
+ err = -ENOMEM;
+ goto cleanup;
+ }
do_corr(schedule());
BUFFER_TRACE(frame->bh, "get_write_access");
err = ldiskfs_journal_get_write_access(handle, frame->bh);
ldiskfs_std_error(dir->i_sb, err);
cleanup:
- iam_unlock_array(dir, lock);
- iam_unlock_array(dir, new_lock);
+ iam_unlock_array(path->ip_container, lock);
+ iam_unlock_array(path->ip_container, new_lock);
assert_corr(err || iam_frame_is_locked(path, path->ip_frame));
err = iam_txn_dirty(handle, path,
path->ip_frame->bh);
}
- iam_unlock_htree(iam_path_obj(path), lh);
+ iam_unlock_htree(path->ip_container, lh);
do_corr(schedule());
}
if (err == 0) {