@@ -2228,21 +2228,37 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, st
2228
2228
return NULL ;
2229
2229
}
2230
2230
2231
- static int nfs_access_get_cached (struct inode * inode , struct rpc_cred * cred , struct nfs_access_entry * res )
2231
+ static int nfs_access_get_cached (struct inode * inode , struct rpc_cred * cred , struct nfs_access_entry * res , bool may_block )
2232
2232
{
2233
2233
struct nfs_inode * nfsi = NFS_I (inode );
2234
2234
struct nfs_access_entry * cache ;
2235
- int err = - ENOENT ;
2235
+ bool retry = true;
2236
+ int err ;
2236
2237
2237
2238
spin_lock (& inode -> i_lock );
2238
- if (nfsi -> cache_validity & NFS_INO_INVALID_ACCESS )
2239
- goto out_zap ;
2240
- cache = nfs_access_search_rbtree (inode , cred );
2241
- if (cache == NULL )
2242
- goto out ;
2243
- if (!nfs_have_delegated_attributes (inode ) &&
2244
- !time_in_range_open (jiffies , cache -> jiffies , cache -> jiffies + nfsi -> attrtimeo ))
2245
- goto out_stale ;
2239
+ for (;;) {
2240
+ if (nfsi -> cache_validity & NFS_INO_INVALID_ACCESS )
2241
+ goto out_zap ;
2242
+ cache = nfs_access_search_rbtree (inode , cred );
2243
+ err = - ENOENT ;
2244
+ if (cache == NULL )
2245
+ goto out ;
2246
+ /* Found an entry, is our attribute cache valid? */
2247
+ if (!nfs_attribute_cache_expired (inode ) &&
2248
+ !(nfsi -> cache_validity & NFS_INO_INVALID_ATTR ))
2249
+ break ;
2250
+ err = - ECHILD ;
2251
+ if (!may_block )
2252
+ goto out ;
2253
+ if (!retry )
2254
+ goto out_zap ;
2255
+ spin_unlock (& inode -> i_lock );
2256
+ err = __nfs_revalidate_inode (NFS_SERVER (inode ), inode );
2257
+ if (err )
2258
+ return err ;
2259
+ spin_lock (& inode -> i_lock );
2260
+ retry = false;
2261
+ }
2246
2262
res -> jiffies = cache -> jiffies ;
2247
2263
res -> cred = cache -> cred ;
2248
2264
res -> mask = cache -> mask ;
@@ -2251,12 +2267,6 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
2251
2267
out :
2252
2268
spin_unlock (& inode -> i_lock );
2253
2269
return err ;
2254
- out_stale :
2255
- rb_erase (& cache -> rb_node , & nfsi -> access_cache );
2256
- list_del (& cache -> lru );
2257
- spin_unlock (& inode -> i_lock );
2258
- nfs_access_free_entry (cache );
2259
- return - ENOENT ;
2260
2270
out_zap :
2261
2271
spin_unlock (& inode -> i_lock );
2262
2272
nfs_access_zap_cache (inode );
@@ -2283,13 +2293,12 @@ static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred,
2283
2293
cache = NULL ;
2284
2294
if (cache == NULL )
2285
2295
goto out ;
2286
- if (! nfs_have_delegated_attributes (inode ) &&
2287
- ! time_in_range_open ( jiffies , cache -> jiffies , cache -> jiffies + nfsi -> attrtimeo ) )
2296
+ err = nfs_revalidate_inode_rcu ( NFS_SERVER (inode ), inode );
2297
+ if ( err )
2288
2298
goto out ;
2289
2299
res -> jiffies = cache -> jiffies ;
2290
2300
res -> cred = cache -> cred ;
2291
2301
res -> mask = cache -> mask ;
2292
- err = 0 ;
2293
2302
out :
2294
2303
rcu_read_unlock ();
2295
2304
return err ;
@@ -2378,18 +2387,19 @@ EXPORT_SYMBOL_GPL(nfs_access_set_mask);
2378
2387
static int nfs_do_access (struct inode * inode , struct rpc_cred * cred , int mask )
2379
2388
{
2380
2389
struct nfs_access_entry cache ;
2390
+ bool may_block = (mask & MAY_NOT_BLOCK ) == 0 ;
2381
2391
int status ;
2382
2392
2383
2393
trace_nfs_access_enter (inode );
2384
2394
2385
2395
status = nfs_access_get_cached_rcu (inode , cred , & cache );
2386
2396
if (status != 0 )
2387
- status = nfs_access_get_cached (inode , cred , & cache );
2397
+ status = nfs_access_get_cached (inode , cred , & cache , may_block );
2388
2398
if (status == 0 )
2389
2399
goto out_cached ;
2390
2400
2391
2401
status = - ECHILD ;
2392
- if (mask & MAY_NOT_BLOCK )
2402
+ if (! may_block )
2393
2403
goto out ;
2394
2404
2395
2405
/* Be clever: ask server to check for all possible rights */
0 commit comments