From: Pavel Emelyanov <xemul@xxxxxxxxxx> Subject: [patch 2/3] vfs, dcache: Factor out rename_lock locking The set of routnes that try to get the dentry path with various flavours end up in two "core" routines -- the prepend_path and the __dentry_path. Since the rename_lock only protects the path integrity, it's OK to move the rename_lock locking inside these two. Signed-off-by: Pavel Emelyanov <xemul@xxxxxxxxxx> Signed-off-by: Cyrill Gorcunov <gorcunov@xxxxxxxxxx> --- fs/dcache.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) Index: linux-2.6.git/fs/dcache.c =================================================================== --- linux-2.6.git.orig/fs/dcache.c +++ linux-2.6.git/fs/dcache.c @@ -2489,6 +2489,7 @@ static int prepend_path(const struct pat bool slash = false; int error = 0; + read_seqlock(&rename_lock); br_read_lock(vfsmount_lock); while (dentry != root->dentry || vfsmnt != root->mnt) { struct dentry * parent; @@ -2521,6 +2522,7 @@ out: error = prepend(buffer, buflen, "/", 1); br_read_unlock(vfsmount_lock); + read_sequnlock(&rename_lock); return error; global_root: @@ -2562,10 +2564,7 @@ char *__d_path(const struct path *path, int error; prepend(&res, &buflen, "\0", 1); - read_seqlock(&rename_lock); error = prepend_path(path, root, &res, &buflen); - read_sequnlock(&rename_lock); - if (error) return ERR_PTR(error); return res; @@ -2626,12 +2625,10 @@ char *d_path(const struct path *path, ch return path->dentry->d_op->d_dname(path->dentry, buf, buflen); get_fs_root(current->fs, &root); - read_seqlock(&rename_lock); tmp = root; error = path_with_deleted(path, &tmp, &res, &buflen); if (error) res = ERR_PTR(error); - read_sequnlock(&rename_lock); path_put(&root); return res; } @@ -2657,12 +2654,10 @@ char *d_path_with_unreachable(const stru return path->dentry->d_op->d_dname(path->dentry, buf, buflen); get_fs_root(current->fs, &root); - read_seqlock(&rename_lock); tmp = root; error = path_with_deleted(path, &tmp, &res, &buflen); if (!error && !path_equal(&tmp, &root)) error = prepend_unreachable(&res, &buflen); - read_sequnlock(&rename_lock); path_put(&root); if (error) res = ERR_PTR(error); @@ -2706,6 +2701,7 @@ static char *__dentry_path(struct dentry retval = end-1; *retval = '/'; + read_seqlock(&rename_lock); while (!IS_ROOT(dentry)) { struct dentry *parent = dentry->d_parent; int error; @@ -2720,20 +2716,16 @@ static char *__dentry_path(struct dentry retval = end; dentry = parent; } + read_sequnlock(&rename_lock); return retval; Elong: + read_sequnlock(&rename_lock); return ERR_PTR(-ENAMETOOLONG); } char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen) { - char *retval; - - read_seqlock(&rename_lock); - retval = __dentry_path(dentry, buf, buflen); - read_sequnlock(&rename_lock); - - return retval; + return __dentry_path(dentry, buf, buflen); } EXPORT_SYMBOL(dentry_path_raw); @@ -2742,7 +2734,6 @@ char *dentry_path(struct dentry *dentry, char *p = NULL; char *retval; - read_seqlock(&rename_lock); if (d_unlinked(dentry)) { p = buf + buflen; if (prepend(&p, &buflen, "//deleted", 10) != 0) @@ -2750,7 +2741,6 @@ char *dentry_path(struct dentry *dentry, buflen++; } retval = __dentry_path(dentry, buf, buflen); - read_sequnlock(&rename_lock); if (!IS_ERR(retval) && p) *p = '/'; /* restore '/' overriden with '\0' */ return retval; @@ -2788,7 +2778,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, b get_fs_root_and_pwd(current->fs, &root, &pwd); error = -ENOENT; - read_seqlock(&rename_lock); if (!d_unlinked(pwd.dentry)) { unsigned long len; struct path tmp = root; @@ -2797,7 +2786,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, b prepend(&cwd, &buflen, "\0", 1); error = prepend_path(&pwd, &tmp, &cwd, &buflen); - read_sequnlock(&rename_lock); if (error) goto out; @@ -2816,10 +2804,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, b if (copy_to_user(buf, cwd, len)) error = -EFAULT; } - } else { - read_sequnlock(&rename_lock); } - out: path_put(&pwd); path_put(&root); -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html