[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>

authored by Al Viro and committed by Linus Torvalds 2fb1e308 91aa9fb5

+6 -4
+6 -4
fs/jffs2/symlink.c
··· 30 static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 31 { 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); 33 34 /* 35 * We don't acquire the f->sem mutex here since the only data we ··· 46 * nd_set_link() call. 47 */ 48 49 - if (!f->dents) { 50 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); 51 - return -EIO; 52 } 53 - D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); 54 55 - nd_set_link(nd, (char *)f->dents); 56 57 /* 58 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
··· 30 static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 31 { 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); 33 + char *p = (char *)f->dents; 34 35 /* 36 * We don't acquire the f->sem mutex here since the only data we ··· 45 * nd_set_link() call. 46 */ 47 48 + if (!p) { 49 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); 50 + p = ERR_PTR(-EIO); 51 + } else { 52 + D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); 53 } 54 55 + nd_set_link(nd, p); 56 57 /* 58 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe