Commit 23b08769 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] nfsd4: move special stateid processing

Move special stateid processing to nfs4_preprocess_stateid_op().  Also make
stateid processing for setattr the same as that for write.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2eeb8d7b
......@@ -473,25 +473,6 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
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, struct svc_fh *current_fh, struct nfsd4_se
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, struct svc_fh *current_fh, struct nfsd4_writ
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;
......
......@@ -2007,6 +2007,22 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
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 *current_fh, stateid_t *stateid, int fl
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))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment