dir.c (2ac5e38ea4203852d6e99edd3cf11f044b0a409f) | dir.c (b68572e07c58324cb8c274f1d84a20cad479c2d3) |
---|---|
1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 2125 unchanged lines hidden (view full) --- 2134static atomic_long_t nfs_access_nr_entries; 2135 2136static unsigned long nfs_access_max_cachesize = ULONG_MAX; 2137module_param(nfs_access_max_cachesize, ulong, 0644); 2138MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length"); 2139 2140static void nfs_access_free_entry(struct nfs_access_entry *entry) 2141{ | 1/* 2 * linux/fs/nfs/dir.c 3 * 4 * Copyright (C) 1992 Rick Sladkey 5 * 6 * nfs directory handling functions 7 * 8 * 10 Apr 1996 Added silly rename for unlink --okir --- 2125 unchanged lines hidden (view full) --- 2134static atomic_long_t nfs_access_nr_entries; 2135 2136static unsigned long nfs_access_max_cachesize = ULONG_MAX; 2137module_param(nfs_access_max_cachesize, ulong, 0644); 2138MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length"); 2139 2140static void nfs_access_free_entry(struct nfs_access_entry *entry) 2141{ |
2142 put_rpccred(entry->cred); | 2142 put_cred(entry->cred); |
2143 kfree_rcu(entry, rcu_head); 2144 smp_mb__before_atomic(); 2145 atomic_long_dec(&nfs_access_nr_entries); 2146 smp_mb__after_atomic(); 2147} 2148 2149static void nfs_access_free_list(struct list_head *head) 2150{ --- 109 unchanged lines hidden (view full) --- 2260 spin_lock(&inode->i_lock); 2261 __nfs_access_zap_cache(NFS_I(inode), &head); 2262 spin_unlock(&inode->i_lock); 2263 spin_unlock(&nfs_access_lru_lock); 2264 nfs_access_free_list(&head); 2265} 2266EXPORT_SYMBOL_GPL(nfs_access_zap_cache); 2267 | 2143 kfree_rcu(entry, rcu_head); 2144 smp_mb__before_atomic(); 2145 atomic_long_dec(&nfs_access_nr_entries); 2146 smp_mb__after_atomic(); 2147} 2148 2149static void nfs_access_free_list(struct list_head *head) 2150{ --- 109 unchanged lines hidden (view full) --- 2260 spin_lock(&inode->i_lock); 2261 __nfs_access_zap_cache(NFS_I(inode), &head); 2262 spin_unlock(&inode->i_lock); 2263 spin_unlock(&nfs_access_lru_lock); 2264 nfs_access_free_list(&head); 2265} 2266EXPORT_SYMBOL_GPL(nfs_access_zap_cache); 2267 |
2268static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) | 2268static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred) |
2269{ 2270 struct rb_node *n = NFS_I(inode)->access_cache.rb_node; | 2269{ 2270 struct rb_node *n = NFS_I(inode)->access_cache.rb_node; |
2271 struct nfs_access_entry *entry; | |
2272 2273 while (n != NULL) { | 2271 2272 while (n != NULL) { |
2274 entry = rb_entry(n, struct nfs_access_entry, rb_node); | 2273 struct nfs_access_entry *entry = 2274 rb_entry(n, struct nfs_access_entry, rb_node); 2275 int cmp = cred_fscmp(cred, entry->cred); |
2275 | 2276 |
2276 if (cred < entry->cred) | 2277 if (cmp < 0) |
2277 n = n->rb_left; | 2278 n = n->rb_left; |
2278 else if (cred > entry->cred) | 2279 else if (cmp > 0) |
2279 n = n->rb_right; 2280 else 2281 return entry; 2282 } 2283 return NULL; 2284} 2285 | 2280 n = n->rb_right; 2281 else 2282 return entry; 2283 } 2284 return NULL; 2285} 2286 |
2286static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res, bool may_block) | 2287static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block) |
2287{ 2288 struct nfs_inode *nfsi = NFS_I(inode); 2289 struct nfs_access_entry *cache; 2290 bool retry = true; 2291 int err; 2292 2293 spin_lock(&inode->i_lock); 2294 for(;;) { --- 26 unchanged lines hidden (view full) --- 2321 spin_unlock(&inode->i_lock); 2322 return err; 2323out_zap: 2324 spin_unlock(&inode->i_lock); 2325 nfs_access_zap_cache(inode); 2326 return -ENOENT; 2327} 2328 | 2288{ 2289 struct nfs_inode *nfsi = NFS_I(inode); 2290 struct nfs_access_entry *cache; 2291 bool retry = true; 2292 int err; 2293 2294 spin_lock(&inode->i_lock); 2295 for(;;) { --- 26 unchanged lines hidden (view full) --- 2322 spin_unlock(&inode->i_lock); 2323 return err; 2324out_zap: 2325 spin_unlock(&inode->i_lock); 2326 nfs_access_zap_cache(inode); 2327 return -ENOENT; 2328} 2329 |
2329static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) | 2330static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res) |
2330{ 2331 /* Only check the most recently returned cache entry, 2332 * but do it without locking. 2333 */ 2334 struct nfs_inode *nfsi = NFS_I(inode); 2335 struct nfs_access_entry *cache; 2336 int err = -ECHILD; 2337 struct list_head *lh; --- 20 unchanged lines hidden (view full) --- 2358 2359static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set) 2360{ 2361 struct nfs_inode *nfsi = NFS_I(inode); 2362 struct rb_root *root_node = &nfsi->access_cache; 2363 struct rb_node **p = &root_node->rb_node; 2364 struct rb_node *parent = NULL; 2365 struct nfs_access_entry *entry; | 2331{ 2332 /* Only check the most recently returned cache entry, 2333 * but do it without locking. 2334 */ 2335 struct nfs_inode *nfsi = NFS_I(inode); 2336 struct nfs_access_entry *cache; 2337 int err = -ECHILD; 2338 struct list_head *lh; --- 20 unchanged lines hidden (view full) --- 2359 2360static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set) 2361{ 2362 struct nfs_inode *nfsi = NFS_I(inode); 2363 struct rb_root *root_node = &nfsi->access_cache; 2364 struct rb_node **p = &root_node->rb_node; 2365 struct rb_node *parent = NULL; 2366 struct nfs_access_entry *entry; |
2367 int cmp; |
|
2366 2367 spin_lock(&inode->i_lock); 2368 while (*p != NULL) { 2369 parent = *p; 2370 entry = rb_entry(parent, struct nfs_access_entry, rb_node); | 2368 2369 spin_lock(&inode->i_lock); 2370 while (*p != NULL) { 2371 parent = *p; 2372 entry = rb_entry(parent, struct nfs_access_entry, rb_node); |
2373 cmp = cred_fscmp(set->cred, entry->cred); |
|
2371 | 2374 |
2372 if (set->cred < entry->cred) | 2375 if (cmp < 0) |
2373 p = &parent->rb_left; | 2376 p = &parent->rb_left; |
2374 else if (set->cred > entry->cred) | 2377 else if (cmp > 0) |
2375 p = &parent->rb_right; 2376 else 2377 goto found; 2378 } 2379 rb_link_node(&set->rb_node, parent, p); 2380 rb_insert_color(&set->rb_node, root_node); 2381 list_add_tail(&set->lru, &nfsi->access_cache_entry_lru); 2382 spin_unlock(&inode->i_lock); --- 7 unchanged lines hidden (view full) --- 2390} 2391 2392void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) 2393{ 2394 struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); 2395 if (cache == NULL) 2396 return; 2397 RB_CLEAR_NODE(&cache->rb_node); | 2378 p = &parent->rb_right; 2379 else 2380 goto found; 2381 } 2382 rb_link_node(&set->rb_node, parent, p); 2383 rb_insert_color(&set->rb_node, root_node); 2384 list_add_tail(&set->lru, &nfsi->access_cache_entry_lru); 2385 spin_unlock(&inode->i_lock); --- 7 unchanged lines hidden (view full) --- 2393} 2394 2395void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) 2396{ 2397 struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); 2398 if (cache == NULL) 2399 return; 2400 RB_CLEAR_NODE(&cache->rb_node); |
2398 cache->cred = get_rpccred(set->cred); | 2401 cache->cred = get_cred(set->cred); |
2399 cache->mask = set->mask; 2400 2401 /* The above field assignments must be visible 2402 * before this item appears on the lru. We cannot easily 2403 * use rcu_assign_pointer, so just force the memory barrier. 2404 */ 2405 smp_wmb(); 2406 nfs_access_add_rbtree(inode, cache); --- 47 unchanged lines hidden (view full) --- 2454} 2455 2456void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result) 2457{ 2458 entry->mask = access_result; 2459} 2460EXPORT_SYMBOL_GPL(nfs_access_set_mask); 2461 | 2402 cache->mask = set->mask; 2403 2404 /* The above field assignments must be visible 2405 * before this item appears on the lru. We cannot easily 2406 * use rcu_assign_pointer, so just force the memory barrier. 2407 */ 2408 smp_wmb(); 2409 nfs_access_add_rbtree(inode, cache); --- 47 unchanged lines hidden (view full) --- 2457} 2458 2459void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result) 2460{ 2461 entry->mask = access_result; 2462} 2463EXPORT_SYMBOL_GPL(nfs_access_set_mask); 2464 |
2462static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | 2465static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask) |
2463{ 2464 struct nfs_access_entry cache; 2465 bool may_block = (mask & MAY_NOT_BLOCK) == 0; 2466 int cache_mask; 2467 int status; 2468 2469 trace_nfs_access_enter(inode); 2470 --- 47 unchanged lines hidden (view full) --- 2518 mask |= MAY_READ; 2519 if ((openflags & O_ACCMODE) != O_RDONLY) 2520 mask |= MAY_WRITE; 2521 } 2522 2523 return mask; 2524} 2525 | 2466{ 2467 struct nfs_access_entry cache; 2468 bool may_block = (mask & MAY_NOT_BLOCK) == 0; 2469 int cache_mask; 2470 int status; 2471 2472 trace_nfs_access_enter(inode); 2473 --- 47 unchanged lines hidden (view full) --- 2521 mask |= MAY_READ; 2522 if ((openflags & O_ACCMODE) != O_RDONLY) 2523 mask |= MAY_WRITE; 2524 } 2525 2526 return mask; 2527} 2528 |
2526int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) | 2529int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags) |
2527{ 2528 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); 2529} 2530EXPORT_SYMBOL_GPL(nfs_may_open); 2531 2532static int nfs_execute_ok(struct inode *inode, int mask) 2533{ 2534 struct nfs_server *server = NFS_SERVER(inode); --- 8 unchanged lines hidden (view full) --- 2543 } 2544 if (ret == 0 && !execute_ok(inode)) 2545 ret = -EACCES; 2546 return ret; 2547} 2548 2549int nfs_permission(struct inode *inode, int mask) 2550{ | 2530{ 2531 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); 2532} 2533EXPORT_SYMBOL_GPL(nfs_may_open); 2534 2535static int nfs_execute_ok(struct inode *inode, int mask) 2536{ 2537 struct nfs_server *server = NFS_SERVER(inode); --- 8 unchanged lines hidden (view full) --- 2546 } 2547 if (ret == 0 && !execute_ok(inode)) 2548 ret = -EACCES; 2549 return ret; 2550} 2551 2552int nfs_permission(struct inode *inode, int mask) 2553{ |
2551 struct rpc_cred *cred; | 2554 const struct cred *cred = current_cred(); |
2552 int res = 0; 2553 2554 nfs_inc_stats(inode, NFSIOS_VFSACCESS); 2555 2556 if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 2557 goto out; 2558 /* Is this sys_access() ? */ 2559 if (mask & (MAY_ACCESS | MAY_CHDIR)) --- 17 unchanged lines hidden (view full) --- 2577 } 2578 2579force_lookup: 2580 if (!NFS_PROTO(inode)->access) 2581 goto out_notsup; 2582 2583 /* Always try fast lookups first */ 2584 rcu_read_lock(); | 2555 int res = 0; 2556 2557 nfs_inc_stats(inode, NFSIOS_VFSACCESS); 2558 2559 if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 2560 goto out; 2561 /* Is this sys_access() ? */ 2562 if (mask & (MAY_ACCESS | MAY_CHDIR)) --- 17 unchanged lines hidden (view full) --- 2580 } 2581 2582force_lookup: 2583 if (!NFS_PROTO(inode)->access) 2584 goto out_notsup; 2585 2586 /* Always try fast lookups first */ 2587 rcu_read_lock(); |
2585 cred = rpc_lookup_cred_nonblock(); 2586 if (!IS_ERR(cred)) 2587 res = nfs_do_access(inode, cred, mask|MAY_NOT_BLOCK); 2588 else 2589 res = PTR_ERR(cred); | 2588 res = nfs_do_access(inode, cred, mask|MAY_NOT_BLOCK); |
2590 rcu_read_unlock(); 2591 if (res == -ECHILD && !(mask & MAY_NOT_BLOCK)) { 2592 /* Fast lookup failed, try the slow way */ | 2589 rcu_read_unlock(); 2590 if (res == -ECHILD && !(mask & MAY_NOT_BLOCK)) { 2591 /* Fast lookup failed, try the slow way */ |
2593 cred = rpc_lookup_cred(); 2594 if (!IS_ERR(cred)) { 2595 res = nfs_do_access(inode, cred, mask); 2596 put_rpccred(cred); 2597 } else 2598 res = PTR_ERR(cred); | 2592 res = nfs_do_access(inode, cred, mask); |
2599 } 2600out: 2601 if (!res && (mask & MAY_EXEC)) 2602 res = nfs_execute_ok(inode, mask); 2603 2604 dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n", 2605 inode->i_sb->s_id, inode->i_ino, mask, res); 2606 return res; --- 17 unchanged lines hidden --- | 2593 } 2594out: 2595 if (!res && (mask & MAY_EXEC)) 2596 res = nfs_execute_ok(inode, mask); 2597 2598 dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n", 2599 inode->i_sb->s_id, inode->i_ino, mask, res); 2600 return res; --- 17 unchanged lines hidden --- |