From 21fc61c73c3903c4c312d0802da01ec2b323d174 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Nov 2015 01:07:57 -0500 Subject: 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 --- fs/squashfs/inode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/squashfs') 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 @@ #include #include #include +#include #include "squashfs_fs.h" #include "squashfs_fs_sb.h" @@ -291,6 +292,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); inode->i_op = &squashfs_symlink_inode_ops; + inode_nohighmem(inode); inode->i_data.a_ops = &squashfs_symlink_aops; inode->i_mode |= S_IFLNK; squashfs_i(inode)->start = block; -- cgit From 6b2553918d8b4e6de9853fd6315bec7271a2e592 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Nov 2015 10:20:54 -0500 Subject: replace ->follow_link() with new method that could stay in RCU mode new method: ->get_link(); replacement of ->follow_link(). The differences are: * inode and dentry are passed separately * might be called both in RCU and non-RCU mode; the former is indicated by passing it a NULL dentry. * when called that way it isn't allowed to block and should return ERR_PTR(-ECHILD) if it needs to be called in non-RCU mode. It's a flagday change - the old method is gone, all in-tree instances converted. Conversion isn't hard; said that, so far very few instances do not immediately bail out when called in RCU mode. That'll change in the next commits. Signed-off-by: Al Viro --- fs/squashfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index 12806dffb345..7c635a5da783 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c @@ -119,7 +119,7 @@ const struct address_space_operations squashfs_symlink_aops = { const struct inode_operations squashfs_symlink_inode_ops = { .readlink = generic_readlink, - .follow_link = page_follow_link_light, + .get_link = page_get_link, .put_link = page_put_link, .getxattr = generic_getxattr, .listxattr = squashfs_listxattr -- cgit From fceef393a538134f03b778c5d2519e670269342f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 29 Dec 2015 15:58:39 -0500 Subject: switch ->get_link() to delayed_call, kill ->put_link() Signed-off-by: Al Viro --- fs/squashfs/symlink.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/squashfs') diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index 7c635a5da783..dbcc2f54bad4 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c @@ -120,7 +120,6 @@ const struct address_space_operations squashfs_symlink_aops = { const struct inode_operations squashfs_symlink_inode_ops = { .readlink = generic_readlink, .get_link = page_get_link, - .put_link = page_put_link, .getxattr = generic_getxattr, .listxattr = squashfs_listxattr }; -- cgit