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 ---