diff options
| author | Christoph Hellwig <hch@lst.de> | 2006-01-18 20:43:52 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:28 -0500 |
| commit | e2f99018eb7b29954747a2dd78e9fc0c36a60f0f (patch) | |
| tree | 6e74677c01a13d2ec5285df9bffd34357b966e57 /fs/exportfs | |
| parent | 846f2fcd77850ef8f0aab46df9cadd5c35a5fef0 (diff) | |
[PATCH] exportfs: add find_acceptable_alias helper
find_exported_dentry contains two duplicate loops to find an alias that the
acceptable callback likes. Split this out to a new helper and switch from
list_for_each to list_for_each_entry to make it more readable.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: NeilBrown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/exportfs')
| -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); |
