aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:29 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:20 -0500
commitec2447c278ee973d35f38e53ca16ba7f965ae33d (patch)
tree5d17a0523c301b8c71c0f198ffe7782c5e9c0ea9
parentb1e6a015a580ad145689ad1d6b4aa0e03e6c868b (diff)
hostfs: simplify locking
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>
-rw-r--r--fs/dcache.c15
-rw-r--r--fs/hostfs/hostfs_kern.c24
-rw-r--r--include/linux/dcache.h2
3 files changed, 24 insertions, 17 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 6f59f375ed9d..61beb40dd6bf 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2171,7 +2171,7 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
2171/* 2171/*
2172 * Write full pathname from the root of the filesystem into the buffer. 2172 * Write full pathname from the root of the filesystem into the buffer.
2173 */ 2173 */
2174char *__dentry_path(struct dentry *dentry, char *buf, int buflen) 2174static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
2175{ 2175{
2176 char *end = buf + buflen; 2176 char *end = buf + buflen;
2177 char *retval; 2177 char *retval;
@@ -2198,7 +2198,18 @@ char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
2198Elong: 2198Elong:
2199 return ERR_PTR(-ENAMETOOLONG); 2199 return ERR_PTR(-ENAMETOOLONG);
2200} 2200}
2201EXPORT_SYMBOL(__dentry_path); 2201
2202char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
2203{
2204 char *retval;
2205
2206 spin_lock(&dcache_lock);
2207 retval = __dentry_path(dentry, buf, buflen);
2208 spin_unlock(&dcache_lock);
2209
2210 return retval;
2211}
2212EXPORT_SYMBOL(dentry_path_raw);
2202 2213
2203char *dentry_path(struct dentry *dentry, char *buf, int buflen) 2214char *dentry_path(struct dentry *dentry, char *buf, int buflen)
2204{ 2215{
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index cfe8bc7de511..39dc505ed273 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -92,12 +92,10 @@ __uml_setup("hostfs=", hostfs_args,
92 92
93static char *__dentry_name(struct dentry *dentry, char *name) 93static char *__dentry_name(struct dentry *dentry, char *name)
94{ 94{
95 char *p = __dentry_path(dentry, name, PATH_MAX); 95 char *p = dentry_path_raw(dentry, name, PATH_MAX);
96 char *root; 96 char *root;
97 size_t len; 97 size_t len;
98 98
99 spin_unlock(&dcache_lock);
100
101 root = dentry->d_sb->s_fs_info; 99 root = dentry->d_sb->s_fs_info;
102 len = strlen(root); 100 len = strlen(root);
103 if (IS_ERR(p)) { 101 if (IS_ERR(p)) {
@@ -123,25 +121,23 @@ static char *dentry_name(struct dentry *dentry)
123 if (!name) 121 if (!name)
124 return NULL; 122 return NULL;
125 123
126 spin_lock(&dcache_lock);
127 return __dentry_name(dentry, name); /* will unlock */ 124 return __dentry_name(dentry, name); /* will unlock */
128} 125}
129 126
130static char *inode_name(struct inode *ino) 127static char *inode_name(struct inode *ino)
131{ 128{
132 struct dentry *dentry; 129 struct dentry *dentry;
133 char *name = __getname(); 130 char *name;
134 if (!name)
135 return NULL;
136 131
137 spin_lock(&dcache_lock); 132 dentry = d_find_alias(ino);
138 if (list_empty(&ino->i_dentry)) { 133 if (!dentry)
139 spin_unlock(&dcache_lock);
140 __putname(name);
141 return NULL; 134 return NULL;
142 } 135
143 dentry = list_first_entry(&ino->i_dentry, struct dentry, d_alias); 136 name = dentry_name(dentry);
144 return __dentry_name(dentry, name); /* will unlock */ 137
138 dput(dentry);
139
140 return name;
145} 141}
146 142
147static char *follow_link(char *link) 143static char *follow_link(char *link)
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 1149e706f04d..cea27dfca532 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -311,7 +311,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
311extern char *__d_path(const struct path *path, struct path *root, char *, int); 311extern char *__d_path(const struct path *path, struct path *root, char *, int);
312extern char *d_path(const struct path *, char *, int); 312extern char *d_path(const struct path *, char *, int);
313extern char *d_path_with_unreachable(const struct path *, char *, int); 313extern char *d_path_with_unreachable(const struct path *, char *, int);
314extern char *__dentry_path(struct dentry *, char *, int); 314extern char *dentry_path_raw(struct dentry *, char *, int);
315extern char *dentry_path(struct dentry *, char *, int); 315extern char *dentry_path(struct dentry *, char *, int);
316 316
317/* Allocation counts.. */ 317/* Allocation counts.. */