aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2005-01-04 05:47:55 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:47:55 -0800
commita733375f250c756d166c92c922cf0c1dab23122c (patch)
tree83ae3499619abd2ccac168f0a4a7961cec424857 /fs
parent4798d59e2391e5bd66e3af6be4ba5c22fbccbf3d (diff)
downloadhistory-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.c40
-rw-r--r--fs/nfsd/nfs4state.c42
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) &&