diff options
author | Al Viro <viro@parcelfarce.linux.theplanet.co.uk> | 2005-08-19 22:42:16 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-19 17:57:19 -0700 |
commit | 2fb1e3086df9b454538491fba8121298da37cd23 (patch) | |
tree | d84587462e0378c5aa9c5581d6920d76242b8c65 | |
parent | 91aa9fb573fcc50bc74d5ee64c7e9b36131f1804 (diff) | |
download | op-kernel-dev-2fb1e3086df9b454538491fba8121298da37cd23.zip op-kernel-dev-2fb1e3086df9b454538491fba8121298da37cd23.tar.gz |
[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>
-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 65ab6b0..073633e 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c @@ -30,6 +30,7 @@ struct inode_operations jffs2_symlink_inode_operations = static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); + char *p = (char *)f->dents; /* * 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) * nd_set_link() call. */ - if (!f->dents) { + if (!p) { printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); - return -EIO; + p = ERR_PTR(-EIO); + } else { + D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); } - D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); - nd_set_link(nd, (char *)f->dents); + nd_set_link(nd, p); /* * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe |