Lines Matching +full:wait +full:- +full:monitoring +full:- +full:ns
1 // SPDX-License-Identifier: GPL-2.0
5 * (c) 2015 - Jeff Layton <jeff.layton@primarydata.com>
7 * An nfsd_file object is a per-file collection of open state that binds
9 * - a struct file *
10 * - a user credential
11 * - a network namespace
12 * - a read-ahead context
13 * - monitoring for writeback errors
15 * nfsd_file objects are reference-counted. Consumers acquire a new
21 * * non-garbage-collected: When a consumer wants to precisely control
22 * the lifetime of a file's open state, it acquires a non-garbage-
26 * * garbage-collected: When a consumer does not control the lifetime
27 * of open state, it acquires a garbage-collected nfsd_file. The
29 * during which it may be re-used.
83 if (!uid_eq(c1->fsuid, c2->fsuid)) in nfsd_match_cred()
85 if (!gid_eq(c1->fsgid, c2->fsgid)) in nfsd_match_cred()
87 if (c1->group_info == NULL || c2->group_info == NULL) in nfsd_match_cred()
88 return c1->group_info == c2->group_info; in nfsd_match_cred()
89 if (c1->group_info->ngroups != c2->group_info->ngroups) in nfsd_match_cred()
91 for (i = 0; i < c1->group_info->ngroups; i++) { in nfsd_match_cred()
92 if (!gid_eq(c1->group_info->gid[i], c2->group_info->gid[i])) in nfsd_match_cred()
124 put_cred(nf->nf_cred); in nfsd_file_slab_free()
140 if (!refcount_inc_not_zero(&nfm->nfm_ref)) in nfsd_file_mark_get()
148 if (refcount_dec_and_test(&nfm->nfm_ref)) { in nfsd_file_mark_put()
149 fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group); in nfsd_file_mark_put()
150 fsnotify_put_mark(&nfm->nfm_mark); in nfsd_file_mark_put()
185 fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group); in nfsd_file_mark_find_or_create()
186 new->nfm_mark.mask = FS_ATTRIB|FS_DELETE_SELF; in nfsd_file_mark_find_or_create()
187 refcount_set(&new->nfm_ref, 1); in nfsd_file_mark_find_or_create()
189 err = fsnotify_add_inode_mark(&new->nfm_mark, inode, 0); in nfsd_file_mark_find_or_create()
197 * mark->group will be NULL. Thus, we can't let the nfm_ref in nfsd_file_mark_find_or_create()
203 fsnotify_put_mark(&new->nfm_mark); in nfsd_file_mark_find_or_create()
204 } while (unlikely(err == -EEXIST)); in nfsd_file_mark_find_or_create()
220 INIT_LIST_HEAD(&nf->nf_lru); in nfsd_file_alloc()
221 INIT_LIST_HEAD(&nf->nf_gc); in nfsd_file_alloc()
222 nf->nf_birthtime = ktime_get(); in nfsd_file_alloc()
223 nf->nf_file = NULL; in nfsd_file_alloc()
224 nf->nf_cred = get_current_cred(); in nfsd_file_alloc()
225 nf->nf_net = net; in nfsd_file_alloc()
226 nf->nf_flags = want_gc ? in nfsd_file_alloc()
229 nf->nf_inode = inode; in nfsd_file_alloc()
230 refcount_set(&nf->nf_ref, 1); in nfsd_file_alloc()
231 nf->nf_may = need; in nfsd_file_alloc()
232 nf->nf_mark = NULL; in nfsd_file_alloc()
237 * nfsd_file_check_write_error - check for writeback errors on a file
246 struct file *file = nf->nf_file; in nfsd_file_check_write_error()
248 if ((file->f_mode & FMODE_WRITE) && in nfsd_file_check_write_error()
249 filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err))) in nfsd_file_check_write_error()
250 nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id)); in nfsd_file_check_write_error()
257 rhltable_remove(&nfsd_file_rhltable, &nf->nf_rlist, in nfsd_file_hash_remove()
264 if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { in nfsd_file_unhash()
274 s64 age = ktime_to_ms(ktime_sub(ktime_get(), nf->nf_birthtime)); in nfsd_file_free()
282 if (nf->nf_mark) in nfsd_file_free()
283 nfsd_file_mark_put(nf->nf_mark); in nfsd_file_free()
284 if (nf->nf_file) { in nfsd_file_free()
286 nfsd_filp_close(nf->nf_file); in nfsd_file_free()
293 if (WARN_ON_ONCE(!list_empty(&nf->nf_lru))) in nfsd_file_free()
296 call_rcu(&nf->nf_rcu, nfsd_file_slab_free); in nfsd_file_free()
302 struct file *file = nf->nf_file; in nfsd_file_check_writeback()
306 if (!(file->f_mode & FMODE_WRITE)) in nfsd_file_check_writeback()
311 * On others, there is no need to wait for writeback. in nfsd_file_check_writeback()
313 if (!(file_inode(file)->i_sb->s_export_op->flags & EXPORT_OP_FLUSH_ON_CLOSE)) in nfsd_file_check_writeback()
316 mapping = file->f_mapping; in nfsd_file_check_writeback()
324 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); in nfsd_file_lru_add()
325 if (list_lru_add_obj(&nfsd_file_lru, &nf->nf_lru)) { in nfsd_file_lru_add()
334 if (list_lru_del_obj(&nfsd_file_lru, &nf->nf_lru)) { in nfsd_file_lru_remove()
344 if (nf && refcount_inc_not_zero(&nf->nf_ref)) in nfsd_file_get()
350 * nfsd_file_put - put the reference to a nfsd_file
353 * Put a reference to a nfsd_file. In the non-GC case, we just put the
363 if (test_bit(NFSD_FILE_GC, &nf->nf_flags) && in nfsd_file_put()
364 test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { in nfsd_file_put()
369 if (refcount_dec_not_one(&nf->nf_ref)) in nfsd_file_put()
375 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { in nfsd_file_put()
389 if (refcount_dec_and_test(&nf->nf_ref)) in nfsd_file_put()
394 * nfsd_file_put_local - put nfsd_file reference and arm nfsd_serv_put in caller
403 struct net *net = nf->nf_net; in nfsd_file_put_local()
410 * nfsd_file_file - get the backing file of an nfsd_file
418 return nf->nf_file; in nfsd_file_file()
428 list_del_init(&nf->nf_gc); in nfsd_file_dispose_list()
434 * nfsd_file_dispose_list_delayed - move list of dead files to net's freeme list
438 * be disposed of by the per-net garbage collector.
446 struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id); in nfsd_file_dispose_list_delayed()
447 struct nfsd_fcache_disposal *l = nn->fcache_disposal; in nfsd_file_dispose_list_delayed()
449 spin_lock(&l->lock); in nfsd_file_dispose_list_delayed()
450 list_move_tail(&nf->nf_gc, &l->freeme); in nfsd_file_dispose_list_delayed()
451 spin_unlock(&l->lock); in nfsd_file_dispose_list_delayed()
452 svc_wake_up(nn->nfsd_serv); in nfsd_file_dispose_list_delayed()
457 * nfsd_file_net_dispose - deal with nfsd_files waiting to be disposed.
462 * a per-net-ns queue. This function completes the disposal, either
467 struct nfsd_fcache_disposal *l = nn->fcache_disposal; in nfsd_file_net_dispose()
469 if (!list_empty(&l->freeme)) { in nfsd_file_net_dispose()
473 spin_lock(&l->lock); in nfsd_file_net_dispose()
474 for (i = 0; i < 8 && !list_empty(&l->freeme); i++) in nfsd_file_net_dispose()
475 list_move(l->freeme.next, &dispose); in nfsd_file_net_dispose()
476 spin_unlock(&l->lock); in nfsd_file_net_dispose()
477 if (!list_empty(&l->freeme)) in nfsd_file_net_dispose()
481 svc_wake_up(nn->nfsd_serv); in nfsd_file_net_dispose()
487 * nfsd_file_lru_cb - Examine an entry on the LRU list
505 WARN_ON_ONCE(!test_bit(NFSD_FILE_GC, &nf->nf_flags)); in nfsd_file_lru_cb()
517 if (test_and_clear_bit(NFSD_FILE_REFERENCED, &nf->nf_flags)) { in nfsd_file_lru_cb()
526 if (!refcount_dec_and_test(&nf->nf_ref)) { in nfsd_file_lru_cb()
528 list_lru_isolate(lru, &nf->nf_lru); in nfsd_file_lru_cb()
534 list_lru_isolate(lru, &nf->nf_lru); in nfsd_file_lru_cb()
535 list_add(&nf->nf_gc, head); in nfsd_file_lru_cb()
583 * nfsd_file_cond_queue - conditionally unhash and queue a nfsd_file
585 * @dispose: private list to queue successfully-put objects
609 if (refcount_sub_and_test(decrement, &nf->nf_ref)) { in nfsd_file_cond_queue()
610 list_add(&nf->nf_gc, dispose); in nfsd_file_cond_queue()
622 * undesirable behavior (e.g. spurious silly-renames when reexporting NFS).
629 * so we leave it up to the caller whether it wants to wait or not.
641 if (!test_bit(NFSD_FILE_GC, &nf->nf_flags)) in nfsd_file_queue_for_close()
649 * nfsd_file_close_inode - attempt a delayed close of a nfsd_file
667 * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file
673 * This is called from nfsd_rename and nfsd_unlink to avoid silly-renames
687 list_del_init(&nf->nf_gc); in nfsd_file_close_inode_sync()
699 if (fl->c.flc_flags & FL_LEASE) in nfsd_file_lease_notifier_call()
700 nfsd_file_close_inode(file_inode(fl->c.flc_file)); in nfsd_file_lease_notifier_call()
718 /* Should be no marks on non-regular files */ in nfsd_file_fsnotify_handle_event()
719 if (!S_ISREG(inode->i_mode)) { in nfsd_file_fsnotify_handle_event()
726 if (inode->i_nlink) in nfsd_file_fsnotify_handle_event()
753 ret = -ENOMEM; in nfsd_file_cache_init()
772 nfsd_file_shrinker = shrinker_alloc(0, "nfsd-filecache"); in nfsd_file_cache_init()
774 ret = -ENOMEM; in nfsd_file_cache_init()
779 nfsd_file_shrinker->count_objects = nfsd_file_lru_count; in nfsd_file_cache_init()
780 nfsd_file_shrinker->scan_objects = nfsd_file_lru_scan; in nfsd_file_cache_init()
781 nfsd_file_shrinker->seeks = 1; in nfsd_file_cache_init()
823 * @net: net-namespace to shut down the cache (may be NULL)
842 if (!net || nf->nf_net == net) in __nfsd_file_cache_purge()
848 } while (nf == ERR_PTR(-EAGAIN)); in __nfsd_file_cache_purge()
862 spin_lock_init(&l->lock); in nfsd_alloc_fcache_disposal()
863 INIT_LIST_HEAD(&l->freeme); in nfsd_alloc_fcache_disposal()
870 nfsd_file_dispose_list(&l->freeme); in nfsd_free_fcache_disposal()
878 struct nfsd_fcache_disposal *l = nn->fcache_disposal; in nfsd_free_fcache_disposal_net()
888 nn->fcache_disposal = nfsd_alloc_fcache_disposal(); in nfsd_file_cache_start_net()
889 return nn->fcache_disposal ? 0 : -ENOMEM; in nfsd_file_cache_start_net()
893 * nfsd_file_cache_purge - Remove all cache items associated with @net
961 if (nf->nf_may != need) in nfsd_file_lookup_locked()
963 if (nf->nf_net != net) in nfsd_file_lookup_locked()
965 if (!nfsd_match_cred(nf->nf_cred, cred)) in nfsd_file_lookup_locked()
967 if (test_bit(NFSD_FILE_GC, &nf->nf_flags) != want_gc) in nfsd_file_lookup_locked()
969 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) in nfsd_file_lookup_locked()
980 * nfsd_file_is_cached - are there any cached open files for this inode?
1001 if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) { in nfsd_file_is_cached()
1037 inode = d_inode(fhp->fh_dentry); in nfsd_file_do_acquire()
1050 refcount_dec(&nf->nf_ref); in nfsd_file_do_acquire()
1061 spin_lock(&inode->i_lock); in nfsd_file_do_acquire()
1064 spin_unlock(&inode->i_lock); in nfsd_file_do_acquire()
1070 ret = rhltable_insert(&nfsd_file_rhltable, &nf->nf_rlist, in nfsd_file_do_acquire()
1072 spin_unlock(&inode->i_lock); in nfsd_file_do_acquire()
1082 wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE); in nfsd_file_do_acquire()
1085 if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { in nfsd_file_do_acquire()
1098 status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); in nfsd_file_do_acquire()
1115 nf->nf_mark = nfsd_file_mark_find_or_create(inode); in nfsd_file_do_acquire()
1116 if (nf->nf_mark) { in nfsd_file_do_acquire()
1119 nf->nf_file = file; in nfsd_file_do_acquire()
1123 ret = nfsd_open_verified(fhp, may_flags, &nf->nf_file); in nfsd_file_do_acquire()
1124 if (ret == -EOPENSTALE && stale_retry) { in nfsd_file_do_acquire()
1128 &nf->nf_flags); in nfsd_file_do_acquire()
1129 if (refcount_dec_and_test(&nf->nf_ref)) in nfsd_file_do_acquire()
1144 if (status != nfs_ok || inode->i_nlink == 0) in nfsd_file_do_acquire()
1146 clear_and_wake_up_bit(NFSD_FILE_PENDING, &nf->nf_flags); in nfsd_file_do_acquire()
1151 if (refcount_dec_and_test(&nf->nf_ref)) in nfsd_file_do_acquire()
1158 * nfsd_file_acquire_gc - Get a struct nfsd_file with an open file
1164 * The nfsd_file object returned by this API is reference-counted
1165 * and garbage-collected. The object is retained for a few
1167 * wants to re-use it.
1170 * %nfs_ok - @pnf points to an nfsd_file with its reference
1184 * nfsd_file_acquire - Get a struct nfsd_file with an open file
1190 * The nfsd_file_object returned by this API is reference-counted
1191 * but not garbage-collected. The object is unhashed after the
1195 * %nfs_ok - @pnf points to an nfsd_file with its reference
1209 * nfsd_file_acquire_local - Get a struct nfsd_file with an open file for localio
1218 * filehandle and credential. No connection-based authorisation
1225 * The nfsd_file object returned by this API is reference-counted
1226 * and garbage-collected. The object is retained for a few
1228 * wants to re-use it.
1231 * %nfs_ok - @pnf points to an nfsd_file with its reference
1256 * nfsd_file_acquire_opened - Get a struct nfsd_file using existing open file
1260 * @file: cached, already-open file (may be NULL)
1264 * and @file is non-NULL, use it to instantiate a new nfsd_file instead of
1268 * %nfs_ok - @pnf points to an nfsd_file with its reference
1304 count = atomic_read(&ht->nelems); in nfsd_file_cache_stats_show()
1305 tbl = rht_dereference_rcu(ht->tbl, ht); in nfsd_file_cache_stats_show()
1306 buckets = tbl->size; in nfsd_file_cache_stats_show()
1331 seq_printf(m, "mean age (ms): -\n"); in nfsd_file_cache_stats_show()