diff options
author | Neil Brown <neilb@cse.unsw.edu.au> | 2005-01-04 05:47:55 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 05:47:55 -0800 |
commit | a733375f250c756d166c92c922cf0c1dab23122c (patch) | |
tree | 83ae3499619abd2ccac168f0a4a7961cec424857 /fs | |
parent | 4798d59e2391e5bd66e3af6be4ba5c22fbccbf3d (diff) | |
download | history-a733375f250c756d166c92c922cf0c1dab23122c.tar.gz |
[PATCH] knfsd: move nfserr_openmode checking from nfsd_read/write into nfs4_preprocess_stateid_op() in preparation for delegation state.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 40 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 42 |
2 files changed, 39 insertions, 43 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ff6240f305c74e..cd0e552b2ce1d7 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -461,23 +461,8 @@ nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_loo } static inline int -access_bits_permit_read(unsigned long access_bmap) -{ - return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); -} - -static inline int -access_bits_permit_write(unsigned long access_bmap) -{ - return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || - test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); -} - -static inline int nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) { - struct nfs4_stateid *stp; int status; /* no need to check permission - this will be done in nfsd_read() */ @@ -509,15 +494,10 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read } /* check stateid */ if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | RD_STATE))) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; } - status = nfserr_openmode; - if (!access_bits_permit_read(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_read: file not opened for read!\n"); - goto out; - } status = nfs_ok; out: nfs4_unlock_state(); @@ -605,7 +585,6 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, static inline int nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) { - struct nfs4_stateid *stp; int status = nfs_ok; if (nfs4_in_grace()) @@ -626,15 +605,10 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se nfs4_lock_state(); if ((status = nfs4_preprocess_stateid_op(current_fh, &setattr->sa_stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | WR_STATE))) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); goto out_unlock; } - status = nfserr_openmode; - if (!access_bits_permit_write(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_setattr: not opened for write!\n"); - goto out_unlock; - } nfs4_unlock_state(); } status = nfs_ok; @@ -654,7 +628,6 @@ out_unlock: static inline int nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) { - struct nfs4_stateid *stp; stateid_t *stateid = &write->wr_stateid; u32 *p; int status = nfs_ok; @@ -677,18 +650,13 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ goto zero_stateid; } if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, - CHECK_FH | RDWR_STATE, &stp))) { + CHECK_FH | WR_STATE))) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); goto out; } - status = nfserr_openmode; - if (!access_bits_permit_write(stp->st_access_bmap)) { - dprintk("NFSD: nfsd4_write: file not open for write!\n"); - goto out; - } - zero_stateid: + nfs4_unlock_state(); write->wr_bytes_written = write->wr_buflen; write->wr_how_written = write->wr_stable_how; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index cc132073c9de51..ebecbd97df719a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1564,12 +1564,39 @@ STALE_STATEID(stateid_t *stateid) return 1; } +static inline int +access_permit_read(unsigned long access_bmap) +{ + return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || + test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); +} + +static inline int +access_permit_write(unsigned long access_bmap) +{ + return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || + test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); +} + +static +int check_openmode(struct nfs4_stateid *stp, int flags) +{ + int status = nfserr_openmode; + + if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) + goto out; + if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) + goto out; + status = nfs_ok; +out: + return status; +} /* * Checks for stateid operations */ int -nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp) +nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags) { struct nfs4_stateid *stp; int status; @@ -1578,8 +1605,6 @@ 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); - *stpp = NULL; - /* STALE STATEID */ status = nfserr_stale_stateid; if (STALE_STATEID(stateid)) @@ -1611,9 +1636,12 @@ nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int fl dprintk("preprocess_stateid_op: old stateid!\n"); goto out; } - *stpp = stp; - status = nfs_ok; renew_client(stp->st_stateowner->so_client); + + if((status = check_openmode(stp, flags))) + goto out; + + status = nfs_ok; out: return status; } @@ -1938,7 +1966,7 @@ find_stateid(stateid_t *stid, int flags) unsigned int hashval; dprintk("NFSD: find_stateid flags 0x%x\n",flags); - if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) { + if ((flags & LOCK_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) { hashval = stateid_hashval(st_id, f_id); list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) { if ((local->st_stateid.si_stateownerid == st_id) && @@ -1946,7 +1974,7 @@ find_stateid(stateid_t *stid, int flags) return local; } } - if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) { + if ((flags & OPEN_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) { hashval = stateid_hashval(st_id, f_id); list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) { if ((local->st_stateid.si_stateownerid == st_id) && |