浏览代码

nfsd4: fix bad seqid on lock request incompatible with open mode

The failure to return a stateowner from nfs4_preprocess_seqid_op() means
in the case where a lock request is of a type incompatible with an open
(due to, e.g., an application attempting a write lock on a file open for
read), means that fs/nfsd/nfs4xdr.c:ENCODE_SEQID_OP_TAIL() never bumps
the seqid as it should.  The client, attempting to close the file
afterwards, then gets an (incorrect) bad sequence id error.  Worse, this
prevents the open file from ever being closed, so we leak state.

Thanks to Benny Halevy and Trond Myklebust for analysis, and to Steven
Wilton for the report and extensive data-gathering.

Cc: Benny Halevy <bhalevy@panasas.com>
Cc: Steven Wilton <steven.wilton@team.eftel.com.au>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
J. Bruce Fields 17 年之前
父节点
当前提交
39325bd03f
共有 1 个文件被更改,包括 3 次插入4 次删除
  1. 3 4
      fs/nfsd/nfs4state.c

+ 3 - 4
fs/nfsd/nfs4state.c

@@ -2093,8 +2093,10 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
 		goto check_replay;
 		goto check_replay;
 	}
 	}
 
 
+	*stpp = stp;
+	*sopp = sop = stp->st_stateowner;
+
 	if (lock) {
 	if (lock) {
-		struct nfs4_stateowner *sop = stp->st_stateowner;
 		clientid_t *lockclid = &lock->v.new.clientid;
 		clientid_t *lockclid = &lock->v.new.clientid;
 		struct nfs4_client *clp = sop->so_client;
 		struct nfs4_client *clp = sop->so_client;
 		int lkflg = 0;
 		int lkflg = 0;
@@ -2124,9 +2126,6 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
 		return nfserr_bad_stateid;
 		return nfserr_bad_stateid;
 	}
 	}
 
 
-	*stpp = stp;
-	*sopp = sop = stp->st_stateowner;
-
 	/*
 	/*
 	*  We now validate the seqid and stateid generation numbers.
 	*  We now validate the seqid and stateid generation numbers.
 	*  For the moment, we ignore the possibility of 
 	*  For the moment, we ignore the possibility of