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:
Коммит
231753ef78
|
@ -596,3 +596,7 @@ in your dentry operations instead.
|
||||||
[mandatory]
|
[mandatory]
|
||||||
->rename() has an added flags argument. Any flags not handled by the
|
->rename() has an added flags argument. Any flags not handled by the
|
||||||
filesystem should result in EINVAL being returned.
|
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).
|
||||||
|
|
|
@ -451,9 +451,6 @@ otherwise noted.
|
||||||
exist; this is checked by the VFS. Unlike plain rename,
|
exist; this is checked by the VFS. Unlike plain rename,
|
||||||
source and target may be of different type.
|
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
|
get_link: called by the VFS to follow a symbolic link to the
|
||||||
inode it points to. Only required if you want to support
|
inode it points to. Only required if you want to support
|
||||||
symbolic links. This method returns the symlink body
|
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,
|
argument. If request can't be handled without leaving RCU mode,
|
||||||
have it return ERR_PTR(-ECHILD).
|
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
|
permission: called by the VFS to check for access rights on a POSIX-like
|
||||||
filesystem.
|
filesystem.
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,6 @@ static const char *ll_get_link(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations ll_fast_symlink_inode_operations = {
|
const struct inode_operations ll_fast_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.setattr = ll_setattr,
|
.setattr = ll_setattr,
|
||||||
.get_link = ll_get_link,
|
.get_link = ll_get_link,
|
||||||
.getattr = ll_getattr,
|
.getattr = ll_getattr,
|
||||||
|
|
|
@ -1464,7 +1464,6 @@ static const struct inode_operations v9fs_file_inode_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations v9fs_symlink_inode_operations = {
|
static const struct inode_operations v9fs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = v9fs_vfs_get_link,
|
.get_link = v9fs_vfs_get_link,
|
||||||
.getattr = v9fs_vfs_getattr,
|
.getattr = v9fs_vfs_getattr,
|
||||||
.setattr = v9fs_vfs_setattr,
|
.setattr = v9fs_vfs_setattr,
|
||||||
|
|
|
@ -979,7 +979,6 @@ const struct inode_operations v9fs_file_inode_operations_dotl = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations v9fs_symlink_inode_operations_dotl = {
|
const struct inode_operations v9fs_symlink_inode_operations_dotl = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = v9fs_vfs_get_link_dotl,
|
.get_link = v9fs_vfs_get_link_dotl,
|
||||||
.getattr = v9fs_vfs_getattr_dotl,
|
.getattr = v9fs_vfs_getattr_dotl,
|
||||||
.setattr = v9fs_vfs_setattr_dotl,
|
.setattr = v9fs_vfs_setattr_dotl,
|
||||||
|
|
|
@ -70,7 +70,6 @@ const struct address_space_operations affs_symlink_aops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations affs_symlink_inode_operations = {
|
const struct inode_operations affs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = affs_notify_change,
|
.setattr = affs_notify_change,
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,5 @@ static const char *autofs4_get_link(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations autofs4_symlink_inode_operations = {
|
const struct inode_operations autofs4_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = autofs4_get_link
|
.get_link = autofs4_get_link
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,6 +106,50 @@ static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
|
||||||
return -EIO;
|
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 =
|
static const struct inode_operations bad_inode_ops =
|
||||||
{
|
{
|
||||||
.create = bad_inode_create,
|
.create = bad_inode_create,
|
||||||
|
@ -118,14 +162,17 @@ static const struct inode_operations bad_inode_ops =
|
||||||
.mknod = bad_inode_mknod,
|
.mknod = bad_inode_mknod,
|
||||||
.rename = bad_inode_rename2,
|
.rename = bad_inode_rename2,
|
||||||
.readlink = bad_inode_readlink,
|
.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,
|
.permission = bad_inode_permission,
|
||||||
.getattr = bad_inode_getattr,
|
.getattr = bad_inode_getattr,
|
||||||
.setattr = bad_inode_setattr,
|
.setattr = bad_inode_setattr,
|
||||||
.listxattr = bad_inode_listxattr,
|
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10653,7 +10653,6 @@ static const struct inode_operations btrfs_special_inode_operations = {
|
||||||
.update_time = btrfs_update_time,
|
.update_time = btrfs_update_time,
|
||||||
};
|
};
|
||||||
static const struct inode_operations btrfs_symlink_inode_operations = {
|
static const struct inode_operations btrfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.getattr = btrfs_getattr,
|
.getattr = btrfs_getattr,
|
||||||
.setattr = btrfs_setattr,
|
.setattr = btrfs_setattr,
|
||||||
|
|
|
@ -1869,7 +1869,6 @@ retry:
|
||||||
* symlinks
|
* symlinks
|
||||||
*/
|
*/
|
||||||
static const struct inode_operations ceph_symlink_iops = {
|
static const struct inode_operations ceph_symlink_iops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = ceph_setattr,
|
.setattr = ceph_setattr,
|
||||||
.getattr = ceph_getattr,
|
.getattr = ceph_getattr,
|
||||||
|
|
|
@ -914,7 +914,6 @@ const struct inode_operations cifs_file_inode_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations cifs_symlink_inode_ops = {
|
const struct inode_operations cifs_symlink_inode_ops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = cifs_get_link,
|
.get_link = cifs_get_link,
|
||||||
.permission = cifs_permission,
|
.permission = cifs_permission,
|
||||||
.listxattr = cifs_listxattr,
|
.listxattr = cifs_listxattr,
|
||||||
|
|
|
@ -17,7 +17,6 @@ static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct inode_operations coda_symlink_inode_operations = {
|
static const struct inode_operations coda_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = coda_setattr,
|
.setattr = coda_setattr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -305,7 +305,6 @@ static const char *configfs_get_link(struct dentry *dentry,
|
||||||
|
|
||||||
const struct inode_operations configfs_symlink_inode_operations = {
|
const struct inode_operations configfs_symlink_inode_operations = {
|
||||||
.get_link = configfs_get_link,
|
.get_link = configfs_get_link,
|
||||||
.readlink = generic_readlink,
|
|
||||||
.setattr = configfs_setattr,
|
.setattr = configfs_setattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -631,28 +631,23 @@ out_lock:
|
||||||
|
|
||||||
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
|
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
|
||||||
{
|
{
|
||||||
|
DEFINE_DELAYED_CALL(done);
|
||||||
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
char *lower_buf;
|
const char *link;
|
||||||
char *buf;
|
char *buf;
|
||||||
mm_segment_t old_fs;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
|
link = vfs_get_link(lower_dentry, &done);
|
||||||
if (!lower_buf)
|
if (IS_ERR(link))
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_CAST(link);
|
||||||
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;
|
|
||||||
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
|
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
|
||||||
lower_buf, rc);
|
link, strlen(link));
|
||||||
out:
|
do_delayed_call(&done);
|
||||||
kfree(lower_buf);
|
if (rc)
|
||||||
return rc ? ERR_PTR(rc) : buf;
|
return ERR_PTR(rc);
|
||||||
|
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *ecryptfs_get_link(struct dentry *dentry,
|
static const char *ecryptfs_get_link(struct dentry *dentry,
|
||||||
|
@ -1089,7 +1084,6 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations ecryptfs_symlink_iops = {
|
const struct inode_operations ecryptfs_symlink_iops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = ecryptfs_get_link,
|
.get_link = ecryptfs_get_link,
|
||||||
.permission = ecryptfs_permission,
|
.permission = ecryptfs_permission,
|
||||||
.setattr = ecryptfs_setattr,
|
.setattr = ecryptfs_setattr,
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "xattr.h"
|
#include "xattr.h"
|
||||||
|
|
||||||
const struct inode_operations ext2_symlink_inode_operations = {
|
const struct inode_operations ext2_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = ext2_setattr,
|
.setattr = ext2_setattr,
|
||||||
#ifdef CONFIG_EXT2_FS_XATTR
|
#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 = {
|
const struct inode_operations ext2_fast_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = ext2_setattr,
|
.setattr = ext2_setattr,
|
||||||
#ifdef CONFIG_EXT2_FS_XATTR
|
#ifdef CONFIG_EXT2_FS_XATTR
|
||||||
|
|
|
@ -83,21 +83,18 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations ext4_encrypted_symlink_inode_operations = {
|
const struct inode_operations ext4_encrypted_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = ext4_encrypted_get_link,
|
.get_link = ext4_encrypted_get_link,
|
||||||
.setattr = ext4_setattr,
|
.setattr = ext4_setattr,
|
||||||
.listxattr = ext4_listxattr,
|
.listxattr = ext4_listxattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations ext4_symlink_inode_operations = {
|
const struct inode_operations ext4_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = ext4_setattr,
|
.setattr = ext4_setattr,
|
||||||
.listxattr = ext4_listxattr,
|
.listxattr = ext4_listxattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations ext4_fast_symlink_inode_operations = {
|
const struct inode_operations ext4_fast_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = ext4_setattr,
|
.setattr = ext4_setattr,
|
||||||
.listxattr = ext4_listxattr,
|
.listxattr = ext4_listxattr,
|
||||||
|
|
|
@ -1075,7 +1075,6 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
|
const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = f2fs_encrypted_get_link,
|
.get_link = f2fs_encrypted_get_link,
|
||||||
.getattr = f2fs_getattr,
|
.getattr = f2fs_getattr,
|
||||||
.setattr = f2fs_setattr,
|
.setattr = f2fs_setattr,
|
||||||
|
@ -1105,7 +1104,6 @@ const struct inode_operations f2fs_dir_inode_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations f2fs_symlink_inode_operations = {
|
const struct inode_operations f2fs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = f2fs_get_link,
|
.get_link = f2fs_get_link,
|
||||||
.getattr = f2fs_getattr,
|
.getattr = f2fs_getattr,
|
||||||
.setattr = f2fs_setattr,
|
.setattr = f2fs_setattr,
|
||||||
|
|
|
@ -1831,7 +1831,6 @@ static const struct inode_operations fuse_common_inode_operations = {
|
||||||
static const struct inode_operations fuse_symlink_inode_operations = {
|
static const struct inode_operations fuse_symlink_inode_operations = {
|
||||||
.setattr = fuse_setattr,
|
.setattr = fuse_setattr,
|
||||||
.get_link = fuse_get_link,
|
.get_link = fuse_get_link,
|
||||||
.readlink = generic_readlink,
|
|
||||||
.getattr = fuse_getattr,
|
.getattr = fuse_getattr,
|
||||||
.listxattr = fuse_listxattr,
|
.listxattr = fuse_listxattr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -2067,7 +2067,6 @@ const struct inode_operations gfs2_dir_iops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations gfs2_symlink_iops = {
|
const struct inode_operations gfs2_symlink_iops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = gfs2_get_link,
|
.get_link = gfs2_get_link,
|
||||||
.permission = gfs2_permission,
|
.permission = gfs2_permission,
|
||||||
.setattr = gfs2_setattr,
|
.setattr = gfs2_setattr,
|
||||||
|
|
|
@ -920,7 +920,6 @@ static const char *hostfs_get_link(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct inode_operations hostfs_link_iops = {
|
static const struct inode_operations hostfs_link_iops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = hostfs_get_link,
|
.get_link = hostfs_get_link,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
const struct inode_operations jffs2_symlink_inode_operations =
|
const struct inode_operations jffs2_symlink_inode_operations =
|
||||||
{
|
{
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = jffs2_setattr,
|
.setattr = jffs2_setattr,
|
||||||
.listxattr = jffs2_listxattr,
|
.listxattr = jffs2_listxattr,
|
||||||
|
|
|
@ -22,14 +22,12 @@
|
||||||
#include "jfs_xattr.h"
|
#include "jfs_xattr.h"
|
||||||
|
|
||||||
const struct inode_operations jfs_fast_symlink_inode_operations = {
|
const struct inode_operations jfs_fast_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = jfs_setattr,
|
.setattr = jfs_setattr,
|
||||||
.listxattr = jfs_listxattr,
|
.listxattr = jfs_listxattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations jfs_symlink_inode_operations = {
|
const struct inode_operations jfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = jfs_setattr,
|
.setattr = jfs_setattr,
|
||||||
.listxattr = jfs_listxattr,
|
.listxattr = jfs_listxattr,
|
||||||
|
|
|
@ -135,7 +135,6 @@ static const char *kernfs_iop_get_link(struct dentry *dentry,
|
||||||
|
|
||||||
const struct inode_operations kernfs_symlink_iops = {
|
const struct inode_operations kernfs_symlink_iops = {
|
||||||
.listxattr = kernfs_iop_listxattr,
|
.listxattr = kernfs_iop_listxattr,
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = kernfs_iop_get_link,
|
.get_link = kernfs_iop_get_link,
|
||||||
.setattr = kernfs_iop_setattr,
|
.setattr = kernfs_iop_setattr,
|
||||||
.getattr = kernfs_iop_getattr,
|
.getattr = kernfs_iop_getattr,
|
||||||
|
|
|
@ -1131,7 +1131,6 @@ EXPORT_SYMBOL(simple_get_link);
|
||||||
|
|
||||||
const struct inode_operations simple_symlink_inode_operations = {
|
const struct inode_operations simple_symlink_inode_operations = {
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.readlink = generic_readlink
|
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(simple_symlink_inode_operations);
|
EXPORT_SYMBOL(simple_symlink_inode_operations);
|
||||||
|
|
||||||
|
|
|
@ -434,7 +434,6 @@ static const struct address_space_operations minix_aops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations minix_symlink_inode_operations = {
|
static const struct inode_operations minix_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.getattr = minix_getattr,
|
.getattr = minix_getattr,
|
||||||
};
|
};
|
||||||
|
|
35
fs/namei.c
35
fs/namei.c
|
@ -4606,7 +4606,8 @@ out:
|
||||||
* have ->get_link() not calling nd_jump_link(). Using (or not using) it
|
* have ->get_link() not calling nd_jump_link(). Using (or not using) it
|
||||||
* for any given inode is up to filesystem.
|
* 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);
|
DEFINE_DELAYED_CALL(done);
|
||||||
struct inode *inode = d_inode(dentry);
|
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);
|
do_delayed_call(&done);
|
||||||
return res;
|
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
|
* 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);
|
EXPORT_SYMBOL(page_symlink);
|
||||||
|
|
||||||
const struct inode_operations page_symlink_inode_operations = {
|
const struct inode_operations page_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(page_symlink_inode_operations);
|
EXPORT_SYMBOL(page_symlink_inode_operations);
|
||||||
|
|
|
@ -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)
|
#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
|
||||||
static const struct inode_operations ncp_symlink_inode_operations = {
|
static const struct inode_operations ncp_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = ncp_notify_change,
|
.setattr = ncp_notify_change,
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,7 +77,6 @@ static const char *nfs_get_link(struct dentry *dentry,
|
||||||
* symlinks can't do much...
|
* symlinks can't do much...
|
||||||
*/
|
*/
|
||||||
const struct inode_operations nfs_symlink_inode_operations = {
|
const struct inode_operations nfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = nfs_get_link,
|
.get_link = nfs_get_link,
|
||||||
.getattr = nfs_getattr,
|
.getattr = nfs_getattr,
|
||||||
.setattr = nfs_setattr,
|
.setattr = nfs_setattr,
|
||||||
|
|
|
@ -3605,10 +3605,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
|
||||||
if (!p)
|
if (!p)
|
||||||
return nfserr_resource;
|
return nfserr_resource;
|
||||||
/*
|
/*
|
||||||
* XXX: By default, the ->readlink() VFS op will truncate symlinks
|
* XXX: By default, vfs_readlink() will truncate symlinks if they
|
||||||
* if they would overflow the buffer. Is this kosher in NFSv4? If
|
* would overflow the buffer. Is this kosher in NFSv4? If not, one
|
||||||
* not, one easy fix is: if ->readlink() precisely fills the buffer,
|
* easy fix is: if vfs_readlink() precisely fills the buffer, assume
|
||||||
* assume that truncation occurred, and return NFS4ERR_RESOURCE.
|
* that truncation occurred, and return NFS4ERR_RESOURCE.
|
||||||
*/
|
*/
|
||||||
nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
|
nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
|
||||||
(char *)p, &maxcount);
|
(char *)p, &maxcount);
|
||||||
|
|
|
@ -1450,7 +1450,6 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||||
__be32
|
__be32
|
||||||
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
|
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
|
||||||
mm_segment_t oldfs;
|
mm_segment_t oldfs;
|
||||||
__be32 err;
|
__be32 err;
|
||||||
int host_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.mnt = fhp->fh_export->ex_path.mnt;
|
||||||
path.dentry = fhp->fh_dentry;
|
path.dentry = fhp->fh_dentry;
|
||||||
inode = d_inode(path.dentry);
|
|
||||||
|
|
||||||
err = nfserr_inval;
|
err = nfserr_inval;
|
||||||
if (!inode->i_op->readlink)
|
if (!d_is_symlink(path.dentry))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
touch_atime(&path);
|
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);
|
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);
|
set_fs(oldfs);
|
||||||
|
|
||||||
if (host_err < 0)
|
if (host_err < 0)
|
||||||
|
|
|
@ -568,7 +568,6 @@ const struct inode_operations nilfs_special_inode_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations nilfs_symlink_inode_operations = {
|
const struct inode_operations nilfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.permission = nilfs_permission,
|
.permission = nilfs_permission,
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,7 +87,6 @@ const struct address_space_operations ocfs2_fast_symlink_aops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations ocfs2_symlink_inode_operations = {
|
const struct inode_operations ocfs2_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.getattr = ocfs2_getattr,
|
.getattr = ocfs2_getattr,
|
||||||
.setattr = ocfs2_setattr,
|
.setattr = ocfs2_setattr,
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "orangefs-bufmap.h"
|
#include "orangefs-bufmap.h"
|
||||||
|
|
||||||
const struct inode_operations orangefs_symlink_inode_operations = {
|
const struct inode_operations orangefs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
.setattr = orangefs_setattr,
|
.setattr = orangefs_setattr,
|
||||||
.getattr = orangefs_getattr,
|
.getattr = orangefs_getattr,
|
||||||
|
|
|
@ -296,7 +296,6 @@ static const struct inode_operations ovl_file_inode_operations = {
|
||||||
static const struct inode_operations ovl_symlink_inode_operations = {
|
static const struct inode_operations ovl_symlink_inode_operations = {
|
||||||
.setattr = ovl_setattr,
|
.setattr = ovl_setattr,
|
||||||
.get_link = ovl_get_link,
|
.get_link = ovl_get_link,
|
||||||
.readlink = generic_readlink,
|
|
||||||
.getattr = ovl_getattr,
|
.getattr = ovl_getattr,
|
||||||
.listxattr = ovl_listxattr,
|
.listxattr = ovl_listxattr,
|
||||||
.update_time = ovl_update_time,
|
.update_time = ovl_update_time,
|
||||||
|
|
|
@ -425,7 +425,6 @@ static const char *proc_get_link(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct inode_operations proc_link_inode_operations = {
|
const struct inode_operations proc_link_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = proc_get_link,
|
.get_link = proc_get_link,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
/*
|
/*
|
||||||
* /proc/self:
|
* /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,
|
static const char *proc_self_get_link(struct dentry *dentry,
|
||||||
struct inode *inode,
|
struct inode *inode,
|
||||||
struct delayed_call *done)
|
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 = {
|
static const struct inode_operations proc_self_inode_operations = {
|
||||||
.readlink = proc_self_readlink,
|
|
||||||
.get_link = proc_self_get_link,
|
.get_link = proc_self_get_link,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,19 +6,6 @@
|
||||||
/*
|
/*
|
||||||
* /proc/thread_self:
|
* /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,
|
static const char *proc_thread_self_get_link(struct dentry *dentry,
|
||||||
struct inode *inode,
|
struct inode *inode,
|
||||||
struct delayed_call *done)
|
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 = {
|
static const struct inode_operations proc_thread_self_inode_operations = {
|
||||||
.readlink = proc_thread_self_readlink,
|
|
||||||
.get_link = proc_thread_self_get_link,
|
.get_link = proc_thread_self_get_link,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1665,7 +1665,6 @@ const struct inode_operations reiserfs_dir_inode_operations = {
|
||||||
* stuff added
|
* stuff added
|
||||||
*/
|
*/
|
||||||
const struct inode_operations reiserfs_symlink_inode_operations = {
|
const struct inode_operations reiserfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.setattr = reiserfs_setattr,
|
.setattr = reiserfs_setattr,
|
||||||
.listxattr = reiserfs_listxattr,
|
.listxattr = reiserfs_listxattr,
|
||||||
|
|
|
@ -118,7 +118,6 @@ const struct address_space_operations squashfs_symlink_aops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations squashfs_symlink_inode_ops = {
|
const struct inode_operations squashfs_symlink_inode_ops = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.listxattr = squashfs_listxattr
|
.listxattr = squashfs_listxattr
|
||||||
};
|
};
|
||||||
|
|
|
@ -329,12 +329,14 @@ retry:
|
||||||
struct inode *inode = d_backing_inode(path.dentry);
|
struct inode *inode = d_backing_inode(path.dentry);
|
||||||
|
|
||||||
error = empty ? -ENOENT : -EINVAL;
|
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);
|
error = security_inode_readlink(path.dentry);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
touch_atime(&path);
|
touch_atime(&path);
|
||||||
error = inode->i_op->readlink(path.dentry,
|
error = vfs_readlink(path.dentry, buf, bufsiz);
|
||||||
buf, bufsiz);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path_put(&path);
|
path_put(&path);
|
||||||
|
|
|
@ -145,7 +145,6 @@ static inline void write3byte(struct sysv_sb_info *sbi,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct inode_operations sysv_symlink_inode_operations = {
|
static const struct inode_operations sysv_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = page_get_link,
|
.get_link = page_get_link,
|
||||||
.getattr = sysv_getattr,
|
.getattr = sysv_getattr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1733,7 +1733,6 @@ const struct inode_operations ubifs_file_inode_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations ubifs_symlink_inode_operations = {
|
const struct inode_operations ubifs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = ubifs_get_link,
|
.get_link = ubifs_get_link,
|
||||||
.setattr = ubifs_setattr,
|
.setattr = ubifs_setattr,
|
||||||
.getattr = ubifs_getattr,
|
.getattr = ubifs_getattr,
|
||||||
|
|
|
@ -287,7 +287,7 @@ xfs_readlink_by_handle(
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
/* Restrict this handle operation to symlinks only. */
|
/* Restrict this handle operation to symlinks only. */
|
||||||
if (!d_inode(dentry)->i_op->readlink) {
|
if (!d_is_symlink(dentry)) {
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ xfs_readlink_by_handle(
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = d_inode(dentry)->i_op->readlink(dentry, hreq->ohandle, olen);
|
error = vfs_readlink(dentry, hreq->ohandle, olen);
|
||||||
|
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
|
|
|
@ -1120,7 +1120,6 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations xfs_symlink_inode_operations = {
|
static const struct inode_operations xfs_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = xfs_vn_get_link,
|
.get_link = xfs_vn_get_link,
|
||||||
.getattr = xfs_vn_getattr,
|
.getattr = xfs_vn_getattr,
|
||||||
.setattr = xfs_vn_setattr,
|
.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 = {
|
static const struct inode_operations xfs_inline_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = xfs_vn_get_link_inline,
|
.get_link = xfs_vn_get_link_inline,
|
||||||
.getattr = xfs_vn_getattr,
|
.getattr = xfs_vn_getattr,
|
||||||
.setattr = xfs_vn_setattr,
|
.setattr = xfs_vn_setattr,
|
||||||
|
|
|
@ -543,6 +543,7 @@ is_uncached_acl(struct posix_acl *acl)
|
||||||
#define IOP_LOOKUP 0x0002
|
#define IOP_LOOKUP 0x0002
|
||||||
#define IOP_NOFOLLOW 0x0004
|
#define IOP_NOFOLLOW 0x0004
|
||||||
#define IOP_XATTR 0x0008
|
#define IOP_XATTR 0x0008
|
||||||
|
#define IOP_DEFAULT_READLINK 0x0010
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep mostly read-only and often accessed (especially for
|
* 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 int page_symlink(struct inode *inode, const char *symname, int len);
|
||||||
extern const struct inode_operations page_symlink_inode_operations;
|
extern const struct inode_operations page_symlink_inode_operations;
|
||||||
extern void kfree_link(void *);
|
extern void kfree_link(void *);
|
||||||
extern int generic_readlink(struct dentry *, char __user *, int);
|
|
||||||
extern void generic_fillattr(struct inode *, struct kstat *);
|
extern void generic_fillattr(struct inode *, struct kstat *);
|
||||||
int vfs_getattr_nosec(struct path *path, struct kstat *stat);
|
int vfs_getattr_nosec(struct path *path, struct kstat *stat);
|
||||||
extern int vfs_getattr(struct path *, struct kstat *);
|
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_fstat(unsigned int, struct kstat *);
|
||||||
extern int vfs_fstatat(int , const char __user *, struct kstat *, int);
|
extern int vfs_fstatat(int , const char __user *, struct kstat *, int);
|
||||||
extern const char *vfs_get_link(struct dentry *, struct delayed_call *);
|
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,
|
extern int __generic_block_fiemap(struct inode *inode,
|
||||||
struct fiemap_extent_info *fieinfo,
|
struct fiemap_extent_info *fieinfo,
|
||||||
|
|
|
@ -3212,7 +3212,6 @@ static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size)
|
||||||
#endif /* CONFIG_TMPFS_XATTR */
|
#endif /* CONFIG_TMPFS_XATTR */
|
||||||
|
|
||||||
static const struct inode_operations shmem_short_symlink_operations = {
|
static const struct inode_operations shmem_short_symlink_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = simple_get_link,
|
.get_link = simple_get_link,
|
||||||
#ifdef CONFIG_TMPFS_XATTR
|
#ifdef CONFIG_TMPFS_XATTR
|
||||||
.listxattr = shmem_listxattr,
|
.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 = {
|
static const struct inode_operations shmem_symlink_inode_operations = {
|
||||||
.readlink = generic_readlink,
|
|
||||||
.get_link = shmem_get_link,
|
.get_link = shmem_get_link,
|
||||||
#ifdef CONFIG_TMPFS_XATTR
|
#ifdef CONFIG_TMPFS_XATTR
|
||||||
.listxattr = shmem_listxattr,
|
.listxattr = shmem_listxattr,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче