Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

teach nfs_get_link() to work in RCU mode

based upon the corresponding patch from Neil's March patchset,
again with kmap-related horrors removed.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 0d0def49 1a384eaa

+42 -10
+21
fs/nfs/inode.c
··· 1087 1087 || NFS_STALE(inode); 1088 1088 } 1089 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 + 1090 1111 /** 1091 1112 * __nfs_revalidate_mapping - Revalidate the pagecache 1092 1113 * @inode - pointer to host inode
+20 -10
fs/nfs/symlink.c
··· 48 48 struct page *page; 49 49 void *err; 50 50 51 - if (!dentry) 52 - return ERR_PTR(-ECHILD); 53 - 54 - err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); 55 - if (err) 56 - return err; 57 - page = read_cache_page(&inode->i_data, 0, 58 - (filler_t *)nfs_symlink_filler, inode); 59 - if (IS_ERR(page)) 60 - return ERR_CAST(page); 51 + if (!dentry) { 52 + err = ERR_PTR(nfs_revalidate_mapping_rcu(inode)); 53 + if (err) 54 + return err; 55 + page = find_get_page(inode->i_mapping, 0); 56 + if (!page) 57 + return ERR_PTR(-ECHILD); 58 + if (!PageUptodate(page)) { 59 + put_page(page); 60 + return ERR_PTR(-ECHILD); 61 + } 62 + } else { 63 + err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); 64 + if (err) 65 + return err; 66 + page = read_cache_page(&inode->i_data, 0, 67 + (filler_t *)nfs_symlink_filler, inode); 68 + if (IS_ERR(page)) 69 + return ERR_CAST(page); 70 + } 61 71 *cookie = page; 62 72 return page_address(page); 63 73 }
+1
include/linux/nfs_fs.h
··· 359 359 extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode); 360 360 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); 361 361 extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); 362 + extern int nfs_revalidate_mapping_rcu(struct inode *inode); 362 363 extern int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping); 363 364 extern int nfs_setattr(struct dentry *, struct iattr *); 364 365 extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);