[PATCH] nfsd4: ERR_GRACE should bump seqid on lock
[powerpc.git] / fs / nfsd / nfs4state.c
index 89e3652..92968c9 100644 (file)
@@ -874,6 +874,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
                          * change request correctly. */
                        atomic_set(&conf->cl_callback.cb_set, 0);
                        gen_confirm(conf);
+                       nfsd4_remove_clid_dir(unconf);
                        expire_client(unconf);
                        status = nfs_ok;
 
@@ -1789,6 +1790,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
        struct nfs4_delegation *dp = NULL;
        int status;
 
+       if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
+               return nfserr_grace;
+
+       if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+               return nfserr_no_grace;
+
        status = nfserr_inval;
        if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
                goto out;
@@ -2699,11 +2706,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
                (long long) lock->lk_offset,
                (long long) lock->lk_length);
 
-       if (nfs4_in_grace() && !lock->lk_reclaim)
-               return nfserr_grace;
-       if (!nfs4_in_grace() && lock->lk_reclaim)
-               return nfserr_no_grace;
-
        if (check_lock_length(lock->lk_offset, lock->lk_length))
                 return nfserr_inval;
 
@@ -2778,6 +2780,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
                goto out;
        }
 
+       status = nfserr_grace;
+       if (nfs4_in_grace() && !lock->lk_reclaim)
+               goto out;
+       status = nfserr_no_grace;
+       if (!nfs4_in_grace() && lock->lk_reclaim)
+               goto out;
+
        locks_init_lock(&file_lock);
        switch (lock->lk_type) {
                case NFS4_READ_LT:
@@ -3083,7 +3092,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
         * of the lockowner state released; so don't release any until all
         * have been checked. */
        status = nfs_ok;
-       list_for_each_entry(sop, &matches, so_perclient) {
+       while (!list_empty(&matches)) {
+               sop = list_entry(matches.next, struct nfs4_stateowner,
+                                                               so_perclient);
+               /* unhash_stateowner deletes so_perclient only
+                * for openowners. */
+               list_del(&sop->so_perclient);
                release_stateowner(sop);
        }
 out: