summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-11-17 10:20:54 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-12-08 22:41:54 -0500
commit6b2553918d8b4e6de9853fd6315bec7271a2e592 (patch)
tree85540dcb0dc0de3d67c68d0aa7b17058f4e96539 /fs
parent21fc61c73c3903c4c312d0802da01ec2b323d174 (diff)
replace ->follow_link() with new method that could stay in RCU mode
new method: ->get_link(); replacement of ->follow_link(). The differences are: * inode and dentry are passed separately * might be called both in RCU and non-RCU mode; the former is indicated by passing it a NULL dentry. * when called that way it isn't allowed to block and should return ERR_PTR(-ECHILD) if it needs to be called in non-RCU mode. It's a flagday change - the old method is gone, all in-tree instances converted. Conversion isn't hard; said that, so far very few instances do not immediately bail out when called in RCU mode. That'll change in the next commits. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_inode.c17
-rw-r--r--fs/9p/vfs_inode_dotl.c14
-rw-r--r--fs/affs/symlink.c4
-rw-r--r--fs/autofs4/symlink.c13
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/ceph/inode.c2
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/link.c6
-rw-r--r--fs/coda/cnode.c2
-rw-r--r--fs/configfs/symlink.c11
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/ecryptfs/inode.c12
-rw-r--r--fs/ext2/symlink.c4
-rw-r--r--fs/ext4/symlink.c13
-rw-r--r--fs/f2fs/namei.c16
-rw-r--r--fs/fuse/dir.c9
-rw-r--r--fs/gfs2/inode.c15
-rw-r--r--fs/hostfs/hostfs_kern.c10
-rw-r--r--fs/jffs2/symlink.c2
-rw-r--r--fs/jfs/symlink.c4
-rw-r--r--fs/kernfs/symlink.c11
-rw-r--r--fs/libfs.c9
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/namei.c45
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/nfs/symlink.c9
-rw-r--r--fs/nilfs2/namei.c2
-rw-r--r--fs/ocfs2/symlink.c2
-rw-r--r--fs/overlayfs/inode.c12
-rw-r--r--fs/proc/base.c22
-rw-r--r--fs/proc/inode.c7
-rw-r--r--fs/proc/namespaces.c9
-rw-r--r--fs/proc/self.c9
-rw-r--r--fs/proc/thread_self.c9
-rw-r--r--fs/reiserfs/namei.c2
-rw-r--r--fs/squashfs/symlink.c2
-rw-r--r--fs/sysv/inode.c2
-rw-r--r--fs/ubifs/file.c2
-rw-r--r--fs/xfs/xfs_iops.c8
40 files changed, 210 insertions, 120 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 699941e90667..8ba5a897fc0a 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1223,18 +1223,25 @@ ino_t v9fs_qid2ino(struct p9_qid *qid)
1223} 1223}
1224 1224
1225/** 1225/**
1226 * v9fs_vfs_follow_link - follow a symlink path 1226 * v9fs_vfs_get_link - follow a symlink path
1227 * @dentry: dentry for symlink 1227 * @dentry: dentry for symlink
1228 * @inode: inode for symlink
1228 * @cookie: place to pass the data to put_link() 1229 * @cookie: place to pass the data to put_link()
1229 */ 1230 */
1230 1231
1231static const char *v9fs_vfs_follow_link(struct dentry *dentry, void **cookie) 1232static const char *v9fs_vfs_get_link(struct dentry *dentry,
1233 struct inode *inode, void **cookie)
1232{ 1234{
1233 struct v9fs_session_info *v9ses = v9fs_dentry2v9ses(dentry); 1235 struct v9fs_session_info *v9ses;
1234 struct p9_fid *fid = v9fs_fid_lookup(dentry); 1236 struct p9_fid *fid;
1235 struct p9_wstat *st; 1237 struct p9_wstat *st;
1236 char *res; 1238 char *res;
1237 1239
1240 if (!dentry)
1241 return ERR_PTR(-ECHILD);
1242
1243 v9ses = v9fs_dentry2v9ses(dentry);
1244 fid = v9fs_fid_lookup(dentry);
1238 p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); 1245 p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
1239 1246
1240 if (IS_ERR(fid)) 1247 if (IS_ERR(fid))
@@ -1452,7 +1459,7 @@ static const struct inode_operations v9fs_file_inode_operations = {
1452 1459
1453static const struct inode_operations v9fs_symlink_inode_operations = { 1460static const struct inode_operations v9fs_symlink_inode_operations = {
1454 .readlink = generic_readlink, 1461 .readlink = generic_readlink,
1455 .follow_link = v9fs_vfs_follow_link, 1462 .get_link = v9fs_vfs_get_link,
1456 .put_link = kfree_put_link, 1463 .put_link = kfree_put_link,
1457 .getattr = v9fs_vfs_getattr, 1464 .getattr = v9fs_vfs_getattr,
1458 .setattr = v9fs_vfs_setattr, 1465 .setattr = v9fs_vfs_setattr,
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index cb899af1babc..0cc105d804dd 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -899,20 +899,26 @@ error:
899} 899}
900 900
901/** 901/**
902 * v9fs_vfs_follow_link_dotl - follow a symlink path 902 * v9fs_vfs_get_link_dotl - follow a symlink path
903 * @dentry: dentry for symlink 903 * @dentry: dentry for symlink
904 * @inode: inode for symlink
904 * @cookie: place to pass the data to put_link() 905 * @cookie: place to pass the data to put_link()
905 */ 906 */
906 907
907static const char * 908static const char *
908v9fs_vfs_follow_link_dotl(struct dentry *dentry, void **cookie) 909v9fs_vfs_get_link_dotl(struct dentry *dentry,
910 struct inode *inode, void **cookie)
909{ 911{
910 struct p9_fid *fid = v9fs_fid_lookup(dentry); 912 struct p9_fid *fid;
911 char *target; 913 char *target;
912 int retval; 914 int retval;
913 915
916 if (!dentry)
917 return ERR_PTR(-ECHILD);
918
914 p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); 919 p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
915 920
921 fid = v9fs_fid_lookup(dentry);
916 if (IS_ERR(fid)) 922 if (IS_ERR(fid))
917 return ERR_CAST(fid); 923 return ERR_CAST(fid);
918 retval = p9_client_readlink(fid, &target); 924 retval = p9_client_readlink(fid, &target);
@@ -984,7 +990,7 @@ const struct inode_operations v9fs_file_inode_operations_dotl = {
984 990
985const struct inode_operations v9fs_symlink_inode_operations_dotl = { 991const struct inode_operations v9fs_symlink_inode_operations_dotl = {
986 .readlink = generic_readlink, 992 .readlink = generic_readlink,
987 .follow_link = v9fs_vfs_follow_link_dotl, 993 .get_link = v9fs_vfs_get_link_dotl,
988 .put_link = kfree_put_link, 994 .put_link = kfree_put_link,
989 .getattr = v9fs_vfs_getattr_dotl, 995 .getattr = v9fs_vfs_getattr_dotl,
990 .setattr = v9fs_vfs_setattr_dotl, 996 .setattr = v9fs_vfs_setattr_dotl,
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index e3f9dc3ae8cc..39d1194445e1 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -20,7 +20,7 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
20 char c; 20 char c;
21 char lc; 21 char lc;
22 22
23 pr_debug("follow_link(ino=%lu)\n", inode->i_ino); 23 pr_debug("get_link(ino=%lu)\n", inode->i_ino);
24 24
25 bh = affs_bread(inode->i_sb, inode->i_ino); 25 bh = affs_bread(inode->i_sb, inode->i_ino);
26 if (!bh) 26 if (!bh)
@@ -71,7 +71,7 @@ const struct address_space_operations affs_symlink_aops = {
71 71
72const struct inode_operations affs_symlink_inode_operations = { 72const struct inode_operations affs_symlink_inode_operations = {
73 .readlink = generic_readlink, 73 .readlink = generic_readlink,
74 .follow_link = page_follow_link_light, 74 .get_link = page_get_link,
75 .put_link = page_put_link, 75 .put_link = page_put_link,
76 .setattr = affs_notify_change, 76 .setattr = affs_notify_change,
77}; 77};
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
index da0c33481bc0..39e6f0bdf8e3 100644
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -12,10 +12,15 @@
12 12
13#include "autofs_i.h" 13#include "autofs_i.h"
14 14
15static const char *autofs4_follow_link(struct dentry *dentry, void **cookie) 15static const char *autofs4_get_link(struct dentry *dentry,
16 struct inode *inode, void **cookie)
16{ 17{
17 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 18 struct autofs_sb_info *sbi;
18 struct autofs_info *ino = autofs4_dentry_ino(dentry); 19 struct autofs_info *ino;
20 if (!dentry)
21 return ERR_PTR(-ECHILD);
22 sbi = autofs4_sbi(dentry->d_sb);
23 ino = autofs4_dentry_ino(dentry);
19 if (ino && !autofs4_oz_mode(sbi)) 24 if (ino && !autofs4_oz_mode(sbi))
20 ino->last_used = jiffies; 25 ino->last_used = jiffies;
21 return d_inode(dentry)->i_private; 26 return d_inode(dentry)->i_private;
@@ -23,5 +28,5 @@ static const char *autofs4_follow_link(struct dentry *dentry, void **cookie)
23 28
24const struct inode_operations autofs4_symlink_inode_operations = { 29const struct inode_operations autofs4_symlink_inode_operations = {
25 .readlink = generic_readlink, 30 .readlink = generic_readlink,
26 .follow_link = autofs4_follow_link 31 .get_link = autofs4_get_link
27}; 32};
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 70f98bfde277..3d4aa69f1e0c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -10096,7 +10096,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
10096}; 10096};
10097static const struct inode_operations btrfs_symlink_inode_operations = { 10097static const struct inode_operations btrfs_symlink_inode_operations = {
10098 .readlink = generic_readlink, 10098 .readlink = generic_readlink,
10099 .follow_link = page_follow_link_light, 10099 .get_link = page_get_link,
10100 .put_link = page_put_link, 10100 .put_link = page_put_link,
10101 .getattr = btrfs_getattr, 10101 .getattr = btrfs_getattr,
10102 .setattr = btrfs_setattr, 10102 .setattr = btrfs_setattr,
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 498dcfa2dcdb..da55eb8bcffa 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1756,7 +1756,7 @@ retry:
1756 */ 1756 */
1757static const struct inode_operations ceph_symlink_iops = { 1757static const struct inode_operations ceph_symlink_iops = {
1758 .readlink = generic_readlink, 1758 .readlink = generic_readlink,
1759 .follow_link = simple_follow_link, 1759 .get_link = simple_get_link,
1760 .setattr = ceph_setattr, 1760 .setattr = ceph_setattr,
1761 .getattr = ceph_getattr, 1761 .getattr = ceph_getattr,
1762 .setxattr = ceph_setxattr, 1762 .setxattr = ceph_setxattr,
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index cbc0f4bca0c0..4593f41678ef 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -900,7 +900,7 @@ const struct inode_operations cifs_file_inode_ops = {
900 900
901const struct inode_operations cifs_symlink_inode_ops = { 901const struct inode_operations cifs_symlink_inode_ops = {
902 .readlink = generic_readlink, 902 .readlink = generic_readlink,
903 .follow_link = cifs_follow_link, 903 .get_link = cifs_get_link,
904 .put_link = kfree_put_link, 904 .put_link = kfree_put_link,
905 .permission = cifs_permission, 905 .permission = cifs_permission,
906 /* BB add the following two eventually */ 906 /* BB add the following two eventually */
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index c3cc1609025f..6886328cf3c4 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -120,9 +120,7 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
120#endif 120#endif
121 121
122/* Functions related to symlinks */ 122/* Functions related to symlinks */
123extern const char *cifs_follow_link(struct dentry *direntry, void **cookie); 123extern const char *cifs_get_link(struct dentry *, struct inode *, void **);
124extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
125 int buflen);
126extern int cifs_symlink(struct inode *inode, struct dentry *direntry, 124extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
127 const char *symname); 125 const char *symname);
128extern int cifs_removexattr(struct dentry *, const char *); 126extern int cifs_removexattr(struct dentry *, const char *);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index e3548f73bdea..6f2439b508b5 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -627,9 +627,8 @@ cifs_hl_exit:
627} 627}
628 628
629const char * 629const char *
630cifs_follow_link(struct dentry *direntry, void **cookie) 630cifs_get_link(struct dentry *direntry, struct inode *inode, void **cookie)
631{ 631{
632 struct inode *inode = d_inode(direntry);
633 int rc = -ENOMEM; 632 int rc = -ENOMEM;
634 unsigned int xid; 633 unsigned int xid;
635 char *full_path = NULL; 634 char *full_path = NULL;
@@ -639,6 +638,9 @@ cifs_follow_link(struct dentry *direntry, void **cookie)
639 struct cifs_tcon *tcon; 638 struct cifs_tcon *tcon;
640 struct TCP_Server_Info *server; 639 struct TCP_Server_Info *server;
641 640
641 if (!direntry)
642 return ERR_PTR(-ECHILD);
643
642 xid = get_xid(); 644 xid = get_xid();
643 645
644 tlink = cifs_sb_tlink(cifs_sb); 646 tlink = cifs_sb_tlink(cifs_sb);
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index dd6a79ef4750..f18139c7690a 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -18,7 +18,7 @@ static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
18 18
19static const struct inode_operations coda_symlink_inode_operations = { 19static const struct inode_operations coda_symlink_inode_operations = {
20 .readlink = generic_readlink, 20 .readlink = generic_readlink,
21 .follow_link = page_follow_link_light, 21 .get_link = page_get_link,
22 .put_link = page_put_link, 22 .put_link = page_put_link,
23 .setattr = coda_setattr, 23 .setattr = coda_setattr,
24}; 24};
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index ec5c8325b503..b91c01ebb688 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -279,11 +279,16 @@ static int configfs_getlink(struct dentry *dentry, char * path)
279 279
280} 280}
281 281
282static const char *configfs_follow_link(struct dentry *dentry, void **cookie) 282static const char *configfs_get_link(struct dentry *dentry,
283 struct inode *inode, void **cookie)
283{ 284{
284 unsigned long page = get_zeroed_page(GFP_KERNEL); 285 unsigned long page;
285 int error; 286 int error;
286 287
288 if (!dentry)
289 return ERR_PTR(-ECHILD);
290
291 page = get_zeroed_page(GFP_KERNEL);
287 if (!page) 292 if (!page)
288 return ERR_PTR(-ENOMEM); 293 return ERR_PTR(-ENOMEM);
289 294
@@ -297,7 +302,7 @@ static const char *configfs_follow_link(struct dentry *dentry, void **cookie)
297} 302}
298 303
299const struct inode_operations configfs_symlink_inode_operations = { 304const struct inode_operations configfs_symlink_inode_operations = {
300 .follow_link = configfs_follow_link, 305 .get_link = configfs_get_link,
301 .readlink = generic_readlink, 306 .readlink = generic_readlink,
302 .put_link = free_page_put_link, 307 .put_link = free_page_put_link,
303 .setattr = configfs_setattr, 308 .setattr = configfs_setattr,
diff --git a/fs/dcache.c b/fs/dcache.c
index 5c33aeb0f68f..d27f0909d9f6 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1734,7 +1734,7 @@ static unsigned d_flags_for_inode(struct inode *inode)
1734 } 1734 }
1735 1735
1736 if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) { 1736 if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) {
1737 if (unlikely(inode->i_op->follow_link)) { 1737 if (unlikely(inode->i_op->get_link)) {
1738 add_flags = DCACHE_SYMLINK_TYPE; 1738 add_flags = DCACHE_SYMLINK_TYPE;
1739 goto type_determined; 1739 goto type_determined;
1740 } 1740 }
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index e2e47ba5d313..5a05559cb23d 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -674,10 +674,16 @@ out:
674 return rc ? ERR_PTR(rc) : buf; 674 return rc ? ERR_PTR(rc) : buf;
675} 675}
676 676
677static const char *ecryptfs_follow_link(struct dentry *dentry, void **cookie) 677static const char *ecryptfs_get_link(struct dentry *dentry,
678 struct inode *inode, void **cookie)
678{ 679{
679 size_t len; 680 size_t len;
680 char *buf = ecryptfs_readlink_lower(dentry, &len); 681 char *buf;
682
683 if (!dentry)
684 return ERR_PTR(-ECHILD);
685
686 buf = ecryptfs_readlink_lower(dentry, &len);
681 if (IS_ERR(buf)) 687 if (IS_ERR(buf))
682 return buf; 688 return buf;
683 fsstack_copy_attr_atime(d_inode(dentry), 689 fsstack_copy_attr_atime(d_inode(dentry),
@@ -1095,7 +1101,7 @@ out:
1095 1101
1096const struct inode_operations ecryptfs_symlink_iops = { 1102const struct inode_operations ecryptfs_symlink_iops = {
1097 .readlink = generic_readlink, 1103 .readlink = generic_readlink,
1098 .follow_link = ecryptfs_follow_link, 1104 .get_link = ecryptfs_get_link,
1099 .put_link = kfree_put_link, 1105 .put_link = kfree_put_link,
1100 .permission = ecryptfs_permission, 1106 .permission = ecryptfs_permission,
1101 .setattr = ecryptfs_setattr, 1107 .setattr = ecryptfs_setattr,
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index ae17179f3810..46905119a27c 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -22,7 +22,7 @@
22 22
23const struct inode_operations ext2_symlink_inode_operations = { 23const struct inode_operations ext2_symlink_inode_operations = {
24 .readlink = generic_readlink, 24 .readlink = generic_readlink,
25 .follow_link = page_follow_link_light, 25 .get_link = page_get_link,
26 .put_link = page_put_link, 26 .put_link = page_put_link,
27 .setattr = ext2_setattr, 27 .setattr = ext2_setattr,
28#ifdef CONFIG_EXT2_FS_XATTR 28#ifdef CONFIG_EXT2_FS_XATTR
@@ -35,7 +35,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
35 35
36const struct inode_operations ext2_fast_symlink_inode_operations = { 36const struct inode_operations ext2_fast_symlink_inode_operations = {
37 .readlink = generic_readlink, 37 .readlink = generic_readlink,
38 .follow_link = simple_follow_link, 38 .get_link = simple_get_link,
39 .setattr = ext2_setattr, 39 .setattr = ext2_setattr,
40#ifdef CONFIG_EXT2_FS_XATTR 40#ifdef CONFIG_EXT2_FS_XATTR
41 .setxattr = generic_setxattr, 41 .setxattr = generic_setxattr,
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index 0e6dc44c5ebf..3b4bfe2ebd75 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -23,17 +23,20 @@
23#include "xattr.h" 23#include "xattr.h"
24 24
25#ifdef CONFIG_EXT4_FS_ENCRYPTION 25#ifdef CONFIG_EXT4_FS_ENCRYPTION
26static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cookie) 26static const char *ext4_encrypted_get_link(struct dentry *dentry,
27 struct inode *inode, void **cookie)
27{ 28{
28 struct page *cpage = NULL; 29 struct page *cpage = NULL;
29 char *caddr, *paddr = NULL; 30 char *caddr, *paddr = NULL;
30 struct ext4_str cstr, pstr; 31 struct ext4_str cstr, pstr;
31 struct inode *inode = d_inode(dentry);
32 struct ext4_encrypted_symlink_data *sd; 32 struct ext4_encrypted_symlink_data *sd;
33 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); 33 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
34 int res; 34 int res;
35 u32 plen, max_size = inode->i_sb->s_blocksize; 35 u32 plen, max_size = inode->i_sb->s_blocksize;
36 36
37 if (!dentry)
38 return ERR_PTR(-ECHILD);
39
37 res = ext4_get_encryption_info(inode); 40 res = ext4_get_encryption_info(inode);
38 if (res) 41 if (res)
39 return ERR_PTR(res); 42 return ERR_PTR(res);
@@ -87,7 +90,7 @@ errout:
87 90
88const struct inode_operations ext4_encrypted_symlink_inode_operations = { 91const struct inode_operations ext4_encrypted_symlink_inode_operations = {
89 .readlink = generic_readlink, 92 .readlink = generic_readlink,
90 .follow_link = ext4_encrypted_follow_link, 93 .get_link = ext4_encrypted_get_link,
91 .put_link = kfree_put_link, 94 .put_link = kfree_put_link,
92 .setattr = ext4_setattr, 95 .setattr = ext4_setattr,
93 .setxattr = generic_setxattr, 96 .setxattr = generic_setxattr,
@@ -99,7 +102,7 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
99 102
100const struct inode_operations ext4_symlink_inode_operations = { 103const struct inode_operations ext4_symlink_inode_operations = {
101 .readlink = generic_readlink, 104 .readlink = generic_readlink,
102 .follow_link = page_follow_link_light, 105 .get_link = page_get_link,
103 .put_link = page_put_link, 106 .put_link = page_put_link,
104 .setattr = ext4_setattr, 107 .setattr = ext4_setattr,
105 .setxattr = generic_setxattr, 108 .setxattr = generic_setxattr,
@@ -110,7 +113,7 @@ const struct inode_operations ext4_symlink_inode_operations = {
110 113
111const struct inode_operations ext4_fast_symlink_inode_operations = { 114const struct inode_operations ext4_fast_symlink_inode_operations = {
112 .readlink = generic_readlink, 115 .readlink = generic_readlink,
113 .follow_link = simple_follow_link, 116 .get_link = simple_get_link,
114 .setattr = ext4_setattr, 117 .setattr = ext4_setattr,
115 .setxattr = generic_setxattr, 118 .setxattr = generic_setxattr,
116 .getxattr = generic_getxattr, 119 .getxattr = generic_getxattr,
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 484df6850747..2a8d84b727ce 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -315,9 +315,10 @@ fail:
315 return err; 315 return err;
316} 316}
317 317
318static const char *f2fs_follow_link(struct dentry *dentry, void **cookie) 318static const char *f2fs_get_link(struct dentry *dentry,
319 struct inode *inode, void **cookie)
319{ 320{
320 const char *link = page_follow_link_light(dentry, cookie); 321 const char *link = page_get_link(dentry, inode, cookie);
321 if (!IS_ERR(link) && !*link) { 322 if (!IS_ERR(link) && !*link) {
322 /* this is broken symlink case */ 323 /* this is broken symlink case */
323 page_put_link(NULL, *cookie); 324 page_put_link(NULL, *cookie);
@@ -924,18 +925,21 @@ static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
924} 925}
925 926
926#ifdef CONFIG_F2FS_FS_ENCRYPTION 927#ifdef CONFIG_F2FS_FS_ENCRYPTION
927static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cookie) 928static const char *f2fs_encrypted_get_link(struct dentry *dentry,
929 struct inode *inode, void **cookie)
928{ 930{
929 struct page *cpage = NULL; 931 struct page *cpage = NULL;
930 char *caddr, *paddr = NULL; 932 char *caddr, *paddr = NULL;
931 struct f2fs_str cstr; 933 struct f2fs_str cstr;
932 struct f2fs_str pstr = FSTR_INIT(NULL, 0); 934 struct f2fs_str pstr = FSTR_INIT(NULL, 0);
933 struct inode *inode = d_inode(dentry);
934 struct f2fs_encrypted_symlink_data *sd; 935 struct f2fs_encrypted_symlink_data *sd;
935 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); 936 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
936 u32 max_size = inode->i_sb->s_blocksize; 937 u32 max_size = inode->i_sb->s_blocksize;
937 int res; 938 int res;
938 939
940 if (!dentry)
941 return ERR_PTR(-ECHILD);
942
939 res = f2fs_get_encryption_info(inode); 943 res = f2fs_get_encryption_info(inode);
940 if (res) 944 if (res)
941 return ERR_PTR(res); 945 return ERR_PTR(res);
@@ -994,7 +998,7 @@ errout:
994 998
995const struct inode_operations f2fs_encrypted_symlink_inode_operations = { 999const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
996 .readlink = generic_readlink, 1000 .readlink = generic_readlink,
997 .follow_link = f2fs_encrypted_follow_link, 1001 .get_link = f2fs_encrypted_get_link,
998 .put_link = kfree_put_link, 1002 .put_link = kfree_put_link,
999 .getattr = f2fs_getattr, 1003 .getattr = f2fs_getattr,
1000 .setattr = f2fs_setattr, 1004 .setattr = f2fs_setattr,
@@ -1030,7 +1034,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
1030 1034
1031const struct inode_operations f2fs_symlink_inode_operations = { 1035const struct inode_operations f2fs_symlink_inode_operations = {
1032 .readlink = generic_readlink, 1036 .readlink = generic_readlink,
1033 .follow_link = f2fs_follow_link, 1037 .get_link = f2fs_get_link,
1034 .put_link = page_put_link, 1038 .put_link = page_put_link,
1035 .getattr = f2fs_getattr, 1039 .getattr = f2fs_getattr,
1036 .setattr = f2fs_setattr, 1040 .setattr = f2fs_setattr,
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 5e2e08712d3b..148e8ef7c541 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1365,14 +1365,17 @@ static int fuse_readdir(struct file *file, struct dir_context *ctx)
1365 return err; 1365 return err;
1366} 1366}
1367 1367
1368static const char *fuse_follow_link(struct dentry *dentry, void **cookie) 1368static const char *fuse_get_link(struct dentry *dentry,
1369 struct inode *inode, void **cookie)
1369{ 1370{
1370 struct inode *inode = d_inode(dentry);
1371 struct fuse_conn *fc = get_fuse_conn(inode); 1371 struct fuse_conn *fc = get_fuse_conn(inode);
1372 FUSE_ARGS(args); 1372 FUSE_ARGS(args);
1373 char *link; 1373 char *link;
1374 ssize_t ret; 1374 ssize_t ret;
1375 1375
1376 if (!dentry)
1377 return ERR_PTR(-ECHILD);
1378
1376 link = (char *) __get_free_page(GFP_KERNEL); 1379 link = (char *) __get_free_page(GFP_KERNEL);
1377 if (!link) 1380 if (!link)
1378 return ERR_PTR(-ENOMEM); 1381 return ERR_PTR(-ENOMEM);
@@ -1909,7 +1912,7 @@ static const struct inode_operations fuse_common_inode_operations = {
1909 1912
1910static const struct inode_operations fuse_symlink_inode_operations = { 1913static const struct inode_operations fuse_symlink_inode_operations = {
1911 .setattr = fuse_setattr, 1914 .setattr = fuse_setattr,
1912 .follow_link = fuse_follow_link, 1915 .get_link = fuse_get_link,
1913 .put_link = free_page_put_link, 1916 .put_link = free_page_put_link,
1914 .readlink = generic_readlink, 1917 .readlink = generic_readlink,
1915 .getattr = fuse_getattr, 1918 .getattr = fuse_getattr,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 063fdfcf8275..1095056046cc 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1712,24 +1712,29 @@ static int gfs2_rename2(struct inode *odir, struct dentry *odentry,
1712} 1712}
1713 1713
1714/** 1714/**
1715 * gfs2_follow_link - Follow a symbolic link 1715 * gfs2_get_link - Follow a symbolic link
1716 * @dentry: The dentry of the link 1716 * @dentry: The dentry of the link
1717 * @nd: Data that we pass to vfs_follow_link() 1717 * @inode: The inode of the link
1718 * @cookie: place to store the information for ->put_link()
1718 * 1719 *
1719 * This can handle symlinks of any size. 1720 * This can handle symlinks of any size.
1720 * 1721 *
1721 * Returns: 0 on success or error code 1722 * Returns: 0 on success or error code
1722 */ 1723 */
1723 1724
1724static const char *gfs2_follow_link(struct dentry *dentry, void **cookie) 1725static const char *gfs2_get_link(struct dentry *dentry,
1726 struct inode *inode, void **cookie)
1725{ 1727{
1726 struct gfs2_inode *ip = GFS2_I(d_inode(dentry)); 1728 struct gfs2_inode *ip = GFS2_I(inode);
1727 struct gfs2_holder i_gh; 1729 struct gfs2_holder i_gh;
1728 struct buffer_head *dibh; 1730 struct buffer_head *dibh;
1729 unsigned int size; 1731 unsigned int size;
1730 char *buf; 1732 char *buf;
1731 int error; 1733 int error;
1732 1734
1735 if (!dentry)
1736 return ERR_PTR(-ECHILD);
1737
1733 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); 1738 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
1734 error = gfs2_glock_nq(&i_gh); 1739 error = gfs2_glock_nq(&i_gh);
1735 if (error) { 1740 if (error) {
@@ -2132,7 +2137,7 @@ const struct inode_operations gfs2_dir_iops = {
2132 2137
2133const struct inode_operations gfs2_symlink_iops = { 2138const struct inode_operations gfs2_symlink_iops = {
2134 .readlink = generic_readlink, 2139 .readlink = generic_readlink,
2135 .follow_link = gfs2_follow_link, 2140 .get_link = gfs2_get_link,
2136 .put_link = kfree_put_link, 2141 .put_link = kfree_put_link,
2137 .permission = gfs2_permission, 2142 .permission = gfs2_permission,
2138 .setattr = gfs2_setattr, 2143 .setattr = gfs2_setattr,
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 2ac99db3750e..6ce5309ecb7b 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -892,9 +892,13 @@ static const struct inode_operations hostfs_dir_iops = {
892 .setattr = hostfs_setattr, 892 .setattr = hostfs_setattr,
893}; 893};
894 894
895static const char *hostfs_follow_link(struct dentry *dentry, void **cookie) 895static const char *hostfs_get_link(struct dentry *dentry,
896 struct inode *inode, void **cookie)
896{ 897{
897 char *link = __getname(); 898 char *link;
899 if (!dentry)
900 return ERR_PTR(-ECHILD);
901 link = __getname();
898 if (link) { 902 if (link) {
899 char *path = dentry_name(dentry); 903 char *path = dentry_name(dentry);
900 int err = -ENOMEM; 904 int err = -ENOMEM;
@@ -922,7 +926,7 @@ static void hostfs_put_link(struct inode *unused, void *cookie)
922 926
923static const struct inode_operations hostfs_link_iops = { 927static const struct inode_operations hostfs_link_iops = {
924 .readlink = generic_readlink, 928 .readlink = generic_readlink,
925 .follow_link = hostfs_follow_link, 929 .get_link = hostfs_get_link,
926 .put_link = hostfs_put_link, 930 .put_link = hostfs_put_link,
927}; 931};
928 932
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 8ce2f240125b..2cabd649d4fb 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -14,7 +14,7 @@
14const struct inode_operations jffs2_symlink_inode_operations = 14const struct inode_operations jffs2_symlink_inode_operations =
15{ 15{
16 .readlink = generic_readlink, 16 .readlink = generic_readlink,
17 .follow_link = simple_follow_link, 17 .get_link = simple_get_link,
18 .setattr = jffs2_setattr, 18 .setattr = jffs2_setattr,
19 .setxattr = jffs2_setxattr, 19 .setxattr = jffs2_setxattr,
20 .getxattr = jffs2_getxattr, 20 .getxattr = jffs2_getxattr,
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 5929e2363cb8..02113282772e 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -23,7 +23,7 @@
23 23
24const struct inode_operations jfs_fast_symlink_inode_operations = { 24const struct inode_operations jfs_fast_symlink_inode_operations = {
25 .readlink = generic_readlink, 25 .readlink = generic_readlink,
26 .follow_link = simple_follow_link, 26 .get_link = simple_get_link,
27 .setattr = jfs_setattr, 27 .setattr = jfs_setattr,
28 .setxattr = jfs_setxattr, 28 .setxattr = jfs_setxattr,
29 .getxattr = jfs_getxattr, 29 .getxattr = jfs_getxattr,
@@ -33,7 +33,7 @@ const struct inode_operations jfs_fast_symlink_inode_operations = {
33 33
34const struct inode_operations jfs_symlink_inode_operations = { 34const struct inode_operations jfs_symlink_inode_operations = {
35 .readlink = generic_readlink, 35 .readlink = generic_readlink,
36 .follow_link = page_follow_link_light, 36 .get_link = page_get_link,
37 .put_link = page_put_link, 37 .put_link = page_put_link,
38 .setattr = jfs_setattr, 38 .setattr = jfs_setattr,
39 .setxattr = jfs_setxattr, 39 .setxattr = jfs_setxattr,
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
index db272528ab5b..ffae8579045d 100644
--- a/fs/kernfs/symlink.c
+++ b/fs/kernfs/symlink.c
@@ -112,10 +112,15 @@ static int kernfs_getlink(struct dentry *dentry, char *path)
112 return error; 112 return error;
113} 113}
114 114
115static const char *kernfs_iop_follow_link(struct dentry *dentry, void **cookie) 115static const char *kernfs_iop_get_link(struct dentry *dentry,
116 struct inode *inode, void **cookie)
116{ 117{
117 int error = -ENOMEM; 118 int error = -ENOMEM;
118 unsigned long page = get_zeroed_page(GFP_KERNEL); 119 unsigned long page;
120
121 if (!dentry)
122 return ERR_PTR(-ECHILD);
123 page = get_zeroed_page(GFP_KERNEL);
119 if (!page) 124 if (!page)
120 return ERR_PTR(-ENOMEM); 125 return ERR_PTR(-ENOMEM);
121 error = kernfs_getlink(dentry, (char *)page); 126 error = kernfs_getlink(dentry, (char *)page);
@@ -132,7 +137,7 @@ const struct inode_operations kernfs_symlink_iops = {
132 .getxattr = kernfs_iop_getxattr, 137 .getxattr = kernfs_iop_getxattr,
133 .listxattr = kernfs_iop_listxattr, 138 .listxattr = kernfs_iop_listxattr,
134 .readlink = generic_readlink, 139 .readlink = generic_readlink,
135 .follow_link = kernfs_iop_follow_link, 140 .get_link = kernfs_iop_get_link,
136 .put_link = free_page_put_link, 141 .put_link = free_page_put_link,
137 .setattr = kernfs_iop_setattr, 142 .setattr = kernfs_iop_setattr,
138 .getattr = kernfs_iop_getattr, 143 .getattr = kernfs_iop_getattr,
diff --git a/fs/libfs.c b/fs/libfs.c
index c7cbfb092e94..8dc37fc4b6df 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1092,14 +1092,15 @@ simple_nosetlease(struct file *filp, long arg, struct file_lock **flp,
1092} 1092}
1093EXPORT_SYMBOL(simple_nosetlease); 1093EXPORT_SYMBOL(simple_nosetlease);
1094 1094
1095const char *simple_follow_link(struct dentry *dentry, void **cookie) 1095const char *simple_get_link(struct dentry *dentry, struct inode *inode,
1096 void **cookie)
1096{ 1097{
1097 return d_inode(dentry)->i_link; 1098 return inode->i_link;
1098} 1099}
1099EXPORT_SYMBOL(simple_follow_link); 1100EXPORT_SYMBOL(simple_get_link);
1100 1101
1101const struct inode_operations simple_symlink_inode_operations = { 1102const struct inode_operations simple_symlink_inode_operations = {
1102 .follow_link = simple_follow_link, 1103 .get_link = simple_get_link,
1103 .readlink = generic_readlink 1104 .readlink = generic_readlink
1104}; 1105};
1105EXPORT_SYMBOL(simple_symlink_inode_operations); 1106EXPORT_SYMBOL(simple_symlink_inode_operations);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 67a23bfd7303..3cce709a8729 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -435,7 +435,7 @@ static const struct address_space_operations minix_aops = {
435 435
436static const struct inode_operations minix_symlink_inode_operations = { 436static const struct inode_operations minix_symlink_inode_operations = {
437 .readlink = generic_readlink, 437 .readlink = generic_readlink,
438 .follow_link = page_follow_link_light, 438 .get_link = page_get_link,
439 .put_link = page_put_link, 439 .put_link = page_put_link,
440 .getattr = minix_getattr, 440 .getattr = minix_getattr,
441}; 441};
diff --git a/fs/namei.c b/fs/namei.c
index 2808958e6c67..1da3064311e2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -842,7 +842,7 @@ static inline void path_to_nameidata(const struct path *path,
842} 842}
843 843
844/* 844/*
845 * Helper to directly jump to a known parsed path from ->follow_link, 845 * Helper to directly jump to a known parsed path from ->get_link,
846 * caller must have taken a reference to path beforehand. 846 * caller must have taken a reference to path beforehand.
847 */ 847 */
848void nd_jump_link(struct path *path) 848void nd_jump_link(struct path *path)
@@ -1005,10 +1005,18 @@ const char *get_link(struct nameidata *nd)
1005 res = inode->i_link; 1005 res = inode->i_link;
1006 if (!res) { 1006 if (!res) {
1007 if (nd->flags & LOOKUP_RCU) { 1007 if (nd->flags & LOOKUP_RCU) {
1008 if (unlikely(unlazy_walk(nd, NULL, 0))) 1008 res = inode->i_op->get_link(NULL, inode,
1009 return ERR_PTR(-ECHILD); 1009 &last->cookie);
1010 if (res == ERR_PTR(-ECHILD)) {
1011 if (unlikely(unlazy_walk(nd, NULL, 0)))
1012 return ERR_PTR(-ECHILD);
1013 res = inode->i_op->get_link(dentry, inode,
1014 &last->cookie);
1015 }
1016 } else {
1017 res = inode->i_op->get_link(dentry, inode,
1018 &last->cookie);
1010 } 1019 }
1011 res = inode->i_op->follow_link(dentry, &last->cookie);
1012 if (IS_ERR_OR_NULL(res)) { 1020 if (IS_ERR_OR_NULL(res)) {
1013 last->cookie = NULL; 1021 last->cookie = NULL;
1014 return res; 1022 return res;
@@ -4495,8 +4503,8 @@ EXPORT_SYMBOL(readlink_copy);
4495 4503
4496/* 4504/*
4497 * A helper for ->readlink(). This should be used *ONLY* for symlinks that 4505 * A helper for ->readlink(). This should be used *ONLY* for symlinks that
4498 * have ->follow_link() touching nd only in nd_set_link(). Using (or not 4506 * have ->get_link() not calling nd_jump_link(). Using (or not using) it
4499 * using) it for any given inode is up to filesystem. 4507 * for any given inode is up to filesystem.
4500 */ 4508 */
4501int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) 4509int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
4502{ 4510{
@@ -4506,7 +4514,7 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
4506 int res; 4514 int res;
4507 4515
4508 if (!link) { 4516 if (!link) {
4509 link = inode->i_op->follow_link(dentry, &cookie); 4517 link = inode->i_op->get_link(dentry, inode, &cookie);
4510 if (IS_ERR(link)) 4518 if (IS_ERR(link))
4511 return PTR_ERR(link); 4519 return PTR_ERR(link);
4512 } 4520 }
@@ -4518,26 +4526,27 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
4518EXPORT_SYMBOL(generic_readlink); 4526EXPORT_SYMBOL(generic_readlink);
4519 4527
4520/* get the link contents into pagecache */ 4528/* get the link contents into pagecache */
4521static const char *page_getlink(struct dentry * dentry, void **cookie) 4529const char *page_get_link(struct dentry *dentry, struct inode *inode,
4530 void **cookie)
4522{ 4531{
4523 char *kaddr; 4532 char *kaddr;
4524 struct page *page; 4533 struct page *page;
4525 struct address_space *mapping = dentry->d_inode->i_mapping; 4534 struct address_space *mapping = inode->i_mapping;
4535
4536 if (!dentry)
4537 return ERR_PTR(-ECHILD);
4538
4526 page = read_mapping_page(mapping, 0, NULL); 4539 page = read_mapping_page(mapping, 0, NULL);
4527 if (IS_ERR(page)) 4540 if (IS_ERR(page))
4528 return (char*)page; 4541 return (char*)page;
4529 *cookie = page; 4542 *cookie = page;
4530 BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM); 4543 BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM);
4531 kaddr = page_address(page); 4544 kaddr = page_address(page);
4532 nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1); 4545 nd_terminate_link(kaddr, inode->i_size, PAGE_SIZE - 1);
4533 return kaddr; 4546 return kaddr;
4534} 4547}
4535 4548
4536const char *page_follow_link_light(struct dentry *dentry, void **cookie) 4549EXPORT_SYMBOL(page_get_link);
4537{
4538 return page_getlink(dentry, cookie);
4539}
4540EXPORT_SYMBOL(page_follow_link_light);
4541 4550
4542void page_put_link(struct inode *unused, void *cookie) 4551void page_put_link(struct inode *unused, void *cookie)
4543{ 4552{
@@ -4549,7 +4558,9 @@ EXPORT_SYMBOL(page_put_link);
4549int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) 4558int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
4550{ 4559{
4551 void *cookie = NULL; 4560 void *cookie = NULL;
4552 int res = readlink_copy(buffer, buflen, page_getlink(dentry, &cookie)); 4561 int res = readlink_copy(buffer, buflen,
4562 page_get_link(dentry, d_inode(dentry),
4563 &cookie));
4553 if (cookie) 4564 if (cookie)
4554 page_put_link(NULL, cookie); 4565 page_put_link(NULL, cookie);
4555 return res; 4566 return res;
@@ -4600,7 +4611,7 @@ EXPORT_SYMBOL(page_symlink);
4600 4611
4601const struct inode_operations page_symlink_inode_operations = { 4612const struct inode_operations page_symlink_inode_operations = {
4602 .readlink = generic_readlink, 4613 .readlink = generic_readlink,
4603 .follow_link = page_follow_link_light, 4614 .get_link = page_get_link,
4604 .put_link = page_put_link, 4615 .put_link = page_put_link,
4605}; 4616};
4606EXPORT_SYMBOL(page_symlink_inode_operations); 4617EXPORT_SYMBOL(page_symlink_inode_operations);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index bb856f7e05fd..3ab6cdbcde60 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -244,7 +244,7 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
244#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) 244#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
245static const struct inode_operations ncp_symlink_inode_operations = { 245static const struct inode_operations ncp_symlink_inode_operations = {
246 .readlink = generic_readlink, 246 .readlink = generic_readlink,
247 .follow_link = page_follow_link_light, 247 .get_link = page_get_link,
248 .put_link = page_put_link, 248 .put_link = page_put_link,
249 .setattr = ncp_notify_change, 249 .setattr = ncp_notify_change,
250}; 250};
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index abd93bf015d6..8ade8a812607 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -42,12 +42,15 @@ error:
42 return -EIO; 42 return -EIO;
43} 43}
44 44
45static const char *nfs_follow_link(struct dentry *dentry, void **cookie) 45static const char *nfs_get_link(struct dentry *dentry,
46 struct inode *inode, void **cookie)
46{ 47{
47 struct inode *inode = d_inode(dentry);
48 struct page *page; 48 struct page *page;
49 void *err; 49 void *err;
50 50
51 if (!dentry)
52 return ERR_PTR(-ECHILD);
53
51 err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); 54 err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
52 if (err) 55 if (err)
53 return err; 56 return err;
@@ -64,7 +67,7 @@ static const char *nfs_follow_link(struct dentry *dentry, void **cookie)
64 */ 67 */
65const struct inode_operations nfs_symlink_inode_operations = { 68const struct inode_operations nfs_symlink_inode_operations = {
66 .readlink = generic_readlink, 69 .readlink = generic_readlink,
67 .follow_link = nfs_follow_link, 70 .get_link = nfs_get_link,
68 .put_link = page_put_link, 71 .put_link = page_put_link,
69 .getattr = nfs_getattr, 72 .getattr = nfs_getattr,
70 .setattr = nfs_setattr, 73 .setattr = nfs_setattr,
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 90b3ba960b9b..63dddb7d4b18 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -569,7 +569,7 @@ const struct inode_operations nilfs_special_inode_operations = {
569 569
570const struct inode_operations nilfs_symlink_inode_operations = { 570const struct inode_operations nilfs_symlink_inode_operations = {
571 .readlink = generic_readlink, 571 .readlink = generic_readlink,
572 .follow_link = page_follow_link_light, 572 .get_link = page_get_link,
573 .put_link = page_put_link, 573 .put_link = page_put_link,
574 .permission = nilfs_permission, 574 .permission = nilfs_permission,
575}; 575};
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 66edce7ecfd7..b4e79bc720f7 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -88,7 +88,7 @@ const struct address_space_operations ocfs2_fast_symlink_aops = {
88 88
89const struct inode_operations ocfs2_symlink_inode_operations = { 89const struct inode_operations ocfs2_symlink_inode_operations = {
90 .readlink = generic_readlink, 90 .readlink = generic_readlink,
91 .follow_link = page_follow_link_light, 91 .get_link = page_get_link,
92 .put_link = page_put_link, 92 .put_link = page_put_link,
93 .getattr = ocfs2_getattr, 93 .getattr = ocfs2_getattr,
94 .setattr = ocfs2_setattr, 94 .setattr = ocfs2_setattr,
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 4060ffde8722..38a0b8b9f8b9 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -137,17 +137,21 @@ struct ovl_link_data {
137 void *cookie; 137 void *cookie;
138}; 138};
139 139
140static const char *ovl_follow_link(struct dentry *dentry, void **cookie) 140static const char *ovl_get_link(struct dentry *dentry,
141 struct inode *inode, void **cookie)
141{ 142{
142 struct dentry *realdentry; 143 struct dentry *realdentry;
143 struct inode *realinode; 144 struct inode *realinode;
144 struct ovl_link_data *data = NULL; 145 struct ovl_link_data *data = NULL;
145 const char *ret; 146 const char *ret;
146 147
148 if (!dentry)
149 return ERR_PTR(-ECHILD);
150
147 realdentry = ovl_dentry_real(dentry); 151 realdentry = ovl_dentry_real(dentry);
148 realinode = realdentry->d_inode; 152 realinode = realdentry->d_inode;
149 153
150 if (WARN_ON(!realinode->i_op->follow_link)) 154 if (WARN_ON(!realinode->i_op->get_link))
151 return ERR_PTR(-EPERM); 155 return ERR_PTR(-EPERM);
152 156
153 if (realinode->i_op->put_link) { 157 if (realinode->i_op->put_link) {
@@ -157,7 +161,7 @@ static const char *ovl_follow_link(struct dentry *dentry, void **cookie)
157 data->realdentry = realdentry; 161 data->realdentry = realdentry;
158 } 162 }
159 163
160 ret = realinode->i_op->follow_link(realdentry, cookie); 164 ret = realinode->i_op->get_link(realdentry, realinode, cookie);
161 if (IS_ERR_OR_NULL(ret)) { 165 if (IS_ERR_OR_NULL(ret)) {
162 kfree(data); 166 kfree(data);
163 return ret; 167 return ret;
@@ -378,7 +382,7 @@ static const struct inode_operations ovl_file_inode_operations = {
378 382
379static const struct inode_operations ovl_symlink_inode_operations = { 383static const struct inode_operations ovl_symlink_inode_operations = {
380 .setattr = ovl_setattr, 384 .setattr = ovl_setattr,
381 .follow_link = ovl_follow_link, 385 .get_link = ovl_get_link,
382 .put_link = ovl_put_link, 386 .put_link = ovl_put_link,
383 .readlink = ovl_readlink, 387 .readlink = ovl_readlink,
384 .getattr = ovl_getattr, 388 .getattr = ovl_getattr,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index bd3e9e68125b..1a489e2b9768 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1564,12 +1564,15 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
1564 return -ENOENT; 1564 return -ENOENT;
1565} 1565}
1566 1566
1567static const char *proc_pid_follow_link(struct dentry *dentry, void **cookie) 1567static const char *proc_pid_get_link(struct dentry *dentry,
1568 struct inode *inode, void **cookie)
1568{ 1569{
1569 struct inode *inode = d_inode(dentry);
1570 struct path path; 1570 struct path path;
1571 int error = -EACCES; 1571 int error = -EACCES;
1572 1572
1573 if (!dentry)
1574 return ERR_PTR(-ECHILD);
1575
1573 /* Are we allowed to snoop on the tasks file descriptors? */ 1576 /* Are we allowed to snoop on the tasks file descriptors? */
1574 if (!proc_fd_access_allowed(inode)) 1577 if (!proc_fd_access_allowed(inode))
1575 goto out; 1578 goto out;
@@ -1630,7 +1633,7 @@ out:
1630 1633
1631const struct inode_operations proc_pid_link_inode_operations = { 1634const struct inode_operations proc_pid_link_inode_operations = {
1632 .readlink = proc_pid_readlink, 1635 .readlink = proc_pid_readlink,
1633 .follow_link = proc_pid_follow_link, 1636 .get_link = proc_pid_get_link,
1634 .setattr = proc_setattr, 1637 .setattr = proc_setattr,
1635}; 1638};
1636 1639
@@ -1895,7 +1898,7 @@ static const struct dentry_operations tid_map_files_dentry_operations = {
1895 .d_delete = pid_delete_dentry, 1898 .d_delete = pid_delete_dentry,
1896}; 1899};
1897 1900
1898static int proc_map_files_get_link(struct dentry *dentry, struct path *path) 1901static int map_files_get_link(struct dentry *dentry, struct path *path)
1899{ 1902{
1900 unsigned long vm_start, vm_end; 1903 unsigned long vm_start, vm_end;
1901 struct vm_area_struct *vma; 1904 struct vm_area_struct *vma;
@@ -1945,20 +1948,21 @@ struct map_files_info {
1945 * path to the file in question. 1948 * path to the file in question.
1946 */ 1949 */
1947static const char * 1950static const char *
1948proc_map_files_follow_link(struct dentry *dentry, void **cookie) 1951proc_map_files_get_link(struct dentry *dentry,
1952 struct inode *inode, void **cookie)
1949{ 1953{
1950 if (!capable(CAP_SYS_ADMIN)) 1954 if (!capable(CAP_SYS_ADMIN))
1951 return ERR_PTR(-EPERM); 1955 return ERR_PTR(-EPERM);
1952 1956
1953 return proc_pid_follow_link(dentry, NULL); 1957 return proc_pid_get_link(dentry, inode, NULL);
1954} 1958}
1955 1959
1956/* 1960/*
1957 * Identical to proc_pid_link_inode_operations except for follow_link() 1961 * Identical to proc_pid_link_inode_operations except for get_link()
1958 */ 1962 */
1959static const struct inode_operations proc_map_files_link_inode_operations = { 1963static const struct inode_operations proc_map_files_link_inode_operations = {
1960 .readlink = proc_pid_readlink, 1964 .readlink = proc_pid_readlink,
1961 .follow_link = proc_map_files_follow_link, 1965 .get_link = proc_map_files_get_link,
1962 .setattr = proc_setattr, 1966 .setattr = proc_setattr,
1963}; 1967};
1964 1968
@@ -1975,7 +1979,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
1975 return -ENOENT; 1979 return -ENOENT;
1976 1980
1977 ei = PROC_I(inode); 1981 ei = PROC_I(inode);
1978 ei->op.proc_get_link = proc_map_files_get_link; 1982 ei->op.proc_get_link = map_files_get_link;
1979 1983
1980 inode->i_op = &proc_map_files_link_inode_operations; 1984 inode->i_op = &proc_map_files_link_inode_operations;
1981 inode->i_size = 64; 1985 inode->i_size = 64;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index bd95b9fdebb0..10360b268794 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -393,9 +393,10 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
393}; 393};
394#endif 394#endif
395 395
396static const char *proc_follow_link(struct dentry *dentry, void **cookie) 396static const char *proc_get_link(struct dentry *dentry,
397 struct inode *inode, void **cookie)
397{ 398{
398 struct proc_dir_entry *pde = PDE(d_inode(dentry)); 399 struct proc_dir_entry *pde = PDE(inode);
399 if (unlikely(!use_pde(pde))) 400 if (unlikely(!use_pde(pde)))
400 return ERR_PTR(-EINVAL); 401 return ERR_PTR(-EINVAL);
401 *cookie = pde; 402 *cookie = pde;
@@ -409,7 +410,7 @@ static void proc_put_link(struct inode *unused, void *p)
409 410
410const struct inode_operations proc_link_inode_operations = { 411const struct inode_operations proc_link_inode_operations = {
411 .readlink = generic_readlink, 412 .readlink = generic_readlink,
412 .follow_link = proc_follow_link, 413 .get_link = proc_get_link,
413 .put_link = proc_put_link, 414 .put_link = proc_put_link,
414}; 415};
415 416
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index f6e8354b8cea..63861c15e109 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -30,14 +30,17 @@ static const struct proc_ns_operations *ns_entries[] = {
30 &mntns_operations, 30 &mntns_operations,
31}; 31};
32 32
33static const char *proc_ns_follow_link(struct dentry *dentry, void **cookie) 33static const char *proc_ns_get_link(struct dentry *dentry,
34 struct inode *inode, void **cookie)
34{ 35{
35 struct inode *inode = d_inode(dentry);
36 const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; 36 const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
37 struct task_struct *task; 37 struct task_struct *task;
38 struct path ns_path; 38 struct path ns_path;
39 void *error = ERR_PTR(-EACCES); 39 void *error = ERR_PTR(-EACCES);
40 40
41 if (!dentry)
42 return ERR_PTR(-ECHILD);
43
41 task = get_proc_task(inode); 44 task = get_proc_task(inode);
42 if (!task) 45 if (!task)
43 return error; 46 return error;
@@ -74,7 +77,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
74 77
75static const struct inode_operations proc_ns_link_inode_operations = { 78static const struct inode_operations proc_ns_link_inode_operations = {
76 .readlink = proc_ns_readlink, 79 .readlink = proc_ns_readlink,
77 .follow_link = proc_ns_follow_link, 80 .get_link = proc_ns_get_link,
78 .setattr = proc_setattr, 81 .setattr = proc_setattr,
79}; 82};
80 83
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 113b8d061fc0..9dd0ae6aefdb 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -18,12 +18,15 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
18 return readlink_copy(buffer, buflen, tmp); 18 return readlink_copy(buffer, buflen, tmp);
19} 19}
20 20
21static const char *proc_self_follow_link(struct dentry *dentry, void **cookie) 21static const char *proc_self_get_link(struct dentry *dentry,
22 struct inode *inode, void **cookie)
22{ 23{
23 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 24 struct pid_namespace *ns = inode->i_sb->s_fs_info;
24 pid_t tgid = task_tgid_nr_ns(current, ns); 25 pid_t tgid = task_tgid_nr_ns(current, ns);
25 char *name; 26 char *name;
26 27
28 if (!dentry)
29 return ERR_PTR(-ECHILD);
27 if (!tgid) 30 if (!tgid)
28 return ERR_PTR(-ENOENT); 31 return ERR_PTR(-ENOENT);
29 /* 11 for max length of signed int in decimal + NULL term */ 32 /* 11 for max length of signed int in decimal + NULL term */
@@ -36,7 +39,7 @@ static const char *proc_self_follow_link(struct dentry *dentry, void **cookie)
36 39
37static const struct inode_operations proc_self_inode_operations = { 40static const struct inode_operations proc_self_inode_operations = {
38 .readlink = proc_self_readlink, 41 .readlink = proc_self_readlink,
39 .follow_link = proc_self_follow_link, 42 .get_link = proc_self_get_link,
40 .put_link = kfree_put_link, 43 .put_link = kfree_put_link,
41}; 44};
42 45
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index 947b0f4fd0a1..50eef6f3e671 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -19,13 +19,16 @@ static int proc_thread_self_readlink(struct dentry *dentry, char __user *buffer,
19 return readlink_copy(buffer, buflen, tmp); 19 return readlink_copy(buffer, buflen, tmp);
20} 20}
21 21
22static const char *proc_thread_self_follow_link(struct dentry *dentry, void **cookie) 22static const char *proc_thread_self_get_link(struct dentry *dentry,
23 struct inode *inode, void **cookie)
23{ 24{
24 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 25 struct pid_namespace *ns = inode->i_sb->s_fs_info;
25 pid_t tgid = task_tgid_nr_ns(current, ns); 26 pid_t tgid = task_tgid_nr_ns(current, ns);
26 pid_t pid = task_pid_nr_ns(current, ns); 27 pid_t pid = task_pid_nr_ns(current, ns);
27 char *name; 28 char *name;
28 29
30 if (!dentry)
31 return ERR_PTR(-ECHILD);
29 if (!pid) 32 if (!pid)
30 return ERR_PTR(-ENOENT); 33 return ERR_PTR(-ENOENT);
31 name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL); 34 name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL);
@@ -37,7 +40,7 @@ static const char *proc_thread_self_follow_link(struct dentry *dentry, void **co
37 40
38static const struct inode_operations proc_thread_self_inode_operations = { 41static const struct inode_operations proc_thread_self_inode_operations = {
39 .readlink = proc_thread_self_readlink, 42 .readlink = proc_thread_self_readlink,
40 .follow_link = proc_thread_self_follow_link, 43 .get_link = proc_thread_self_get_link,
41 .put_link = kfree_put_link, 44 .put_link = kfree_put_link,
42}; 45};
43 46
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 4fc2326fac03..ecbf11e961ab 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1665,7 +1665,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
1665 */ 1665 */
1666const struct inode_operations reiserfs_symlink_inode_operations = { 1666const struct inode_operations reiserfs_symlink_inode_operations = {
1667 .readlink = generic_readlink, 1667 .readlink = generic_readlink,
1668 .follow_link = page_follow_link_light, 1668 .get_link = page_get_link,
1669 .put_link = page_put_link, 1669 .put_link = page_put_link,
1670 .setattr = reiserfs_setattr, 1670 .setattr = reiserfs_setattr,
1671 .setxattr = reiserfs_setxattr, 1671 .setxattr = reiserfs_setxattr,
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
index 12806dffb345..7c635a5da783 100644
--- a/fs/squashfs/symlink.c
+++ b/fs/squashfs/symlink.c
@@ -119,7 +119,7 @@ const struct address_space_operations squashfs_symlink_aops = {
119 119
120const struct inode_operations squashfs_symlink_inode_ops = { 120const struct inode_operations squashfs_symlink_inode_ops = {
121 .readlink = generic_readlink, 121 .readlink = generic_readlink,
122 .follow_link = page_follow_link_light, 122 .get_link = page_get_link,
123 .put_link = page_put_link, 123 .put_link = page_put_link,
124 .getxattr = generic_getxattr, 124 .getxattr = generic_getxattr,
125 .listxattr = squashfs_listxattr 125 .listxattr = squashfs_listxattr
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index ef8bcdb80aca..80a40bcb721c 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -146,7 +146,7 @@ static inline void write3byte(struct sysv_sb_info *sbi,
146 146
147static const struct inode_operations sysv_symlink_inode_operations = { 147static const struct inode_operations sysv_symlink_inode_operations = {
148 .readlink = generic_readlink, 148 .readlink = generic_readlink,
149 .follow_link = page_follow_link_light, 149 .get_link = page_get_link,
150 .put_link = page_put_link, 150 .put_link = page_put_link,
151 .getattr = sysv_getattr, 151 .getattr = sysv_getattr,
152}; 152};
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 0edc12856147..eff62801acbf 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1608,7 +1608,7 @@ const struct inode_operations ubifs_file_inode_operations = {
1608 1608
1609const struct inode_operations ubifs_symlink_inode_operations = { 1609const struct inode_operations ubifs_symlink_inode_operations = {
1610 .readlink = generic_readlink, 1610 .readlink = generic_readlink,
1611 .follow_link = simple_follow_link, 1611 .get_link = simple_get_link,
1612 .setattr = ubifs_setattr, 1612 .setattr = ubifs_setattr,
1613 .getattr = ubifs_getattr, 1613 .getattr = ubifs_getattr,
1614 .setxattr = ubifs_setxattr, 1614 .setxattr = ubifs_setxattr,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 245268a0cdf0..f638fd58b5b3 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -414,13 +414,17 @@ xfs_vn_rename(
414 * uio is kmalloced for this reason... 414 * uio is kmalloced for this reason...
415 */ 415 */
416STATIC const char * 416STATIC const char *
417xfs_vn_follow_link( 417xfs_vn_get_link(
418 struct dentry *dentry, 418 struct dentry *dentry,
419 struct inode *inode,
419 void **cookie) 420 void **cookie)
420{ 421{
421 char *link; 422 char *link;
422 int error = -ENOMEM; 423 int error = -ENOMEM;
423 424
425 if (!dentry)
426 return ERR_PTR(-ECHILD);
427
424 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); 428 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
425 if (!link) 429 if (!link)
426 goto out_err; 430 goto out_err;
@@ -1172,7 +1176,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1172 1176
1173static const struct inode_operations xfs_symlink_inode_operations = { 1177static const struct inode_operations xfs_symlink_inode_operations = {
1174 .readlink = generic_readlink, 1178 .readlink = generic_readlink,
1175 .follow_link = xfs_vn_follow_link, 1179 .get_link = xfs_vn_get_link,
1176 .put_link = kfree_put_link, 1180 .put_link = kfree_put_link,
1177 .getattr = xfs_vn_getattr, 1181 .getattr = xfs_vn_getattr,
1178 .setattr = xfs_vn_setattr, 1182 .setattr = xfs_vn_setattr,