nfsd: clean up nfsd4_release_lockowner
authorJeff Layton <jlayton@primarydata.com>
Mon, 30 Jun 2014 15:48:41 +0000 (11:48 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 10 Jul 2014 00:54:59 +0000 (20:54 -0400)
Now that we know that we won't have several lockowners with the same,
owner->data, we can simplify nfsd4_release_lockowner and get rid of
the lo_list in the process.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4state.c
fs/nfsd/state.h

index ff10919eebde5ada582ba0115775f615c28ce291..86ec359349c62508935508e3e4f36b9d01a077dd 100644 (file)
@@ -4783,11 +4783,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
                        struct nfsd4_release_lockowner *rlockowner)
 {
        clientid_t *clid = &rlockowner->rl_clientid;
-       struct nfs4_stateowner *sop;
+       struct nfs4_stateowner *sop = NULL, *tmp;
        struct nfs4_lockowner *lo;
        struct nfs4_ol_stateid *stp;
        struct xdr_netobj *owner = &rlockowner->rl_owner;
-       struct list_head matches;
        unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
        __be32 status;
        struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
@@ -4802,33 +4801,32 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
                goto out;
 
        status = nfserr_locks_held;
-       INIT_LIST_HEAD(&matches);
 
-       list_for_each_entry(sop, &nn->ownerstr_hashtbl[hashval], so_strhash) {
-               if (sop->so_is_open_owner)
-                       continue;
-               if (!same_owner_str(sop, owner, clid))
+       /* Find the matching lock stateowner */
+       list_for_each_entry(tmp, &nn->ownerstr_hashtbl[hashval], so_strhash) {
+               if (tmp->so_is_open_owner)
                        continue;
-               list_for_each_entry(stp, &sop->so_stateids,
-                               st_perstateowner) {
-                       lo = lockowner(sop);
-                       if (check_for_locks(stp->st_file, lo))
-                               goto out;
-                       list_add(&lo->lo_list, &matches);
+               if (same_owner_str(tmp, owner, clid)) {
+                       sop = tmp;
+                       break;
                }
        }
-       /* Clients probably won't expect us to return with some (but not all)
-        * of the lockowner state released; so don't release any until all
-        * have been checked. */
-       status = nfs_ok;
-       while (!list_empty(&matches)) {
-               lo = list_entry(matches.next, struct nfs4_lockowner,
-                                                               lo_list);
-               /* unhash_stateowner deletes so_perclient only
-                * for openowners. */
-               list_del(&lo->lo_list);
-               release_lockowner(lo);
+
+       /* No matching owner found, maybe a replay? Just declare victory... */
+       if (!sop) {
+               status = nfs_ok;
+               goto out;
+       }
+
+       lo = lockowner(sop);
+       /* see if there are still any locks associated with it */
+       list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
+               if (check_for_locks(stp->st_file, lo))
+                       goto out;
        }
+
+       status = nfs_ok;
+       release_lockowner(lo);
 out:
        nfs4_unlock_state();
        return status;
index 23b110939da180494118fd48be62daa0993c791a..ab937b5f10ab95d26c2813eadf85ce50688de8f3 100644 (file)
@@ -364,7 +364,6 @@ struct nfs4_openowner {
 
 struct nfs4_lockowner {
        struct nfs4_stateowner  lo_owner; /* must be first element */
-       struct list_head        lo_list; /* for temporary uses */
 };
 
 static inline struct nfs4_openowner * openowner(struct nfs4_stateowner *so)