From: xfs switched to new scheme; leaks plugged. --- 25-akpm/fs/xfs/linux/xfs_iops.c | 30 +++++++++++++++++++----------- 1 files changed, 19 insertions(+), 11 deletions(-) diff -puN fs/xfs/linux/xfs_iops.c~SL5-xfs-RC6-bk5 fs/xfs/linux/xfs_iops.c --- 25/fs/xfs/linux/xfs_iops.c~SL5-xfs-RC6-bk5 2004-05-19 20:51:20.738913336 -0700 +++ 25-akpm/fs/xfs/linux/xfs_iops.c 2004-05-19 20:51:20.741912880 -0700 @@ -419,13 +419,16 @@ linvfs_follow_link( ASSERT(nd); link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); - if (!link) - return -ENOMEM; + if (!link) { + nd_set_link(nd, ERR_PTR(-ENOMEM)); + return 0; + } uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL); if (!uio) { kfree(link); - return -ENOMEM; + nd_set_link(nd, ERR_PTR(-ENOMEM)); + return 0; } vp = LINVFS_GET_VP(dentry->d_inode); @@ -441,18 +444,22 @@ linvfs_follow_link( VOP_READLINK(vp, uio, 0, NULL, error); if (error) { - kfree(uio); kfree(link); - return -error; + link = ERR_PTR(-error); + } else { + link[MAXNAMELEN - uio->uio_resid] = '\0'; } - - link[MAXNAMELEN - uio->uio_resid] = '\0'; kfree(uio); - /* vfs_follow_link returns (-) errors */ - error = vfs_follow_link(nd, link); - kfree(link); - return error; + nd_set_link(nd, link); + return 0; +} + +static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd) +{ + char *s = nd_get_link(nd); + if (!IS_ERR(s)) + kfree(s); } #ifdef CONFIG_XFS_POSIX_ACL @@ -698,6 +705,7 @@ struct inode_operations linvfs_dir_inode struct inode_operations linvfs_symlink_inode_operations = { .readlink = linvfs_readlink, .follow_link = linvfs_follow_link, + .put_link = linvfs_put_link, .permission = linvfs_permission, .getattr = linvfs_getattr, .setattr = linvfs_setattr, _