@@ -1231,7 +1231,8 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
1231
1231
}
1232
1232
1233
1233
static int
1234
- nfs_lookup_revalidate (struct dentry * dentry , unsigned int flags )
1234
+ __nfs_lookup_revalidate (struct dentry * dentry , unsigned int flags ,
1235
+ int (* reval )(struct inode * , struct dentry * , unsigned int ))
1235
1236
{
1236
1237
struct dentry * parent ;
1237
1238
struct inode * dir ;
@@ -1242,17 +1243,22 @@ nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1242
1243
dir = d_inode_rcu (parent );
1243
1244
if (!dir )
1244
1245
return - ECHILD ;
1245
- ret = nfs_do_lookup_revalidate (dir , dentry , flags );
1246
+ ret = reval (dir , dentry , flags );
1246
1247
if (parent != READ_ONCE (dentry -> d_parent ))
1247
1248
return - ECHILD ;
1248
1249
} else {
1249
1250
parent = dget_parent (dentry );
1250
- ret = nfs_do_lookup_revalidate (d_inode (parent ), dentry , flags );
1251
+ ret = reval (d_inode (parent ), dentry , flags );
1251
1252
dput (parent );
1252
1253
}
1253
1254
return ret ;
1254
1255
}
1255
1256
1257
+ static int nfs_lookup_revalidate (struct dentry * dentry , unsigned int flags )
1258
+ {
1259
+ return __nfs_lookup_revalidate (dentry , flags , nfs_do_lookup_revalidate );
1260
+ }
1261
+
1256
1262
/*
1257
1263
* A weaker form of d_revalidate for revalidating just the d_inode(dentry)
1258
1264
* when we don't really care about the dentry name. This is called when a
@@ -1609,62 +1615,55 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1609
1615
}
1610
1616
EXPORT_SYMBOL_GPL (nfs_atomic_open );
1611
1617
1612
- static int nfs4_lookup_revalidate (struct dentry * dentry , unsigned int flags )
1618
+ static int
1619
+ nfs4_do_lookup_revalidate (struct inode * dir , struct dentry * dentry ,
1620
+ unsigned int flags )
1613
1621
{
1614
1622
struct inode * inode ;
1615
- int ret = 0 ;
1616
1623
1617
1624
if (!(flags & LOOKUP_OPEN ) || (flags & LOOKUP_DIRECTORY ))
1618
- goto no_open ;
1625
+ goto full_reval ;
1619
1626
if (d_mountpoint (dentry ))
1620
- goto no_open ;
1621
- if (NFS_SB (dentry -> d_sb )-> caps & NFS_CAP_ATOMIC_OPEN_V1 )
1622
- goto no_open ;
1627
+ goto full_reval ;
1623
1628
1624
1629
inode = d_inode (dentry );
1625
1630
1626
1631
/* We can't create new files in nfs_open_revalidate(), so we
1627
1632
* optimize away revalidation of negative dentries.
1628
1633
*/
1629
- if (inode == NULL ) {
1630
- struct dentry * parent ;
1631
- struct inode * dir ;
1632
-
1633
- if (flags & LOOKUP_RCU ) {
1634
- parent = READ_ONCE (dentry -> d_parent );
1635
- dir = d_inode_rcu (parent );
1636
- if (!dir )
1637
- return - ECHILD ;
1638
- } else {
1639
- parent = dget_parent (dentry );
1640
- dir = d_inode (parent );
1641
- }
1642
- if (!nfs_neg_need_reval (dir , dentry , flags ))
1643
- ret = 1 ;
1644
- else if (flags & LOOKUP_RCU )
1645
- ret = - ECHILD ;
1646
- if (!(flags & LOOKUP_RCU ))
1647
- dput (parent );
1648
- else if (parent != READ_ONCE (dentry -> d_parent ))
1649
- return - ECHILD ;
1650
- goto out ;
1651
- }
1634
+ if (inode == NULL )
1635
+ goto full_reval ;
1636
+
1637
+ if (NFS_PROTO (dir )-> have_delegation (inode , FMODE_READ ))
1638
+ return nfs_lookup_revalidate_delegated (dir , dentry , inode );
1652
1639
1653
1640
/* NFS only supports OPEN on regular files */
1654
1641
if (!S_ISREG (inode -> i_mode ))
1655
- goto no_open ;
1642
+ goto full_reval ;
1643
+
1656
1644
/* We cannot do exclusive creation on a positive dentry */
1657
- if (flags & LOOKUP_EXCL )
1658
- goto no_open ;
1645
+ if (flags & (LOOKUP_EXCL | LOOKUP_REVAL ))
1646
+ goto reval_dentry ;
1647
+
1648
+ /* Check if the directory changed */
1649
+ if (!nfs_check_verifier (dir , dentry , flags & LOOKUP_RCU ))
1650
+ goto reval_dentry ;
1659
1651
1660
1652
/* Let f_op->open() actually open (and revalidate) the file */
1661
- ret = 1 ;
1653
+ return 1 ;
1654
+ reval_dentry :
1655
+ if (flags & LOOKUP_RCU )
1656
+ return - ECHILD ;
1657
+ return nfs_lookup_revalidate_dentry (dir , dentry , inode );;
1662
1658
1663
- out :
1664
- return ret ;
1659
+ full_reval :
1660
+ return nfs_do_lookup_revalidate (dir , dentry , flags );
1661
+ }
1665
1662
1666
- no_open :
1667
- return nfs_lookup_revalidate (dentry , flags );
1663
+ static int nfs4_lookup_revalidate (struct dentry * dentry , unsigned int flags )
1664
+ {
1665
+ return __nfs_lookup_revalidate (dentry , flags ,
1666
+ nfs4_do_lookup_revalidate );
1668
1667
}
1669
1668
1670
1669
#endif /* CONFIG_NFSV4 */
0 commit comments