From: NeilBrown Move special stateid processing to nfs4_preprocess_stateid_op(). Also make stateid processing for setattr the same as that for write. Signed-off-by: J. Bruce Fields Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/fs/nfsd/nfs4proc.c | 38 +------------------------------------- 25-akpm/fs/nfsd/nfs4state.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 37 deletions(-) diff -puN fs/nfsd/nfs4proc.c~nfsd4-move-special-stateid-processing fs/nfsd/nfs4proc.c --- 25/fs/nfsd/nfs4proc.c~nfsd4-move-special-stateid-processing 2005-03-07 23:55:18.000000000 -0800 +++ 25-akpm/fs/nfsd/nfs4proc.c 2005-03-07 23:55:18.000000000 -0800 @@ -473,25 +473,6 @@ nfsd4_read(struct svc_rqst *rqstp, struc return nfserr_inval; nfs4_lock_state(); - status = nfs_ok; - /* For stateid -1, we don't check share reservations. */ - if (ONE_STATEID(&read->rd_stateid)) { - dprintk("NFSD: nfsd4_read: -1 stateid...\n"); - goto out; - } - /* - * For stateid 0, the client doesn't have to have the file open, but - * we still check for share reservation conflicts. - */ - if (ZERO_STATEID(&read->rd_stateid)) { - dprintk("NFSD: nfsd4_read: zero stateid...\n"); - if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_READ))) { - dprintk("NFSD: nfsd4_read: conflicting share reservation!\n"); - goto out; - } - status = nfs_ok; - goto out; - } /* check stateid */ if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, CHECK_FH | RD_STATE))) { @@ -595,13 +576,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, st status = nfs_ok; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { - - status = nfserr_bad_stateid; - if (ZERO_STATEID(&setattr->sa_stateid) || ONE_STATEID(&setattr->sa_stateid)) { - dprintk("NFSD: nfsd4_setattr: magic stateid!\n"); - goto out; - } - nfs4_lock_state(); if ((status = nfs4_preprocess_stateid_op(current_fh, &setattr->sa_stateid, @@ -641,23 +615,13 @@ nfsd4_write(struct svc_rqst *rqstp, stru return nfserr_inval; nfs4_lock_state(); - if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { - dprintk("NFSD: nfsd4_write: zero stateid...\n"); - if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_WRITE))) { - dprintk("NFSD: nfsd4_write: conflicting share reservation!\n"); - goto out; - } - goto zero_stateid; - } if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, CHECK_FH | WR_STATE))) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); goto out; } - -zero_stateid: - nfs4_unlock_state(); + write->wr_bytes_written = write->wr_buflen; write->wr_how_written = write->wr_stable_how; p = (u32 *)write->wr_verifier.data; diff -puN fs/nfsd/nfs4state.c~nfsd4-move-special-stateid-processing fs/nfsd/nfs4state.c --- 25/fs/nfsd/nfs4state.c~nfsd4-move-special-stateid-processing 2005-03-07 23:55:18.000000000 -0800 +++ 25-akpm/fs/nfsd/nfs4state.c 2005-03-07 23:55:18.000000000 -0800 @@ -2007,6 +2007,22 @@ out: return status; } +static inline int +check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) +{ + /* Trying to call delegreturn with a special stateid? Yuch: */ + if (!(flags & (RD_STATE | WR_STATE))) + return nfserr_bad_stateid; + else if (ONE_STATEID(stateid) && (flags & RD_STATE)) + return nfs_ok; + else if (flags & WR_STATE) + return nfs4_share_conflict(current_fh, + NFS4_SHARE_DENY_WRITE); + else /* (flags & RD_STATE) && ZERO_STATEID(stateid) */ + return nfs4_share_conflict(current_fh, + NFS4_SHARE_DENY_READ); +} + /* * Checks for stateid operations */ @@ -2022,6 +2038,9 @@ nfs4_preprocess_stateid_op(struct svc_fh stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, stateid->si_generation); + if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) + return check_special_stateids(current_fh, stateid, flags); + /* STALE STATEID */ status = nfserr_stale_stateid; if (STALE_STATEID(stateid)) _