summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-11-17 01:07:57 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-12-08 22:41:36 -0500
commit21fc61c73c3903c4c312d0802da01ec2b323d174 (patch)
treea26c29e3fbb766f00b023724e9e5b8b9bba9b879 /fs/namei.c
parentaa80deab33a8fb180e718f5e45514db19aade165 (diff)
downloadlinux-21fc61c73c3903c4c312d0802da01ec2b323d174.tar.bz2
don't put symlink bodies in pagecache into highmem
kmap() in page_follow_link_light() needed to go - allowing to hold an arbitrary number of kmaps for long is a great way to deadlocking the system. new helper (inode_nohighmem(inode)) needs to be used for pagecache symlinks inodes; done for all in-tree cases. page_follow_link_light() instrumented to yell about anything missed. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4bae5cbfaa85..2808958e6c67 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4527,7 +4527,8 @@ static const char *page_getlink(struct dentry * dentry, void **cookie)
if (IS_ERR(page))
return (char*)page;
*cookie = page;
- kaddr = kmap(page);
+ BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM);
+ kaddr = page_address(page);
nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
return kaddr;
}
@@ -4541,7 +4542,6 @@ EXPORT_SYMBOL(page_follow_link_light);
void page_put_link(struct inode *unused, void *cookie)
{
struct page *page = cookie;
- kunmap(page);
page_cache_release(page);
}
EXPORT_SYMBOL(page_put_link);
@@ -4565,7 +4565,6 @@ int __page_symlink(struct inode *inode, const char *symname, int len, int nofs)
struct page *page;
void *fsdata;
int err;
- char *kaddr;
unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
if (nofs)
flags |= AOP_FLAG_NOFS;
@@ -4576,9 +4575,7 @@ retry:
if (err)
goto fail;
- kaddr = kmap_atomic(page);
- memcpy(kaddr, symname, len-1);
- kunmap_atomic(kaddr);
+ memcpy(page_address(page), symname, len-1);
err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
page, fsdata);