aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-05-11 09:45:13 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-05-31 20:29:47 -0400
commit82c5ff1b1409f43ccb282cbdfcb06991714e4c5f (patch)
treeac739fd456e92cd514208341c58918b62f4e90b0 /fs/nfsd
parent3a3286147f557f05e002be3ec7512b582373ae65 (diff)
nfsd: wrap accesses to st_access_bmap
Currently, we do this for the most part with "bare" bitops, but eventually we'll need to expand the share mode code to handle access and deny modes on other nodes. In order to facilitate that code in the future, move to some generic accessor functions. For now, these are mostly static inlines, but eventually we'll want to move these to "real" functions that are able to handle multi-node configurations or have a way to "swap in" new operations to be done in lieu of or in conjunction with these atomic bitops. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 88a897a484ec..83066abc66bb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -471,6 +471,27 @@ test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
471 return true; 471 return true;
472} 472}
473 473
474/* set share access for a given stateid */
475static inline void
476set_access(u32 access, struct nfs4_ol_stateid *stp)
477{
478 __set_bit(access, &stp->st_access_bmap);
479}
480
481/* clear share access for a given stateid */
482static inline void
483clear_access(u32 access, struct nfs4_ol_stateid *stp)
484{
485 __clear_bit(access, &stp->st_access_bmap);
486}
487
488/* test whether a given stateid has access */
489static inline bool
490test_access(u32 access, struct nfs4_ol_stateid *stp)
491{
492 return test_bit(access, &stp->st_access_bmap);
493}
494
474static int nfs4_access_to_omode(u32 access) 495static int nfs4_access_to_omode(u32 access)
475{ 496{
476 switch (access & NFS4_SHARE_ACCESS_BOTH) { 497 switch (access & NFS4_SHARE_ACCESS_BOTH) {
@@ -484,6 +505,20 @@ static int nfs4_access_to_omode(u32 access)
484 BUG(); 505 BUG();
485} 506}
486 507
508/* release all access and file references for a given stateid */
509static void
510release_all_access(struct nfs4_ol_stateid *stp)
511{
512 int i;
513
514 for (i = 1; i < 4; i++) {
515 if (test_access(i, stp))
516 nfs4_file_put_access(stp->st_file,
517 nfs4_access_to_omode(i));
518 clear_access(i, stp);
519 }
520}
521
487static void unhash_generic_stateid(struct nfs4_ol_stateid *stp) 522static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
488{ 523{
489 list_del(&stp->st_perfile); 524 list_del(&stp->st_perfile);
@@ -492,16 +527,7 @@ static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
492 527
493static void close_generic_stateid(struct nfs4_ol_stateid *stp) 528static void close_generic_stateid(struct nfs4_ol_stateid *stp)
494{ 529{
495 int i; 530 release_all_access(stp);
496
497 if (stp->st_access_bmap) {
498 for (i = 1; i < 4; i++) {
499 if (test_bit(i, &stp->st_access_bmap))
500 nfs4_file_put_access(stp->st_file,
501 nfs4_access_to_omode(i));
502 __clear_bit(i, &stp->st_access_bmap);
503 }
504 }
505 put_nfs4_file(stp->st_file); 531 put_nfs4_file(stp->st_file);
506 stp->st_file = NULL; 532 stp->st_file = NULL;
507} 533}
@@ -2435,7 +2461,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
2435 stp->st_file = fp; 2461 stp->st_file = fp;
2436 stp->st_access_bmap = 0; 2462 stp->st_access_bmap = 0;
2437 stp->st_deny_bmap = 0; 2463 stp->st_deny_bmap = 0;
2438 __set_bit(open->op_share_access, &stp->st_access_bmap); 2464 set_access(open->op_share_access, stp);
2439 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2465 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2440 stp->st_openstp = NULL; 2466 stp->st_openstp = NULL;
2441} 2467}
@@ -2772,7 +2798,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2772 bool new_access; 2798 bool new_access;
2773 __be32 status; 2799 __be32 status;
2774 2800
2775 new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2801 new_access = !test_access(op_share_access, stp);
2776 if (new_access) { 2802 if (new_access) {
2777 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2803 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2778 if (status) 2804 if (status)
@@ -2787,7 +2813,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2787 return status; 2813 return status;
2788 } 2814 }
2789 /* remember the open */ 2815 /* remember the open */
2790 __set_bit(op_share_access, &stp->st_access_bmap); 2816 set_access(op_share_access, stp);
2791 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2817 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2792 2818
2793 return nfs_ok; 2819 return nfs_ok;
@@ -3263,18 +3289,18 @@ STALE_STATEID(stateid_t *stateid)
3263} 3289}
3264 3290
3265static inline int 3291static inline int
3266access_permit_read(unsigned long access_bmap) 3292access_permit_read(struct nfs4_ol_stateid *stp)
3267{ 3293{
3268 return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || 3294 return test_access(NFS4_SHARE_ACCESS_READ, stp) ||
3269 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) || 3295 test_access(NFS4_SHARE_ACCESS_BOTH, stp) ||
3270 test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap); 3296 test_access(NFS4_SHARE_ACCESS_WRITE, stp);
3271} 3297}
3272 3298
3273static inline int 3299static inline int
3274access_permit_write(unsigned long access_bmap) 3300access_permit_write(struct nfs4_ol_stateid *stp)
3275{ 3301{
3276 return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || 3302 return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
3277 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); 3303 test_access(NFS4_SHARE_ACCESS_BOTH, stp);
3278} 3304}
3279 3305
3280static 3306static
@@ -3285,9 +3311,9 @@ __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
3285 /* For lock stateid's, we test the parent open, not the lock: */ 3311 /* For lock stateid's, we test the parent open, not the lock: */
3286 if (stp->st_openstp) 3312 if (stp->st_openstp)
3287 stp = stp->st_openstp; 3313 stp = stp->st_openstp;
3288 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 3314 if ((flags & WR_STATE) && !access_permit_write(stp))
3289 goto out; 3315 goto out;
3290 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 3316 if ((flags & RD_STATE) && !access_permit_read(stp))
3291 goto out; 3317 goto out;
3292 status = nfs_ok; 3318 status = nfs_ok;
3293out: 3319out:
@@ -3636,10 +3662,10 @@ out:
3636 3662
3637static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access) 3663static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
3638{ 3664{
3639 if (!test_bit(access, &stp->st_access_bmap)) 3665 if (!test_access(access, stp))
3640 return; 3666 return;
3641 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access)); 3667 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access));
3642 __clear_bit(access, &stp->st_access_bmap); 3668 clear_access(access, stp);
3643} 3669}
3644 3670
3645static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access) 3671static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
@@ -3693,8 +3719,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3693 if (status) 3719 if (status)
3694 goto out; 3720 goto out;
3695 status = nfserr_inval; 3721 status = nfserr_inval;
3696 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3722 if (!test_access(od->od_share_access, stp)) {
3697 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3723 dprintk("NFSD: access not a subset current bitmap: 0x%lx, input access=%08x\n",
3698 stp->st_access_bmap, od->od_share_access); 3724 stp->st_access_bmap, od->od_share_access);
3699 goto out; 3725 goto out;
3700 } 3726 }
@@ -3995,10 +4021,10 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
3995 struct nfs4_file *fp = lock_stp->st_file; 4021 struct nfs4_file *fp = lock_stp->st_file;
3996 int oflag = nfs4_access_to_omode(access); 4022 int oflag = nfs4_access_to_omode(access);
3997 4023
3998 if (test_bit(access, &lock_stp->st_access_bmap)) 4024 if (test_access(access, lock_stp))
3999 return; 4025 return;
4000 nfs4_file_get_access(fp, oflag); 4026 nfs4_file_get_access(fp, oflag);
4001 __set_bit(access, &lock_stp->st_access_bmap); 4027 set_access(access, lock_stp);
4002} 4028}
4003 4029
4004static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) 4030static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new)