Loading fs/nfsd/filecache.c +36 −25 Original line number Diff line number Diff line Loading @@ -661,6 +661,39 @@ static struct shrinker nfsd_file_shrinker = { .seeks = 1, }; /** * nfsd_file_cond_queue - conditionally unhash and queue a nfsd_file * @nf: nfsd_file to attempt to queue * @dispose: private list to queue successfully-put objects * * Unhash an nfsd_file, try to get a reference to it, and then put that * reference. If it's the last reference, queue it to the dispose list. */ static void nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) __must_hold(RCU) { int decrement = 1; /* If we raced with someone else unhashing, ignore it */ if (!nfsd_file_unhash(nf)) return; /* If we can't get a reference, ignore it */ if (!nfsd_file_get(nf)) return; /* Extra decrement if we remove from the LRU */ if (nfsd_file_lru_remove(nf)) ++decrement; /* If refcount goes to 0, then put on the dispose list */ if (refcount_sub_and_test(decrement, &nf->nf_ref)) { list_add(&nf->nf_lru, dispose); trace_nfsd_file_closing(nf); } } /** * nfsd_file_queue_for_close: try to close out any open nfsd_files for an inode * @inode: inode on which to close out nfsd_files Loading Loading @@ -688,30 +721,11 @@ nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose) rcu_read_lock(); do { int decrement = 1; nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, nfsd_file_rhash_params); if (!nf) break; /* If we raced with someone else unhashing, ignore it */ if (!nfsd_file_unhash(nf)) continue; /* If we can't get a reference, ignore it */ if (!nfsd_file_get(nf)) continue; /* Extra decrement if we remove from the LRU */ if (nfsd_file_lru_remove(nf)) ++decrement; /* If refcount goes to 0, then put on the dispose list */ if (refcount_sub_and_test(decrement, &nf->nf_ref)) { list_add(&nf->nf_lru, dispose); trace_nfsd_file_closing(nf); } nfsd_file_cond_queue(nf, dispose); } while (1); rcu_read_unlock(); } Loading Loading @@ -928,11 +942,8 @@ __nfsd_file_cache_purge(struct net *net) nf = rhashtable_walk_next(&iter); while (!IS_ERR_OR_NULL(nf)) { if (!net || nf->nf_net == net) { nfsd_file_unhash(nf); nfsd_file_lru_remove(nf); list_add(&nf->nf_lru, &dispose); } if (!net || nf->nf_net == net) nfsd_file_cond_queue(nf, &dispose); nf = rhashtable_walk_next(&iter); } Loading Loading
fs/nfsd/filecache.c +36 −25 Original line number Diff line number Diff line Loading @@ -661,6 +661,39 @@ static struct shrinker nfsd_file_shrinker = { .seeks = 1, }; /** * nfsd_file_cond_queue - conditionally unhash and queue a nfsd_file * @nf: nfsd_file to attempt to queue * @dispose: private list to queue successfully-put objects * * Unhash an nfsd_file, try to get a reference to it, and then put that * reference. If it's the last reference, queue it to the dispose list. */ static void nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) __must_hold(RCU) { int decrement = 1; /* If we raced with someone else unhashing, ignore it */ if (!nfsd_file_unhash(nf)) return; /* If we can't get a reference, ignore it */ if (!nfsd_file_get(nf)) return; /* Extra decrement if we remove from the LRU */ if (nfsd_file_lru_remove(nf)) ++decrement; /* If refcount goes to 0, then put on the dispose list */ if (refcount_sub_and_test(decrement, &nf->nf_ref)) { list_add(&nf->nf_lru, dispose); trace_nfsd_file_closing(nf); } } /** * nfsd_file_queue_for_close: try to close out any open nfsd_files for an inode * @inode: inode on which to close out nfsd_files Loading Loading @@ -688,30 +721,11 @@ nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose) rcu_read_lock(); do { int decrement = 1; nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, nfsd_file_rhash_params); if (!nf) break; /* If we raced with someone else unhashing, ignore it */ if (!nfsd_file_unhash(nf)) continue; /* If we can't get a reference, ignore it */ if (!nfsd_file_get(nf)) continue; /* Extra decrement if we remove from the LRU */ if (nfsd_file_lru_remove(nf)) ++decrement; /* If refcount goes to 0, then put on the dispose list */ if (refcount_sub_and_test(decrement, &nf->nf_ref)) { list_add(&nf->nf_lru, dispose); trace_nfsd_file_closing(nf); } nfsd_file_cond_queue(nf, dispose); } while (1); rcu_read_unlock(); } Loading Loading @@ -928,11 +942,8 @@ __nfsd_file_cache_purge(struct net *net) nf = rhashtable_walk_next(&iter); while (!IS_ERR_OR_NULL(nf)) { if (!net || nf->nf_net == net) { nfsd_file_unhash(nf); nfsd_file_lru_remove(nf); list_add(&nf->nf_lru, &dispose); } if (!net || nf->nf_net == net) nfsd_file_cond_queue(nf, &dispose); nf = rhashtable_walk_next(&iter); } Loading