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>
This commit is contained in:
parent
3a3286147f
commit
82c5ff1b14
@ -471,6 +471,27 @@ test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* set share access for a given stateid */
|
||||
static inline void
|
||||
set_access(u32 access, struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
__set_bit(access, &stp->st_access_bmap);
|
||||
}
|
||||
|
||||
/* clear share access for a given stateid */
|
||||
static inline void
|
||||
clear_access(u32 access, struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
__clear_bit(access, &stp->st_access_bmap);
|
||||
}
|
||||
|
||||
/* test whether a given stateid has access */
|
||||
static inline bool
|
||||
test_access(u32 access, struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
return test_bit(access, &stp->st_access_bmap);
|
||||
}
|
||||
|
||||
static int nfs4_access_to_omode(u32 access)
|
||||
{
|
||||
switch (access & NFS4_SHARE_ACCESS_BOTH) {
|
||||
@ -484,6 +505,20 @@ static int nfs4_access_to_omode(u32 access)
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* release all access and file references for a given stateid */
|
||||
static void
|
||||
release_all_access(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < 4; i++) {
|
||||
if (test_access(i, stp))
|
||||
nfs4_file_put_access(stp->st_file,
|
||||
nfs4_access_to_omode(i));
|
||||
clear_access(i, stp);
|
||||
}
|
||||
}
|
||||
|
||||
static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
list_del(&stp->st_perfile);
|
||||
@ -492,16 +527,7 @@ static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
|
||||
|
||||
static void close_generic_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (stp->st_access_bmap) {
|
||||
for (i = 1; i < 4; i++) {
|
||||
if (test_bit(i, &stp->st_access_bmap))
|
||||
nfs4_file_put_access(stp->st_file,
|
||||
nfs4_access_to_omode(i));
|
||||
__clear_bit(i, &stp->st_access_bmap);
|
||||
}
|
||||
}
|
||||
release_all_access(stp);
|
||||
put_nfs4_file(stp->st_file);
|
||||
stp->st_file = NULL;
|
||||
}
|
||||
@ -2435,7 +2461,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
|
||||
stp->st_file = fp;
|
||||
stp->st_access_bmap = 0;
|
||||
stp->st_deny_bmap = 0;
|
||||
__set_bit(open->op_share_access, &stp->st_access_bmap);
|
||||
set_access(open->op_share_access, stp);
|
||||
__set_bit(open->op_share_deny, &stp->st_deny_bmap);
|
||||
stp->st_openstp = NULL;
|
||||
}
|
||||
@ -2772,7 +2798,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
|
||||
bool new_access;
|
||||
__be32 status;
|
||||
|
||||
new_access = !test_bit(op_share_access, &stp->st_access_bmap);
|
||||
new_access = !test_access(op_share_access, stp);
|
||||
if (new_access) {
|
||||
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
|
||||
if (status)
|
||||
@ -2787,7 +2813,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
|
||||
return status;
|
||||
}
|
||||
/* remember the open */
|
||||
__set_bit(op_share_access, &stp->st_access_bmap);
|
||||
set_access(op_share_access, stp);
|
||||
__set_bit(open->op_share_deny, &stp->st_deny_bmap);
|
||||
|
||||
return nfs_ok;
|
||||
@ -3263,18 +3289,18 @@ STALE_STATEID(stateid_t *stateid)
|
||||
}
|
||||
|
||||
static inline int
|
||||
access_permit_read(unsigned long access_bmap)
|
||||
access_permit_read(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
|
||||
test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) ||
|
||||
test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap);
|
||||
return test_access(NFS4_SHARE_ACCESS_READ, stp) ||
|
||||
test_access(NFS4_SHARE_ACCESS_BOTH, stp) ||
|
||||
test_access(NFS4_SHARE_ACCESS_WRITE, stp);
|
||||
}
|
||||
|
||||
static inline int
|
||||
access_permit_write(unsigned long access_bmap)
|
||||
access_permit_write(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
|
||||
test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
|
||||
return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
|
||||
test_access(NFS4_SHARE_ACCESS_BOTH, stp);
|
||||
}
|
||||
|
||||
static
|
||||
@ -3285,9 +3311,9 @@ __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
|
||||
/* For lock stateid's, we test the parent open, not the lock: */
|
||||
if (stp->st_openstp)
|
||||
stp = stp->st_openstp;
|
||||
if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
|
||||
if ((flags & WR_STATE) && !access_permit_write(stp))
|
||||
goto out;
|
||||
if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
|
||||
if ((flags & RD_STATE) && !access_permit_read(stp))
|
||||
goto out;
|
||||
status = nfs_ok;
|
||||
out:
|
||||
@ -3636,10 +3662,10 @@ out:
|
||||
|
||||
static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
|
||||
{
|
||||
if (!test_bit(access, &stp->st_access_bmap))
|
||||
if (!test_access(access, stp))
|
||||
return;
|
||||
nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access));
|
||||
__clear_bit(access, &stp->st_access_bmap);
|
||||
clear_access(access, stp);
|
||||
}
|
||||
|
||||
static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
|
||||
@ -3693,8 +3719,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
|
||||
if (status)
|
||||
goto out;
|
||||
status = nfserr_inval;
|
||||
if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
|
||||
dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
|
||||
if (!test_access(od->od_share_access, stp)) {
|
||||
dprintk("NFSD: access not a subset current bitmap: 0x%lx, input access=%08x\n",
|
||||
stp->st_access_bmap, od->od_share_access);
|
||||
goto out;
|
||||
}
|
||||
@ -3995,10 +4021,10 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
|
||||
struct nfs4_file *fp = lock_stp->st_file;
|
||||
int oflag = nfs4_access_to_omode(access);
|
||||
|
||||
if (test_bit(access, &lock_stp->st_access_bmap))
|
||||
if (test_access(access, lock_stp))
|
||||
return;
|
||||
nfs4_file_get_access(fp, oflag);
|
||||
__set_bit(access, &lock_stp->st_access_bmap);
|
||||
set_access(access, lock_stp);
|
||||
}
|
||||
|
||||
static __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)
|
||||
|
Loading…
Reference in New Issue
Block a user