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

nfs{,4}_lookup_validate(): use stable parent inode passed by caller

we can't kill __nfs_lookup_revalidate() completely, but ->d_parent boilerplate
in it is gone

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

+13 -30
+13 -30
fs/nfs/dir.c
··· 1732 1732 * cached dentry and do a new lookup. 1733 1733 */ 1734 1734 static int 1735 - nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, 1736 - unsigned int flags) 1735 + nfs_do_lookup_revalidate(struct inode *dir, const struct qstr *name, 1736 + struct dentry *dentry, unsigned int flags) 1737 1737 { 1738 1738 struct inode *inode; 1739 1739 int error = 0; ··· 1785 1785 } 1786 1786 1787 1787 static int 1788 - __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags, 1789 - int (*reval)(struct inode *, struct dentry *, unsigned int)) 1788 + __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) 1790 1789 { 1791 - struct dentry *parent; 1792 - struct inode *dir; 1793 - int ret; 1794 - 1795 1790 if (flags & LOOKUP_RCU) { 1796 1791 if (dentry->d_fsdata == NFS_FSDATA_BLOCKED) 1797 - return -ECHILD; 1798 - parent = READ_ONCE(dentry->d_parent); 1799 - dir = d_inode_rcu(parent); 1800 - if (!dir) 1801 - return -ECHILD; 1802 - ret = reval(dir, dentry, flags); 1803 - if (parent != READ_ONCE(dentry->d_parent)) 1804 1792 return -ECHILD; 1805 1793 } else { 1806 1794 /* Wait for unlink to complete - see unblock_revalidate() */ 1807 1795 wait_var_event(&dentry->d_fsdata, 1808 1796 smp_load_acquire(&dentry->d_fsdata) 1809 1797 != NFS_FSDATA_BLOCKED); 1810 - parent = dget_parent(dentry); 1811 - ret = reval(d_inode(parent), dentry, flags); 1812 - dput(parent); 1813 1798 } 1814 - return ret; 1799 + return 0; 1815 1800 } 1816 1801 1817 1802 static int nfs_lookup_revalidate(struct inode *dir, const struct qstr *name, 1818 1803 struct dentry *dentry, unsigned int flags) 1819 1804 { 1820 - return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate); 1805 + if (__nfs_lookup_revalidate(dentry, flags)) 1806 + return -ECHILD; 1807 + return nfs_do_lookup_revalidate(dir, name, dentry, flags); 1821 1808 } 1822 1809 1823 1810 static void block_revalidate(struct dentry *dentry) ··· 2203 2216 EXPORT_SYMBOL_GPL(nfs_atomic_open); 2204 2217 2205 2218 static int 2206 - nfs4_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, 2207 - unsigned int flags) 2219 + nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, 2220 + struct dentry *dentry, unsigned int flags) 2208 2221 { 2209 2222 struct inode *inode; 2223 + 2224 + if (__nfs_lookup_revalidate(dentry, flags)) 2225 + return -ECHILD; 2210 2226 2211 2227 trace_nfs_lookup_revalidate_enter(dir, dentry, flags); 2212 2228 ··· 2249 2259 return nfs_lookup_revalidate_dentry(dir, dentry, inode, flags); 2250 2260 2251 2261 full_reval: 2252 - return nfs_do_lookup_revalidate(dir, dentry, flags); 2253 - } 2254 - 2255 - static int nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, 2256 - struct dentry *dentry, unsigned int flags) 2257 - { 2258 - return __nfs_lookup_revalidate(dentry, flags, 2259 - nfs4_do_lookup_revalidate); 2262 + return nfs_do_lookup_revalidate(dir, name, dentry, flags); 2260 2263 } 2261 2264 2262 2265 #endif /* CONFIG_NFSV4 */