vfs: default to generic_readlink()

If i_op->readlink is NULL, but i_op->get_link is set then vfs_readlink()
defaults to calling generic_readlink().

The IOP_DEFAULT_READLINK flag indicates that the above conditions are met
and the default action can be taken.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2016-12-09 16:45:04 +01:00
parent fd4a0edf2a
commit 76fca90e9f
4 changed files with 23 additions and 6 deletions

View File

@ -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).

View File

@ -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.

View File

@ -4682,10 +4682,19 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{ {
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
if (!inode->i_op->readlink) if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) {
return -EINVAL; if (unlikely(inode->i_op->readlink))
return inode->i_op->readlink(dentry, buffer, buflen);
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); EXPORT_SYMBOL(vfs_readlink);

View File

@ -595,6 +595,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