Commit ffc9a3c3 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] symlink 3/9: trivial filesystems

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.
parent 6143b9ad
......@@ -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
};
......@@ -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
};
......@@ -13,6 +13,7 @@
#include <linux/stat.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/namei.h>
/*
* The follow_link operation is special: it must behave as a no-op
......@@ -21,7 +22,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)
......
......@@ -2490,29 +2490,11 @@ static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
return 0;
} /* End Function devfs_mknod */
static int devfs_readlink(struct dentry *dentry, char __user *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 = {
......@@ -2530,7 +2512,7 @@ static struct inode_operations devfs_dir_iops = {
};
static struct inode_operations devfs_symlink_iops = {
.readlink = devfs_readlink,
.readlink = generic_readlink,
.follow_link = devfs_follow_link,
.setattr = devfs_notify_change,
};
......
......@@ -32,12 +32,12 @@
*/
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/namei.h>
#include "vxfs.h"
#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 +49,7 @@ static int vxfs_immed_readpage(struct file *, struct page *);
* 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 +60,6 @@ struct address_space_operations vxfs_immed_aops = {
.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 +76,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;
}
/**
......
......@@ -17,23 +17,19 @@
*/
#include <linux/fs.h>
#include <linux/namei.h>
#include "jfs_incore.h"
#include "jfs_xattr.h"
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,
......
......@@ -17,6 +17,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
......@@ -321,21 +322,14 @@ static void release_inode_number(unsigned int inum)
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,
};
......
......@@ -6,20 +6,15 @@
*/
#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);
}
#include <linux/namei.h>
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,
};
......@@ -26,21 +26,17 @@
*/
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/ufs_fs.h>
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,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment