nfsd: make close_lru list per net
authorStanislav Kinsbursky <skinsbursky@parallels.com>
Wed, 14 Nov 2012 15:22:01 +0000 (18:22 +0300)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 15 Nov 2012 12:40:49 +0000 (07:40 -0500)
This list holds nfs4 clients (open) stateowner queue for last close replay,
which are network namespace aware. So let's make this list per network
namespace too.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/netns.h
fs/nfsd/nfs4state.c

index 9a98a0a..a356ea3 100644 (file)
@@ -71,8 +71,14 @@ struct nfsd_net {
        /*
         * client_lru holds client queue ordered by nfs4_client.cl_time
         * for lease renewal.
+        *
+        * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
+        * for last close replay.
+        *
+        * All of the above fields are protected by the client_mutex.
         */
        struct list_head client_lru;
+       struct list_head close_lru;
 };
 
 extern int nfsd_net_id;
index 9cf7e9b..a8e4064 100644 (file)
@@ -401,14 +401,6 @@ static unsigned int clientstr_hashval(const char *name)
        return opaque_hashval(name, 8) & CLIENT_HASH_MASK;
 }
 
-/*
- * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
- * for last close replay.
- *
- * All of the above fields are protected by the client_mutex.
- */
-static struct list_head close_lru;
-
 /*
  * We store the NONE, READ, WRITE, and BOTH bits separately in the
  * st_{access,deny}_bmap field of the stateid, in order to track not
@@ -2465,11 +2457,13 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
 }
 
 static void
-move_to_close_lru(struct nfs4_openowner *oo)
+move_to_close_lru(struct nfs4_openowner *oo, struct net *net)
 {
+       struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+
        dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
 
-       list_move_tail(&oo->oo_close_lru, &close_lru);
+       list_move_tail(&oo->oo_close_lru, &nn->close_lru);
        oo->oo_time = get_seconds();
 }
 
@@ -3242,7 +3236,7 @@ nfs4_laundromat(void)
                unhash_delegation(dp);
        }
        test_val = nfsd4_lease;
-       list_for_each_safe(pos, next, &close_lru) {
+       list_for_each_safe(pos, next, &nn->close_lru) {
                oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
                if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
                        u = oo->oo_time - cutoff;
@@ -3820,7 +3814,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                         * little while to handle CLOSE replay.
                         */
                        if (list_empty(&oo->oo_owner.so_stateids))
-                               move_to_close_lru(oo);
+                               move_to_close_lru(oo, SVC_NET(rqstp));
                }
        }
 out:
@@ -4721,7 +4715,6 @@ nfs4_state_init(void)
        for (i = 0; i < FILE_HASH_SIZE; i++) {
                INIT_LIST_HEAD(&file_hashtbl[i]);
        }
-       INIT_LIST_HEAD(&close_lru);
        INIT_LIST_HEAD(&del_recall_lru);
 }
 
@@ -4785,6 +4778,7 @@ static int nfs4_state_start_net(struct net *net)
        nn->conf_name_tree = RB_ROOT;
        nn->unconf_name_tree = RB_ROOT;
        INIT_LIST_HEAD(&nn->client_lru);
+       INIT_LIST_HEAD(&nn->close_lru);
 
        return 0;