vfs: add vfs_get_link() helper

This helper is for filesystems that want to read the symlink and are better
off with the get_link() interface (returning a char *) rather than the
readlink() interface (copy into a userspace buffer).

Also call the LSM hook for readlink (not get_link) since this is for
symlink reading not following.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

+26
+25
fs/namei.c
··· 4677 4677 } 4678 4678 EXPORT_SYMBOL(generic_readlink); 4679 4679 4680 + /** 4681 + * vfs_get_link - get symlink body 4682 + * @dentry: dentry on which to get symbolic link 4683 + * @done: caller needs to free returned data with this 4684 + * 4685 + * Calls security hook and i_op->get_link() on the supplied inode. 4686 + * 4687 + * It does not touch atime. That's up to the caller if necessary. 4688 + * 4689 + * Does not work on "special" symlinks like /proc/$$/fd/N 4690 + */ 4691 + const char *vfs_get_link(struct dentry *dentry, struct delayed_call *done) 4692 + { 4693 + const char *res = ERR_PTR(-EINVAL); 4694 + struct inode *inode = d_inode(dentry); 4695 + 4696 + if (d_is_symlink(dentry)) { 4697 + res = ERR_PTR(security_inode_readlink(dentry)); 4698 + if (!res) 4699 + res = inode->i_op->get_link(dentry, inode, done); 4700 + } 4701 + return res; 4702 + } 4703 + EXPORT_SYMBOL(vfs_get_link); 4704 + 4680 4705 /* get the link contents into pagecache */ 4681 4706 const char *page_get_link(struct dentry *dentry, struct inode *inode, 4682 4707 struct delayed_call *callback)
+1
include/linux/fs.h
··· 2919 2919 extern int vfs_lstat(const char __user *, struct kstat *); 2920 2920 extern int vfs_fstat(unsigned int, struct kstat *); 2921 2921 extern int vfs_fstatat(int , const char __user *, struct kstat *, int); 2922 + extern const char *vfs_get_link(struct dentry *, struct delayed_call *); 2922 2923 2923 2924 extern int __generic_block_fiemap(struct inode *inode, 2924 2925 struct fiemap_extent_info *fieinfo,