diff options
author | Al Viro <viro@parcelfarce.linux.theplanet.co.uk> | 2005-08-19 17:42:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-19 20:57:19 -0400 |
commit | 2fb1e3086df9b454538491fba8121298da37cd23 (patch) | |
tree | d84587462e0378c5aa9c5581d6920d76242b8c65 /fs/jffs2/symlink.c | |
parent | 91aa9fb573fcc50bc74d5ee64c7e9b36131f1804 (diff) |
[PATCH] jffs2: fix symlink error handling
The current calling conventions for ->follow_link() are already fairly
complex.
What we have is
1) you can return -error; then you must release nameidata yourself
and ->put_link() will _not_ be called.
2) you can do nd_set_link(nd, ERR_PTR(-error)) and return 0
3) you can do nd_set_link(nd, path) and return 0
4) you can return 0 (after having moved nameidata yourself)
jffs2 follow_link() is broken - it has an exit where it returns
-EIO and leaks nameidata.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/jffs2/symlink.c')
-rw-r--r-- | fs/jffs2/symlink.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index 65ab6b001dca..073633e11ea9 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c | |||
@@ -30,6 +30,7 @@ struct inode_operations jffs2_symlink_inode_operations = | |||
30 | static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) | 30 | static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) |
31 | { | 31 | { |
32 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); | 32 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); |
33 | char *p = (char *)f->dents; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * We don't acquire the f->sem mutex here since the only data we | 36 | * We don't acquire the f->sem mutex here since the only data we |
@@ -45,13 +46,14 @@ static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
45 | * nd_set_link() call. | 46 | * nd_set_link() call. |
46 | */ | 47 | */ |
47 | 48 | ||
48 | if (!f->dents) { | 49 | if (!p) { |
49 | printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); | 50 | printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); |
50 | return -EIO; | 51 | p = ERR_PTR(-EIO); |
52 | } else { | ||
53 | D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); | ||
51 | } | 54 | } |
52 | D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); | ||
53 | 55 | ||
54 | nd_set_link(nd, (char *)f->dents); | 56 | nd_set_link(nd, p); |
55 | 57 | ||
56 | /* | 58 | /* |
57 | * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe | 59 | * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe |