From: trivial cases - ones where we have no need to clean up after pathname traversal (link body embedded into inode, etc.). Plugged leak in devfs_follow_link(), while we are at it. --- 25-akpm/fs/autofs/symlink.c | 11 +++-------- 25-akpm/fs/autofs4/symlink.c | 13 +++---------- 25-akpm/fs/bad_inode.c | 3 ++- 25-akpm/fs/devfs/base.c | 25 ++++--------------------- 25-akpm/fs/freevxfs/vxfs_immed.c | 29 +++-------------------------- 25-akpm/fs/jfs/symlink.c | 11 +++-------- 25-akpm/fs/proc/generic.c | 13 +++---------- 25-akpm/fs/sysv/symlink.c | 12 +++--------- 25-akpm/fs/ufs/symlink.c | 11 +++-------- 9 files changed, 27 insertions(+), 101 deletions(-) diff -puN fs/autofs4/symlink.c~SL2-trivial-RC6-bk5 fs/autofs4/symlink.c --- 25/fs/autofs4/symlink.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.670197192 -0700 +++ 25-akpm/fs/autofs4/symlink.c 2004-05-19 20:50:19.683195216 -0700 @@ -12,21 +12,14 @@ #include "autofs_i.h" -static int autofs4_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - struct autofs_info *ino = autofs4_dentry_ino(dentry); - - return vfs_readlink(dentry, buffer, buflen, ino->u.symlink); -} - static int autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) { struct autofs_info *ino = autofs4_dentry_ino(dentry); - - return vfs_follow_link(nd, ino->u.symlink); + nd_set_link(nd, (char *)ino->u.symlink); + return 0; } struct inode_operations autofs4_symlink_inode_operations = { - .readlink = autofs4_readlink, + .readlink = generic_readlink, .follow_link = autofs4_follow_link }; diff -puN fs/autofs/symlink.c~SL2-trivial-RC6-bk5 fs/autofs/symlink.c --- 25/fs/autofs/symlink.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.671197040 -0700 +++ 25-akpm/fs/autofs/symlink.c 2004-05-19 20:50:19.683195216 -0700 @@ -12,19 +12,14 @@ #include "autofs_i.h" -static int autofs_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; - return vfs_readlink(dentry, buffer, buflen, s); -} - static int autofs_follow_link(struct dentry *dentry, struct nameidata *nd) { char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; - return vfs_follow_link(nd, s); + nd_set_link(nd, s); + return 0; } struct inode_operations autofs_symlink_inode_operations = { - .readlink = autofs_readlink, + .readlink = generic_readlink, .follow_link = autofs_follow_link }; diff -puN fs/bad_inode.c~SL2-trivial-RC6-bk5 fs/bad_inode.c --- 25/fs/bad_inode.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.672196888 -0700 +++ 25-akpm/fs/bad_inode.c 2004-05-19 20:50:19.684195064 -0700 @@ -21,7 +21,8 @@ */ static int bad_follow_link(struct dentry *dent, struct nameidata *nd) { - return vfs_follow_link(nd, ERR_PTR(-EIO)); + nd_set_link(nd, ERR_PTR(-EIO)); + return 0; } static int return_EIO(void) diff -puN fs/devfs/base.c~SL2-trivial-RC6-bk5 fs/devfs/base.c --- 25/fs/devfs/base.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.674196584 -0700 +++ 25-akpm/fs/devfs/base.c 2004-05-19 20:50:19.686194760 -0700 @@ -2490,28 +2490,11 @@ static int devfs_mknod(struct inode *dir return 0; } /* End Function devfs_mknod */ -static int devfs_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - int err; - struct devfs_entry *de; - - de = get_devfs_entry_from_vfs_inode(dentry->d_inode); - if (!de) - return -ENODEV; - err = vfs_readlink(dentry, buffer, buflen, de->u.symlink.linkname); - return err; -} /* End Function devfs_readlink */ - static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd) { - int err; - struct devfs_entry *de; - - de = get_devfs_entry_from_vfs_inode(dentry->d_inode); - if (!de) - return -ENODEV; - err = vfs_follow_link(nd, de->u.symlink.linkname); - return err; + struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode); + nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV)); + return 0; } /* End Function devfs_follow_link */ static struct inode_operations devfs_iops = { @@ -2529,7 +2512,7 @@ static struct inode_operations devfs_dir }; static struct inode_operations devfs_symlink_iops = { - .readlink = devfs_readlink, + .readlink = generic_readlink, .follow_link = devfs_follow_link, .setattr = devfs_notify_change, }; diff -puN fs/freevxfs/vxfs_immed.c~SL2-trivial-RC6-bk5 fs/freevxfs/vxfs_immed.c --- 25/fs/freevxfs/vxfs_immed.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.675196432 -0700 +++ 25-akpm/fs/freevxfs/vxfs_immed.c 2004-05-19 20:50:19.687194608 -0700 @@ -37,7 +37,6 @@ #include "vxfs_inode.h" -static int vxfs_immed_readlink(struct dentry *, char __user *, int); static int vxfs_immed_follow_link(struct dentry *, struct nameidata *); static int vxfs_immed_readpage(struct file *, struct page *); @@ -49,7 +48,7 @@ static int vxfs_immed_readpage(struct fi * but do all work directly on the inode. */ struct inode_operations vxfs_immed_symlink_iops = { - .readlink = vxfs_immed_readlink, + .readlink = generic_readlink, .follow_link = vxfs_immed_follow_link, }; @@ -60,28 +59,6 @@ struct address_space_operations vxfs_imm .readpage = vxfs_immed_readpage, }; - -/** - * vxfs_immed_readlink - read immed symlink - * @dp: dentry for the link - * @bp: output buffer - * @buflen: length of @bp - * - * Description: - * vxfs_immed_readlink calls vfs_readlink to read the link - * described by @dp into userspace. - * - * Returns: - * Number of bytes successfully copied to userspace. - */ -static int -vxfs_immed_readlink(struct dentry *dp, char __user *bp, int buflen) -{ - struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); - - return (vfs_readlink(dp, bp, buflen, vip->vii_immed.vi_immed)); -} - /** * vxfs_immed_follow_link - follow immed symlink * @dp: dentry for the link @@ -98,8 +75,8 @@ static int vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) { struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); - - return (vfs_follow_link(np, vip->vii_immed.vi_immed)); + nd_set_link(np, vip->vii_immed.vi_immed); + return 0; } /** diff -puN fs/jfs/symlink.c~SL2-trivial-RC6-bk5 fs/jfs/symlink.c --- 25/fs/jfs/symlink.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.677196128 -0700 +++ 25-akpm/fs/jfs/symlink.c 2004-05-19 20:50:19.687194608 -0700 @@ -23,17 +23,12 @@ static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) { char *s = JFS_IP(dentry->d_inode)->i_inline; - return vfs_follow_link(nd, s); -} - -static int jfs_readlink(struct dentry *dentry, char __user *buffer, int buflen) -{ - char *s = JFS_IP(dentry->d_inode)->i_inline; - return vfs_readlink(dentry, buffer, buflen, s); + nd_set_link(nd, s); + return 0; } struct inode_operations jfs_symlink_inode_operations = { - .readlink = jfs_readlink, + .readlink = generic_readlink, .follow_link = jfs_follow_link, .setxattr = jfs_setxattr, .getxattr = jfs_getxattr, diff -puN fs/proc/generic.c~SL2-trivial-RC6-bk5 fs/proc/generic.c --- 25/fs/proc/generic.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.678195976 -0700 +++ 25-akpm/fs/proc/generic.c 2004-05-19 20:50:19.688194456 -0700 @@ -321,21 +321,14 @@ static void release_inode_number(unsigne spin_unlock(&proc_inum_lock); } -static int -proc_readlink(struct dentry *dentry, char __user *buffer, int buflen) -{ - char *s = PDE(dentry->d_inode)->data; - return vfs_readlink(dentry, buffer, buflen, s); -} - static int proc_follow_link(struct dentry *dentry, struct nameidata *nd) { - char *s = PDE(dentry->d_inode)->data; - return vfs_follow_link(nd, s); + nd_set_link(nd, PDE(dentry->d_inode)->data); + return 0; } static struct inode_operations proc_link_inode_operations = { - .readlink = proc_readlink, + .readlink = generic_readlink, .follow_link = proc_follow_link, }; diff -puN fs/sysv/symlink.c~SL2-trivial-RC6-bk5 fs/sysv/symlink.c --- 25/fs/sysv/symlink.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.679195824 -0700 +++ 25-akpm/fs/sysv/symlink.c 2004-05-19 20:50:19.688194456 -0700 @@ -7,19 +7,13 @@ #include "sysv.h" -static int sysv_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - char *s = (char *)SYSV_I(dentry->d_inode)->i_data; - return vfs_readlink(dentry, buffer, buflen, s); -} - static int sysv_follow_link(struct dentry *dentry, struct nameidata *nd) { - char *s = (char *)SYSV_I(dentry->d_inode)->i_data; - return vfs_follow_link(nd, s); + nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data); + return 0; } struct inode_operations sysv_fast_symlink_inode_operations = { - .readlink = sysv_readlink, + .readlink = generic_readlink, .follow_link = sysv_follow_link, }; diff -puN fs/ufs/symlink.c~SL2-trivial-RC6-bk5 fs/ufs/symlink.c --- 25/fs/ufs/symlink.c~SL2-trivial-RC6-bk5 2004-05-19 20:50:19.680195672 -0700 +++ 25-akpm/fs/ufs/symlink.c 2004-05-19 20:50:19.688194456 -0700 @@ -28,19 +28,14 @@ #include #include -static int ufs_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - struct ufs_inode_info *p = UFS_I(dentry->d_inode); - return vfs_readlink(dentry, buffer, buflen, (char*)p->i_u1.i_symlink); -} - static int ufs_follow_link(struct dentry *dentry, struct nameidata *nd) { struct ufs_inode_info *p = UFS_I(dentry->d_inode); - return vfs_follow_link(nd, (char*)p->i_u1.i_symlink); + nd_set_link(nd, (char*)p->i_u1.i_symlink); + return 0; } struct inode_operations ufs_fast_symlink_inode_operations = { - .readlink = ufs_readlink, + .readlink = generic_readlink, .follow_link = ufs_follow_link, }; _