diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-11-17 10:20:54 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-12-08 22:41:54 -0500 |
commit | 6b2553918d8b4e6de9853fd6315bec7271a2e592 (patch) | |
tree | 85540dcb0dc0de3d67c68d0aa7b17058f4e96539 /fs | |
parent | 21fc61c73c3903c4c312d0802da01ec2b323d174 (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')
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 | ||
1231 | static const char *v9fs_vfs_follow_link(struct dentry *dentry, void **cookie) | 1232 | static 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 | ||
1453 | static const struct inode_operations v9fs_symlink_inode_operations = { | 1460 | static 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 | ||
907 | static const char * | 908 | static const char * |
908 | v9fs_vfs_follow_link_dotl(struct dentry *dentry, void **cookie) | 909 | v9fs_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 | ||
985 | const struct inode_operations v9fs_symlink_inode_operations_dotl = { | 991 | const 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 | ||
72 | const struct inode_operations affs_symlink_inode_operations = { | 72 | const 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 | ||
15 | static const char *autofs4_follow_link(struct dentry *dentry, void **cookie) | 15 | static 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 | ||
24 | const struct inode_operations autofs4_symlink_inode_operations = { | 29 | const 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 | }; |
10097 | static const struct inode_operations btrfs_symlink_inode_operations = { | 10097 | static 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 | */ |
1757 | static const struct inode_operations ceph_symlink_iops = { | 1757 | static 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 | ||
901 | const struct inode_operations cifs_symlink_inode_ops = { | 901 | const 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 */ |
123 | extern const char *cifs_follow_link(struct dentry *direntry, void **cookie); | 123 | extern const char *cifs_get_link(struct dentry *, struct inode *, void **); |
124 | extern int cifs_readlink(struct dentry *direntry, char __user *buffer, | ||
125 | int buflen); | ||
126 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | 124 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, |
127 | const char *symname); | 125 | const char *symname); |
128 | extern int cifs_removexattr(struct dentry *, const char *); | 126 | extern 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 | ||
629 | const char * | 629 | const char * |
630 | cifs_follow_link(struct dentry *direntry, void **cookie) | 630 | cifs_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 | ||
19 | static const struct inode_operations coda_symlink_inode_operations = { | 19 | static 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 | ||
282 | static const char *configfs_follow_link(struct dentry *dentry, void **cookie) | 282 | static 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 | ||
299 | const struct inode_operations configfs_symlink_inode_operations = { | 304 | const 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 | ||
677 | static const char *ecryptfs_follow_link(struct dentry *dentry, void **cookie) | 677 | static 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 | ||
1096 | const struct inode_operations ecryptfs_symlink_iops = { | 1102 | const 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 | ||
23 | const struct inode_operations ext2_symlink_inode_operations = { | 23 | const 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 | ||
36 | const struct inode_operations ext2_fast_symlink_inode_operations = { | 36 | const 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 |
26 | static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cookie) | 26 | static 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 | ||
88 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { | 91 | const 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 | ||
100 | const struct inode_operations ext4_symlink_inode_operations = { | 103 | const 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 | ||
111 | const struct inode_operations ext4_fast_symlink_inode_operations = { | 114 | const 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 | ||
318 | static const char *f2fs_follow_link(struct dentry *dentry, void **cookie) | 318 | static 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 |
927 | static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cookie) | 928 | static 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 | ||
995 | const struct inode_operations f2fs_encrypted_symlink_inode_operations = { | 999 | const 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 | ||
1031 | const struct inode_operations f2fs_symlink_inode_operations = { | 1035 | const 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 | ||
1368 | static const char *fuse_follow_link(struct dentry *dentry, void **cookie) | 1368 | static 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 | ||
1910 | static const struct inode_operations fuse_symlink_inode_operations = { | 1913 | static 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 | ||
1724 | static const char *gfs2_follow_link(struct dentry *dentry, void **cookie) | 1725 | static 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 | ||
2133 | const struct inode_operations gfs2_symlink_iops = { | 2138 | const 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 | ||
895 | static const char *hostfs_follow_link(struct dentry *dentry, void **cookie) | 895 | static 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 | ||
923 | static const struct inode_operations hostfs_link_iops = { | 927 | static 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 @@ | |||
14 | const struct inode_operations jffs2_symlink_inode_operations = | 14 | const 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 | ||
24 | const struct inode_operations jfs_fast_symlink_inode_operations = { | 24 | const 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 | ||
34 | const struct inode_operations jfs_symlink_inode_operations = { | 34 | const 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 | ||
115 | static const char *kernfs_iop_follow_link(struct dentry *dentry, void **cookie) | 115 | static 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 | } |
1093 | EXPORT_SYMBOL(simple_nosetlease); | 1093 | EXPORT_SYMBOL(simple_nosetlease); |
1094 | 1094 | ||
1095 | const char *simple_follow_link(struct dentry *dentry, void **cookie) | 1095 | const 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 | } |
1099 | EXPORT_SYMBOL(simple_follow_link); | 1100 | EXPORT_SYMBOL(simple_get_link); |
1100 | 1101 | ||
1101 | const struct inode_operations simple_symlink_inode_operations = { | 1102 | const 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 | }; |
1105 | EXPORT_SYMBOL(simple_symlink_inode_operations); | 1106 | EXPORT_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 | ||
436 | static const struct inode_operations minix_symlink_inode_operations = { | 436 | static 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 | */ |
848 | void nd_jump_link(struct path *path) | 848 | void 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 | */ |
4501 | int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 4509 | int 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) | |||
4518 | EXPORT_SYMBOL(generic_readlink); | 4526 | EXPORT_SYMBOL(generic_readlink); |
4519 | 4527 | ||
4520 | /* get the link contents into pagecache */ | 4528 | /* get the link contents into pagecache */ |
4521 | static const char *page_getlink(struct dentry * dentry, void **cookie) | 4529 | const 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 | ||
4536 | const char *page_follow_link_light(struct dentry *dentry, void **cookie) | 4549 | EXPORT_SYMBOL(page_get_link); |
4537 | { | ||
4538 | return page_getlink(dentry, cookie); | ||
4539 | } | ||
4540 | EXPORT_SYMBOL(page_follow_link_light); | ||
4541 | 4550 | ||
4542 | void page_put_link(struct inode *unused, void *cookie) | 4551 | void page_put_link(struct inode *unused, void *cookie) |
4543 | { | 4552 | { |
@@ -4549,7 +4558,9 @@ EXPORT_SYMBOL(page_put_link); | |||
4549 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 4558 | int 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 | ||
4601 | const struct inode_operations page_symlink_inode_operations = { | 4612 | const 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 | }; |
4606 | EXPORT_SYMBOL(page_symlink_inode_operations); | 4617 | EXPORT_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) |
245 | static const struct inode_operations ncp_symlink_inode_operations = { | 245 | static 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 | ||
45 | static const char *nfs_follow_link(struct dentry *dentry, void **cookie) | 45 | static 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 | */ |
65 | const struct inode_operations nfs_symlink_inode_operations = { | 68 | const 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 | ||
570 | const struct inode_operations nilfs_symlink_inode_operations = { | 570 | const 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 | ||
89 | const struct inode_operations ocfs2_symlink_inode_operations = { | 89 | const 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 | ||
140 | static const char *ovl_follow_link(struct dentry *dentry, void **cookie) | 140 | static 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 | ||
379 | static const struct inode_operations ovl_symlink_inode_operations = { | 383 | static 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 | ||
1567 | static const char *proc_pid_follow_link(struct dentry *dentry, void **cookie) | 1567 | static 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 | ||
1631 | const struct inode_operations proc_pid_link_inode_operations = { | 1634 | const 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 | ||
1898 | static int proc_map_files_get_link(struct dentry *dentry, struct path *path) | 1901 | static 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 | */ |
1947 | static const char * | 1950 | static const char * |
1948 | proc_map_files_follow_link(struct dentry *dentry, void **cookie) | 1951 | proc_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 | */ |
1959 | static const struct inode_operations proc_map_files_link_inode_operations = { | 1963 | static 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 | ||
396 | static const char *proc_follow_link(struct dentry *dentry, void **cookie) | 396 | static 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 | ||
410 | const struct inode_operations proc_link_inode_operations = { | 411 | const 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 | ||
33 | static const char *proc_ns_follow_link(struct dentry *dentry, void **cookie) | 33 | static 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 | ||
75 | static const struct inode_operations proc_ns_link_inode_operations = { | 78 | static 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 | ||
21 | static const char *proc_self_follow_link(struct dentry *dentry, void **cookie) | 21 | static 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 | ||
37 | static const struct inode_operations proc_self_inode_operations = { | 40 | static 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 | ||
22 | static const char *proc_thread_self_follow_link(struct dentry *dentry, void **cookie) | 22 | static 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 | ||
38 | static const struct inode_operations proc_thread_self_inode_operations = { | 41 | static 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 | */ |
1666 | const struct inode_operations reiserfs_symlink_inode_operations = { | 1666 | const 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 | ||
120 | const struct inode_operations squashfs_symlink_inode_ops = { | 120 | const 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 | ||
147 | static const struct inode_operations sysv_symlink_inode_operations = { | 147 | static 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 | ||
1609 | const struct inode_operations ubifs_symlink_inode_operations = { | 1609 | const 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 | */ |
416 | STATIC const char * | 416 | STATIC const char * |
417 | xfs_vn_follow_link( | 417 | xfs_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 | ||
1173 | static const struct inode_operations xfs_symlink_inode_operations = { | 1177 | static 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, |