Merge uncontroversial parts of branch 'readlink' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull partial readlink cleanups from Miklos Szeredi.

This is the uncontroversial part of the readlink cleanup patch-set that
simplifies the default readlink handling.

Miklos and Al are still discussing the rest of the series.

* git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
  vfs: make generic_readlink() static
  vfs: remove ".readlink = generic_readlink" assignments
  vfs: default to generic_readlink()
  vfs: replace calling i_op->readlink with vfs_readlink()
  proc/self: use generic_readlink
  ecryptfs: use vfs_get_link()
  bad_inode: add missing i_op initializers
This commit is contained in:
Linus Torvalds 2016-12-17 19:16:12 -08:00
commit 231753ef78
46 changed files with 120 additions and 110 deletions

View File

@ -596,3 +596,7 @@ in your dentry operations instead.
[mandatory]
->rename() has an added flags argument. Any flags not handled by the
filesystem should result in EINVAL being returned.
--
[recommended]
->readlink is optional for symlinks. Don't set, unless filesystem needs
to fake something for readlink(2).

View File

@ -451,9 +451,6 @@ otherwise noted.
exist; this is checked by the VFS. Unlike plain rename,
source and target may be of different type.
readlink: called by the readlink(2) system call. Only required if
you want to support reading symbolic links
get_link: called by the VFS to follow a symbolic link to the
inode it points to. Only required if you want to support
symbolic links. This method returns the symlink body
@ -468,6 +465,12 @@ otherwise noted.
argument. If request can't be handled without leaving RCU mode,
have it return ERR_PTR(-ECHILD).
readlink: this is now just an override for use by readlink(2) for the
cases when ->get_link uses nd_jump_link() or object is not in
fact a symlink. Normally filesystems should only implement
->get_link for symlinks and readlink(2) will automatically use
that.
permission: called by the VFS to check for access rights on a POSIX-like
filesystem.

View File

@ -149,7 +149,6 @@ static const char *ll_get_link(struct dentry *dentry,
}
const struct inode_operations ll_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.setattr = ll_setattr,
.get_link = ll_get_link,
.getattr = ll_getattr,

View File

@ -1464,7 +1464,6 @@ static const struct inode_operations v9fs_file_inode_operations = {
};
static const struct inode_operations v9fs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = v9fs_vfs_get_link,
.getattr = v9fs_vfs_getattr,
.setattr = v9fs_vfs_setattr,

View File

@ -979,7 +979,6 @@ const struct inode_operations v9fs_file_inode_operations_dotl = {
};
const struct inode_operations v9fs_symlink_inode_operations_dotl = {
.readlink = generic_readlink,
.get_link = v9fs_vfs_get_link_dotl,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr_dotl,

View File

@ -70,7 +70,6 @@ const struct address_space_operations affs_symlink_aops = {
};
const struct inode_operations affs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = affs_notify_change,
};

View File

@ -25,6 +25,5 @@ static const char *autofs4_get_link(struct dentry *dentry,
}
const struct inode_operations autofs4_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = autofs4_get_link
};

View File

@ -106,6 +106,50 @@ static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
return -EIO;
}
static const char *bad_inode_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{
return ERR_PTR(-EIO);
}
static struct posix_acl *bad_inode_get_acl(struct inode *inode, int type)
{
return ERR_PTR(-EIO);
}
static int bad_inode_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo, u64 start,
u64 len)
{
return -EIO;
}
static int bad_inode_update_time(struct inode *inode, struct timespec *time,
int flags)
{
return -EIO;
}
static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
struct file *file, unsigned int open_flag,
umode_t create_mode, int *opened)
{
return -EIO;
}
static int bad_inode_tmpfile(struct inode *inode, struct dentry *dentry,
umode_t mode)
{
return -EIO;
}
static int bad_inode_set_acl(struct inode *inode, struct posix_acl *acl,
int type)
{
return -EIO;
}
static const struct inode_operations bad_inode_ops =
{
.create = bad_inode_create,
@ -118,14 +162,17 @@ static const struct inode_operations bad_inode_ops =
.mknod = bad_inode_mknod,
.rename = bad_inode_rename2,
.readlink = bad_inode_readlink,
/* follow_link must be no-op, otherwise unmounting this inode
won't work */
/* put_link returns void */
/* truncate returns void */
.permission = bad_inode_permission,
.getattr = bad_inode_getattr,
.setattr = bad_inode_setattr,
.listxattr = bad_inode_listxattr,
.get_link = bad_inode_get_link,
.get_acl = bad_inode_get_acl,
.fiemap = bad_inode_fiemap,
.update_time = bad_inode_update_time,
.atomic_open = bad_inode_atomic_open,
.tmpfile = bad_inode_tmpfile,
.set_acl = bad_inode_set_acl,
};

View File

@ -10653,7 +10653,6 @@ static const struct inode_operations btrfs_special_inode_operations = {
.update_time = btrfs_update_time,
};
static const struct inode_operations btrfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.getattr = btrfs_getattr,
.setattr = btrfs_setattr,

View File

@ -1869,7 +1869,6 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
* symlinks
*/
static const struct inode_operations ceph_symlink_iops = {
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = ceph_setattr,
.getattr = ceph_getattr,

View File

@ -914,7 +914,6 @@ const struct inode_operations cifs_file_inode_ops = {
};
const struct inode_operations cifs_symlink_inode_ops = {
.readlink = generic_readlink,
.get_link = cifs_get_link,
.permission = cifs_permission,
.listxattr = cifs_listxattr,

View File

@ -17,7 +17,6 @@ static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
}
static const struct inode_operations coda_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = coda_setattr,
};

View File

@ -305,7 +305,6 @@ static const char *configfs_get_link(struct dentry *dentry,
const struct inode_operations configfs_symlink_inode_operations = {
.get_link = configfs_get_link,
.readlink = generic_readlink,
.setattr = configfs_setattr,
};

View File

@ -631,28 +631,23 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
{
DEFINE_DELAYED_CALL(done);
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
char *lower_buf;
const char *link;
char *buf;
mm_segment_t old_fs;
int rc;
lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!lower_buf)
return ERR_PTR(-ENOMEM);
old_fs = get_fs();
set_fs(get_ds());
rc = d_inode(lower_dentry)->i_op->readlink(lower_dentry,
(char __user *)lower_buf,
PATH_MAX);
set_fs(old_fs);
if (rc < 0)
goto out;
link = vfs_get_link(lower_dentry, &done);
if (IS_ERR(link))
return ERR_CAST(link);
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
lower_buf, rc);
out:
kfree(lower_buf);
return rc ? ERR_PTR(rc) : buf;
link, strlen(link));
do_delayed_call(&done);
if (rc)
return ERR_PTR(rc);
return buf;
}
static const char *ecryptfs_get_link(struct dentry *dentry,
@ -1089,7 +1084,6 @@ static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
}
const struct inode_operations ecryptfs_symlink_iops = {
.readlink = generic_readlink,
.get_link = ecryptfs_get_link,
.permission = ecryptfs_permission,
.setattr = ecryptfs_setattr,

View File

@ -21,7 +21,6 @@
#include "xattr.h"
const struct inode_operations ext2_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = ext2_setattr,
#ifdef CONFIG_EXT2_FS_XATTR
@ -30,7 +29,6 @@ const struct inode_operations ext2_symlink_inode_operations = {
};
const struct inode_operations ext2_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = ext2_setattr,
#ifdef CONFIG_EXT2_FS_XATTR

View File

@ -83,21 +83,18 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
}
const struct inode_operations ext4_encrypted_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = ext4_encrypted_get_link,
.setattr = ext4_setattr,
.listxattr = ext4_listxattr,
};
const struct inode_operations ext4_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = ext4_setattr,
.listxattr = ext4_listxattr,
};
const struct inode_operations ext4_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = ext4_setattr,
.listxattr = ext4_listxattr,

View File

@ -1075,7 +1075,6 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
}
const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = f2fs_encrypted_get_link,
.getattr = f2fs_getattr,
.setattr = f2fs_setattr,
@ -1105,7 +1104,6 @@ const struct inode_operations f2fs_dir_inode_operations = {
};
const struct inode_operations f2fs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = f2fs_get_link,
.getattr = f2fs_getattr,
.setattr = f2fs_setattr,

View File

@ -1831,7 +1831,6 @@ static const struct inode_operations fuse_common_inode_operations = {
static const struct inode_operations fuse_symlink_inode_operations = {
.setattr = fuse_setattr,
.get_link = fuse_get_link,
.readlink = generic_readlink,
.getattr = fuse_getattr,
.listxattr = fuse_listxattr,
};

View File

@ -2067,7 +2067,6 @@ const struct inode_operations gfs2_dir_iops = {
};
const struct inode_operations gfs2_symlink_iops = {
.readlink = generic_readlink,
.get_link = gfs2_get_link,
.permission = gfs2_permission,
.setattr = gfs2_setattr,

View File

@ -920,7 +920,6 @@ static const char *hostfs_get_link(struct dentry *dentry,
}
static const struct inode_operations hostfs_link_iops = {
.readlink = generic_readlink,
.get_link = hostfs_get_link,
};

View File

@ -13,7 +13,6 @@
const struct inode_operations jffs2_symlink_inode_operations =
{
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = jffs2_setattr,
.listxattr = jffs2_listxattr,

View File

@ -22,14 +22,12 @@
#include "jfs_xattr.h"
const struct inode_operations jfs_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = jfs_setattr,
.listxattr = jfs_listxattr,
};
const struct inode_operations jfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = jfs_setattr,
.listxattr = jfs_listxattr,

View File

@ -135,7 +135,6 @@ static const char *kernfs_iop_get_link(struct dentry *dentry,
const struct inode_operations kernfs_symlink_iops = {
.listxattr = kernfs_iop_listxattr,
.readlink = generic_readlink,
.get_link = kernfs_iop_get_link,
.setattr = kernfs_iop_setattr,
.getattr = kernfs_iop_getattr,

View File

@ -1131,7 +1131,6 @@ EXPORT_SYMBOL(simple_get_link);
const struct inode_operations simple_symlink_inode_operations = {
.get_link = simple_get_link,
.readlink = generic_readlink
};
EXPORT_SYMBOL(simple_symlink_inode_operations);

View File

@ -434,7 +434,6 @@ static const struct address_space_operations minix_aops = {
};
static const struct inode_operations minix_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.getattr = minix_getattr,
};

View File

@ -4606,7 +4606,8 @@ int readlink_copy(char __user *buffer, int buflen, const char *link)
* have ->get_link() not calling nd_jump_link(). Using (or not using) it
* for any given inode is up to filesystem.
*/
int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
static int generic_readlink(struct dentry *dentry, char __user *buffer,
int buflen)
{
DEFINE_DELAYED_CALL(done);
struct inode *inode = d_inode(dentry);
@ -4622,7 +4623,36 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
do_delayed_call(&done);
return res;
}
EXPORT_SYMBOL(generic_readlink);
/**
* vfs_readlink - copy symlink body into userspace buffer
* @dentry: dentry on which to get symbolic link
* @buffer: user memory pointer
* @buflen: size of buffer
*
* Does not touch atime. That's up to the caller if necessary
*
* Does not call security hook.
*/
int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
struct inode *inode = d_inode(dentry);
if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) {
if (unlikely(inode->i_op->readlink))
return inode->i_op->readlink(dentry, buffer, buflen);
if (!d_is_symlink(dentry))
return -EINVAL;
spin_lock(&inode->i_lock);
inode->i_opflags |= IOP_DEFAULT_READLINK;
spin_unlock(&inode->i_lock);
}
return generic_readlink(dentry, buffer, buflen);
}
EXPORT_SYMBOL(vfs_readlink);
/**
* vfs_get_link - get symlink body
@ -4739,7 +4769,6 @@ int page_symlink(struct inode *inode, const char *symname, int len)
EXPORT_SYMBOL(page_symlink);
const struct inode_operations page_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
};
EXPORT_SYMBOL(page_symlink_inode_operations);

View File

@ -243,7 +243,6 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
static const struct inode_operations ncp_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = ncp_notify_change,
};

View File

@ -77,7 +77,6 @@ static const char *nfs_get_link(struct dentry *dentry,
* symlinks can't do much...
*/
const struct inode_operations nfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = nfs_get_link,
.getattr = nfs_getattr,
.setattr = nfs_setattr,

View File

@ -3605,10 +3605,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
if (!p)
return nfserr_resource;
/*
* XXX: By default, the ->readlink() VFS op will truncate symlinks
* if they would overflow the buffer. Is this kosher in NFSv4? If
* not, one easy fix is: if ->readlink() precisely fills the buffer,
* assume that truncation occurred, and return NFS4ERR_RESOURCE.
* XXX: By default, vfs_readlink() will truncate symlinks if they
* would overflow the buffer. Is this kosher in NFSv4? If not, one
* easy fix is: if vfs_readlink() precisely fills the buffer, assume
* that truncation occurred, and return NFS4ERR_RESOURCE.
*/
nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
(char *)p, &maxcount);

View File

@ -1450,7 +1450,6 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
{
struct inode *inode;
mm_segment_t oldfs;
__be32 err;
int host_err;
@ -1462,10 +1461,9 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
path.mnt = fhp->fh_export->ex_path.mnt;
path.dentry = fhp->fh_dentry;
inode = d_inode(path.dentry);
err = nfserr_inval;
if (!inode->i_op->readlink)
if (!d_is_symlink(path.dentry))
goto out;
touch_atime(&path);
@ -1474,7 +1472,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
*/
oldfs = get_fs(); set_fs(KERNEL_DS);
host_err = inode->i_op->readlink(path.dentry, (char __user *)buf, *lenp);
host_err = vfs_readlink(path.dentry, (char __user *)buf, *lenp);
set_fs(oldfs);
if (host_err < 0)

View File

@ -568,7 +568,6 @@ const struct inode_operations nilfs_special_inode_operations = {
};
const struct inode_operations nilfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.permission = nilfs_permission,
};

View File

@ -87,7 +87,6 @@ const struct address_space_operations ocfs2_fast_symlink_aops = {
};
const struct inode_operations ocfs2_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.getattr = ocfs2_getattr,
.setattr = ocfs2_setattr,

View File

@ -9,7 +9,6 @@
#include "orangefs-bufmap.h"
const struct inode_operations orangefs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = simple_get_link,
.setattr = orangefs_setattr,
.getattr = orangefs_getattr,

View File

@ -296,7 +296,6 @@ static const struct inode_operations ovl_file_inode_operations = {
static const struct inode_operations ovl_symlink_inode_operations = {
.setattr = ovl_setattr,
.get_link = ovl_get_link,
.readlink = generic_readlink,
.getattr = ovl_getattr,
.listxattr = ovl_listxattr,
.update_time = ovl_update_time,

View File

@ -425,7 +425,6 @@ static const char *proc_get_link(struct dentry *dentry,
}
const struct inode_operations proc_link_inode_operations = {
.readlink = generic_readlink,
.get_link = proc_get_link,
};

View File

@ -6,18 +6,6 @@
/*
* /proc/self:
*/
static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
int buflen)
{
struct pid_namespace *ns = dentry->d_sb->s_fs_info;
pid_t tgid = task_tgid_nr_ns(current, ns);
char tmp[PROC_NUMBUF];
if (!tgid)
return -ENOENT;
sprintf(tmp, "%d", tgid);
return readlink_copy(buffer, buflen, tmp);
}
static const char *proc_self_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
@ -38,7 +26,6 @@ static const char *proc_self_get_link(struct dentry *dentry,
}
static const struct inode_operations proc_self_inode_operations = {
.readlink = proc_self_readlink,
.get_link = proc_self_get_link,
};

View File

@ -6,19 +6,6 @@
/*
* /proc/thread_self:
*/
static int proc_thread_self_readlink(struct dentry *dentry, char __user *buffer,
int buflen)
{
struct pid_namespace *ns = dentry->d_sb->s_fs_info;
pid_t tgid = task_tgid_nr_ns(current, ns);
pid_t pid = task_pid_nr_ns(current, ns);
char tmp[PROC_NUMBUF + 6 + PROC_NUMBUF];
if (!pid)
return -ENOENT;
sprintf(tmp, "%d/task/%d", tgid, pid);
return readlink_copy(buffer, buflen, tmp);
}
static const char *proc_thread_self_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
@ -40,7 +27,6 @@ static const char *proc_thread_self_get_link(struct dentry *dentry,
}
static const struct inode_operations proc_thread_self_inode_operations = {
.readlink = proc_thread_self_readlink,
.get_link = proc_thread_self_get_link,
};

View File

@ -1665,7 +1665,6 @@ const struct inode_operations reiserfs_dir_inode_operations = {
* stuff added
*/
const struct inode_operations reiserfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.setattr = reiserfs_setattr,
.listxattr = reiserfs_listxattr,

View File

@ -118,7 +118,6 @@ const struct address_space_operations squashfs_symlink_aops = {
};
const struct inode_operations squashfs_symlink_inode_ops = {
.readlink = generic_readlink,
.get_link = page_get_link,
.listxattr = squashfs_listxattr
};

View File

@ -329,12 +329,14 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
struct inode *inode = d_backing_inode(path.dentry);
error = empty ? -ENOENT : -EINVAL;
if (inode->i_op->readlink) {
/*
* AFS mountpoints allow readlink(2) but are not symlinks
*/
if (d_is_symlink(path.dentry) || inode->i_op->readlink) {
error = security_inode_readlink(path.dentry);
if (!error) {
touch_atime(&path);
error = inode->i_op->readlink(path.dentry,
buf, bufsiz);
error = vfs_readlink(path.dentry, buf, bufsiz);
}
}
path_put(&path);

View File

@ -145,7 +145,6 @@ static inline void write3byte(struct sysv_sb_info *sbi,
}
static const struct inode_operations sysv_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = page_get_link,
.getattr = sysv_getattr,
};

View File

@ -1733,7 +1733,6 @@ const struct inode_operations ubifs_file_inode_operations = {
};
const struct inode_operations ubifs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = ubifs_get_link,
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,

View File

@ -287,7 +287,7 @@ xfs_readlink_by_handle(
return PTR_ERR(dentry);
/* Restrict this handle operation to symlinks only. */
if (!d_inode(dentry)->i_op->readlink) {
if (!d_is_symlink(dentry)) {
error = -EINVAL;
goto out_dput;
}
@ -297,7 +297,7 @@ xfs_readlink_by_handle(
goto out_dput;
}
error = d_inode(dentry)->i_op->readlink(dentry, hreq->ohandle, olen);
error = vfs_readlink(dentry, hreq->ohandle, olen);
out_dput:
dput(dentry);

View File

@ -1120,7 +1120,6 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
};
static const struct inode_operations xfs_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = xfs_vn_get_link,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
@ -1129,7 +1128,6 @@ static const struct inode_operations xfs_symlink_inode_operations = {
};
static const struct inode_operations xfs_inline_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = xfs_vn_get_link_inline,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,

View File

@ -543,6 +543,7 @@ is_uncached_acl(struct posix_acl *acl)
#define IOP_LOOKUP 0x0002
#define IOP_NOFOLLOW 0x0004
#define IOP_XATTR 0x0008
#define IOP_DEFAULT_READLINK 0x0010
/*
* Keep mostly read-only and often accessed (especially for
@ -2867,7 +2868,6 @@ extern int __page_symlink(struct inode *inode, const char *symname, int len,
extern int page_symlink(struct inode *inode, const char *symname, int len);
extern const struct inode_operations page_symlink_inode_operations;
extern void kfree_link(void *);
extern int generic_readlink(struct dentry *, char __user *, int);
extern void generic_fillattr(struct inode *, struct kstat *);
int vfs_getattr_nosec(struct path *path, struct kstat *stat);
extern int vfs_getattr(struct path *, struct kstat *);
@ -2888,6 +2888,7 @@ extern int vfs_lstat(const char __user *, struct kstat *);
extern int vfs_fstat(unsigned int, struct kstat *);
extern int vfs_fstatat(int , const char __user *, struct kstat *, int);
extern const char *vfs_get_link(struct dentry *, struct delayed_call *);
extern int vfs_readlink(struct dentry *, char __user *, int);
extern int __generic_block_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo,

View File

@ -3212,7 +3212,6 @@ static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size)
#endif /* CONFIG_TMPFS_XATTR */
static const struct inode_operations shmem_short_symlink_operations = {
.readlink = generic_readlink,
.get_link = simple_get_link,
#ifdef CONFIG_TMPFS_XATTR
.listxattr = shmem_listxattr,
@ -3220,7 +3219,6 @@ static const struct inode_operations shmem_short_symlink_operations = {
};
static const struct inode_operations shmem_symlink_inode_operations = {
.readlink = generic_readlink,
.get_link = shmem_get_link,
#ifdef CONFIG_TMPFS_XATTR
.listxattr = shmem_listxattr,