hostfs: simplify locking
Nick Piggin [Fri, 7 Jan 2011 06:49:29 +0000 (17:49 +1100)]
Remove dcache_lock locking from hostfs filesystem, and move it into dcache
helpers. All that is required is a coherent path name. Protection from
concurrent modification of the namespace after path name generation is not
provided in current code, because dcache_lock is dropped before the path is
used.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>

fs/dcache.c
fs/hostfs/hostfs_kern.c
include/linux/dcache.h

index 6f59f37..61beb40 100644 (file)
@@ -2171,7 +2171,7 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
 /*
  * Write full pathname from the root of the filesystem into the buffer.
  */
-char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
+static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
 {
        char *end = buf + buflen;
        char *retval;
@@ -2198,7 +2198,18 @@ char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
 Elong:
        return ERR_PTR(-ENAMETOOLONG);
 }
-EXPORT_SYMBOL(__dentry_path);
+
+char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
+{
+       char *retval;
+
+       spin_lock(&dcache_lock);
+       retval = __dentry_path(dentry, buf, buflen);
+       spin_unlock(&dcache_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(dentry_path_raw);
 
 char *dentry_path(struct dentry *dentry, char *buf, int buflen)
 {
index cfe8bc7..39dc505 100644 (file)
@@ -92,12 +92,10 @@ __uml_setup("hostfs=", hostfs_args,
 
 static char *__dentry_name(struct dentry *dentry, char *name)
 {
-       char *p = __dentry_path(dentry, name, PATH_MAX);
+       char *p = dentry_path_raw(dentry, name, PATH_MAX);
        char *root;
        size_t len;
 
-       spin_unlock(&dcache_lock);
-
        root = dentry->d_sb->s_fs_info;
        len = strlen(root);
        if (IS_ERR(p)) {
@@ -123,25 +121,23 @@ static char *dentry_name(struct dentry *dentry)
        if (!name)
                return NULL;
 
-       spin_lock(&dcache_lock);
        return __dentry_name(dentry, name); /* will unlock */
 }
 
 static char *inode_name(struct inode *ino)
 {
        struct dentry *dentry;
-       char *name = __getname();
-       if (!name)
-               return NULL;
+       char *name;
 
-       spin_lock(&dcache_lock);
-       if (list_empty(&ino->i_dentry)) {
-               spin_unlock(&dcache_lock);
-               __putname(name);
+       dentry = d_find_alias(ino);
+       if (!dentry)
                return NULL;
-       }
-       dentry = list_first_entry(&ino->i_dentry, struct dentry, d_alias);
-       return __dentry_name(dentry, name); /* will unlock */
+
+       name = dentry_name(dentry);
+
+       dput(dentry);
+
+       return name;
 }
 
 static char *follow_link(char *link)
index 1149e70..cea27df 100644 (file)
@@ -311,7 +311,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 extern char *__d_path(const struct path *path, struct path *root, char *, int);
 extern char *d_path(const struct path *, char *, int);
 extern char *d_path_with_unreachable(const struct path *, char *, int);
-extern char *__dentry_path(struct dentry *, char *, int);
+extern char *dentry_path_raw(struct dentry *, char *, int);
 extern char *dentry_path(struct dentry *, char *, int);
 
 /* Allocation counts.. */