Skip to content

Commit a37f08b

Browse files
chuckleversmb49
authored andcommitted
NFSD: Replace the "init once" mechanism
BugLink: https://bugs.launchpad.net/bugs/2065435 [ Upstream commit c7b824c ] In a moment, the nfsd_file_hashtbl global will be replaced with an rhashtable. Replace the one or two spots that need to check if the hash table is available. We can easily reuse the SHUTDOWN flag for this purpose. Document that this mechanism relies on callers to hold the nfsd_mutex to prevent init, shutdown, and purging to run concurrently. Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: Manuel Diewald <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent 3ff54d4 commit a37f08b

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

fs/nfsd/filecache.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#define NFSD_FILE_HASH_SIZE (1 << NFSD_FILE_HASH_BITS)
2828
#define NFSD_LAUNDRETTE_DELAY (2 * HZ)
2929

30-
#define NFSD_FILE_SHUTDOWN (1)
30+
#define NFSD_FILE_CACHE_UP (0)
3131

3232
/* We only care about NFSD_MAY_READ/WRITE for this cache */
3333
#define NFSD_FILE_MAY_MASK (NFSD_MAY_READ|NFSD_MAY_WRITE)
@@ -58,17 +58,16 @@ static struct kmem_cache *nfsd_file_slab;
5858
static struct kmem_cache *nfsd_file_mark_slab;
5959
static struct nfsd_fcache_bucket *nfsd_file_hashtbl;
6060
static struct list_lru nfsd_file_lru;
61-
static long nfsd_file_lru_flags;
61+
static unsigned long nfsd_file_flags;
6262
static struct fsnotify_group *nfsd_file_fsnotify_group;
6363
static atomic_long_t nfsd_filecache_count;
6464
static struct delayed_work nfsd_filecache_laundrette;
6565

6666
static void
6767
nfsd_file_schedule_laundrette(void)
6868
{
69-
long count = atomic_long_read(&nfsd_filecache_count);
70-
71-
if (count == 0 || test_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags))
69+
if ((atomic_long_read(&nfsd_filecache_count) == 0) ||
70+
test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 0)
7271
return;
7372

7473
queue_delayed_work(system_wq, &nfsd_filecache_laundrette,
@@ -697,9 +696,8 @@ nfsd_file_cache_init(void)
697696
int ret = -ENOMEM;
698697
unsigned int i;
699698

700-
clear_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags);
701-
702-
if (nfsd_file_hashtbl)
699+
lockdep_assert_held(&nfsd_mutex);
700+
if (test_and_set_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1)
703701
return 0;
704702

705703
nfsd_filecache_wq = alloc_workqueue("nfsd_filecache", 0, 0);
@@ -785,18 +783,15 @@ nfsd_file_cache_init(void)
785783
/*
786784
* Note this can deadlock with nfsd_file_lru_cb.
787785
*/
788-
void
789-
nfsd_file_cache_purge(struct net *net)
786+
static void
787+
__nfsd_file_cache_purge(struct net *net)
790788
{
791789
unsigned int i;
792790
struct nfsd_file *nf;
793791
struct hlist_node *next;
794792
LIST_HEAD(dispose);
795793
bool del;
796794

797-
if (!nfsd_file_hashtbl)
798-
return;
799-
800795
for (i = 0; i < NFSD_FILE_HASH_SIZE; i++) {
801796
struct nfsd_fcache_bucket *nfb = &nfsd_file_hashtbl[i];
802797

@@ -857,6 +852,19 @@ nfsd_file_cache_start_net(struct net *net)
857852
return nn->fcache_disposal ? 0 : -ENOMEM;
858853
}
859854

855+
/**
856+
* nfsd_file_cache_purge - Remove all cache items associated with @net
857+
* @net: target net namespace
858+
*
859+
*/
860+
void
861+
nfsd_file_cache_purge(struct net *net)
862+
{
863+
lockdep_assert_held(&nfsd_mutex);
864+
if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1)
865+
__nfsd_file_cache_purge(net);
866+
}
867+
860868
void
861869
nfsd_file_cache_shutdown_net(struct net *net)
862870
{
@@ -869,7 +877,9 @@ nfsd_file_cache_shutdown(void)
869877
{
870878
int i;
871879

872-
set_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags);
880+
lockdep_assert_held(&nfsd_mutex);
881+
if (test_and_clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 0)
882+
return;
873883

874884
lease_unregister_notifier(&nfsd_file_lease_notifier);
875885
unregister_shrinker(&nfsd_file_shrinker);
@@ -878,7 +888,7 @@ nfsd_file_cache_shutdown(void)
878888
* calling nfsd_file_cache_purge
879889
*/
880890
cancel_delayed_work_sync(&nfsd_filecache_laundrette);
881-
nfsd_file_cache_purge(NULL);
891+
__nfsd_file_cache_purge(NULL);
882892
list_lru_destroy(&nfsd_file_lru);
883893
rcu_barrier();
884894
fsnotify_put_group(nfsd_file_fsnotify_group);
@@ -1142,7 +1152,7 @@ static int nfsd_file_cache_stats_show(struct seq_file *m, void *v)
11421152
* don't end up racing with server shutdown
11431153
*/
11441154
mutex_lock(&nfsd_mutex);
1145-
if (nfsd_file_hashtbl) {
1155+
if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1) {
11461156
for (i = 0; i < NFSD_FILE_HASH_SIZE; i++) {
11471157
count += nfsd_file_hashtbl[i].nfb_count;
11481158
longest = max(longest, nfsd_file_hashtbl[i].nfb_count);

0 commit comments

Comments
 (0)