diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:29 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:20 -0500 |
commit | ec2447c278ee973d35f38e53ca16ba7f965ae33d (patch) | |
tree | 5d17a0523c301b8c71c0f198ffe7782c5e9c0ea9 | |
parent | b1e6a015a580ad145689ad1d6b4aa0e03e6c868b (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.c | 15 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 24 | ||||
-rw-r--r-- | include/linux/dcache.h | 2 |
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 | */ |
2174 | char *__dentry_path(struct dentry *dentry, char *buf, int buflen) | 2174 | static 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) | |||
2198 | Elong: | 2198 | Elong: |
2199 | return ERR_PTR(-ENAMETOOLONG); | 2199 | return ERR_PTR(-ENAMETOOLONG); |
2200 | } | 2200 | } |
2201 | EXPORT_SYMBOL(__dentry_path); | 2201 | |
2202 | char *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 | } | ||
2212 | EXPORT_SYMBOL(dentry_path_raw); | ||
2202 | 2213 | ||
2203 | char *dentry_path(struct dentry *dentry, char *buf, int buflen) | 2214 | char *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 | ||
93 | static char *__dentry_name(struct dentry *dentry, char *name) | 93 | static 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 | ||
130 | static char *inode_name(struct inode *ino) | 127 | static 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 | ||
147 | static char *follow_link(char *link) | 143 | static 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 *, ...); | |||
311 | extern char *__d_path(const struct path *path, struct path *root, char *, int); | 311 | extern char *__d_path(const struct path *path, struct path *root, char *, int); |
312 | extern char *d_path(const struct path *, char *, int); | 312 | extern char *d_path(const struct path *, char *, int); |
313 | extern char *d_path_with_unreachable(const struct path *, char *, int); | 313 | extern char *d_path_with_unreachable(const struct path *, char *, int); |
314 | extern char *__dentry_path(struct dentry *, char *, int); | 314 | extern char *dentry_path_raw(struct dentry *, char *, int); |
315 | extern char *dentry_path(struct dentry *, char *, int); | 315 | extern char *dentry_path(struct dentry *, char *, int); |
316 | 316 | ||
317 | /* Allocation counts.. */ | 317 | /* Allocation counts.. */ |