Skip to content
Snippets Groups Projects
Commit 7e3248a2 authored by alex's avatar alex
Browse files

- pdirops patches against vanilla-2.4.20 series

NOTE: vanilla-2.4.20 runs CMD now
parent b5f04105
No related branches found
No related tags found
No related merge requests found
This diff is collapsed.
fs/inode.c | 1
fs/namei.c | 66 ++++++++++++++++++++++++++++++++++++++---------------
include/linux/fs.h | 11 ++++----
3 files changed, 54 insertions(+), 24 deletions(-)
Index: linux-2.4.20-rh/fs/namei.c
===================================================================
--- linux-2.4.20-rh.orig/fs/namei.c 2003-09-04 20:58:33.000000000 +0800
+++ linux-2.4.20-rh/fs/namei.c 2003-09-04 21:21:20.000000000 +0800
@@ -101,6 +101,36 @@
}
+static void *lock_dir(struct inode *dir, struct qstr *name)
+{
+ unsigned long hash;
+
+ if (!IS_PDIROPS(dir)) {
+ down(&dir->i_sem);
+ return 0;
+ }
+
+ /* OK. fs understands parallel directory operations.
+ * so, we try to acquire lock for hash of requested
+ * filename in order to prevent any operations with
+ * same name in same time -bzzz */
+
+ /* calculate name hash */
+ hash = full_name_hash(name->name, name->len);
+
+ /* lock this hash */
+ return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC);
+}
+
+static void unlock_dir(struct inode *dir, void *lock)
+{
+ if (!IS_PDIROPS(dir)) {
+ up(&dir->i_sem);
+ return;
+ }
+ dynlock_unlock(&dir->i_dcache_lock, lock);
+}
+
/* In order to reduce some races, while at the same time doing additional
* checking and hopefully speeding things up, we copy filenames to the
* kernel data space before using them..
@@ -303,10 +333,11 @@
struct dentry * result;
struct inode *dir = parent->d_inode;
int counter = 0;
+ void *lock;
again:
counter++;
- down(&dir->i_sem);
+ lock = lock_dir(dir, name);
/*
* First re-do the cached lookup just in case it was created
* while we waited for the directory semaphore..
@@ -329,7 +359,7 @@
else
result = dentry;
}
- up(&dir->i_sem);
+ unlock_dir(dir, lock);
return result;
}
@@ -337,7 +367,7 @@
* Uhhuh! Nasty case: the cache was re-populated while
* we waited on the semaphore. Need to revalidate.
*/
- up(&dir->i_sem);
+ unlock_dir(dir, lock);
if (result->d_op && result->d_op->d_revalidate) {
if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
dput(result);
@@ -1180,13 +1210,13 @@
goto exit;
dir = nd->dentry;
- down(&dir->d_inode->i_sem);
+ nd->lock = lock_dir(dir->d_inode, &nd->last);
dentry = lookup_hash_it(&nd->last, nd->dentry, it);
do_last:
error = PTR_ERR(dentry);
if (IS_ERR(dentry)) {
- up(&dir->d_inode->i_sem);
+ unlock_dir(dir->d_inode, nd->lock);
goto exit;
}
@@ -1195,7 +1225,7 @@
if (!dentry->d_inode) {
error = vfs_create_it(dir->d_inode, dentry,
mode & ~current->fs->umask, it);
- up(&dir->d_inode->i_sem);
+ unlock_dir(dir->d_inode, nd->lock);
dput(nd->dentry);
nd->dentry = dentry;
if (error)
@@ -1209,7 +1239,7 @@
/*
* It already exists.
*/
- up(&dir->d_inode->i_sem);
+ unlock_dir(dir->d_inode, nd->lock);
error = -EEXIST;
if (flag & O_EXCL)
@@ -1362,7 +1392,7 @@
goto exit;
}
dir = nd->dentry;
- down(&dir->d_inode->i_sem);
+ nd->lock = lock_dir(dir->d_inode, &nd->last);
dentry = lookup_hash_it(&nd->last, nd->dentry, it);
putname(nd->last.name);
goto do_last;
@@ -1380,7 +1410,7 @@
{
struct dentry *dentry;
- down(&nd->dentry->d_inode->i_sem);
+ nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
dentry = ERR_PTR(-EEXIST);
if (nd->last_type != LAST_NORM)
goto fail;
@@ -1469,7 +1499,7 @@
}
dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
out2:
path_release(&nd);
out:
@@ -1532,7 +1562,7 @@
mode & ~current->fs->umask);
dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
out2:
path_release(&nd);
out:
@@ -1642,14 +1672,14 @@
if (error != -EOPNOTSUPP)
goto exit1;
}
- down(&nd.dentry->d_inode->i_sem);
+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_rmdir(nd.dentry->d_inode, dentry);
dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
exit1:
path_release(&nd);
exit:
@@ -1708,7 +1738,7 @@
if (error != -EOPNOTSUPP)
goto exit1;
}
- down(&nd.dentry->d_inode->i_sem);
+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
@@ -1719,7 +1749,7 @@
exit2:
dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
exit1:
path_release(&nd);
exit:
@@ -1789,7 +1819,7 @@
error = vfs_symlink(nd.dentry->d_inode, dentry, from);
dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
out2:
path_release(&nd);
out:
@@ -1881,7 +1911,7 @@
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
dput(new_dentry);
}
- up(&nd.dentry->d_inode->i_sem);
+ unlock_dir(nd.dentry->d_inode, nd.lock);
out_release:
path_release(&nd);
out:
Index: linux-2.4.20-rh/include/linux/fs.h
===================================================================
--- linux-2.4.20-rh.orig/include/linux/fs.h 2003-09-04 20:59:14.000000000 +0800
+++ linux-2.4.20-rh/include/linux/fs.h 2003-09-04 21:03:46.000000000 +0800
@@ -21,6 +21,7 @@
#include <linux/cache.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/dynlocks.h>
#include <asm/atomic.h>
#include <asm/bitops.h>
@@ -136,6 +137,7 @@
#define S_IMMUTABLE 16 /* Immutable file */
#define S_DEAD 32 /* removed, but still open directory */
#define S_NOQUOTA 64 /* Inode is not counted to quota */
+#define S_PDIROPS 256 /* Parallel directory operations */
/*
* Note that nosuid etc flags are inode-specific: setting some file-system
@@ -162,6 +164,7 @@
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
+#define IS_PDIROPS(inode) __IS_FLG(inode, S_PDIROPS)
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
@@ -489,6 +492,7 @@
atomic_t i_writecount;
unsigned int i_attr_flags;
__u32 i_generation;
+ struct dynlock i_dcache_lock; /* for parallel directory ops */
union {
struct minix_inode_info minix_i;
struct ext2_inode_info ext2_i;
@@ -708,6 +712,7 @@
unsigned int flags;
int last_type;
struct lookup_intent *intent;
+ void *lock;
};
/*
@@ -1621,12 +1626,6 @@
return dget(dentry->d_parent);
}
-static inline void unlock_dir(struct dentry *dir)
-{
- up(&dir->d_inode->i_sem);
- dput(dir);
-}
-
/*
* Whee.. Deadlock country. Happily there are only two VFS
* operations that does this..
Index: linux-2.4.20-rh/fs/inode.c
===================================================================
--- linux-2.4.20-rh.orig/fs/inode.c 2003-09-04 20:58:35.000000000 +0800
+++ linux-2.4.20-rh/fs/inode.c 2003-09-04 21:03:46.000000000 +0800
@@ -121,6 +121,7 @@
inode->i_data.host = inode;
inode->i_data.gfp_mask = GFP_HIGHUSER;
inode->i_mapping = &inode->i_data;
+ dynlock_init(&inode->i_dcache_lock);
}
/**
...@@ -54,3 +54,7 @@ linux-2.4.20-tmpfs-xattr.patch ...@@ -54,3 +54,7 @@ linux-2.4.20-tmpfs-xattr.patch
linux-2.4.20-tmpfs-iopen.patch linux-2.4.20-tmpfs-iopen.patch
linux-2.4.20-filemap.patch linux-2.4.20-filemap.patch
ext3-truncate-buffer-head.patch ext3-truncate-buffer-head.patch
dynamic-locks-2.4.20-rh.patch
vfs-pdirops-2.4.20.patch
ext3-pdirops-2.4.20.patch
ext3-mds-num-2.4.24.patch
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment