diff options
-rw-r--r-- | fs/exportfs/expfs.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 5bfe40085fbc..b06b54f1bbbb 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -11,6 +11,33 @@ struct export_operations export_op_default; | |||
11 | 11 | ||
12 | #define dprintk(fmt, args...) do{}while(0) | 12 | #define dprintk(fmt, args...) do{}while(0) |
13 | 13 | ||
14 | static struct dentry * | ||
15 | find_acceptable_alias(struct dentry *result, | ||
16 | int (*acceptable)(void *context, struct dentry *dentry), | ||
17 | void *context) | ||
18 | { | ||
19 | struct dentry *dentry, *toput = NULL; | ||
20 | |||
21 | spin_lock(&dcache_lock); | ||
22 | list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) { | ||
23 | dget_locked(dentry); | ||
24 | spin_unlock(&dcache_lock); | ||
25 | if (toput) | ||
26 | dput(toput); | ||
27 | if (dentry != result && acceptable(context, dentry)) { | ||
28 | dput(result); | ||
29 | return dentry; | ||
30 | } | ||
31 | spin_lock(&dcache_lock); | ||
32 | toput = dentry; | ||
33 | } | ||
34 | spin_unlock(&dcache_lock); | ||
35 | |||
36 | if (toput) | ||
37 | dput(toput); | ||
38 | return NULL; | ||
39 | } | ||
40 | |||
14 | /** | 41 | /** |
15 | * find_exported_dentry - helper routine to implement export_operations->decode_fh | 42 | * find_exported_dentry - helper routine to implement export_operations->decode_fh |
16 | * @sb: The &super_block identifying the filesystem | 43 | * @sb: The &super_block identifying the filesystem |
@@ -52,8 +79,7 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
52 | struct dentry *target_dir; | 79 | struct dentry *target_dir; |
53 | int err; | 80 | int err; |
54 | struct export_operations *nops = sb->s_export_op; | 81 | struct export_operations *nops = sb->s_export_op; |
55 | struct list_head *le, *head; | 82 | struct dentry *alias; |
56 | struct dentry *toput = NULL; | ||
57 | int noprogress; | 83 | int noprogress; |
58 | char nbuf[NAME_MAX+1]; | 84 | char nbuf[NAME_MAX+1]; |
59 | 85 | ||
@@ -79,27 +105,10 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
79 | /* there is no other dentry, so fail */ | 105 | /* there is no other dentry, so fail */ |
80 | goto err_result; | 106 | goto err_result; |
81 | } | 107 | } |
82 | /* try any other aliases */ | 108 | |
83 | spin_lock(&dcache_lock); | 109 | alias = find_acceptable_alias(result, acceptable, context); |
84 | head = &result->d_inode->i_dentry; | 110 | if (alias) |
85 | list_for_each(le, head) { | 111 | return alias; |
86 | struct dentry *dentry = list_entry(le, struct dentry, d_alias); | ||
87 | dget_locked(dentry); | ||
88 | spin_unlock(&dcache_lock); | ||
89 | if (toput) | ||
90 | dput(toput); | ||
91 | toput = NULL; | ||
92 | if (dentry != result && | ||
93 | acceptable(context, dentry)) { | ||
94 | dput(result); | ||
95 | return dentry; | ||
96 | } | ||
97 | spin_lock(&dcache_lock); | ||
98 | toput = dentry; | ||
99 | } | ||
100 | spin_unlock(&dcache_lock); | ||
101 | if (toput) | ||
102 | dput(toput); | ||
103 | } | 112 | } |
104 | 113 | ||
105 | /* It's a directory, or we are required to confirm the file's | 114 | /* It's a directory, or we are required to confirm the file's |
@@ -258,26 +267,10 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, | |||
258 | /* now result is properly connected, it is our best bet */ | 267 | /* now result is properly connected, it is our best bet */ |
259 | if (acceptable(context, result)) | 268 | if (acceptable(context, result)) |
260 | return result; | 269 | return result; |
261 | /* one last try of the aliases.. */ | 270 | |
262 | spin_lock(&dcache_lock); | 271 | alias = find_acceptable_alias(result, acceptable, context); |
263 | toput = NULL; | 272 | if (alias) |
264 | head = &result->d_inode->i_dentry; | 273 | return alias; |
265 | list_for_each(le, head) { | ||
266 | struct dentry *dentry = list_entry(le, struct dentry, d_alias); | ||
267 | dget_locked(dentry); | ||
268 | spin_unlock(&dcache_lock); | ||
269 | if (toput) dput(toput); | ||
270 | if (dentry != result && | ||
271 | acceptable(context, dentry)) { | ||
272 | dput(result); | ||
273 | return dentry; | ||
274 | } | ||
275 | spin_lock(&dcache_lock); | ||
276 | toput = dentry; | ||
277 | } | ||
278 | spin_unlock(&dcache_lock); | ||
279 | if (toput) | ||
280 | dput(toput); | ||
281 | 274 | ||
282 | /* drat - I just cannot find anything acceptable */ | 275 | /* drat - I just cannot find anything acceptable */ |
283 | dput(result); | 276 | dput(result); |