diff options
95 files changed, 570 insertions, 470 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 06d443450f21..619af9bfdcb3 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -50,8 +50,7 @@ prototypes: | |||
50 | int (*rename2) (struct inode *, struct dentry *, | 50 | int (*rename2) (struct inode *, struct dentry *, |
51 | struct inode *, struct dentry *, unsigned int); | 51 | struct inode *, struct dentry *, unsigned int); |
52 | int (*readlink) (struct dentry *, char __user *,int); | 52 | int (*readlink) (struct dentry *, char __user *,int); |
53 | const char *(*follow_link) (struct dentry *, void **); | 53 | const char *(*get_link) (struct dentry *, struct inode *, void **); |
54 | void (*put_link) (struct inode *, void *); | ||
55 | void (*truncate) (struct inode *); | 54 | void (*truncate) (struct inode *); |
56 | int (*permission) (struct inode *, int, unsigned int); | 55 | int (*permission) (struct inode *, int, unsigned int); |
57 | int (*get_acl)(struct inode *, int); | 56 | int (*get_acl)(struct inode *, int); |
@@ -83,8 +82,7 @@ rmdir: yes (both) (see below) | |||
83 | rename: yes (all) (see below) | 82 | rename: yes (all) (see below) |
84 | rename2: yes (all) (see below) | 83 | rename2: yes (all) (see below) |
85 | readlink: no | 84 | readlink: no |
86 | follow_link: no | 85 | get_link: no |
87 | put_link: no | ||
88 | setattr: yes | 86 | setattr: yes |
89 | permission: no (may not block if called in rcu-walk mode) | 87 | permission: no (may not block if called in rcu-walk mode) |
90 | get_acl: no | 88 | get_acl: no |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index f24d1b833957..0f88e6020487 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -504,3 +504,20 @@ in your dentry operations instead. | |||
504 | [mandatory] | 504 | [mandatory] |
505 | __fd_install() & fd_install() can now sleep. Callers should not | 505 | __fd_install() & fd_install() can now sleep. Callers should not |
506 | hold a spinlock or other resources that do not allow a schedule. | 506 | hold a spinlock or other resources that do not allow a schedule. |
507 | -- | ||
508 | [mandatory] | ||
509 | any symlink that might use page_follow_link_light/page_put_link() must | ||
510 | have inode_nohighmem(inode) called before anything might start playing with | ||
511 | its pagecache. | ||
512 | -- | ||
513 | [mandatory] | ||
514 | ->follow_link() is replaced with ->get_link(); same API, except that | ||
515 | * ->get_link() gets inode as a separate argument | ||
516 | * ->get_link() may be called in RCU mode - in that case NULL | ||
517 | dentry is passed | ||
518 | -- | ||
519 | [mandatory] | ||
520 | ->get_link() gets struct delayed_call *done now, and should do | ||
521 | set_delayed_call() where it used to set *cookie. | ||
522 | ->put_link() is gone - just give the destructor to set_delayed_call() | ||
523 | in ->get_link(). | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 8c6f07ad373a..b02a7d598258 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -350,8 +350,8 @@ struct inode_operations { | |||
350 | int (*rename2) (struct inode *, struct dentry *, | 350 | int (*rename2) (struct inode *, struct dentry *, |
351 | struct inode *, struct dentry *, unsigned int); | 351 | struct inode *, struct dentry *, unsigned int); |
352 | int (*readlink) (struct dentry *, char __user *,int); | 352 | int (*readlink) (struct dentry *, char __user *,int); |
353 | const char *(*follow_link) (struct dentry *, void **); | 353 | const char *(*get_link) (struct dentry *, struct inode *, |
354 | void (*put_link) (struct inode *, void *); | 354 | struct delayed_call *); |
355 | int (*permission) (struct inode *, int); | 355 | int (*permission) (struct inode *, int); |
356 | int (*get_acl)(struct inode *, int); | 356 | int (*get_acl)(struct inode *, int); |
357 | int (*setattr) (struct dentry *, struct iattr *); | 357 | int (*setattr) (struct dentry *, struct iattr *); |
@@ -434,20 +434,19 @@ otherwise noted. | |||
434 | readlink: called by the readlink(2) system call. Only required if | 434 | readlink: called by the readlink(2) system call. Only required if |
435 | you want to support reading symbolic links | 435 | you want to support reading symbolic links |
436 | 436 | ||
437 | follow_link: called by the VFS to follow a symbolic link to the | 437 | get_link: called by the VFS to follow a symbolic link to the |
438 | inode it points to. Only required if you want to support | 438 | inode it points to. Only required if you want to support |
439 | symbolic links. This method returns the symlink body | 439 | symbolic links. This method returns the symlink body |
440 | to traverse (and possibly resets the current position with | 440 | to traverse (and possibly resets the current position with |
441 | nd_jump_link()). If the body won't go away until the inode | 441 | nd_jump_link()). If the body won't go away until the inode |
442 | is gone, nothing else is needed; if it needs to be otherwise | 442 | is gone, nothing else is needed; if it needs to be otherwise |
443 | pinned, the data needed to release whatever we'd grabbed | 443 | pinned, arrange for its release by having get_link(..., ..., done) |
444 | is to be stored in void * variable passed by address to | 444 | do set_delayed_call(done, destructor, argument). |
445 | follow_link() instance. | 445 | In that case destructor(argument) will be called once VFS is |
446 | 446 | done with the body you've returned. | |
447 | put_link: called by the VFS to release resources allocated by | 447 | May be called in RCU mode; that is indicated by NULL dentry |
448 | follow_link(). The cookie stored by follow_link() is passed | 448 | argument. If request can't be handled without leaving RCU mode, |
449 | to this method as the last parameter; only called when | 449 | have it return ERR_PTR(-ECHILD). |
450 | cookie isn't NULL. | ||
451 | 450 | ||
452 | permission: called by the VFS to check for access rights on a POSIX-like | 451 | permission: called by the VFS to check for access rights on a POSIX-like |
453 | filesystem. | 452 | filesystem. |
diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c index 69b203651905..e489a3271f06 100644 --- a/drivers/staging/lustre/lustre/llite/symlink.c +++ b/drivers/staging/lustre/lustre/llite/symlink.c | |||
@@ -118,12 +118,20 @@ failed: | |||
118 | return rc; | 118 | return rc; |
119 | } | 119 | } |
120 | 120 | ||
121 | static const char *ll_follow_link(struct dentry *dentry, void **cookie) | 121 | static void ll_put_link(void *p) |
122 | { | ||
123 | ptlrpc_req_finished(p); | ||
124 | } | ||
125 | |||
126 | static const char *ll_get_link(struct dentry *dentry, | ||
127 | struct inode *inode, | ||
128 | struct delayed_call *done) | ||
122 | { | 129 | { |
123 | struct inode *inode = d_inode(dentry); | ||
124 | struct ptlrpc_request *request = NULL; | 130 | struct ptlrpc_request *request = NULL; |
125 | int rc; | 131 | int rc; |
126 | char *symname = NULL; | 132 | char *symname = NULL; |
133 | if (!dentry) | ||
134 | return ERR_PTR(-ECHILD); | ||
127 | 135 | ||
128 | CDEBUG(D_VFSTRACE, "VFS Op\n"); | 136 | CDEBUG(D_VFSTRACE, "VFS Op\n"); |
129 | ll_inode_size_lock(inode); | 137 | ll_inode_size_lock(inode); |
@@ -135,22 +143,16 @@ static const char *ll_follow_link(struct dentry *dentry, void **cookie) | |||
135 | } | 143 | } |
136 | 144 | ||
137 | /* symname may contain a pointer to the request message buffer, | 145 | /* symname may contain a pointer to the request message buffer, |
138 | * we delay request releasing until ll_put_link then. | 146 | * we delay request releasing then. |
139 | */ | 147 | */ |
140 | *cookie = request; | 148 | set_delayed_call(done, ll_put_link, request); |
141 | return symname; | 149 | return symname; |
142 | } | 150 | } |
143 | 151 | ||
144 | static void ll_put_link(struct inode *unused, void *cookie) | ||
145 | { | ||
146 | ptlrpc_req_finished(cookie); | ||
147 | } | ||
148 | |||
149 | struct inode_operations ll_fast_symlink_inode_operations = { | 152 | struct inode_operations ll_fast_symlink_inode_operations = { |
150 | .readlink = generic_readlink, | 153 | .readlink = generic_readlink, |
151 | .setattr = ll_setattr, | 154 | .setattr = ll_setattr, |
152 | .follow_link = ll_follow_link, | 155 | .get_link = ll_get_link, |
153 | .put_link = ll_put_link, | ||
154 | .getattr = ll_getattr, | 156 | .getattr = ll_getattr, |
155 | .permission = ll_inode_permission, | 157 | .permission = ll_inode_permission, |
156 | .setxattr = ll_setxattr, | 158 | .setxattr = ll_setxattr, |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 511078586fa1..c7cc7c30f0c8 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -1223,18 +1223,26 @@ 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 | * @cookie: place to pass the data to put_link() | 1228 | * @inode: inode for symlink |
1229 | * @done: delayed call for when we are done with the return value | ||
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, | ||
1234 | struct delayed_call *done) | ||
1232 | { | 1235 | { |
1233 | struct v9fs_session_info *v9ses = v9fs_dentry2v9ses(dentry); | 1236 | struct v9fs_session_info *v9ses; |
1234 | struct p9_fid *fid = v9fs_fid_lookup(dentry); | 1237 | struct p9_fid *fid; |
1235 | struct p9_wstat *st; | 1238 | struct p9_wstat *st; |
1236 | char *res; | 1239 | char *res; |
1237 | 1240 | ||
1241 | if (!dentry) | ||
1242 | return ERR_PTR(-ECHILD); | ||
1243 | |||
1244 | v9ses = v9fs_dentry2v9ses(dentry); | ||
1245 | fid = v9fs_fid_lookup(dentry); | ||
1238 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); | 1246 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
1239 | 1247 | ||
1240 | if (IS_ERR(fid)) | 1248 | if (IS_ERR(fid)) |
@@ -1259,7 +1267,8 @@ static const char *v9fs_vfs_follow_link(struct dentry *dentry, void **cookie) | |||
1259 | 1267 | ||
1260 | p9stat_free(st); | 1268 | p9stat_free(st); |
1261 | kfree(st); | 1269 | kfree(st); |
1262 | return *cookie = res; | 1270 | set_delayed_call(done, kfree_link, res); |
1271 | return res; | ||
1263 | } | 1272 | } |
1264 | 1273 | ||
1265 | /** | 1274 | /** |
@@ -1452,8 +1461,7 @@ static const struct inode_operations v9fs_file_inode_operations = { | |||
1452 | 1461 | ||
1453 | static const struct inode_operations v9fs_symlink_inode_operations = { | 1462 | static const struct inode_operations v9fs_symlink_inode_operations = { |
1454 | .readlink = generic_readlink, | 1463 | .readlink = generic_readlink, |
1455 | .follow_link = v9fs_vfs_follow_link, | 1464 | .get_link = v9fs_vfs_get_link, |
1456 | .put_link = kfree_put_link, | ||
1457 | .getattr = v9fs_vfs_getattr, | 1465 | .getattr = v9fs_vfs_getattr, |
1458 | .setattr = v9fs_vfs_setattr, | 1466 | .setattr = v9fs_vfs_setattr, |
1459 | }; | 1467 | }; |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index cb899af1babc..a34702c998f5 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -899,26 +899,34 @@ 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 | * @cookie: place to pass the data to put_link() | 904 | * @inode: inode for symlink |
905 | * @done: destructor for return value | ||
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, | ||
911 | struct delayed_call *done) | ||
909 | { | 912 | { |
910 | struct p9_fid *fid = v9fs_fid_lookup(dentry); | 913 | struct p9_fid *fid; |
911 | char *target; | 914 | char *target; |
912 | int retval; | 915 | int retval; |
913 | 916 | ||
917 | if (!dentry) | ||
918 | return ERR_PTR(-ECHILD); | ||
919 | |||
914 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); | 920 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
915 | 921 | ||
922 | fid = v9fs_fid_lookup(dentry); | ||
916 | if (IS_ERR(fid)) | 923 | if (IS_ERR(fid)) |
917 | return ERR_CAST(fid); | 924 | return ERR_CAST(fid); |
918 | retval = p9_client_readlink(fid, &target); | 925 | retval = p9_client_readlink(fid, &target); |
919 | if (retval) | 926 | if (retval) |
920 | return ERR_PTR(retval); | 927 | return ERR_PTR(retval); |
921 | return *cookie = target; | 928 | set_delayed_call(done, kfree_link, target); |
929 | return target; | ||
922 | } | 930 | } |
923 | 931 | ||
924 | int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) | 932 | int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) |
@@ -984,8 +992,7 @@ const struct inode_operations v9fs_file_inode_operations_dotl = { | |||
984 | 992 | ||
985 | const struct inode_operations v9fs_symlink_inode_operations_dotl = { | 993 | const struct inode_operations v9fs_symlink_inode_operations_dotl = { |
986 | .readlink = generic_readlink, | 994 | .readlink = generic_readlink, |
987 | .follow_link = v9fs_vfs_follow_link_dotl, | 995 | .get_link = v9fs_vfs_get_link_dotl, |
988 | .put_link = kfree_put_link, | ||
989 | .getattr = v9fs_vfs_getattr_dotl, | 996 | .getattr = v9fs_vfs_getattr_dotl, |
990 | .setattr = v9fs_vfs_setattr_dotl, | 997 | .setattr = v9fs_vfs_setattr_dotl, |
991 | .setxattr = generic_setxattr, | 998 | .setxattr = generic_setxattr, |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 17349500592d..0fdb0f5b2239 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -140,6 +140,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) | |||
140 | break; | 140 | break; |
141 | case ST_SOFTLINK: | 141 | case ST_SOFTLINK: |
142 | inode->i_mode |= S_IFLNK; | 142 | inode->i_mode |= S_IFLNK; |
143 | inode_nohighmem(inode); | ||
143 | inode->i_op = &affs_symlink_inode_operations; | 144 | inode->i_op = &affs_symlink_inode_operations; |
144 | inode->i_data.a_ops = &affs_symlink_aops; | 145 | inode->i_data.a_ops = &affs_symlink_aops; |
145 | break; | 146 | break; |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 181e05b46e72..00d3002a6780 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -344,6 +344,7 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
344 | return -ENOSPC; | 344 | return -ENOSPC; |
345 | 345 | ||
346 | inode->i_op = &affs_symlink_inode_operations; | 346 | inode->i_op = &affs_symlink_inode_operations; |
347 | inode_nohighmem(inode); | ||
347 | inode->i_data.a_ops = &affs_symlink_aops; | 348 | inode->i_data.a_ops = &affs_symlink_aops; |
348 | inode->i_mode = S_IFLNK | 0777; | 349 | inode->i_mode = S_IFLNK | 0777; |
349 | mode_to_prot(inode); | 350 | mode_to_prot(inode); |
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c index ea5b69a18ba9..69b03dbb792f 100644 --- a/fs/affs/symlink.c +++ b/fs/affs/symlink.c | |||
@@ -14,13 +14,13 @@ static int affs_symlink_readpage(struct file *file, struct page *page) | |||
14 | { | 14 | { |
15 | struct buffer_head *bh; | 15 | struct buffer_head *bh; |
16 | struct inode *inode = page->mapping->host; | 16 | struct inode *inode = page->mapping->host; |
17 | char *link = kmap(page); | 17 | char *link = page_address(page); |
18 | struct slink_front *lf; | 18 | struct slink_front *lf; |
19 | int i, j; | 19 | int i, j; |
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) |
@@ -57,12 +57,10 @@ static int affs_symlink_readpage(struct file *file, struct page *page) | |||
57 | link[i] = '\0'; | 57 | link[i] = '\0'; |
58 | affs_brelse(bh); | 58 | affs_brelse(bh); |
59 | SetPageUptodate(page); | 59 | SetPageUptodate(page); |
60 | kunmap(page); | ||
61 | unlock_page(page); | 60 | unlock_page(page); |
62 | return 0; | 61 | return 0; |
63 | fail: | 62 | fail: |
64 | SetPageError(page); | 63 | SetPageError(page); |
65 | kunmap(page); | ||
66 | unlock_page(page); | 64 | unlock_page(page); |
67 | return -EIO; | 65 | return -EIO; |
68 | } | 66 | } |
@@ -73,7 +71,6 @@ const struct address_space_operations affs_symlink_aops = { | |||
73 | 71 | ||
74 | const struct inode_operations affs_symlink_inode_operations = { | 72 | const struct inode_operations affs_symlink_inode_operations = { |
75 | .readlink = generic_readlink, | 73 | .readlink = generic_readlink, |
76 | .follow_link = page_follow_link_light, | 74 | .get_link = page_get_link, |
77 | .put_link = page_put_link, | ||
78 | .setattr = affs_notify_change, | 75 | .setattr = affs_notify_change, |
79 | }; | 76 | }; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index e06f5a23352a..86cc7264c21c 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -56,6 +56,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
56 | case AFS_FTYPE_SYMLINK: | 56 | case AFS_FTYPE_SYMLINK: |
57 | inode->i_mode = S_IFLNK | vnode->status.mode; | 57 | inode->i_mode = S_IFLNK | vnode->status.mode; |
58 | inode->i_op = &page_symlink_inode_operations; | 58 | inode->i_op = &page_symlink_inode_operations; |
59 | inode_nohighmem(inode); | ||
59 | break; | 60 | break; |
60 | default: | 61 | default: |
61 | printk("kAFS: AFS vnode with undefined type\n"); | 62 | printk("kAFS: AFS vnode with undefined type\n"); |
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c index da0c33481bc0..84e037d1d129 100644 --- a/fs/autofs4/symlink.c +++ b/fs/autofs4/symlink.c | |||
@@ -12,10 +12,16 @@ | |||
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, | ||
17 | struct delayed_call *done) | ||
16 | { | 18 | { |
17 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 19 | struct autofs_sb_info *sbi; |
18 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 20 | struct autofs_info *ino; |
21 | if (!dentry) | ||
22 | return ERR_PTR(-ECHILD); | ||
23 | sbi = autofs4_sbi(dentry->d_sb); | ||
24 | ino = autofs4_dentry_ino(dentry); | ||
19 | if (ino && !autofs4_oz_mode(sbi)) | 25 | if (ino && !autofs4_oz_mode(sbi)) |
20 | ino->last_used = jiffies; | 26 | ino->last_used = jiffies; |
21 | return d_inode(dentry)->i_private; | 27 | return d_inode(dentry)->i_private; |
@@ -23,5 +29,5 @@ static const char *autofs4_follow_link(struct dentry *dentry, void **cookie) | |||
23 | 29 | ||
24 | const struct inode_operations autofs4_symlink_inode_operations = { | 30 | const struct inode_operations autofs4_symlink_inode_operations = { |
25 | .readlink = generic_readlink, | 31 | .readlink = generic_readlink, |
26 | .follow_link = autofs4_follow_link | 32 | .get_link = autofs4_get_link |
27 | }; | 33 | }; |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 46aedacfa6a8..25250fa87086 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -42,7 +42,7 @@ static struct inode *befs_iget(struct super_block *, unsigned long); | |||
42 | static struct inode *befs_alloc_inode(struct super_block *sb); | 42 | static struct inode *befs_alloc_inode(struct super_block *sb); |
43 | static void befs_destroy_inode(struct inode *inode); | 43 | static void befs_destroy_inode(struct inode *inode); |
44 | static void befs_destroy_inodecache(void); | 44 | static void befs_destroy_inodecache(void); |
45 | static const char *befs_follow_link(struct dentry *, void **); | 45 | static int befs_symlink_readpage(struct file *, struct page *); |
46 | static int befs_utf2nls(struct super_block *sb, const char *in, int in_len, | 46 | static int befs_utf2nls(struct super_block *sb, const char *in, int in_len, |
47 | char **out, int *out_len); | 47 | char **out, int *out_len); |
48 | static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, | 48 | static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, |
@@ -79,10 +79,8 @@ static const struct address_space_operations befs_aops = { | |||
79 | .bmap = befs_bmap, | 79 | .bmap = befs_bmap, |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static const struct inode_operations befs_symlink_inode_operations = { | 82 | static const struct address_space_operations befs_symlink_aops = { |
83 | .readlink = generic_readlink, | 83 | .readpage = befs_symlink_readpage, |
84 | .follow_link = befs_follow_link, | ||
85 | .put_link = kfree_put_link, | ||
86 | }; | 84 | }; |
87 | 85 | ||
88 | /* | 86 | /* |
@@ -398,7 +396,9 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
398 | inode->i_fop = &befs_dir_operations; | 396 | inode->i_fop = &befs_dir_operations; |
399 | } else if (S_ISLNK(inode->i_mode)) { | 397 | } else if (S_ISLNK(inode->i_mode)) { |
400 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { | 398 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { |
401 | inode->i_op = &befs_symlink_inode_operations; | 399 | inode->i_op = &page_symlink_inode_operations; |
400 | inode_nohighmem(inode); | ||
401 | inode->i_mapping->a_ops = &befs_symlink_aops; | ||
402 | } else { | 402 | } else { |
403 | inode->i_link = befs_ino->i_data.symlink; | 403 | inode->i_link = befs_ino->i_data.symlink; |
404 | inode->i_op = &simple_symlink_inode_operations; | 404 | inode->i_op = &simple_symlink_inode_operations; |
@@ -463,31 +463,33 @@ befs_destroy_inodecache(void) | |||
463 | * The data stream become link name. Unless the LONG_SYMLINK | 463 | * The data stream become link name. Unless the LONG_SYMLINK |
464 | * flag is set. | 464 | * flag is set. |
465 | */ | 465 | */ |
466 | static const char * | 466 | static int befs_symlink_readpage(struct file *unused, struct page *page) |
467 | befs_follow_link(struct dentry *dentry, void **cookie) | ||
468 | { | 467 | { |
469 | struct super_block *sb = dentry->d_sb; | 468 | struct inode *inode = page->mapping->host; |
470 | struct befs_inode_info *befs_ino = BEFS_I(d_inode(dentry)); | 469 | struct super_block *sb = inode->i_sb; |
470 | struct befs_inode_info *befs_ino = BEFS_I(inode); | ||
471 | befs_data_stream *data = &befs_ino->i_data.ds; | 471 | befs_data_stream *data = &befs_ino->i_data.ds; |
472 | befs_off_t len = data->size; | 472 | befs_off_t len = data->size; |
473 | char *link; | 473 | char *link = page_address(page); |
474 | 474 | ||
475 | if (len == 0) { | 475 | if (len == 0 || len > PAGE_SIZE) { |
476 | befs_error(sb, "Long symlink with illegal length"); | 476 | befs_error(sb, "Long symlink with illegal length"); |
477 | return ERR_PTR(-EIO); | 477 | goto fail; |
478 | } | 478 | } |
479 | befs_debug(sb, "Follow long symlink"); | 479 | befs_debug(sb, "Follow long symlink"); |
480 | 480 | ||
481 | link = kmalloc(len, GFP_NOFS); | ||
482 | if (!link) | ||
483 | return ERR_PTR(-ENOMEM); | ||
484 | if (befs_read_lsymlink(sb, data, link, len) != len) { | 481 | if (befs_read_lsymlink(sb, data, link, len) != len) { |
485 | kfree(link); | ||
486 | befs_error(sb, "Failed to read entire long symlink"); | 482 | befs_error(sb, "Failed to read entire long symlink"); |
487 | return ERR_PTR(-EIO); | 483 | goto fail; |
488 | } | 484 | } |
489 | link[len - 1] = '\0'; | 485 | link[len - 1] = '\0'; |
490 | return *cookie = link; | 486 | SetPageUptodate(page); |
487 | unlock_page(page); | ||
488 | return 0; | ||
489 | fail: | ||
490 | SetPageError(page); | ||
491 | unlock_page(page); | ||
492 | return -EIO; | ||
491 | } | 493 | } |
492 | 494 | ||
493 | /* | 495 | /* |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a70c5790f8f5..1a41a65fd2ff 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3774,6 +3774,7 @@ cache_acl: | |||
3774 | break; | 3774 | break; |
3775 | case S_IFLNK: | 3775 | case S_IFLNK: |
3776 | inode->i_op = &btrfs_symlink_inode_operations; | 3776 | inode->i_op = &btrfs_symlink_inode_operations; |
3777 | inode_nohighmem(inode); | ||
3777 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 3778 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
3778 | break; | 3779 | break; |
3779 | default: | 3780 | default: |
@@ -9705,6 +9706,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
9705 | btrfs_free_path(path); | 9706 | btrfs_free_path(path); |
9706 | 9707 | ||
9707 | inode->i_op = &btrfs_symlink_inode_operations; | 9708 | inode->i_op = &btrfs_symlink_inode_operations; |
9709 | inode_nohighmem(inode); | ||
9708 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 9710 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
9709 | inode_set_bytes(inode, name_len); | 9711 | inode_set_bytes(inode, name_len); |
9710 | btrfs_i_size_write(inode, name_len); | 9712 | btrfs_i_size_write(inode, name_len); |
@@ -10094,8 +10096,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
10094 | }; | 10096 | }; |
10095 | static const struct inode_operations btrfs_symlink_inode_operations = { | 10097 | static const struct inode_operations btrfs_symlink_inode_operations = { |
10096 | .readlink = generic_readlink, | 10098 | .readlink = generic_readlink, |
10097 | .follow_link = page_follow_link_light, | 10099 | .get_link = page_get_link, |
10098 | .put_link = page_put_link, | ||
10099 | .getattr = btrfs_getattr, | 10100 | .getattr = btrfs_getattr, |
10100 | .setattr = btrfs_setattr, | 10101 | .setattr = btrfs_setattr, |
10101 | .permission = btrfs_permission, | 10102 | .permission = btrfs_permission, |
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..90e4e2b398b6 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -900,8 +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, | ||
905 | .permission = cifs_permission, | 904 | .permission = cifs_permission, |
906 | /* BB add the following two eventually */ | 905 | /* BB add the following two eventually */ |
907 | /* revalidate: cifs_revalidate, | 906 | /* revalidate: cifs_revalidate, |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index c3cc1609025f..26a1187d4323 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -120,9 +120,8 @@ 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 *, |
124 | extern int cifs_readlink(struct dentry *direntry, char __user *buffer, | 124 | struct delayed_call *); |
125 | int buflen); | ||
126 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | 125 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, |
127 | const char *symname); | 126 | const char *symname); |
128 | extern int cifs_removexattr(struct dentry *, const char *); | 127 | extern int cifs_removexattr(struct dentry *, const char *); |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index e3548f73bdea..062c2375549a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -627,9 +627,9 @@ 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, |
631 | struct delayed_call *done) | ||
631 | { | 632 | { |
632 | struct inode *inode = d_inode(direntry); | ||
633 | int rc = -ENOMEM; | 633 | int rc = -ENOMEM; |
634 | unsigned int xid; | 634 | unsigned int xid; |
635 | char *full_path = NULL; | 635 | char *full_path = NULL; |
@@ -639,6 +639,9 @@ cifs_follow_link(struct dentry *direntry, void **cookie) | |||
639 | struct cifs_tcon *tcon; | 639 | struct cifs_tcon *tcon; |
640 | struct TCP_Server_Info *server; | 640 | struct TCP_Server_Info *server; |
641 | 641 | ||
642 | if (!direntry) | ||
643 | return ERR_PTR(-ECHILD); | ||
644 | |||
642 | xid = get_xid(); | 645 | xid = get_xid(); |
643 | 646 | ||
644 | tlink = cifs_sb_tlink(cifs_sb); | 647 | tlink = cifs_sb_tlink(cifs_sb); |
@@ -678,7 +681,8 @@ cifs_follow_link(struct dentry *direntry, void **cookie) | |||
678 | kfree(target_path); | 681 | kfree(target_path); |
679 | return ERR_PTR(rc); | 682 | return ERR_PTR(rc); |
680 | } | 683 | } |
681 | return *cookie = target_path; | 684 | set_delayed_call(done, kfree_link, target_path); |
685 | return target_path; | ||
682 | } | 686 | } |
683 | 687 | ||
684 | int | 688 | int |
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 7740b1c871c1..1bfb7ba4e85e 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/coda.h> | 9 | #include <linux/coda.h> |
10 | #include <linux/coda_psdev.h> | 10 | #include <linux/coda_psdev.h> |
11 | #include <linux/pagemap.h> | ||
11 | #include "coda_linux.h" | 12 | #include "coda_linux.h" |
12 | 13 | ||
13 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) | 14 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) |
@@ -17,8 +18,7 @@ static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) | |||
17 | 18 | ||
18 | static const struct inode_operations coda_symlink_inode_operations = { | 19 | static const struct inode_operations coda_symlink_inode_operations = { |
19 | .readlink = generic_readlink, | 20 | .readlink = generic_readlink, |
20 | .follow_link = page_follow_link_light, | 21 | .get_link = page_get_link, |
21 | .put_link = page_put_link, | ||
22 | .setattr = coda_setattr, | 22 | .setattr = coda_setattr, |
23 | }; | 23 | }; |
24 | 24 | ||
@@ -35,6 +35,7 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr) | |||
35 | inode->i_fop = &coda_dir_operations; | 35 | inode->i_fop = &coda_dir_operations; |
36 | } else if (S_ISLNK(inode->i_mode)) { | 36 | } else if (S_ISLNK(inode->i_mode)) { |
37 | inode->i_op = &coda_symlink_inode_operations; | 37 | inode->i_op = &coda_symlink_inode_operations; |
38 | inode_nohighmem(inode); | ||
38 | inode->i_data.a_ops = &coda_symlink_aops; | 39 | inode->i_data.a_ops = &coda_symlink_aops; |
39 | inode->i_mapping = &inode->i_data; | 40 | inode->i_mapping = &inode->i_data; |
40 | } else | 41 | } else |
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index ab94ef63caef..03736e20d720 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c | |||
@@ -26,7 +26,7 @@ static int coda_symlink_filler(struct file *file, struct page *page) | |||
26 | int error; | 26 | int error; |
27 | struct coda_inode_info *cii; | 27 | struct coda_inode_info *cii; |
28 | unsigned int len = PAGE_SIZE; | 28 | unsigned int len = PAGE_SIZE; |
29 | char *p = kmap(page); | 29 | char *p = page_address(page); |
30 | 30 | ||
31 | cii = ITOC(inode); | 31 | cii = ITOC(inode); |
32 | 32 | ||
@@ -34,13 +34,11 @@ static int coda_symlink_filler(struct file *file, struct page *page) | |||
34 | if (error) | 34 | if (error) |
35 | goto fail; | 35 | goto fail; |
36 | SetPageUptodate(page); | 36 | SetPageUptodate(page); |
37 | kunmap(page); | ||
38 | unlock_page(page); | 37 | unlock_page(page); |
39 | return 0; | 38 | return 0; |
40 | 39 | ||
41 | fail: | 40 | fail: |
42 | SetPageError(page); | 41 | SetPageError(page); |
43 | kunmap(page); | ||
44 | unlock_page(page); | 42 | unlock_page(page); |
45 | return error; | 43 | return error; |
46 | } | 44 | } |
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index ec5c8325b503..db6d69289608 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c | |||
@@ -279,27 +279,33 @@ 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, | ||
284 | struct delayed_call *done) | ||
283 | { | 285 | { |
284 | unsigned long page = get_zeroed_page(GFP_KERNEL); | 286 | char *body; |
285 | int error; | 287 | int error; |
286 | 288 | ||
287 | if (!page) | 289 | if (!dentry) |
290 | return ERR_PTR(-ECHILD); | ||
291 | |||
292 | body = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
293 | if (!body) | ||
288 | return ERR_PTR(-ENOMEM); | 294 | return ERR_PTR(-ENOMEM); |
289 | 295 | ||
290 | error = configfs_getlink(dentry, (char *)page); | 296 | error = configfs_getlink(dentry, body); |
291 | if (!error) { | 297 | if (!error) { |
292 | return *cookie = (void *)page; | 298 | set_delayed_call(done, kfree_link, body); |
299 | return body; | ||
293 | } | 300 | } |
294 | 301 | ||
295 | free_page(page); | 302 | kfree(body); |
296 | return ERR_PTR(error); | 303 | return ERR_PTR(error); |
297 | } | 304 | } |
298 | 305 | ||
299 | const struct inode_operations configfs_symlink_inode_operations = { | 306 | const struct inode_operations configfs_symlink_inode_operations = { |
300 | .follow_link = configfs_follow_link, | 307 | .get_link = configfs_get_link, |
301 | .readlink = generic_readlink, | 308 | .readlink = generic_readlink, |
302 | .put_link = free_page_put_link, | ||
303 | .setattr = configfs_setattr, | 309 | .setattr = configfs_setattr, |
304 | }; | 310 | }; |
305 | 311 | ||
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 355c522f3585..b862bc219cd7 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -100,6 +100,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, | |||
100 | break; | 100 | break; |
101 | case S_IFLNK: | 101 | case S_IFLNK: |
102 | inode->i_op = &page_symlink_inode_operations; | 102 | inode->i_op = &page_symlink_inode_operations; |
103 | inode_nohighmem(inode); | ||
103 | inode->i_data.a_ops = &cramfs_aops; | 104 | inode->i_data.a_ops = &cramfs_aops; |
104 | break; | 105 | break; |
105 | default: | 106 | default: |
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..a4dddc61594c 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -674,16 +674,24 @@ 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, | ||
679 | struct delayed_call *done) | ||
678 | { | 680 | { |
679 | size_t len; | 681 | size_t len; |
680 | char *buf = ecryptfs_readlink_lower(dentry, &len); | 682 | char *buf; |
683 | |||
684 | if (!dentry) | ||
685 | return ERR_PTR(-ECHILD); | ||
686 | |||
687 | buf = ecryptfs_readlink_lower(dentry, &len); | ||
681 | if (IS_ERR(buf)) | 688 | if (IS_ERR(buf)) |
682 | return buf; | 689 | return buf; |
683 | fsstack_copy_attr_atime(d_inode(dentry), | 690 | fsstack_copy_attr_atime(d_inode(dentry), |
684 | d_inode(ecryptfs_dentry_to_lower(dentry))); | 691 | d_inode(ecryptfs_dentry_to_lower(dentry))); |
685 | buf[len] = '\0'; | 692 | buf[len] = '\0'; |
686 | return *cookie = buf; | 693 | set_delayed_call(done, kfree_link, buf); |
694 | return buf; | ||
687 | } | 695 | } |
688 | 696 | ||
689 | /** | 697 | /** |
@@ -1095,8 +1103,7 @@ out: | |||
1095 | 1103 | ||
1096 | const struct inode_operations ecryptfs_symlink_iops = { | 1104 | const struct inode_operations ecryptfs_symlink_iops = { |
1097 | .readlink = generic_readlink, | 1105 | .readlink = generic_readlink, |
1098 | .follow_link = ecryptfs_follow_link, | 1106 | .get_link = ecryptfs_get_link, |
1099 | .put_link = kfree_put_link, | ||
1100 | .permission = ecryptfs_permission, | 1107 | .permission = ecryptfs_permission, |
1101 | .setattr = ecryptfs_setattr, | 1108 | .setattr = ecryptfs_setattr, |
1102 | .getattr = ecryptfs_getattr_link, | 1109 | .getattr = ecryptfs_getattr_link, |
diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 079d20306ee1..cdf0872382af 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c | |||
@@ -151,6 +151,7 @@ struct inode *efs_iget(struct super_block *super, unsigned long ino) | |||
151 | break; | 151 | break; |
152 | case S_IFLNK: | 152 | case S_IFLNK: |
153 | inode->i_op = &page_symlink_inode_operations; | 153 | inode->i_op = &page_symlink_inode_operations; |
154 | inode_nohighmem(inode); | ||
154 | inode->i_data.a_ops = &efs_symlink_aops; | 155 | inode->i_data.a_ops = &efs_symlink_aops; |
155 | break; | 156 | break; |
156 | case S_IFCHR: | 157 | case S_IFCHR: |
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 75117d0dac2b..4870cc82deb0 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | static int efs_symlink_readpage(struct file *file, struct page *page) | 14 | static int efs_symlink_readpage(struct file *file, struct page *page) |
15 | { | 15 | { |
16 | char *link = kmap(page); | 16 | char *link = page_address(page); |
17 | struct buffer_head * bh; | 17 | struct buffer_head * bh; |
18 | struct inode * inode = page->mapping->host; | 18 | struct inode * inode = page->mapping->host; |
19 | efs_block_t size = inode->i_size; | 19 | efs_block_t size = inode->i_size; |
@@ -39,12 +39,10 @@ static int efs_symlink_readpage(struct file *file, struct page *page) | |||
39 | } | 39 | } |
40 | link[size] = '\0'; | 40 | link[size] = '\0'; |
41 | SetPageUptodate(page); | 41 | SetPageUptodate(page); |
42 | kunmap(page); | ||
43 | unlock_page(page); | 42 | unlock_page(page); |
44 | return 0; | 43 | return 0; |
45 | fail: | 44 | fail: |
46 | SetPageError(page); | 45 | SetPageError(page); |
47 | kunmap(page); | ||
48 | unlock_page(page); | 46 | unlock_page(page); |
49 | return err; | 47 | return err; |
50 | } | 48 | } |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 60f03b78914e..9eaf595aeaf8 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1224,6 +1224,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1224 | inode->i_link = (char *)oi->i_data; | 1224 | inode->i_link = (char *)oi->i_data; |
1225 | } else { | 1225 | } else { |
1226 | inode->i_op = &page_symlink_inode_operations; | 1226 | inode->i_op = &page_symlink_inode_operations; |
1227 | inode_nohighmem(inode); | ||
1227 | inode->i_mapping->a_ops = &exofs_aops; | 1228 | inode->i_mapping->a_ops = &exofs_aops; |
1228 | } | 1229 | } |
1229 | } else { | 1230 | } else { |
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 994e078da4bb..c20d77df2679 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
@@ -111,6 +111,7 @@ static int exofs_symlink(struct inode *dir, struct dentry *dentry, | |||
111 | if (l > sizeof(oi->i_data)) { | 111 | if (l > sizeof(oi->i_data)) { |
112 | /* slow symlink */ | 112 | /* slow symlink */ |
113 | inode->i_op = &page_symlink_inode_operations; | 113 | inode->i_op = &page_symlink_inode_operations; |
114 | inode_nohighmem(inode); | ||
114 | inode->i_mapping->a_ops = &exofs_aops; | 115 | inode->i_mapping->a_ops = &exofs_aops; |
115 | memset(oi->i_data, 0, sizeof(oi->i_data)); | 116 | memset(oi->i_data, 0, sizeof(oi->i_data)); |
116 | 117 | ||
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 0aa9bf6e6e53..338eefda70c6 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -1420,6 +1420,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino) | |||
1420 | sizeof(ei->i_data) - 1); | 1420 | sizeof(ei->i_data) - 1); |
1421 | } else { | 1421 | } else { |
1422 | inode->i_op = &ext2_symlink_inode_operations; | 1422 | inode->i_op = &ext2_symlink_inode_operations; |
1423 | inode_nohighmem(inode); | ||
1423 | if (test_opt(inode->i_sb, NOBH)) | 1424 | if (test_opt(inode->i_sb, NOBH)) |
1424 | inode->i_mapping->a_ops = &ext2_nobh_aops; | 1425 | inode->i_mapping->a_ops = &ext2_nobh_aops; |
1425 | else | 1426 | else |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 3267a80dbbe2..7a2be8f7f3c3 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -183,6 +183,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, | |||
183 | if (l > sizeof (EXT2_I(inode)->i_data)) { | 183 | if (l > sizeof (EXT2_I(inode)->i_data)) { |
184 | /* slow symlink */ | 184 | /* slow symlink */ |
185 | inode->i_op = &ext2_symlink_inode_operations; | 185 | inode->i_op = &ext2_symlink_inode_operations; |
186 | inode_nohighmem(inode); | ||
186 | if (test_opt(inode->i_sb, NOBH)) | 187 | if (test_opt(inode->i_sb, NOBH)) |
187 | inode->i_mapping->a_ops = &ext2_nobh_aops; | 188 | inode->i_mapping->a_ops = &ext2_nobh_aops; |
188 | else | 189 | else |
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index ae17179f3810..3495d8ae4b33 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c | |||
@@ -22,8 +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, | ||
27 | .setattr = ext2_setattr, | 26 | .setattr = ext2_setattr, |
28 | #ifdef CONFIG_EXT2_FS_XATTR | 27 | #ifdef CONFIG_EXT2_FS_XATTR |
29 | .setxattr = generic_setxattr, | 28 | .setxattr = generic_setxattr, |
@@ -35,7 +34,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
35 | 34 | ||
36 | const struct inode_operations ext2_fast_symlink_inode_operations = { | 35 | const struct inode_operations ext2_fast_symlink_inode_operations = { |
37 | .readlink = generic_readlink, | 36 | .readlink = generic_readlink, |
38 | .follow_link = simple_follow_link, | 37 | .get_link = simple_get_link, |
39 | .setattr = ext2_setattr, | 38 | .setattr = ext2_setattr, |
40 | #ifdef CONFIG_EXT2_FS_XATTR | 39 | #ifdef CONFIG_EXT2_FS_XATTR |
41 | .setxattr = generic_setxattr, | 40 | .setxattr = generic_setxattr, |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ea433a7f4bca..b3bd912df6bf 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4283,6 +4283,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4283 | inode->i_op = &ext4_symlink_inode_operations; | 4283 | inode->i_op = &ext4_symlink_inode_operations; |
4284 | ext4_set_aops(inode); | 4284 | ext4_set_aops(inode); |
4285 | } | 4285 | } |
4286 | inode_nohighmem(inode); | ||
4286 | } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || | 4287 | } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || |
4287 | S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | 4288 | S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { |
4288 | inode->i_op = &ext4_special_inode_operations; | 4289 | inode->i_op = &ext4_special_inode_operations; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a969ab39f302..f27e0c2598c5 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -3132,6 +3132,7 @@ static int ext4_symlink(struct inode *dir, | |||
3132 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { | 3132 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { |
3133 | if (!encryption_required) | 3133 | if (!encryption_required) |
3134 | inode->i_op = &ext4_symlink_inode_operations; | 3134 | inode->i_op = &ext4_symlink_inode_operations; |
3135 | inode_nohighmem(inode); | ||
3135 | ext4_set_aops(inode); | 3136 | ext4_set_aops(inode); |
3136 | /* | 3137 | /* |
3137 | * We cannot call page_symlink() with transaction started | 3138 | * We cannot call page_symlink() with transaction started |
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index e8e7af62ac95..6f7ee30a89ce 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c | |||
@@ -23,17 +23,21 @@ | |||
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, | ||
28 | struct delayed_call *done) | ||
27 | { | 29 | { |
28 | struct page *cpage = NULL; | 30 | struct page *cpage = NULL; |
29 | char *caddr, *paddr = NULL; | 31 | char *caddr, *paddr = NULL; |
30 | struct ext4_str cstr, pstr; | 32 | struct ext4_str cstr, pstr; |
31 | struct inode *inode = d_inode(dentry); | ||
32 | struct ext4_encrypted_symlink_data *sd; | 33 | struct ext4_encrypted_symlink_data *sd; |
33 | loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); | 34 | loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); |
34 | int res; | 35 | int res; |
35 | u32 plen, max_size = inode->i_sb->s_blocksize; | 36 | u32 plen, max_size = inode->i_sb->s_blocksize; |
36 | 37 | ||
38 | if (!dentry) | ||
39 | return ERR_PTR(-ECHILD); | ||
40 | |||
37 | res = ext4_get_encryption_info(inode); | 41 | res = ext4_get_encryption_info(inode); |
38 | if (res) | 42 | if (res) |
39 | return ERR_PTR(res); | 43 | return ERR_PTR(res); |
@@ -45,7 +49,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook | |||
45 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); | 49 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); |
46 | if (IS_ERR(cpage)) | 50 | if (IS_ERR(cpage)) |
47 | return ERR_CAST(cpage); | 51 | return ERR_CAST(cpage); |
48 | caddr = kmap(cpage); | 52 | caddr = page_address(cpage); |
49 | caddr[size] = 0; | 53 | caddr[size] = 0; |
50 | } | 54 | } |
51 | 55 | ||
@@ -75,24 +79,20 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook | |||
75 | /* Null-terminate the name */ | 79 | /* Null-terminate the name */ |
76 | if (res <= plen) | 80 | if (res <= plen) |
77 | paddr[res] = '\0'; | 81 | paddr[res] = '\0'; |
78 | if (cpage) { | 82 | if (cpage) |
79 | kunmap(cpage); | ||
80 | page_cache_release(cpage); | 83 | page_cache_release(cpage); |
81 | } | 84 | set_delayed_call(done, kfree_link, paddr); |
82 | return *cookie = paddr; | 85 | return paddr; |
83 | errout: | 86 | errout: |
84 | if (cpage) { | 87 | if (cpage) |
85 | kunmap(cpage); | ||
86 | page_cache_release(cpage); | 88 | page_cache_release(cpage); |
87 | } | ||
88 | kfree(paddr); | 89 | kfree(paddr); |
89 | return ERR_PTR(res); | 90 | return ERR_PTR(res); |
90 | } | 91 | } |
91 | 92 | ||
92 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { | 93 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { |
93 | .readlink = generic_readlink, | 94 | .readlink = generic_readlink, |
94 | .follow_link = ext4_encrypted_follow_link, | 95 | .get_link = ext4_encrypted_get_link, |
95 | .put_link = kfree_put_link, | ||
96 | .setattr = ext4_setattr, | 96 | .setattr = ext4_setattr, |
97 | .setxattr = generic_setxattr, | 97 | .setxattr = generic_setxattr, |
98 | .getxattr = generic_getxattr, | 98 | .getxattr = generic_getxattr, |
@@ -103,8 +103,7 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = { | |||
103 | 103 | ||
104 | const struct inode_operations ext4_symlink_inode_operations = { | 104 | const struct inode_operations ext4_symlink_inode_operations = { |
105 | .readlink = generic_readlink, | 105 | .readlink = generic_readlink, |
106 | .follow_link = page_follow_link_light, | 106 | .get_link = page_get_link, |
107 | .put_link = page_put_link, | ||
108 | .setattr = ext4_setattr, | 107 | .setattr = ext4_setattr, |
109 | .setxattr = generic_setxattr, | 108 | .setxattr = generic_setxattr, |
110 | .getxattr = generic_getxattr, | 109 | .getxattr = generic_getxattr, |
@@ -114,7 +113,7 @@ const struct inode_operations ext4_symlink_inode_operations = { | |||
114 | 113 | ||
115 | const struct inode_operations ext4_fast_symlink_inode_operations = { | 114 | const struct inode_operations ext4_fast_symlink_inode_operations = { |
116 | .readlink = generic_readlink, | 115 | .readlink = generic_readlink, |
117 | .follow_link = simple_follow_link, | 116 | .get_link = simple_get_link, |
118 | .setattr = ext4_setattr, | 117 | .setattr = ext4_setattr, |
119 | .setxattr = generic_setxattr, | 118 | .setxattr = generic_setxattr, |
120 | .getxattr = generic_getxattr, | 119 | .getxattr = generic_getxattr, |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 97e20decacb4..5528801a5baf 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -202,6 +202,7 @@ make_now: | |||
202 | inode->i_op = &f2fs_encrypted_symlink_inode_operations; | 202 | inode->i_op = &f2fs_encrypted_symlink_inode_operations; |
203 | else | 203 | else |
204 | inode->i_op = &f2fs_symlink_inode_operations; | 204 | inode->i_op = &f2fs_symlink_inode_operations; |
205 | inode_nohighmem(inode); | ||
205 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | 206 | inode->i_mapping->a_ops = &f2fs_dblock_aops; |
206 | } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || | 207 | } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || |
207 | S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | 208 | S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 2c32110f9fc0..e7587fce1b80 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -315,12 +315,15 @@ 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, | ||
320 | struct delayed_call *done) | ||
319 | { | 321 | { |
320 | const char *link = page_follow_link_light(dentry, cookie); | 322 | const char *link = page_get_link(dentry, inode, done); |
321 | if (!IS_ERR(link) && !*link) { | 323 | if (!IS_ERR(link) && !*link) { |
322 | /* this is broken symlink case */ | 324 | /* this is broken symlink case */ |
323 | page_put_link(NULL, *cookie); | 325 | do_delayed_call(done); |
326 | clear_delayed_call(done); | ||
324 | link = ERR_PTR(-ENOENT); | 327 | link = ERR_PTR(-ENOENT); |
325 | } | 328 | } |
326 | return link; | 329 | return link; |
@@ -351,6 +354,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
351 | inode->i_op = &f2fs_encrypted_symlink_inode_operations; | 354 | inode->i_op = &f2fs_encrypted_symlink_inode_operations; |
352 | else | 355 | else |
353 | inode->i_op = &f2fs_symlink_inode_operations; | 356 | inode->i_op = &f2fs_symlink_inode_operations; |
357 | inode_nohighmem(inode); | ||
354 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | 358 | inode->i_mapping->a_ops = &f2fs_dblock_aops; |
355 | 359 | ||
356 | f2fs_lock_op(sbi); | 360 | f2fs_lock_op(sbi); |
@@ -923,18 +927,22 @@ static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry, | |||
923 | } | 927 | } |
924 | 928 | ||
925 | #ifdef CONFIG_F2FS_FS_ENCRYPTION | 929 | #ifdef CONFIG_F2FS_FS_ENCRYPTION |
926 | static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cookie) | 930 | static const char *f2fs_encrypted_get_link(struct dentry *dentry, |
931 | struct inode *inode, | ||
932 | struct delayed_call *done) | ||
927 | { | 933 | { |
928 | struct page *cpage = NULL; | 934 | struct page *cpage = NULL; |
929 | char *caddr, *paddr = NULL; | 935 | char *caddr, *paddr = NULL; |
930 | struct f2fs_str cstr; | 936 | struct f2fs_str cstr; |
931 | struct f2fs_str pstr = FSTR_INIT(NULL, 0); | 937 | struct f2fs_str pstr = FSTR_INIT(NULL, 0); |
932 | struct inode *inode = d_inode(dentry); | ||
933 | struct f2fs_encrypted_symlink_data *sd; | 938 | struct f2fs_encrypted_symlink_data *sd; |
934 | loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); | 939 | loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); |
935 | u32 max_size = inode->i_sb->s_blocksize; | 940 | u32 max_size = inode->i_sb->s_blocksize; |
936 | int res; | 941 | int res; |
937 | 942 | ||
943 | if (!dentry) | ||
944 | return ERR_PTR(-ECHILD); | ||
945 | |||
938 | res = f2fs_get_encryption_info(inode); | 946 | res = f2fs_get_encryption_info(inode); |
939 | if (res) | 947 | if (res) |
940 | return ERR_PTR(res); | 948 | return ERR_PTR(res); |
@@ -942,7 +950,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook | |||
942 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); | 950 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); |
943 | if (IS_ERR(cpage)) | 951 | if (IS_ERR(cpage)) |
944 | return ERR_CAST(cpage); | 952 | return ERR_CAST(cpage); |
945 | caddr = kmap(cpage); | 953 | caddr = page_address(cpage); |
946 | caddr[size] = 0; | 954 | caddr[size] = 0; |
947 | 955 | ||
948 | /* Symlink is encrypted */ | 956 | /* Symlink is encrypted */ |
@@ -982,21 +990,19 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook | |||
982 | /* Null-terminate the name */ | 990 | /* Null-terminate the name */ |
983 | paddr[res] = '\0'; | 991 | paddr[res] = '\0'; |
984 | 992 | ||
985 | kunmap(cpage); | ||
986 | page_cache_release(cpage); | 993 | page_cache_release(cpage); |
987 | return *cookie = paddr; | 994 | set_delayed_call(done, kfree_link, paddr); |
995 | return paddr; | ||
988 | errout: | 996 | errout: |
989 | kfree(cstr.name); | 997 | kfree(cstr.name); |
990 | f2fs_fname_crypto_free_buffer(&pstr); | 998 | f2fs_fname_crypto_free_buffer(&pstr); |
991 | kunmap(cpage); | ||
992 | page_cache_release(cpage); | 999 | page_cache_release(cpage); |
993 | return ERR_PTR(res); | 1000 | return ERR_PTR(res); |
994 | } | 1001 | } |
995 | 1002 | ||
996 | const struct inode_operations f2fs_encrypted_symlink_inode_operations = { | 1003 | const struct inode_operations f2fs_encrypted_symlink_inode_operations = { |
997 | .readlink = generic_readlink, | 1004 | .readlink = generic_readlink, |
998 | .follow_link = f2fs_encrypted_follow_link, | 1005 | .get_link = f2fs_encrypted_get_link, |
999 | .put_link = kfree_put_link, | ||
1000 | .getattr = f2fs_getattr, | 1006 | .getattr = f2fs_getattr, |
1001 | .setattr = f2fs_setattr, | 1007 | .setattr = f2fs_setattr, |
1002 | .setxattr = generic_setxattr, | 1008 | .setxattr = generic_setxattr, |
@@ -1031,8 +1037,7 @@ const struct inode_operations f2fs_dir_inode_operations = { | |||
1031 | 1037 | ||
1032 | const struct inode_operations f2fs_symlink_inode_operations = { | 1038 | const struct inode_operations f2fs_symlink_inode_operations = { |
1033 | .readlink = generic_readlink, | 1039 | .readlink = generic_readlink, |
1034 | .follow_link = f2fs_follow_link, | 1040 | .get_link = f2fs_get_link, |
1035 | .put_link = page_put_link, | ||
1036 | .getattr = f2fs_getattr, | 1041 | .getattr = f2fs_getattr, |
1037 | .setattr = f2fs_setattr, | 1042 | .setattr = f2fs_setattr, |
1038 | #ifdef CONFIG_F2FS_FS_XATTR | 1043 | #ifdef CONFIG_F2FS_FS_XATTR |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index ef73ed674a27..3e2ccade61ed 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -326,6 +326,7 @@ vxfs_iget(struct super_block *sbp, ino_t ino) | |||
326 | } else if (S_ISLNK(ip->i_mode)) { | 326 | } else if (S_ISLNK(ip->i_mode)) { |
327 | if (!VXFS_ISIMMED(vip)) { | 327 | if (!VXFS_ISIMMED(vip)) { |
328 | ip->i_op = &page_symlink_inode_operations; | 328 | ip->i_op = &page_symlink_inode_operations; |
329 | inode_nohighmem(ip); | ||
329 | ip->i_mapping->a_ops = &vxfs_aops; | 330 | ip->i_mapping->a_ops = &vxfs_aops; |
330 | } else { | 331 | } else { |
331 | ip->i_op = &simple_symlink_inode_operations; | 332 | ip->i_op = &simple_symlink_inode_operations; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 5e2e08712d3b..712601f299b8 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1365,15 +1365,19 @@ 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, | ||
1370 | struct delayed_call *done) | ||
1369 | { | 1371 | { |
1370 | struct inode *inode = d_inode(dentry); | ||
1371 | struct fuse_conn *fc = get_fuse_conn(inode); | 1372 | struct fuse_conn *fc = get_fuse_conn(inode); |
1372 | FUSE_ARGS(args); | 1373 | FUSE_ARGS(args); |
1373 | char *link; | 1374 | char *link; |
1374 | ssize_t ret; | 1375 | ssize_t ret; |
1375 | 1376 | ||
1376 | link = (char *) __get_free_page(GFP_KERNEL); | 1377 | if (!dentry) |
1378 | return ERR_PTR(-ECHILD); | ||
1379 | |||
1380 | link = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1377 | if (!link) | 1381 | if (!link) |
1378 | return ERR_PTR(-ENOMEM); | 1382 | return ERR_PTR(-ENOMEM); |
1379 | 1383 | ||
@@ -1385,11 +1389,11 @@ static const char *fuse_follow_link(struct dentry *dentry, void **cookie) | |||
1385 | args.out.args[0].value = link; | 1389 | args.out.args[0].value = link; |
1386 | ret = fuse_simple_request(fc, &args); | 1390 | ret = fuse_simple_request(fc, &args); |
1387 | if (ret < 0) { | 1391 | if (ret < 0) { |
1388 | free_page((unsigned long) link); | 1392 | kfree(link); |
1389 | link = ERR_PTR(ret); | 1393 | link = ERR_PTR(ret); |
1390 | } else { | 1394 | } else { |
1391 | link[ret] = '\0'; | 1395 | link[ret] = '\0'; |
1392 | *cookie = link; | 1396 | set_delayed_call(done, kfree_link, link); |
1393 | } | 1397 | } |
1394 | fuse_invalidate_atime(inode); | 1398 | fuse_invalidate_atime(inode); |
1395 | return link; | 1399 | return link; |
@@ -1909,8 +1913,7 @@ static const struct inode_operations fuse_common_inode_operations = { | |||
1909 | 1913 | ||
1910 | static const struct inode_operations fuse_symlink_inode_operations = { | 1914 | static const struct inode_operations fuse_symlink_inode_operations = { |
1911 | .setattr = fuse_setattr, | 1915 | .setattr = fuse_setattr, |
1912 | .follow_link = fuse_follow_link, | 1916 | .get_link = fuse_get_link, |
1913 | .put_link = free_page_put_link, | ||
1914 | .readlink = generic_readlink, | 1917 | .readlink = generic_readlink, |
1915 | .getattr = fuse_getattr, | 1918 | .getattr = fuse_getattr, |
1916 | .setxattr = fuse_setxattr, | 1919 | .setxattr = fuse_setxattr, |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 063fdfcf8275..1bae189f3245 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1712,24 +1712,30 @@ 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 | * @done: destructor for return value | ||
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, | ||
1727 | struct delayed_call *done) | ||
1725 | { | 1728 | { |
1726 | struct gfs2_inode *ip = GFS2_I(d_inode(dentry)); | 1729 | struct gfs2_inode *ip = GFS2_I(inode); |
1727 | struct gfs2_holder i_gh; | 1730 | struct gfs2_holder i_gh; |
1728 | struct buffer_head *dibh; | 1731 | struct buffer_head *dibh; |
1729 | unsigned int size; | 1732 | unsigned int size; |
1730 | char *buf; | 1733 | char *buf; |
1731 | int error; | 1734 | int error; |
1732 | 1735 | ||
1736 | if (!dentry) | ||
1737 | return ERR_PTR(-ECHILD); | ||
1738 | |||
1733 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | 1739 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); |
1734 | error = gfs2_glock_nq(&i_gh); | 1740 | error = gfs2_glock_nq(&i_gh); |
1735 | if (error) { | 1741 | if (error) { |
@@ -1759,7 +1765,7 @@ static const char *gfs2_follow_link(struct dentry *dentry, void **cookie) | |||
1759 | out: | 1765 | out: |
1760 | gfs2_glock_dq_uninit(&i_gh); | 1766 | gfs2_glock_dq_uninit(&i_gh); |
1761 | if (!IS_ERR(buf)) | 1767 | if (!IS_ERR(buf)) |
1762 | *cookie = buf; | 1768 | set_delayed_call(done, kfree_link, buf); |
1763 | return buf; | 1769 | return buf; |
1764 | } | 1770 | } |
1765 | 1771 | ||
@@ -2132,8 +2138,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
2132 | 2138 | ||
2133 | const struct inode_operations gfs2_symlink_iops = { | 2139 | const struct inode_operations gfs2_symlink_iops = { |
2134 | .readlink = generic_readlink, | 2140 | .readlink = generic_readlink, |
2135 | .follow_link = gfs2_follow_link, | 2141 | .get_link = gfs2_get_link, |
2136 | .put_link = kfree_put_link, | ||
2137 | .permission = gfs2_permission, | 2142 | .permission = gfs2_permission, |
2138 | .setattr = gfs2_setattr, | 2143 | .setattr = gfs2_setattr, |
2139 | .getattr = gfs2_getattr, | 2144 | .getattr = gfs2_getattr, |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 6dd107d7421e..19b33f8151f1 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -403,6 +403,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode) | |||
403 | } else if (S_ISLNK(inode->i_mode)) { | 403 | } else if (S_ISLNK(inode->i_mode)) { |
404 | sbi->file_count++; | 404 | sbi->file_count++; |
405 | inode->i_op = &page_symlink_inode_operations; | 405 | inode->i_op = &page_symlink_inode_operations; |
406 | inode_nohighmem(inode); | ||
406 | inode->i_mapping->a_ops = &hfsplus_aops; | 407 | inode->i_mapping->a_ops = &hfsplus_aops; |
407 | hip->clump_blocks = 1; | 408 | hip->clump_blocks = 1; |
408 | } else | 409 | } else |
@@ -526,6 +527,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
526 | inode->i_mapping->a_ops = &hfsplus_aops; | 527 | inode->i_mapping->a_ops = &hfsplus_aops; |
527 | } else if (S_ISLNK(inode->i_mode)) { | 528 | } else if (S_ISLNK(inode->i_mode)) { |
528 | inode->i_op = &page_symlink_inode_operations; | 529 | inode->i_op = &page_symlink_inode_operations; |
530 | inode_nohighmem(inode); | ||
529 | inode->i_mapping->a_ops = &hfsplus_aops; | 531 | inode->i_mapping->a_ops = &hfsplus_aops; |
530 | } else { | 532 | } else { |
531 | init_special_inode(inode, inode->i_mode, | 533 | init_special_inode(inode, inode->i_mode, |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 2ac99db3750e..7db524cc85b6 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -892,9 +892,14 @@ 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, | ||
897 | struct delayed_call *done) | ||
896 | { | 898 | { |
897 | char *link = __getname(); | 899 | char *link; |
900 | if (!dentry) | ||
901 | return ERR_PTR(-ECHILD); | ||
902 | link = kmalloc(PATH_MAX, GFP_KERNEL); | ||
898 | if (link) { | 903 | if (link) { |
899 | char *path = dentry_name(dentry); | 904 | char *path = dentry_name(dentry); |
900 | int err = -ENOMEM; | 905 | int err = -ENOMEM; |
@@ -905,25 +910,20 @@ static const char *hostfs_follow_link(struct dentry *dentry, void **cookie) | |||
905 | __putname(path); | 910 | __putname(path); |
906 | } | 911 | } |
907 | if (err < 0) { | 912 | if (err < 0) { |
908 | __putname(link); | 913 | kfree(link); |
909 | return ERR_PTR(err); | 914 | return ERR_PTR(err); |
910 | } | 915 | } |
911 | } else { | 916 | } else { |
912 | return ERR_PTR(-ENOMEM); | 917 | return ERR_PTR(-ENOMEM); |
913 | } | 918 | } |
914 | 919 | ||
915 | return *cookie = link; | 920 | set_delayed_call(done, kfree_link, link); |
916 | } | 921 | return link; |
917 | |||
918 | static void hostfs_put_link(struct inode *unused, void *cookie) | ||
919 | { | ||
920 | __putname(cookie); | ||
921 | } | 922 | } |
922 | 923 | ||
923 | static const struct inode_operations hostfs_link_iops = { | 924 | static const struct inode_operations hostfs_link_iops = { |
924 | .readlink = generic_readlink, | 925 | .readlink = generic_readlink, |
925 | .follow_link = hostfs_follow_link, | 926 | .get_link = hostfs_get_link, |
926 | .put_link = hostfs_put_link, | ||
927 | }; | 927 | }; |
928 | 928 | ||
929 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | 929 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 933c73780813..1f3c6d76200b 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -77,6 +77,7 @@ void hpfs_read_inode(struct inode *i) | |||
77 | kfree(ea); | 77 | kfree(ea); |
78 | i->i_mode = S_IFLNK | 0777; | 78 | i->i_mode = S_IFLNK | 0777; |
79 | i->i_op = &page_symlink_inode_operations; | 79 | i->i_op = &page_symlink_inode_operations; |
80 | inode_nohighmem(i); | ||
80 | i->i_data.a_ops = &hpfs_symlink_aops; | 81 | i->i_data.a_ops = &hpfs_symlink_aops; |
81 | set_nlink(i, 1); | 82 | set_nlink(i, 1); |
82 | i->i_size = ea_size; | 83 | i->i_size = ea_size; |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index ae4d5a1fa4c9..506765afa1a3 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -332,6 +332,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy | |||
332 | result->i_blocks = 1; | 332 | result->i_blocks = 1; |
333 | set_nlink(result, 1); | 333 | set_nlink(result, 1); |
334 | result->i_size = strlen(symlink); | 334 | result->i_size = strlen(symlink); |
335 | inode_nohighmem(result); | ||
335 | result->i_op = &page_symlink_inode_operations; | 336 | result->i_op = &page_symlink_inode_operations; |
336 | result->i_data.a_ops = &hpfs_symlink_aops; | 337 | result->i_data.a_ops = &hpfs_symlink_aops; |
337 | 338 | ||
@@ -500,7 +501,7 @@ out: | |||
500 | 501 | ||
501 | static int hpfs_symlink_readpage(struct file *file, struct page *page) | 502 | static int hpfs_symlink_readpage(struct file *file, struct page *page) |
502 | { | 503 | { |
503 | char *link = kmap(page); | 504 | char *link = page_address(page); |
504 | struct inode *i = page->mapping->host; | 505 | struct inode *i = page->mapping->host; |
505 | struct fnode *fnode; | 506 | struct fnode *fnode; |
506 | struct buffer_head *bh; | 507 | struct buffer_head *bh; |
@@ -516,14 +517,12 @@ static int hpfs_symlink_readpage(struct file *file, struct page *page) | |||
516 | goto fail; | 517 | goto fail; |
517 | hpfs_unlock(i->i_sb); | 518 | hpfs_unlock(i->i_sb); |
518 | SetPageUptodate(page); | 519 | SetPageUptodate(page); |
519 | kunmap(page); | ||
520 | unlock_page(page); | 520 | unlock_page(page); |
521 | return 0; | 521 | return 0; |
522 | 522 | ||
523 | fail: | 523 | fail: |
524 | hpfs_unlock(i->i_sb); | 524 | hpfs_unlock(i->i_sb); |
525 | SetPageError(page); | 525 | SetPageError(page); |
526 | kunmap(page); | ||
527 | unlock_page(page); | 526 | unlock_page(page); |
528 | return err; | 527 | return err; |
529 | } | 528 | } |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index de4bdfac0cec..d8f51ee8126b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -760,6 +760,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, | |||
760 | break; | 760 | break; |
761 | case S_IFLNK: | 761 | case S_IFLNK: |
762 | inode->i_op = &page_symlink_inode_operations; | 762 | inode->i_op = &page_symlink_inode_operations; |
763 | inode_nohighmem(inode); | ||
763 | break; | 764 | break; |
764 | } | 765 | } |
765 | lockdep_annotate_inode_mutex_key(inode); | 766 | lockdep_annotate_inode_mutex_key(inode); |
diff --git a/fs/inode.c b/fs/inode.c index 1be5f9003eb3..5bb85a064ce7 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -2028,3 +2028,9 @@ void inode_set_flags(struct inode *inode, unsigned int flags, | |||
2028 | new_flags) != old_flags)); | 2028 | new_flags) != old_flags)); |
2029 | } | 2029 | } |
2030 | EXPORT_SYMBOL(inode_set_flags); | 2030 | EXPORT_SYMBOL(inode_set_flags); |
2031 | |||
2032 | void inode_nohighmem(struct inode *inode) | ||
2033 | { | ||
2034 | mapping_set_gfp_mask(inode->i_mapping, GFP_USER); | ||
2035 | } | ||
2036 | EXPORT_SYMBOL(inode_nohighmem); | ||
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index d67a16f2a45d..61abdc4920da 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -1417,6 +1417,7 @@ static int isofs_read_inode(struct inode *inode, int relocated) | |||
1417 | inode->i_fop = &isofs_dir_operations; | 1417 | inode->i_fop = &isofs_dir_operations; |
1418 | } else if (S_ISLNK(inode->i_mode)) { | 1418 | } else if (S_ISLNK(inode->i_mode)) { |
1419 | inode->i_op = &page_symlink_inode_operations; | 1419 | inode->i_op = &page_symlink_inode_operations; |
1420 | inode_nohighmem(inode); | ||
1420 | inode->i_data.a_ops = &isofs_symlink_aops; | 1421 | inode->i_data.a_ops = &isofs_symlink_aops; |
1421 | } else | 1422 | } else |
1422 | /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ | 1423 | /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ |
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 735d7522a3a9..5384ceb35b1c 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
@@ -687,7 +687,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) | |||
687 | struct inode *inode = page->mapping->host; | 687 | struct inode *inode = page->mapping->host; |
688 | struct iso_inode_info *ei = ISOFS_I(inode); | 688 | struct iso_inode_info *ei = ISOFS_I(inode); |
689 | struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); | 689 | struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); |
690 | char *link = kmap(page); | 690 | char *link = page_address(page); |
691 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); | 691 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); |
692 | struct buffer_head *bh; | 692 | struct buffer_head *bh; |
693 | char *rpnt = link; | 693 | char *rpnt = link; |
@@ -774,7 +774,6 @@ repeat: | |||
774 | brelse(bh); | 774 | brelse(bh); |
775 | *rpnt = '\0'; | 775 | *rpnt = '\0'; |
776 | SetPageUptodate(page); | 776 | SetPageUptodate(page); |
777 | kunmap(page); | ||
778 | unlock_page(page); | 777 | unlock_page(page); |
779 | return 0; | 778 | return 0; |
780 | 779 | ||
@@ -791,7 +790,6 @@ fail: | |||
791 | brelse(bh); | 790 | brelse(bh); |
792 | error: | 791 | error: |
793 | SetPageError(page); | 792 | SetPageError(page); |
794 | kunmap(page); | ||
795 | unlock_page(page); | 793 | unlock_page(page); |
796 | return -EIO; | 794 | return -EIO; |
797 | } | 795 | } |
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/inode.c b/fs/jfs/inode.c index 41aa3ca6a6a4..9d9bae63ae2a 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -60,6 +60,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino) | |||
60 | } else if (S_ISLNK(inode->i_mode)) { | 60 | } else if (S_ISLNK(inode->i_mode)) { |
61 | if (inode->i_size >= IDATASIZE) { | 61 | if (inode->i_size >= IDATASIZE) { |
62 | inode->i_op = &page_symlink_inode_operations; | 62 | inode->i_op = &page_symlink_inode_operations; |
63 | inode_nohighmem(inode); | ||
63 | inode->i_mapping->a_ops = &jfs_aops; | 64 | inode->i_mapping->a_ops = &jfs_aops; |
64 | } else { | 65 | } else { |
65 | inode->i_op = &jfs_fast_symlink_inode_operations; | 66 | inode->i_op = &jfs_fast_symlink_inode_operations; |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9d7551f5c32a..701f89370de7 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -983,6 +983,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
983 | jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); | 983 | jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); |
984 | 984 | ||
985 | ip->i_op = &jfs_symlink_inode_operations; | 985 | ip->i_op = &jfs_symlink_inode_operations; |
986 | inode_nohighmem(ip); | ||
986 | ip->i_mapping->a_ops = &jfs_aops; | 987 | ip->i_mapping->a_ops = &jfs_aops; |
987 | 988 | ||
988 | /* | 989 | /* |
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 5929e2363cb8..f8db4fde0b0b 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,8 +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, | ||
38 | .setattr = jfs_setattr, | 37 | .setattr = jfs_setattr, |
39 | .setxattr = jfs_setxattr, | 38 | .setxattr = jfs_setxattr, |
40 | .getxattr = jfs_getxattr, | 39 | .getxattr = jfs_getxattr, |
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index db272528ab5b..117b8b3416f9 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c | |||
@@ -112,18 +112,25 @@ 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, | ||
117 | struct delayed_call *done) | ||
116 | { | 118 | { |
117 | int error = -ENOMEM; | 119 | char *body; |
118 | unsigned long page = get_zeroed_page(GFP_KERNEL); | 120 | int error; |
119 | if (!page) | 121 | |
122 | if (!dentry) | ||
123 | return ERR_PTR(-ECHILD); | ||
124 | body = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
125 | if (!body) | ||
120 | return ERR_PTR(-ENOMEM); | 126 | return ERR_PTR(-ENOMEM); |
121 | error = kernfs_getlink(dentry, (char *)page); | 127 | error = kernfs_getlink(dentry, body); |
122 | if (unlikely(error < 0)) { | 128 | if (unlikely(error < 0)) { |
123 | free_page((unsigned long)page); | 129 | kfree(body); |
124 | return ERR_PTR(error); | 130 | return ERR_PTR(error); |
125 | } | 131 | } |
126 | return *cookie = (char *)page; | 132 | set_delayed_call(done, kfree_link, body); |
133 | return body; | ||
127 | } | 134 | } |
128 | 135 | ||
129 | const struct inode_operations kernfs_symlink_iops = { | 136 | const struct inode_operations kernfs_symlink_iops = { |
@@ -132,8 +139,7 @@ const struct inode_operations kernfs_symlink_iops = { | |||
132 | .getxattr = kernfs_iop_getxattr, | 139 | .getxattr = kernfs_iop_getxattr, |
133 | .listxattr = kernfs_iop_listxattr, | 140 | .listxattr = kernfs_iop_listxattr, |
134 | .readlink = generic_readlink, | 141 | .readlink = generic_readlink, |
135 | .follow_link = kernfs_iop_follow_link, | 142 | .get_link = kernfs_iop_get_link, |
136 | .put_link = free_page_put_link, | ||
137 | .setattr = kernfs_iop_setattr, | 143 | .setattr = kernfs_iop_setattr, |
138 | .getattr = kernfs_iop_getattr, | 144 | .getattr = kernfs_iop_getattr, |
139 | .permission = kernfs_iop_permission, | 145 | .permission = kernfs_iop_permission, |
diff --git a/fs/libfs.c b/fs/libfs.c index c7cbfb092e94..01491299f348 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -1019,17 +1019,12 @@ int noop_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
1019 | } | 1019 | } |
1020 | EXPORT_SYMBOL(noop_fsync); | 1020 | EXPORT_SYMBOL(noop_fsync); |
1021 | 1021 | ||
1022 | void kfree_put_link(struct inode *unused, void *cookie) | 1022 | /* Because kfree isn't assignment-compatible with void(void*) ;-/ */ |
1023 | void kfree_link(void *p) | ||
1023 | { | 1024 | { |
1024 | kfree(cookie); | 1025 | kfree(p); |
1025 | } | 1026 | } |
1026 | EXPORT_SYMBOL(kfree_put_link); | 1027 | EXPORT_SYMBOL(kfree_link); |
1027 | |||
1028 | void free_page_put_link(struct inode *unused, void *cookie) | ||
1029 | { | ||
1030 | free_page((unsigned long) cookie); | ||
1031 | } | ||
1032 | EXPORT_SYMBOL(free_page_put_link); | ||
1033 | 1028 | ||
1034 | /* | 1029 | /* |
1035 | * nop .set_page_dirty method so that people can use .page_mkwrite on | 1030 | * nop .set_page_dirty method so that people can use .page_mkwrite on |
@@ -1092,14 +1087,15 @@ simple_nosetlease(struct file *filp, long arg, struct file_lock **flp, | |||
1092 | } | 1087 | } |
1093 | EXPORT_SYMBOL(simple_nosetlease); | 1088 | EXPORT_SYMBOL(simple_nosetlease); |
1094 | 1089 | ||
1095 | const char *simple_follow_link(struct dentry *dentry, void **cookie) | 1090 | const char *simple_get_link(struct dentry *dentry, struct inode *inode, |
1091 | struct delayed_call *done) | ||
1096 | { | 1092 | { |
1097 | return d_inode(dentry)->i_link; | 1093 | return inode->i_link; |
1098 | } | 1094 | } |
1099 | EXPORT_SYMBOL(simple_follow_link); | 1095 | EXPORT_SYMBOL(simple_get_link); |
1100 | 1096 | ||
1101 | const struct inode_operations simple_symlink_inode_operations = { | 1097 | const struct inode_operations simple_symlink_inode_operations = { |
1102 | .follow_link = simple_follow_link, | 1098 | .get_link = simple_get_link, |
1103 | .readlink = generic_readlink | 1099 | .readlink = generic_readlink |
1104 | }; | 1100 | }; |
1105 | EXPORT_SYMBOL(simple_symlink_inode_operations); | 1101 | EXPORT_SYMBOL(simple_symlink_inode_operations); |
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index f9b45d46d4c4..542468e9bfb4 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -528,7 +528,8 @@ static int logfs_symlink(struct inode *dir, struct dentry *dentry, | |||
528 | if (IS_ERR(inode)) | 528 | if (IS_ERR(inode)) |
529 | return PTR_ERR(inode); | 529 | return PTR_ERR(inode); |
530 | 530 | ||
531 | inode->i_op = &logfs_symlink_iops; | 531 | inode->i_op = &page_symlink_inode_operations; |
532 | inode_nohighmem(inode); | ||
532 | inode->i_mapping->a_ops = &logfs_reg_aops; | 533 | inode->i_mapping->a_ops = &logfs_reg_aops; |
533 | 534 | ||
534 | return __logfs_create(dir, dentry, inode, target, destlen); | 535 | return __logfs_create(dir, dentry, inode, target, destlen); |
@@ -776,12 +777,6 @@ fail: | |||
776 | return -EIO; | 777 | return -EIO; |
777 | } | 778 | } |
778 | 779 | ||
779 | const struct inode_operations logfs_symlink_iops = { | ||
780 | .readlink = generic_readlink, | ||
781 | .follow_link = page_follow_link_light, | ||
782 | .put_link = page_put_link, | ||
783 | }; | ||
784 | |||
785 | const struct inode_operations logfs_dir_iops = { | 780 | const struct inode_operations logfs_dir_iops = { |
786 | .create = logfs_create, | 781 | .create = logfs_create, |
787 | .link = logfs_link, | 782 | .link = logfs_link, |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index af49e2d6941a..0fce46d62b9c 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
@@ -64,7 +64,8 @@ static void logfs_inode_setops(struct inode *inode) | |||
64 | inode->i_mapping->a_ops = &logfs_reg_aops; | 64 | inode->i_mapping->a_ops = &logfs_reg_aops; |
65 | break; | 65 | break; |
66 | case S_IFLNK: | 66 | case S_IFLNK: |
67 | inode->i_op = &logfs_symlink_iops; | 67 | inode->i_op = &page_symlink_inode_operations; |
68 | inode_nohighmem(inode); | ||
68 | inode->i_mapping->a_ops = &logfs_reg_aops; | 69 | inode->i_mapping->a_ops = &logfs_reg_aops; |
69 | break; | 70 | break; |
70 | case S_IFSOCK: /* fall through */ | 71 | case S_IFSOCK: /* fall through */ |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 5f0937609465..209a26d84c38 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -495,7 +495,6 @@ static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) | |||
495 | #endif | 495 | #endif |
496 | 496 | ||
497 | /* dir.c */ | 497 | /* dir.c */ |
498 | extern const struct inode_operations logfs_symlink_iops; | ||
499 | extern const struct inode_operations logfs_dir_iops; | 498 | extern const struct inode_operations logfs_dir_iops; |
500 | extern const struct file_operations logfs_dir_fops; | 499 | extern const struct file_operations logfs_dir_fops; |
501 | int logfs_replay_journal(struct super_block *sb); | 500 | int logfs_replay_journal(struct super_block *sb); |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 086cd0a61e80..cb1789ca1ee6 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -435,8 +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, | ||
440 | .getattr = minix_getattr, | 439 | .getattr = minix_getattr, |
441 | }; | 440 | }; |
442 | 441 | ||
@@ -452,6 +451,7 @@ void minix_set_inode(struct inode *inode, dev_t rdev) | |||
452 | inode->i_mapping->a_ops = &minix_aops; | 451 | inode->i_mapping->a_ops = &minix_aops; |
453 | } else if (S_ISLNK(inode->i_mode)) { | 452 | } else if (S_ISLNK(inode->i_mode)) { |
454 | inode->i_op = &minix_symlink_inode_operations; | 453 | inode->i_op = &minix_symlink_inode_operations; |
454 | inode_nohighmem(inode); | ||
455 | inode->i_mapping->a_ops = &minix_aops; | 455 | inode->i_mapping->a_ops = &minix_aops; |
456 | } else | 456 | } else |
457 | init_special_inode(inode, inode->i_mode, rdev); | 457 | init_special_inode(inode, inode->i_mode, rdev); |
diff --git a/fs/namei.c b/fs/namei.c index 0c3974cd3ecd..3c909aebef70 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -505,13 +505,13 @@ struct nameidata { | |||
505 | int total_link_count; | 505 | int total_link_count; |
506 | struct saved { | 506 | struct saved { |
507 | struct path link; | 507 | struct path link; |
508 | void *cookie; | 508 | struct delayed_call done; |
509 | const char *name; | 509 | const char *name; |
510 | struct inode *inode; | ||
511 | unsigned seq; | 510 | unsigned seq; |
512 | } *stack, internal[EMBEDDED_LEVELS]; | 511 | } *stack, internal[EMBEDDED_LEVELS]; |
513 | struct filename *name; | 512 | struct filename *name; |
514 | struct nameidata *saved; | 513 | struct nameidata *saved; |
514 | struct inode *link_inode; | ||
515 | unsigned root_seq; | 515 | unsigned root_seq; |
516 | int dfd; | 516 | int dfd; |
517 | }; | 517 | }; |
@@ -592,11 +592,8 @@ static void drop_links(struct nameidata *nd) | |||
592 | int i = nd->depth; | 592 | int i = nd->depth; |
593 | while (i--) { | 593 | while (i--) { |
594 | struct saved *last = nd->stack + i; | 594 | struct saved *last = nd->stack + i; |
595 | struct inode *inode = last->inode; | 595 | do_delayed_call(&last->done); |
596 | if (last->cookie && inode->i_op->put_link) { | 596 | clear_delayed_call(&last->done); |
597 | inode->i_op->put_link(inode, last->cookie); | ||
598 | last->cookie = NULL; | ||
599 | } | ||
600 | } | 597 | } |
601 | } | 598 | } |
602 | 599 | ||
@@ -842,7 +839,7 @@ static inline void path_to_nameidata(const struct path *path, | |||
842 | } | 839 | } |
843 | 840 | ||
844 | /* | 841 | /* |
845 | * Helper to directly jump to a known parsed path from ->follow_link, | 842 | * Helper to directly jump to a known parsed path from ->get_link, |
846 | * caller must have taken a reference to path beforehand. | 843 | * caller must have taken a reference to path beforehand. |
847 | */ | 844 | */ |
848 | void nd_jump_link(struct path *path) | 845 | void nd_jump_link(struct path *path) |
@@ -858,9 +855,7 @@ void nd_jump_link(struct path *path) | |||
858 | static inline void put_link(struct nameidata *nd) | 855 | static inline void put_link(struct nameidata *nd) |
859 | { | 856 | { |
860 | struct saved *last = nd->stack + --nd->depth; | 857 | struct saved *last = nd->stack + --nd->depth; |
861 | struct inode *inode = last->inode; | 858 | do_delayed_call(&last->done); |
862 | if (last->cookie && inode->i_op->put_link) | ||
863 | inode->i_op->put_link(inode, last->cookie); | ||
864 | if (!(nd->flags & LOOKUP_RCU)) | 859 | if (!(nd->flags & LOOKUP_RCU)) |
865 | path_put(&last->link); | 860 | path_put(&last->link); |
866 | } | 861 | } |
@@ -892,7 +887,7 @@ static inline int may_follow_link(struct nameidata *nd) | |||
892 | return 0; | 887 | return 0; |
893 | 888 | ||
894 | /* Allowed if owner and follower match. */ | 889 | /* Allowed if owner and follower match. */ |
895 | inode = nd->stack[0].inode; | 890 | inode = nd->link_inode; |
896 | if (uid_eq(current_cred()->fsuid, inode->i_uid)) | 891 | if (uid_eq(current_cred()->fsuid, inode->i_uid)) |
897 | return 0; | 892 | return 0; |
898 | 893 | ||
@@ -983,7 +978,7 @@ const char *get_link(struct nameidata *nd) | |||
983 | { | 978 | { |
984 | struct saved *last = nd->stack + nd->depth - 1; | 979 | struct saved *last = nd->stack + nd->depth - 1; |
985 | struct dentry *dentry = last->link.dentry; | 980 | struct dentry *dentry = last->link.dentry; |
986 | struct inode *inode = last->inode; | 981 | struct inode *inode = nd->link_inode; |
987 | int error; | 982 | int error; |
988 | const char *res; | 983 | const char *res; |
989 | 984 | ||
@@ -1004,15 +999,21 @@ const char *get_link(struct nameidata *nd) | |||
1004 | nd->last_type = LAST_BIND; | 999 | nd->last_type = LAST_BIND; |
1005 | res = inode->i_link; | 1000 | res = inode->i_link; |
1006 | if (!res) { | 1001 | if (!res) { |
1002 | const char * (*get)(struct dentry *, struct inode *, | ||
1003 | struct delayed_call *); | ||
1004 | get = inode->i_op->get_link; | ||
1007 | if (nd->flags & LOOKUP_RCU) { | 1005 | if (nd->flags & LOOKUP_RCU) { |
1008 | if (unlikely(unlazy_walk(nd, NULL, 0))) | 1006 | res = get(NULL, inode, &last->done); |
1009 | return ERR_PTR(-ECHILD); | 1007 | if (res == ERR_PTR(-ECHILD)) { |
1008 | if (unlikely(unlazy_walk(nd, NULL, 0))) | ||
1009 | return ERR_PTR(-ECHILD); | ||
1010 | res = get(dentry, inode, &last->done); | ||
1011 | } | ||
1012 | } else { | ||
1013 | res = get(dentry, inode, &last->done); | ||
1010 | } | 1014 | } |
1011 | res = inode->i_op->follow_link(dentry, &last->cookie); | 1015 | if (IS_ERR_OR_NULL(res)) |
1012 | if (IS_ERR_OR_NULL(res)) { | ||
1013 | last->cookie = NULL; | ||
1014 | return res; | 1016 | return res; |
1015 | } | ||
1016 | } | 1017 | } |
1017 | if (*res == '/') { | 1018 | if (*res == '/') { |
1018 | if (nd->flags & LOOKUP_RCU) { | 1019 | if (nd->flags & LOOKUP_RCU) { |
@@ -1691,8 +1692,8 @@ static int pick_link(struct nameidata *nd, struct path *link, | |||
1691 | 1692 | ||
1692 | last = nd->stack + nd->depth++; | 1693 | last = nd->stack + nd->depth++; |
1693 | last->link = *link; | 1694 | last->link = *link; |
1694 | last->cookie = NULL; | 1695 | clear_delayed_call(&last->done); |
1695 | last->inode = inode; | 1696 | nd->link_inode = inode; |
1696 | last->seq = seq; | 1697 | last->seq = seq; |
1697 | return 1; | 1698 | return 1; |
1698 | } | 1699 | } |
@@ -4495,72 +4496,73 @@ EXPORT_SYMBOL(readlink_copy); | |||
4495 | 4496 | ||
4496 | /* | 4497 | /* |
4497 | * A helper for ->readlink(). This should be used *ONLY* for symlinks that | 4498 | * 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 | 4499 | * have ->get_link() not calling nd_jump_link(). Using (or not using) it |
4499 | * using) it for any given inode is up to filesystem. | 4500 | * for any given inode is up to filesystem. |
4500 | */ | 4501 | */ |
4501 | int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 4502 | int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
4502 | { | 4503 | { |
4503 | void *cookie; | 4504 | DEFINE_DELAYED_CALL(done); |
4504 | struct inode *inode = d_inode(dentry); | 4505 | struct inode *inode = d_inode(dentry); |
4505 | const char *link = inode->i_link; | 4506 | const char *link = inode->i_link; |
4506 | int res; | 4507 | int res; |
4507 | 4508 | ||
4508 | if (!link) { | 4509 | if (!link) { |
4509 | link = inode->i_op->follow_link(dentry, &cookie); | 4510 | link = inode->i_op->get_link(dentry, inode, &done); |
4510 | if (IS_ERR(link)) | 4511 | if (IS_ERR(link)) |
4511 | return PTR_ERR(link); | 4512 | return PTR_ERR(link); |
4512 | } | 4513 | } |
4513 | res = readlink_copy(buffer, buflen, link); | 4514 | res = readlink_copy(buffer, buflen, link); |
4514 | if (inode->i_op->put_link) | 4515 | do_delayed_call(&done); |
4515 | inode->i_op->put_link(inode, cookie); | ||
4516 | return res; | 4516 | return res; |
4517 | } | 4517 | } |
4518 | EXPORT_SYMBOL(generic_readlink); | 4518 | EXPORT_SYMBOL(generic_readlink); |
4519 | 4519 | ||
4520 | /* get the link contents into pagecache */ | 4520 | /* get the link contents into pagecache */ |
4521 | static char *page_getlink(struct dentry * dentry, struct page **ppage) | 4521 | const char *page_get_link(struct dentry *dentry, struct inode *inode, |
4522 | struct delayed_call *callback) | ||
4522 | { | 4523 | { |
4523 | char *kaddr; | 4524 | char *kaddr; |
4524 | struct page *page; | 4525 | struct page *page; |
4525 | struct address_space *mapping = dentry->d_inode->i_mapping; | 4526 | struct address_space *mapping = inode->i_mapping; |
4526 | page = read_mapping_page(mapping, 0, NULL); | 4527 | |
4527 | if (IS_ERR(page)) | 4528 | if (!dentry) { |
4528 | return (char*)page; | 4529 | page = find_get_page(mapping, 0); |
4529 | *ppage = page; | 4530 | if (!page) |
4530 | kaddr = kmap(page); | 4531 | return ERR_PTR(-ECHILD); |
4531 | nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1); | 4532 | if (!PageUptodate(page)) { |
4533 | put_page(page); | ||
4534 | return ERR_PTR(-ECHILD); | ||
4535 | } | ||
4536 | } else { | ||
4537 | page = read_mapping_page(mapping, 0, NULL); | ||
4538 | if (IS_ERR(page)) | ||
4539 | return (char*)page; | ||
4540 | } | ||
4541 | set_delayed_call(callback, page_put_link, page); | ||
4542 | BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM); | ||
4543 | kaddr = page_address(page); | ||
4544 | nd_terminate_link(kaddr, inode->i_size, PAGE_SIZE - 1); | ||
4532 | return kaddr; | 4545 | return kaddr; |
4533 | } | 4546 | } |
4534 | 4547 | ||
4535 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 4548 | EXPORT_SYMBOL(page_get_link); |
4536 | { | ||
4537 | struct page *page = NULL; | ||
4538 | int res = readlink_copy(buffer, buflen, page_getlink(dentry, &page)); | ||
4539 | if (page) { | ||
4540 | kunmap(page); | ||
4541 | page_cache_release(page); | ||
4542 | } | ||
4543 | return res; | ||
4544 | } | ||
4545 | EXPORT_SYMBOL(page_readlink); | ||
4546 | 4549 | ||
4547 | const char *page_follow_link_light(struct dentry *dentry, void **cookie) | 4550 | void page_put_link(void *arg) |
4548 | { | 4551 | { |
4549 | struct page *page = NULL; | 4552 | put_page(arg); |
4550 | char *res = page_getlink(dentry, &page); | ||
4551 | if (!IS_ERR(res)) | ||
4552 | *cookie = page; | ||
4553 | return res; | ||
4554 | } | 4553 | } |
4555 | EXPORT_SYMBOL(page_follow_link_light); | 4554 | EXPORT_SYMBOL(page_put_link); |
4556 | 4555 | ||
4557 | void page_put_link(struct inode *unused, void *cookie) | 4556 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
4558 | { | 4557 | { |
4559 | struct page *page = cookie; | 4558 | DEFINE_DELAYED_CALL(done); |
4560 | kunmap(page); | 4559 | int res = readlink_copy(buffer, buflen, |
4561 | page_cache_release(page); | 4560 | page_get_link(dentry, d_inode(dentry), |
4561 | &done)); | ||
4562 | do_delayed_call(&done); | ||
4563 | return res; | ||
4562 | } | 4564 | } |
4563 | EXPORT_SYMBOL(page_put_link); | 4565 | EXPORT_SYMBOL(page_readlink); |
4564 | 4566 | ||
4565 | /* | 4567 | /* |
4566 | * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS | 4568 | * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS |
@@ -4571,7 +4573,6 @@ int __page_symlink(struct inode *inode, const char *symname, int len, int nofs) | |||
4571 | struct page *page; | 4573 | struct page *page; |
4572 | void *fsdata; | 4574 | void *fsdata; |
4573 | int err; | 4575 | int err; |
4574 | char *kaddr; | ||
4575 | unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE; | 4576 | unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE; |
4576 | if (nofs) | 4577 | if (nofs) |
4577 | flags |= AOP_FLAG_NOFS; | 4578 | flags |= AOP_FLAG_NOFS; |
@@ -4582,9 +4583,7 @@ retry: | |||
4582 | if (err) | 4583 | if (err) |
4583 | goto fail; | 4584 | goto fail; |
4584 | 4585 | ||
4585 | kaddr = kmap_atomic(page); | 4586 | memcpy(page_address(page), symname, len-1); |
4586 | memcpy(kaddr, symname, len-1); | ||
4587 | kunmap_atomic(kaddr); | ||
4588 | 4587 | ||
4589 | err = pagecache_write_end(NULL, mapping, 0, len-1, len-1, | 4588 | err = pagecache_write_end(NULL, mapping, 0, len-1, len-1, |
4590 | page, fsdata); | 4589 | page, fsdata); |
@@ -4609,7 +4608,6 @@ EXPORT_SYMBOL(page_symlink); | |||
4609 | 4608 | ||
4610 | const struct inode_operations page_symlink_inode_operations = { | 4609 | const struct inode_operations page_symlink_inode_operations = { |
4611 | .readlink = generic_readlink, | 4610 | .readlink = generic_readlink, |
4612 | .follow_link = page_follow_link_light, | 4611 | .get_link = page_get_link, |
4613 | .put_link = page_put_link, | ||
4614 | }; | 4612 | }; |
4615 | EXPORT_SYMBOL(page_symlink_inode_operations); | 4613 | EXPORT_SYMBOL(page_symlink_inode_operations); |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 9605a2f63549..ce1eb3f9dfe8 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -244,8 +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, | ||
249 | .setattr = ncp_notify_change, | 248 | .setattr = ncp_notify_change, |
250 | }; | 249 | }; |
251 | #endif | 250 | #endif |
@@ -283,6 +282,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info) | |||
283 | #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) | 282 | #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) |
284 | } else if (S_ISLNK(inode->i_mode)) { | 283 | } else if (S_ISLNK(inode->i_mode)) { |
285 | inode->i_op = &ncp_symlink_inode_operations; | 284 | inode->i_op = &ncp_symlink_inode_operations; |
285 | inode_nohighmem(inode); | ||
286 | inode->i_data.a_ops = &ncp_symlink_aops; | 286 | inode->i_data.a_ops = &ncp_symlink_aops; |
287 | #endif | 287 | #endif |
288 | } else { | 288 | } else { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c7e8b87da5b2..bdb4dc7b4ecd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -408,9 +408,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
408 | inode->i_fop = NULL; | 408 | inode->i_fop = NULL; |
409 | inode->i_flags |= S_AUTOMOUNT; | 409 | inode->i_flags |= S_AUTOMOUNT; |
410 | } | 410 | } |
411 | } else if (S_ISLNK(inode->i_mode)) | 411 | } else if (S_ISLNK(inode->i_mode)) { |
412 | inode->i_op = &nfs_symlink_inode_operations; | 412 | inode->i_op = &nfs_symlink_inode_operations; |
413 | else | 413 | inode_nohighmem(inode); |
414 | } else | ||
414 | init_special_inode(inode, inode->i_mode, fattr->rdev); | 415 | init_special_inode(inode, inode->i_mode, fattr->rdev); |
415 | 416 | ||
416 | memset(&inode->i_atime, 0, sizeof(inode->i_atime)); | 417 | memset(&inode->i_atime, 0, sizeof(inode->i_atime)); |
@@ -1086,6 +1087,27 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode) | |||
1086 | || NFS_STALE(inode); | 1087 | || NFS_STALE(inode); |
1087 | } | 1088 | } |
1088 | 1089 | ||
1090 | int nfs_revalidate_mapping_rcu(struct inode *inode) | ||
1091 | { | ||
1092 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1093 | unsigned long *bitlock = &nfsi->flags; | ||
1094 | int ret = 0; | ||
1095 | |||
1096 | if (IS_SWAPFILE(inode)) | ||
1097 | goto out; | ||
1098 | if (nfs_mapping_need_revalidate_inode(inode)) { | ||
1099 | ret = -ECHILD; | ||
1100 | goto out; | ||
1101 | } | ||
1102 | spin_lock(&inode->i_lock); | ||
1103 | if (test_bit(NFS_INO_INVALIDATING, bitlock) || | ||
1104 | (nfsi->cache_validity & NFS_INO_INVALID_DATA)) | ||
1105 | ret = -ECHILD; | ||
1106 | spin_unlock(&inode->i_lock); | ||
1107 | out: | ||
1108 | return ret; | ||
1109 | } | ||
1110 | |||
1089 | /** | 1111 | /** |
1090 | * __nfs_revalidate_mapping - Revalidate the pagecache | 1112 | * __nfs_revalidate_mapping - Revalidate the pagecache |
1091 | * @inode - pointer to host inode | 1113 | * @inode - pointer to host inode |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index b6de433da5db..4fe3eead3868 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -42,21 +42,35 @@ 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, | ||
47 | struct delayed_call *done) | ||
46 | { | 48 | { |
47 | struct inode *inode = d_inode(dentry); | ||
48 | struct page *page; | 49 | struct page *page; |
49 | void *err; | 50 | void *err; |
50 | 51 | ||
51 | err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); | 52 | if (!dentry) { |
52 | if (err) | 53 | err = ERR_PTR(nfs_revalidate_mapping_rcu(inode)); |
53 | return err; | 54 | if (err) |
54 | page = read_cache_page(&inode->i_data, 0, | 55 | return err; |
55 | (filler_t *)nfs_symlink_filler, inode); | 56 | page = find_get_page(inode->i_mapping, 0); |
56 | if (IS_ERR(page)) | 57 | if (!page) |
57 | return ERR_CAST(page); | 58 | return ERR_PTR(-ECHILD); |
58 | *cookie = page; | 59 | if (!PageUptodate(page)) { |
59 | return kmap(page); | 60 | put_page(page); |
61 | return ERR_PTR(-ECHILD); | ||
62 | } | ||
63 | } else { | ||
64 | err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); | ||
65 | if (err) | ||
66 | return err; | ||
67 | page = read_cache_page(&inode->i_data, 0, | ||
68 | (filler_t *)nfs_symlink_filler, inode); | ||
69 | if (IS_ERR(page)) | ||
70 | return ERR_CAST(page); | ||
71 | } | ||
72 | set_delayed_call(done, page_put_link, page); | ||
73 | return page_address(page); | ||
60 | } | 74 | } |
61 | 75 | ||
62 | /* | 76 | /* |
@@ -64,8 +78,7 @@ static const char *nfs_follow_link(struct dentry *dentry, void **cookie) | |||
64 | */ | 78 | */ |
65 | const struct inode_operations nfs_symlink_inode_operations = { | 79 | const struct inode_operations nfs_symlink_inode_operations = { |
66 | .readlink = generic_readlink, | 80 | .readlink = generic_readlink, |
67 | .follow_link = nfs_follow_link, | 81 | .get_link = nfs_get_link, |
68 | .put_link = page_put_link, | ||
69 | .getattr = nfs_getattr, | 82 | .getattr = nfs_getattr, |
70 | .setattr = nfs_setattr, | 83 | .setattr = nfs_setattr, |
71 | }; | 84 | }; |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index ac2f64943ff4..10b22527a617 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -510,6 +510,7 @@ static int __nilfs_read_inode(struct super_block *sb, | |||
510 | inode->i_mapping->a_ops = &nilfs_aops; | 510 | inode->i_mapping->a_ops = &nilfs_aops; |
511 | } else if (S_ISLNK(inode->i_mode)) { | 511 | } else if (S_ISLNK(inode->i_mode)) { |
512 | inode->i_op = &nilfs_symlink_inode_operations; | 512 | inode->i_op = &nilfs_symlink_inode_operations; |
513 | inode_nohighmem(inode); | ||
513 | inode->i_mapping->a_ops = &nilfs_aops; | 514 | inode->i_mapping->a_ops = &nilfs_aops; |
514 | } else { | 515 | } else { |
515 | inode->i_op = &nilfs_special_inode_operations; | 516 | inode->i_op = &nilfs_special_inode_operations; |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index c9a1a491aa91..7ccdb961eea9 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -161,6 +161,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry, | |||
161 | 161 | ||
162 | /* slow symlink */ | 162 | /* slow symlink */ |
163 | inode->i_op = &nilfs_symlink_inode_operations; | 163 | inode->i_op = &nilfs_symlink_inode_operations; |
164 | inode_nohighmem(inode); | ||
164 | inode->i_mapping->a_ops = &nilfs_aops; | 165 | inode->i_mapping->a_ops = &nilfs_aops; |
165 | err = page_symlink(inode, symname, l); | 166 | err = page_symlink(inode, symname, l); |
166 | if (err) | 167 | if (err) |
@@ -568,8 +569,7 @@ const struct inode_operations nilfs_special_inode_operations = { | |||
568 | 569 | ||
569 | const struct inode_operations nilfs_symlink_inode_operations = { | 570 | const struct inode_operations nilfs_symlink_inode_operations = { |
570 | .readlink = generic_readlink, | 571 | .readlink = generic_readlink, |
571 | .follow_link = page_follow_link_light, | 572 | .get_link = page_get_link, |
572 | .put_link = page_put_link, | ||
573 | .permission = nilfs_permission, | 573 | .permission = nilfs_permission, |
574 | }; | 574 | }; |
575 | 575 | ||
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 8f87e05ee25d..97a563bab9a8 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -361,6 +361,7 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
361 | break; | 361 | break; |
362 | case S_IFLNK: | 362 | case S_IFLNK: |
363 | inode->i_op = &ocfs2_symlink_inode_operations; | 363 | inode->i_op = &ocfs2_symlink_inode_operations; |
364 | inode_nohighmem(inode); | ||
364 | i_size_write(inode, le64_to_cpu(fe->i_size)); | 365 | i_size_write(inode, le64_to_cpu(fe->i_size)); |
365 | break; | 366 | break; |
366 | default: | 367 | default: |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 3123408da935..afb81eae2c18 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -1958,6 +1958,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1958 | inode->i_rdev = 0; | 1958 | inode->i_rdev = 0; |
1959 | newsize = l - 1; | 1959 | newsize = l - 1; |
1960 | inode->i_op = &ocfs2_symlink_inode_operations; | 1960 | inode->i_op = &ocfs2_symlink_inode_operations; |
1961 | inode_nohighmem(inode); | ||
1961 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1962 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1962 | u32 offset = 0; | 1963 | u32 offset = 0; |
1963 | 1964 | ||
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 66edce7ecfd7..6c2a3e3c521c 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -88,8 +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, | ||
93 | .getattr = ocfs2_getattr, | 92 | .getattr = ocfs2_getattr, |
94 | .setattr = ocfs2_setattr, | 93 | .setattr = ocfs2_setattr, |
95 | .setxattr = generic_setxattr, | 94 | .setxattr = generic_setxattr, |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 4060ffde8722..964a60fa7afc 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -131,57 +131,23 @@ out_dput: | |||
131 | return err; | 131 | return err; |
132 | } | 132 | } |
133 | 133 | ||
134 | 134 | static const char *ovl_get_link(struct dentry *dentry, | |
135 | struct ovl_link_data { | 135 | struct inode *inode, |
136 | struct dentry *realdentry; | 136 | struct delayed_call *done) |
137 | void *cookie; | ||
138 | }; | ||
139 | |||
140 | static const char *ovl_follow_link(struct dentry *dentry, void **cookie) | ||
141 | { | 137 | { |
142 | struct dentry *realdentry; | 138 | struct dentry *realdentry; |
143 | struct inode *realinode; | 139 | struct inode *realinode; |
144 | struct ovl_link_data *data = NULL; | 140 | |
145 | const char *ret; | 141 | if (!dentry) |
142 | return ERR_PTR(-ECHILD); | ||
146 | 143 | ||
147 | realdentry = ovl_dentry_real(dentry); | 144 | realdentry = ovl_dentry_real(dentry); |
148 | realinode = realdentry->d_inode; | 145 | realinode = realdentry->d_inode; |
149 | 146 | ||
150 | if (WARN_ON(!realinode->i_op->follow_link)) | 147 | if (WARN_ON(!realinode->i_op->get_link)) |
151 | return ERR_PTR(-EPERM); | 148 | return ERR_PTR(-EPERM); |
152 | 149 | ||
153 | if (realinode->i_op->put_link) { | 150 | return realinode->i_op->get_link(realdentry, realinode, done); |
154 | data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL); | ||
155 | if (!data) | ||
156 | return ERR_PTR(-ENOMEM); | ||
157 | data->realdentry = realdentry; | ||
158 | } | ||
159 | |||
160 | ret = realinode->i_op->follow_link(realdentry, cookie); | ||
161 | if (IS_ERR_OR_NULL(ret)) { | ||
162 | kfree(data); | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | if (data) | ||
167 | data->cookie = *cookie; | ||
168 | |||
169 | *cookie = data; | ||
170 | |||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static void ovl_put_link(struct inode *unused, void *c) | ||
175 | { | ||
176 | struct inode *realinode; | ||
177 | struct ovl_link_data *data = c; | ||
178 | |||
179 | if (!data) | ||
180 | return; | ||
181 | |||
182 | realinode = data->realdentry->d_inode; | ||
183 | realinode->i_op->put_link(realinode, data->cookie); | ||
184 | kfree(data); | ||
185 | } | 151 | } |
186 | 152 | ||
187 | static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | 153 | static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) |
@@ -378,8 +344,7 @@ static const struct inode_operations ovl_file_inode_operations = { | |||
378 | 344 | ||
379 | static const struct inode_operations ovl_symlink_inode_operations = { | 345 | static const struct inode_operations ovl_symlink_inode_operations = { |
380 | .setattr = ovl_setattr, | 346 | .setattr = ovl_setattr, |
381 | .follow_link = ovl_follow_link, | 347 | .get_link = ovl_get_link, |
382 | .put_link = ovl_put_link, | ||
383 | .readlink = ovl_readlink, | 348 | .readlink = ovl_readlink, |
384 | .getattr = ovl_getattr, | 349 | .getattr = ovl_getattr, |
385 | .setxattr = ovl_setxattr, | 350 | .setxattr = ovl_setxattr, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4bd5d3118acd..55e01f88eac9 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1564,12 +1564,16 @@ 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, | ||
1569 | struct delayed_call *done) | ||
1568 | { | 1570 | { |
1569 | struct inode *inode = d_inode(dentry); | ||
1570 | struct path path; | 1571 | struct path path; |
1571 | int error = -EACCES; | 1572 | int error = -EACCES; |
1572 | 1573 | ||
1574 | if (!dentry) | ||
1575 | return ERR_PTR(-ECHILD); | ||
1576 | |||
1573 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1577 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1574 | if (!proc_fd_access_allowed(inode)) | 1578 | if (!proc_fd_access_allowed(inode)) |
1575 | goto out; | 1579 | goto out; |
@@ -1630,7 +1634,7 @@ out: | |||
1630 | 1634 | ||
1631 | const struct inode_operations proc_pid_link_inode_operations = { | 1635 | const struct inode_operations proc_pid_link_inode_operations = { |
1632 | .readlink = proc_pid_readlink, | 1636 | .readlink = proc_pid_readlink, |
1633 | .follow_link = proc_pid_follow_link, | 1637 | .get_link = proc_pid_get_link, |
1634 | .setattr = proc_setattr, | 1638 | .setattr = proc_setattr, |
1635 | }; | 1639 | }; |
1636 | 1640 | ||
@@ -1895,7 +1899,7 @@ static const struct dentry_operations tid_map_files_dentry_operations = { | |||
1895 | .d_delete = pid_delete_dentry, | 1899 | .d_delete = pid_delete_dentry, |
1896 | }; | 1900 | }; |
1897 | 1901 | ||
1898 | static int proc_map_files_get_link(struct dentry *dentry, struct path *path) | 1902 | static int map_files_get_link(struct dentry *dentry, struct path *path) |
1899 | { | 1903 | { |
1900 | unsigned long vm_start, vm_end; | 1904 | unsigned long vm_start, vm_end; |
1901 | struct vm_area_struct *vma; | 1905 | struct vm_area_struct *vma; |
@@ -1945,20 +1949,22 @@ struct map_files_info { | |||
1945 | * path to the file in question. | 1949 | * path to the file in question. |
1946 | */ | 1950 | */ |
1947 | static const char * | 1951 | static const char * |
1948 | proc_map_files_follow_link(struct dentry *dentry, void **cookie) | 1952 | proc_map_files_get_link(struct dentry *dentry, |
1953 | struct inode *inode, | ||
1954 | struct delayed_call *done) | ||
1949 | { | 1955 | { |
1950 | if (!capable(CAP_SYS_ADMIN)) | 1956 | if (!capable(CAP_SYS_ADMIN)) |
1951 | return ERR_PTR(-EPERM); | 1957 | return ERR_PTR(-EPERM); |
1952 | 1958 | ||
1953 | return proc_pid_follow_link(dentry, NULL); | 1959 | return proc_pid_get_link(dentry, inode, done); |
1954 | } | 1960 | } |
1955 | 1961 | ||
1956 | /* | 1962 | /* |
1957 | * Identical to proc_pid_link_inode_operations except for follow_link() | 1963 | * Identical to proc_pid_link_inode_operations except for get_link() |
1958 | */ | 1964 | */ |
1959 | static const struct inode_operations proc_map_files_link_inode_operations = { | 1965 | static const struct inode_operations proc_map_files_link_inode_operations = { |
1960 | .readlink = proc_pid_readlink, | 1966 | .readlink = proc_pid_readlink, |
1961 | .follow_link = proc_map_files_follow_link, | 1967 | .get_link = proc_map_files_get_link, |
1962 | .setattr = proc_setattr, | 1968 | .setattr = proc_setattr, |
1963 | }; | 1969 | }; |
1964 | 1970 | ||
@@ -1975,7 +1981,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1975 | return -ENOENT; | 1981 | return -ENOENT; |
1976 | 1982 | ||
1977 | ei = PROC_I(inode); | 1983 | ei = PROC_I(inode); |
1978 | ei->op.proc_get_link = proc_map_files_get_link; | 1984 | ei->op.proc_get_link = map_files_get_link; |
1979 | 1985 | ||
1980 | inode->i_op = &proc_map_files_link_inode_operations; | 1986 | inode->i_op = &proc_map_files_link_inode_operations; |
1981 | inode->i_size = 64; | 1987 | inode->i_size = 64; |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index bd95b9fdebb0..d0e9b9b6223e 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -393,24 +393,25 @@ 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 void proc_put_link(void *p) |
397 | { | 397 | { |
398 | struct proc_dir_entry *pde = PDE(d_inode(dentry)); | 398 | unuse_pde(p); |
399 | if (unlikely(!use_pde(pde))) | ||
400 | return ERR_PTR(-EINVAL); | ||
401 | *cookie = pde; | ||
402 | return pde->data; | ||
403 | } | 399 | } |
404 | 400 | ||
405 | static void proc_put_link(struct inode *unused, void *p) | 401 | static const char *proc_get_link(struct dentry *dentry, |
402 | struct inode *inode, | ||
403 | struct delayed_call *done) | ||
406 | { | 404 | { |
407 | unuse_pde(p); | 405 | struct proc_dir_entry *pde = PDE(inode); |
406 | if (unlikely(!use_pde(pde))) | ||
407 | return ERR_PTR(-EINVAL); | ||
408 | set_delayed_call(done, proc_put_link, pde); | ||
409 | return pde->data; | ||
408 | } | 410 | } |
409 | 411 | ||
410 | const struct inode_operations proc_link_inode_operations = { | 412 | const struct inode_operations proc_link_inode_operations = { |
411 | .readlink = generic_readlink, | 413 | .readlink = generic_readlink, |
412 | .follow_link = proc_follow_link, | 414 | .get_link = proc_get_link, |
413 | .put_link = proc_put_link, | ||
414 | }; | 415 | }; |
415 | 416 | ||
416 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) | 417 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) |
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index f6e8354b8cea..1dece8781f91 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c | |||
@@ -30,14 +30,18 @@ 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, | ||
35 | struct delayed_call *done) | ||
34 | { | 36 | { |
35 | struct inode *inode = d_inode(dentry); | ||
36 | const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; | 37 | const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; |
37 | struct task_struct *task; | 38 | struct task_struct *task; |
38 | struct path ns_path; | 39 | struct path ns_path; |
39 | void *error = ERR_PTR(-EACCES); | 40 | void *error = ERR_PTR(-EACCES); |
40 | 41 | ||
42 | if (!dentry) | ||
43 | return ERR_PTR(-ECHILD); | ||
44 | |||
41 | task = get_proc_task(inode); | 45 | task = get_proc_task(inode); |
42 | if (!task) | 46 | if (!task) |
43 | return error; | 47 | return error; |
@@ -74,7 +78,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl | |||
74 | 78 | ||
75 | static const struct inode_operations proc_ns_link_inode_operations = { | 79 | static const struct inode_operations proc_ns_link_inode_operations = { |
76 | .readlink = proc_ns_readlink, | 80 | .readlink = proc_ns_readlink, |
77 | .follow_link = proc_ns_follow_link, | 81 | .get_link = proc_ns_get_link, |
78 | .setattr = proc_setattr, | 82 | .setattr = proc_setattr, |
79 | }; | 83 | }; |
80 | 84 | ||
diff --git a/fs/proc/self.c b/fs/proc/self.c index 113b8d061fc0..67e8db442cf0 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c | |||
@@ -18,26 +18,28 @@ 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, | ||
23 | struct delayed_call *done) | ||
22 | { | 24 | { |
23 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | 25 | struct pid_namespace *ns = inode->i_sb->s_fs_info; |
24 | pid_t tgid = task_tgid_nr_ns(current, ns); | 26 | pid_t tgid = task_tgid_nr_ns(current, ns); |
25 | char *name; | 27 | char *name; |
26 | 28 | ||
27 | if (!tgid) | 29 | if (!tgid) |
28 | return ERR_PTR(-ENOENT); | 30 | return ERR_PTR(-ENOENT); |
29 | /* 11 for max length of signed int in decimal + NULL term */ | 31 | /* 11 for max length of signed int in decimal + NULL term */ |
30 | name = kmalloc(12, GFP_KERNEL); | 32 | name = kmalloc(12, dentry ? GFP_KERNEL : GFP_ATOMIC); |
31 | if (!name) | 33 | if (unlikely(!name)) |
32 | return ERR_PTR(-ENOMEM); | 34 | return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD); |
33 | sprintf(name, "%d", tgid); | 35 | sprintf(name, "%d", tgid); |
34 | return *cookie = name; | 36 | set_delayed_call(done, kfree_link, name); |
37 | return name; | ||
35 | } | 38 | } |
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, | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | static unsigned self_inum; | 45 | static unsigned self_inum; |
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c index 947b0f4fd0a1..9eacd59e0360 100644 --- a/fs/proc/thread_self.c +++ b/fs/proc/thread_self.c | |||
@@ -19,26 +19,29 @@ 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, | ||
24 | struct delayed_call *done) | ||
23 | { | 25 | { |
24 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | 26 | struct pid_namespace *ns = inode->i_sb->s_fs_info; |
25 | pid_t tgid = task_tgid_nr_ns(current, ns); | 27 | pid_t tgid = task_tgid_nr_ns(current, ns); |
26 | pid_t pid = task_pid_nr_ns(current, ns); | 28 | pid_t pid = task_pid_nr_ns(current, ns); |
27 | char *name; | 29 | char *name; |
28 | 30 | ||
29 | if (!pid) | 31 | if (!pid) |
30 | return ERR_PTR(-ENOENT); | 32 | return ERR_PTR(-ENOENT); |
31 | name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL); | 33 | name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, |
32 | if (!name) | 34 | dentry ? GFP_KERNEL : GFP_ATOMIC); |
33 | return ERR_PTR(-ENOMEM); | 35 | if (unlikely(!name)) |
36 | return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD); | ||
34 | sprintf(name, "%d/task/%d", tgid, pid); | 37 | sprintf(name, "%d/task/%d", tgid, pid); |
35 | return *cookie = name; | 38 | set_delayed_call(done, kfree_link, name); |
39 | return name; | ||
36 | } | 40 | } |
37 | 41 | ||
38 | static const struct inode_operations proc_thread_self_inode_operations = { | 42 | static const struct inode_operations proc_thread_self_inode_operations = { |
39 | .readlink = proc_thread_self_readlink, | 43 | .readlink = proc_thread_self_readlink, |
40 | .follow_link = proc_thread_self_follow_link, | 44 | .get_link = proc_thread_self_get_link, |
41 | .put_link = kfree_put_link, | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | static unsigned thread_self_inum; | 47 | static unsigned thread_self_inum; |
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index c4bcb778886e..f37b3deb01b4 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -316,6 +316,7 @@ struct inode *qnx4_iget(struct super_block *sb, unsigned long ino) | |||
316 | inode->i_fop = &qnx4_dir_operations; | 316 | inode->i_fop = &qnx4_dir_operations; |
317 | } else if (S_ISLNK(inode->i_mode)) { | 317 | } else if (S_ISLNK(inode->i_mode)) { |
318 | inode->i_op = &page_symlink_inode_operations; | 318 | inode->i_op = &page_symlink_inode_operations; |
319 | inode_nohighmem(inode); | ||
319 | inode->i_mapping->a_ops = &qnx4_aops; | 320 | inode->i_mapping->a_ops = &qnx4_aops; |
320 | qnx4_i(inode)->mmu_private = inode->i_size; | 321 | qnx4_i(inode)->mmu_private = inode->i_size; |
321 | } else { | 322 | } else { |
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 32d2e1a9774c..9728b5499e1d 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c | |||
@@ -582,6 +582,7 @@ struct inode *qnx6_iget(struct super_block *sb, unsigned ino) | |||
582 | inode->i_mapping->a_ops = &qnx6_aops; | 582 | inode->i_mapping->a_ops = &qnx6_aops; |
583 | } else if (S_ISLNK(inode->i_mode)) { | 583 | } else if (S_ISLNK(inode->i_mode)) { |
584 | inode->i_op = &page_symlink_inode_operations; | 584 | inode->i_op = &page_symlink_inode_operations; |
585 | inode_nohighmem(inode); | ||
585 | inode->i_mapping->a_ops = &qnx6_aops; | 586 | inode->i_mapping->a_ops = &qnx6_aops; |
586 | } else | 587 | } else |
587 | init_special_inode(inode, inode->i_mode, 0); | 588 | init_special_inode(inode, inode->i_mode, 0); |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 889d558b4e05..38981b037524 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -79,6 +79,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, | |||
79 | break; | 79 | break; |
80 | case S_IFLNK: | 80 | case S_IFLNK: |
81 | inode->i_op = &page_symlink_inode_operations; | 81 | inode->i_op = &page_symlink_inode_operations; |
82 | inode_nohighmem(inode); | ||
82 | break; | 83 | break; |
83 | } | 84 | } |
84 | } | 85 | } |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3d8e7e671d5b..ae9e5b308cf9 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1361,6 +1361,7 @@ static void init_inode(struct inode *inode, struct treepath *path) | |||
1361 | inode->i_fop = &reiserfs_dir_operations; | 1361 | inode->i_fop = &reiserfs_dir_operations; |
1362 | } else if (S_ISLNK(inode->i_mode)) { | 1362 | } else if (S_ISLNK(inode->i_mode)) { |
1363 | inode->i_op = &reiserfs_symlink_inode_operations; | 1363 | inode->i_op = &reiserfs_symlink_inode_operations; |
1364 | inode_nohighmem(inode); | ||
1364 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; | 1365 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; |
1365 | } else { | 1366 | } else { |
1366 | inode->i_blocks = 0; | 1367 | inode->i_blocks = 0; |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 47f96988fdd4..2a12d46d7fb4 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -1170,6 +1170,7 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1170 | reiserfs_update_inode_transaction(parent_dir); | 1170 | reiserfs_update_inode_transaction(parent_dir); |
1171 | 1171 | ||
1172 | inode->i_op = &reiserfs_symlink_inode_operations; | 1172 | inode->i_op = &reiserfs_symlink_inode_operations; |
1173 | inode_nohighmem(inode); | ||
1173 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; | 1174 | inode->i_mapping->a_ops = &reiserfs_address_space_operations; |
1174 | 1175 | ||
1175 | retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name, | 1176 | retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name, |
@@ -1664,8 +1665,7 @@ const struct inode_operations reiserfs_dir_inode_operations = { | |||
1664 | */ | 1665 | */ |
1665 | const struct inode_operations reiserfs_symlink_inode_operations = { | 1666 | const struct inode_operations reiserfs_symlink_inode_operations = { |
1666 | .readlink = generic_readlink, | 1667 | .readlink = generic_readlink, |
1667 | .follow_link = page_follow_link_light, | 1668 | .get_link = page_get_link, |
1668 | .put_link = page_put_link, | ||
1669 | .setattr = reiserfs_setattr, | 1669 | .setattr = reiserfs_setattr, |
1670 | .setxattr = reiserfs_setxattr, | 1670 | .setxattr = reiserfs_setxattr, |
1671 | .getxattr = reiserfs_getxattr, | 1671 | .getxattr = reiserfs_getxattr, |
diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 268733cda397..bb894e78a821 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c | |||
@@ -360,6 +360,7 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos) | |||
360 | break; | 360 | break; |
361 | case ROMFH_SYM: | 361 | case ROMFH_SYM: |
362 | i->i_op = &page_symlink_inode_operations; | 362 | i->i_op = &page_symlink_inode_operations; |
363 | inode_nohighmem(i); | ||
363 | i->i_data.a_ops = &romfs_aops; | 364 | i->i_data.a_ops = &romfs_aops; |
364 | mode |= S_IRWXUGO; | 365 | mode |= S_IRWXUGO; |
365 | break; | 366 | break; |
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index a1ce5ce60632..0927b1e80ab6 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/fs.h> | 41 | #include <linux/fs.h> |
42 | #include <linux/vfs.h> | 42 | #include <linux/vfs.h> |
43 | #include <linux/xattr.h> | 43 | #include <linux/xattr.h> |
44 | #include <linux/pagemap.h> | ||
44 | 45 | ||
45 | #include "squashfs_fs.h" | 46 | #include "squashfs_fs.h" |
46 | #include "squashfs_fs_sb.h" | 47 | #include "squashfs_fs_sb.h" |
@@ -291,6 +292,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) | |||
291 | set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); | 292 | set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); |
292 | inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); | 293 | inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); |
293 | inode->i_op = &squashfs_symlink_inode_ops; | 294 | inode->i_op = &squashfs_symlink_inode_ops; |
295 | inode_nohighmem(inode); | ||
294 | inode->i_data.a_ops = &squashfs_symlink_aops; | 296 | inode->i_data.a_ops = &squashfs_symlink_aops; |
295 | inode->i_mode |= S_IFLNK; | 297 | inode->i_mode |= S_IFLNK; |
296 | squashfs_i(inode)->start = block; | 298 | squashfs_i(inode)->start = block; |
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index 12806dffb345..dbcc2f54bad4 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c | |||
@@ -119,8 +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, | ||
124 | .getxattr = generic_getxattr, | 123 | .getxattr = generic_getxattr, |
125 | .listxattr = squashfs_listxattr | 124 | .listxattr = squashfs_listxattr |
126 | }; | 125 | }; |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 02fa1dcc5969..07ac18c355e7 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -146,8 +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, | ||
151 | .getattr = sysv_getattr, | 150 | .getattr = sysv_getattr, |
152 | }; | 151 | }; |
153 | 152 | ||
@@ -163,6 +162,7 @@ void sysv_set_inode(struct inode *inode, dev_t rdev) | |||
163 | inode->i_mapping->a_ops = &sysv_aops; | 162 | inode->i_mapping->a_ops = &sysv_aops; |
164 | } else if (S_ISLNK(inode->i_mode)) { | 163 | } else if (S_ISLNK(inode->i_mode)) { |
165 | inode->i_op = &sysv_symlink_inode_operations; | 164 | inode->i_op = &sysv_symlink_inode_operations; |
165 | inode_nohighmem(inode); | ||
166 | inode->i_mapping->a_ops = &sysv_aops; | 166 | inode->i_mapping->a_ops = &sysv_aops; |
167 | } else | 167 | } else |
168 | init_special_inode(inode, inode->i_mode, rdev); | 168 | init_special_inode(inode, inode->i_mode, rdev); |
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/udf/inode.c b/fs/udf/inode.c index 8d0b3ade0ff0..055746350d16 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1540,7 +1540,8 @@ reread: | |||
1540 | break; | 1540 | break; |
1541 | case ICBTAG_FILE_TYPE_SYMLINK: | 1541 | case ICBTAG_FILE_TYPE_SYMLINK: |
1542 | inode->i_data.a_ops = &udf_symlink_aops; | 1542 | inode->i_data.a_ops = &udf_symlink_aops; |
1543 | inode->i_op = &udf_symlink_inode_operations; | 1543 | inode->i_op = &page_symlink_inode_operations; |
1544 | inode_nohighmem(inode); | ||
1544 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1545 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1545 | break; | 1546 | break; |
1546 | case ICBTAG_FILE_TYPE_MAIN: | 1547 | case ICBTAG_FILE_TYPE_MAIN: |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index c97b5a8d1e24..42eafb91f7ff 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -921,7 +921,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
921 | } | 921 | } |
922 | 922 | ||
923 | inode->i_data.a_ops = &udf_symlink_aops; | 923 | inode->i_data.a_ops = &udf_symlink_aops; |
924 | inode->i_op = &udf_symlink_inode_operations; | 924 | inode->i_op = &page_symlink_inode_operations; |
925 | inode_nohighmem(inode); | ||
925 | 926 | ||
926 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 927 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
927 | struct kernel_lb_addr eloc; | 928 | struct kernel_lb_addr eloc; |
@@ -1344,8 +1345,3 @@ const struct inode_operations udf_dir_inode_operations = { | |||
1344 | .rename = udf_rename, | 1345 | .rename = udf_rename, |
1345 | .tmpfile = udf_tmpfile, | 1346 | .tmpfile = udf_tmpfile, |
1346 | }; | 1347 | }; |
1347 | const struct inode_operations udf_symlink_inode_operations = { | ||
1348 | .readlink = generic_readlink, | ||
1349 | .follow_link = page_follow_link_light, | ||
1350 | .put_link = page_put_link, | ||
1351 | }; | ||
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 862535b3ba58..8d619773056b 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -107,7 +107,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
107 | struct buffer_head *bh = NULL; | 107 | struct buffer_head *bh = NULL; |
108 | unsigned char *symlink; | 108 | unsigned char *symlink; |
109 | int err; | 109 | int err; |
110 | unsigned char *p = kmap(page); | 110 | unsigned char *p = page_address(page); |
111 | struct udf_inode_info *iinfo; | 111 | struct udf_inode_info *iinfo; |
112 | uint32_t pos; | 112 | uint32_t pos; |
113 | 113 | ||
@@ -141,7 +141,6 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
141 | 141 | ||
142 | up_read(&iinfo->i_data_sem); | 142 | up_read(&iinfo->i_data_sem); |
143 | SetPageUptodate(page); | 143 | SetPageUptodate(page); |
144 | kunmap(page); | ||
145 | unlock_page(page); | 144 | unlock_page(page); |
146 | return 0; | 145 | return 0; |
147 | 146 | ||
@@ -149,7 +148,6 @@ out_unlock_inode: | |||
149 | up_read(&iinfo->i_data_sem); | 148 | up_read(&iinfo->i_data_sem); |
150 | SetPageError(page); | 149 | SetPageError(page); |
151 | out_unmap: | 150 | out_unmap: |
152 | kunmap(page); | ||
153 | unlock_page(page); | 151 | unlock_page(page); |
154 | return err; | 152 | return err; |
155 | } | 153 | } |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 47bb3f5ca360..ce169b49429d 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -85,7 +85,6 @@ extern const struct inode_operations udf_dir_inode_operations; | |||
85 | extern const struct file_operations udf_dir_operations; | 85 | extern const struct file_operations udf_dir_operations; |
86 | extern const struct inode_operations udf_file_inode_operations; | 86 | extern const struct inode_operations udf_file_inode_operations; |
87 | extern const struct file_operations udf_file_operations; | 87 | extern const struct file_operations udf_file_operations; |
88 | extern const struct inode_operations udf_symlink_inode_operations; | ||
89 | extern const struct address_space_operations udf_aops; | 88 | extern const struct address_space_operations udf_aops; |
90 | extern const struct address_space_operations udf_adinicb_aops; | 89 | extern const struct address_space_operations udf_adinicb_aops; |
91 | extern const struct address_space_operations udf_symlink_aops; | 90 | extern const struct address_space_operations udf_symlink_aops; |
diff --git a/fs/ufs/Makefile b/fs/ufs/Makefile index 392db25c0b56..ec4a6b49fa13 100644 --- a/fs/ufs/Makefile +++ b/fs/ufs/Makefile | |||
@@ -5,5 +5,5 @@ | |||
5 | obj-$(CONFIG_UFS_FS) += ufs.o | 5 | obj-$(CONFIG_UFS_FS) += ufs.o |
6 | 6 | ||
7 | ufs-objs := balloc.o cylinder.o dir.o file.o ialloc.o inode.o \ | 7 | ufs-objs := balloc.o cylinder.o dir.o file.o ialloc.o inode.o \ |
8 | namei.o super.o symlink.o util.o | 8 | namei.o super.o util.o |
9 | ccflags-$(CONFIG_UFS_DEBUG) += -DDEBUG | 9 | ccflags-$(CONFIG_UFS_DEBUG) += -DDEBUG |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index a064cf44b143..d897e169ab9c 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -528,11 +528,12 @@ static void ufs_set_inode_ops(struct inode *inode) | |||
528 | inode->i_mapping->a_ops = &ufs_aops; | 528 | inode->i_mapping->a_ops = &ufs_aops; |
529 | } else if (S_ISLNK(inode->i_mode)) { | 529 | } else if (S_ISLNK(inode->i_mode)) { |
530 | if (!inode->i_blocks) { | 530 | if (!inode->i_blocks) { |
531 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
532 | inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink; | 531 | inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink; |
532 | inode->i_op = &simple_symlink_inode_operations; | ||
533 | } else { | 533 | } else { |
534 | inode->i_op = &ufs_symlink_inode_operations; | ||
535 | inode->i_mapping->a_ops = &ufs_aops; | 534 | inode->i_mapping->a_ops = &ufs_aops; |
535 | inode->i_op = &page_symlink_inode_operations; | ||
536 | inode_nohighmem(inode); | ||
536 | } | 537 | } |
537 | } else | 538 | } else |
538 | init_special_inode(inode, inode->i_mode, | 539 | init_special_inode(inode, inode->i_mode, |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 47966554317c..acf4a3b61b81 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -123,14 +123,15 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
123 | 123 | ||
124 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { | 124 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { |
125 | /* slow symlink */ | 125 | /* slow symlink */ |
126 | inode->i_op = &ufs_symlink_inode_operations; | 126 | inode->i_op = &page_symlink_inode_operations; |
127 | inode_nohighmem(inode); | ||
127 | inode->i_mapping->a_ops = &ufs_aops; | 128 | inode->i_mapping->a_ops = &ufs_aops; |
128 | err = page_symlink(inode, symname, l); | 129 | err = page_symlink(inode, symname, l); |
129 | if (err) | 130 | if (err) |
130 | goto out_fail; | 131 | goto out_fail; |
131 | } else { | 132 | } else { |
132 | /* fast symlink */ | 133 | /* fast symlink */ |
133 | inode->i_op = &ufs_fast_symlink_inode_operations; | 134 | inode->i_op = &simple_symlink_inode_operations; |
134 | inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink; | 135 | inode->i_link = (char *)UFS_I(inode)->i_u1.i_symlink; |
135 | memcpy(inode->i_link, symname, l); | 136 | memcpy(inode->i_link, symname, l); |
136 | inode->i_size = l-1; | 137 | inode->i_size = l-1; |
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c deleted file mode 100644 index 874480bb43e9..000000000000 --- a/fs/ufs/symlink.c +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/ufs/symlink.c | ||
3 | * | ||
4 | * Only fast symlinks left here - the rest is done by generic code. AV, 1999 | ||
5 | * | ||
6 | * Copyright (C) 1998 | ||
7 | * Daniel Pirkl <daniel.pirkl@emai.cz> | ||
8 | * Charles University, Faculty of Mathematics and Physics | ||
9 | * | ||
10 | * from | ||
11 | * | ||
12 | * linux/fs/ext2/symlink.c | ||
13 | * | ||
14 | * Copyright (C) 1992, 1993, 1994, 1995 | ||
15 | * Remy Card (card@masi.ibp.fr) | ||
16 | * Laboratoire MASI - Institut Blaise Pascal | ||
17 | * Universite Pierre et Marie Curie (Paris VI) | ||
18 | * | ||
19 | * from | ||
20 | * | ||
21 | * linux/fs/minix/symlink.c | ||
22 | * | ||
23 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
24 | * | ||
25 | * ext2 symlink handling code | ||
26 | */ | ||
27 | |||
28 | #include "ufs_fs.h" | ||
29 | #include "ufs.h" | ||
30 | |||
31 | const struct inode_operations ufs_fast_symlink_inode_operations = { | ||
32 | .readlink = generic_readlink, | ||
33 | .follow_link = simple_follow_link, | ||
34 | .setattr = ufs_setattr, | ||
35 | }; | ||
36 | |||
37 | const struct inode_operations ufs_symlink_inode_operations = { | ||
38 | .readlink = generic_readlink, | ||
39 | .follow_link = page_follow_link_light, | ||
40 | .put_link = page_put_link, | ||
41 | .setattr = ufs_setattr, | ||
42 | }; | ||
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 7da4aca868c0..c87f4c3fa9dd 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h | |||
@@ -136,10 +136,6 @@ extern __printf(3, 4) | |||
136 | void ufs_panic(struct super_block *, const char *, const char *, ...); | 136 | void ufs_panic(struct super_block *, const char *, const char *, ...); |
137 | void ufs_mark_sb_dirty(struct super_block *sb); | 137 | void ufs_mark_sb_dirty(struct super_block *sb); |
138 | 138 | ||
139 | /* symlink.c */ | ||
140 | extern const struct inode_operations ufs_fast_symlink_inode_operations; | ||
141 | extern const struct inode_operations ufs_symlink_inode_operations; | ||
142 | |||
143 | static inline struct ufs_sb_info *UFS_SB(struct super_block *sb) | 139 | static inline struct ufs_sb_info *UFS_SB(struct super_block *sb) |
144 | { | 140 | { |
145 | return sb->s_fs_info; | 141 | return sb->s_fs_info; |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 245268a0cdf0..06eafafe636e 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 | void **cookie) | 419 | struct inode *inode, |
420 | struct delayed_call *done) | ||
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; |
@@ -429,7 +433,8 @@ xfs_vn_follow_link( | |||
429 | if (unlikely(error)) | 433 | if (unlikely(error)) |
430 | goto out_kfree; | 434 | goto out_kfree; |
431 | 435 | ||
432 | return *cookie = link; | 436 | set_delayed_call(done, kfree_link, link); |
437 | return link; | ||
433 | 438 | ||
434 | out_kfree: | 439 | out_kfree: |
435 | kfree(link); | 440 | kfree(link); |
@@ -1172,8 +1177,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1172 | 1177 | ||
1173 | static const struct inode_operations xfs_symlink_inode_operations = { | 1178 | static const struct inode_operations xfs_symlink_inode_operations = { |
1174 | .readlink = generic_readlink, | 1179 | .readlink = generic_readlink, |
1175 | .follow_link = xfs_vn_follow_link, | 1180 | .get_link = xfs_vn_get_link, |
1176 | .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, |
1179 | .setxattr = generic_setxattr, | 1183 | .setxattr = generic_setxattr, |
diff --git a/include/linux/delayed_call.h b/include/linux/delayed_call.h new file mode 100644 index 000000000000..f7fa76ae1a9b --- /dev/null +++ b/include/linux/delayed_call.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef _DELAYED_CALL_H | ||
2 | #define _DELAYED_CALL_H | ||
3 | |||
4 | /* | ||
5 | * Poor man's closures; I wish we could've done them sanely polymorphic, | ||
6 | * but... | ||
7 | */ | ||
8 | |||
9 | struct delayed_call { | ||
10 | void (*fn)(void *); | ||
11 | void *arg; | ||
12 | }; | ||
13 | |||
14 | #define DEFINE_DELAYED_CALL(name) struct delayed_call name = {NULL, NULL} | ||
15 | |||
16 | /* I really wish we had closures with sane typechecking... */ | ||
17 | static inline void set_delayed_call(struct delayed_call *call, | ||
18 | void (*fn)(void *), void *arg) | ||
19 | { | ||
20 | call->fn = fn; | ||
21 | call->arg = arg; | ||
22 | } | ||
23 | |||
24 | static inline void do_delayed_call(struct delayed_call *call) | ||
25 | { | ||
26 | if (call->fn) | ||
27 | call->fn(call->arg); | ||
28 | } | ||
29 | |||
30 | static inline void clear_delayed_call(struct delayed_call *call) | ||
31 | { | ||
32 | call->fn = NULL; | ||
33 | } | ||
34 | #endif | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 51f9f8d93d4d..ef3cd36689f6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/blk_types.h> | 31 | #include <linux/blk_types.h> |
32 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
33 | #include <linux/percpu-rwsem.h> | 33 | #include <linux/percpu-rwsem.h> |
34 | #include <linux/delayed_call.h> | ||
34 | 35 | ||
35 | #include <asm/byteorder.h> | 36 | #include <asm/byteorder.h> |
36 | #include <uapi/linux/fs.h> | 37 | #include <uapi/linux/fs.h> |
@@ -1633,12 +1634,11 @@ struct file_operations { | |||
1633 | 1634 | ||
1634 | struct inode_operations { | 1635 | struct inode_operations { |
1635 | struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); | 1636 | struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); |
1636 | const char * (*follow_link) (struct dentry *, void **); | 1637 | const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); |
1637 | int (*permission) (struct inode *, int); | 1638 | int (*permission) (struct inode *, int); |
1638 | struct posix_acl * (*get_acl)(struct inode *, int); | 1639 | struct posix_acl * (*get_acl)(struct inode *, int); |
1639 | 1640 | ||
1640 | int (*readlink) (struct dentry *, char __user *,int); | 1641 | int (*readlink) (struct dentry *, char __user *,int); |
1641 | void (*put_link) (struct inode *, void *); | ||
1642 | 1642 | ||
1643 | int (*create) (struct inode *,struct dentry *, umode_t, bool); | 1643 | int (*create) (struct inode *,struct dentry *, umode_t, bool); |
1644 | int (*link) (struct dentry *,struct inode *,struct dentry *); | 1644 | int (*link) (struct dentry *,struct inode *,struct dentry *); |
@@ -2736,14 +2736,14 @@ extern const struct file_operations generic_ro_fops; | |||
2736 | 2736 | ||
2737 | extern int readlink_copy(char __user *, int, const char *); | 2737 | extern int readlink_copy(char __user *, int, const char *); |
2738 | extern int page_readlink(struct dentry *, char __user *, int); | 2738 | extern int page_readlink(struct dentry *, char __user *, int); |
2739 | extern const char *page_follow_link_light(struct dentry *, void **); | 2739 | extern const char *page_get_link(struct dentry *, struct inode *, |
2740 | extern void page_put_link(struct inode *, void *); | 2740 | struct delayed_call *); |
2741 | extern void page_put_link(void *); | ||
2741 | extern int __page_symlink(struct inode *inode, const char *symname, int len, | 2742 | extern int __page_symlink(struct inode *inode, const char *symname, int len, |
2742 | int nofs); | 2743 | int nofs); |
2743 | extern int page_symlink(struct inode *inode, const char *symname, int len); | 2744 | extern int page_symlink(struct inode *inode, const char *symname, int len); |
2744 | extern const struct inode_operations page_symlink_inode_operations; | 2745 | extern const struct inode_operations page_symlink_inode_operations; |
2745 | extern void kfree_put_link(struct inode *, void *); | 2746 | extern void kfree_link(void *); |
2746 | extern void free_page_put_link(struct inode *, void *); | ||
2747 | extern int generic_readlink(struct dentry *, char __user *, int); | 2747 | extern int generic_readlink(struct dentry *, char __user *, int); |
2748 | extern void generic_fillattr(struct inode *, struct kstat *); | 2748 | extern void generic_fillattr(struct inode *, struct kstat *); |
2749 | int vfs_getattr_nosec(struct path *path, struct kstat *stat); | 2749 | int vfs_getattr_nosec(struct path *path, struct kstat *stat); |
@@ -2754,7 +2754,8 @@ void __inode_sub_bytes(struct inode *inode, loff_t bytes); | |||
2754 | void inode_sub_bytes(struct inode *inode, loff_t bytes); | 2754 | void inode_sub_bytes(struct inode *inode, loff_t bytes); |
2755 | loff_t inode_get_bytes(struct inode *inode); | 2755 | loff_t inode_get_bytes(struct inode *inode); |
2756 | void inode_set_bytes(struct inode *inode, loff_t bytes); | 2756 | void inode_set_bytes(struct inode *inode, loff_t bytes); |
2757 | const char *simple_follow_link(struct dentry *, void **); | 2757 | const char *simple_get_link(struct dentry *, struct inode *, |
2758 | struct delayed_call *); | ||
2758 | extern const struct inode_operations simple_symlink_inode_operations; | 2759 | extern const struct inode_operations simple_symlink_inode_operations; |
2759 | 2760 | ||
2760 | extern int iterate_dir(struct file *, struct dir_context *); | 2761 | extern int iterate_dir(struct file *, struct dir_context *); |
@@ -3023,5 +3024,6 @@ static inline bool dir_relax(struct inode *inode) | |||
3023 | } | 3024 | } |
3024 | 3025 | ||
3025 | extern bool path_noexec(const struct path *path); | 3026 | extern bool path_noexec(const struct path *path); |
3027 | extern void inode_nohighmem(struct inode *inode); | ||
3026 | 3028 | ||
3027 | #endif /* _LINUX_FS_H */ | 3029 | #endif /* _LINUX_FS_H */ |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e961474a52..37a3d2981352 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -359,6 +359,7 @@ extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); | |||
359 | extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode); | 359 | extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode); |
360 | extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); | 360 | extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); |
361 | extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); | 361 | extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); |
362 | extern int nfs_revalidate_mapping_rcu(struct inode *inode); | ||
362 | extern int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping); | 363 | extern int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping); |
363 | extern int nfs_setattr(struct dentry *, struct iattr *); | 364 | extern int nfs_setattr(struct dentry *, struct iattr *); |
364 | extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *); | 365 | extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *); |
diff --git a/mm/shmem.c b/mm/shmem.c index 2afcdbbdb685..d00c92fad48f 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2438,7 +2438,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
2438 | int len; | 2438 | int len; |
2439 | struct inode *inode; | 2439 | struct inode *inode; |
2440 | struct page *page; | 2440 | struct page *page; |
2441 | char *kaddr; | ||
2442 | struct shmem_inode_info *info; | 2441 | struct shmem_inode_info *info; |
2443 | 2442 | ||
2444 | len = strlen(symname) + 1; | 2443 | len = strlen(symname) + 1; |
@@ -2477,9 +2476,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
2477 | } | 2476 | } |
2478 | inode->i_mapping->a_ops = &shmem_aops; | 2477 | inode->i_mapping->a_ops = &shmem_aops; |
2479 | inode->i_op = &shmem_symlink_inode_operations; | 2478 | inode->i_op = &shmem_symlink_inode_operations; |
2480 | kaddr = kmap_atomic(page); | 2479 | inode_nohighmem(inode); |
2481 | memcpy(kaddr, symname, len); | 2480 | memcpy(page_address(page), symname, len); |
2482 | kunmap_atomic(kaddr); | ||
2483 | SetPageUptodate(page); | 2481 | SetPageUptodate(page); |
2484 | set_page_dirty(page); | 2482 | set_page_dirty(page); |
2485 | unlock_page(page); | 2483 | unlock_page(page); |
@@ -2492,23 +2490,34 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
2492 | return 0; | 2490 | return 0; |
2493 | } | 2491 | } |
2494 | 2492 | ||
2495 | static const char *shmem_follow_link(struct dentry *dentry, void **cookie) | 2493 | static void shmem_put_link(void *arg) |
2496 | { | 2494 | { |
2497 | struct page *page = NULL; | 2495 | mark_page_accessed(arg); |
2498 | int error = shmem_getpage(d_inode(dentry), 0, &page, SGP_READ, NULL); | 2496 | put_page(arg); |
2499 | if (error) | ||
2500 | return ERR_PTR(error); | ||
2501 | unlock_page(page); | ||
2502 | *cookie = page; | ||
2503 | return kmap(page); | ||
2504 | } | 2497 | } |
2505 | 2498 | ||
2506 | static void shmem_put_link(struct inode *unused, void *cookie) | 2499 | static const char *shmem_get_link(struct dentry *dentry, |
2500 | struct inode *inode, | ||
2501 | struct delayed_call *done) | ||
2507 | { | 2502 | { |
2508 | struct page *page = cookie; | 2503 | struct page *page = NULL; |
2509 | kunmap(page); | 2504 | int error; |
2510 | mark_page_accessed(page); | 2505 | if (!dentry) { |
2511 | page_cache_release(page); | 2506 | page = find_get_page(inode->i_mapping, 0); |
2507 | if (!page) | ||
2508 | return ERR_PTR(-ECHILD); | ||
2509 | if (!PageUptodate(page)) { | ||
2510 | put_page(page); | ||
2511 | return ERR_PTR(-ECHILD); | ||
2512 | } | ||
2513 | } else { | ||
2514 | error = shmem_getpage(inode, 0, &page, SGP_READ, NULL); | ||
2515 | if (error) | ||
2516 | return ERR_PTR(error); | ||
2517 | unlock_page(page); | ||
2518 | } | ||
2519 | set_delayed_call(done, shmem_put_link, page); | ||
2520 | return page_address(page); | ||
2512 | } | 2521 | } |
2513 | 2522 | ||
2514 | #ifdef CONFIG_TMPFS_XATTR | 2523 | #ifdef CONFIG_TMPFS_XATTR |
@@ -2653,7 +2662,7 @@ static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
2653 | 2662 | ||
2654 | static const struct inode_operations shmem_short_symlink_operations = { | 2663 | static const struct inode_operations shmem_short_symlink_operations = { |
2655 | .readlink = generic_readlink, | 2664 | .readlink = generic_readlink, |
2656 | .follow_link = simple_follow_link, | 2665 | .get_link = simple_get_link, |
2657 | #ifdef CONFIG_TMPFS_XATTR | 2666 | #ifdef CONFIG_TMPFS_XATTR |
2658 | .setxattr = shmem_setxattr, | 2667 | .setxattr = shmem_setxattr, |
2659 | .getxattr = shmem_getxattr, | 2668 | .getxattr = shmem_getxattr, |
@@ -2664,8 +2673,7 @@ static const struct inode_operations shmem_short_symlink_operations = { | |||
2664 | 2673 | ||
2665 | static const struct inode_operations shmem_symlink_inode_operations = { | 2674 | static const struct inode_operations shmem_symlink_inode_operations = { |
2666 | .readlink = generic_readlink, | 2675 | .readlink = generic_readlink, |
2667 | .follow_link = shmem_follow_link, | 2676 | .get_link = shmem_get_link, |
2668 | .put_link = shmem_put_link, | ||
2669 | #ifdef CONFIG_TMPFS_XATTR | 2677 | #ifdef CONFIG_TMPFS_XATTR |
2670 | .setxattr = shmem_setxattr, | 2678 | .setxattr = shmem_setxattr, |
2671 | .getxattr = shmem_getxattr, | 2679 | .getxattr = shmem_getxattr, |