diff options
-rw-r--r-- | fs/namei.c | 25 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 26 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c index adb04146df09..8a2c2959da08 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -4677,6 +4677,31 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) | |||
4677 | } | 4677 | } |
4678 | EXPORT_SYMBOL(generic_readlink); | 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 | /* get the link contents into pagecache */ | 4705 | /* get the link contents into pagecache */ |
4681 | const char *page_get_link(struct dentry *dentry, struct inode *inode, | 4706 | const char *page_get_link(struct dentry *dentry, struct inode *inode, |
4682 | struct delayed_call *callback) | 4707 | struct delayed_call *callback) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 901e25d495cc..bc8ac5108368 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2919,6 +2919,7 @@ extern int vfs_stat(const char __user *, struct kstat *); | |||
2919 | extern int vfs_lstat(const char __user *, struct kstat *); | 2919 | extern int vfs_lstat(const char __user *, struct kstat *); |
2920 | extern int vfs_fstat(unsigned int, struct kstat *); | 2920 | extern int vfs_fstat(unsigned int, struct kstat *); |
2921 | extern int vfs_fstatat(int , const char __user *, struct kstat *, int); | 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 | extern int __generic_block_fiemap(struct inode *inode, | 2924 | extern int __generic_block_fiemap(struct inode *inode, |
2924 | struct fiemap_extent_info *fieinfo, | 2925 | struct fiemap_extent_info *fieinfo, |