Commit c11c591f authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

nfsd: shrink st_access_bmap and st_deny_bmap

We never use anything above bit #3, so an unsigned long for each is
wasteful. Shrink them to a char each, and add some WARN_ON_ONCE calls if
we try to set or clear bits that would go outside those sizes.

Note too that because atomic bitops work on unsigned longs, we have to
abandon their use here. That shouldn't be a problem though since we
don't really care about the atomicity in this code anyway. Using them
was just a convenient way to flip bits.
Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 6d338b51
...@@ -721,42 +721,58 @@ test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) { ...@@ -721,42 +721,58 @@ test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
static inline void static inline void
set_access(u32 access, struct nfs4_ol_stateid *stp) set_access(u32 access, struct nfs4_ol_stateid *stp)
{ {
__set_bit(access, &stp->st_access_bmap); unsigned char mask = 1 << access;
WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
stp->st_access_bmap |= mask;
} }
/* clear share access for a given stateid */ /* clear share access for a given stateid */
static inline void static inline void
clear_access(u32 access, struct nfs4_ol_stateid *stp) clear_access(u32 access, struct nfs4_ol_stateid *stp)
{ {
__clear_bit(access, &stp->st_access_bmap); unsigned char mask = 1 << access;
WARN_ON_ONCE(access > NFS4_SHARE_ACCESS_BOTH);
stp->st_access_bmap &= ~mask;
} }
/* test whether a given stateid has access */ /* test whether a given stateid has access */
static inline bool static inline bool
test_access(u32 access, struct nfs4_ol_stateid *stp) test_access(u32 access, struct nfs4_ol_stateid *stp)
{ {
return test_bit(access, &stp->st_access_bmap); unsigned char mask = 1 << access;
return (bool)(stp->st_access_bmap & mask);
} }
/* set share deny for a given stateid */ /* set share deny for a given stateid */
static inline void static inline void
set_deny(u32 access, struct nfs4_ol_stateid *stp) set_deny(u32 deny, struct nfs4_ol_stateid *stp)
{ {
__set_bit(access, &stp->st_deny_bmap); unsigned char mask = 1 << deny;
WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
stp->st_deny_bmap |= mask;
} }
/* clear share deny for a given stateid */ /* clear share deny for a given stateid */
static inline void static inline void
clear_deny(u32 access, struct nfs4_ol_stateid *stp) clear_deny(u32 deny, struct nfs4_ol_stateid *stp)
{ {
__clear_bit(access, &stp->st_deny_bmap); unsigned char mask = 1 << deny;
WARN_ON_ONCE(deny > NFS4_SHARE_DENY_BOTH);
stp->st_deny_bmap &= ~mask;
} }
/* test whether a given stateid is denying specific access */ /* test whether a given stateid is denying specific access */
static inline bool static inline bool
test_deny(u32 access, struct nfs4_ol_stateid *stp) test_deny(u32 deny, struct nfs4_ol_stateid *stp)
{ {
return test_bit(access, &stp->st_deny_bmap); unsigned char mask = 1 << deny;
return (bool)(stp->st_deny_bmap & mask);
} }
static int nfs4_access_to_omode(u32 access) static int nfs4_access_to_omode(u32 access)
...@@ -4282,12 +4298,12 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, ...@@ -4282,12 +4298,12 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
goto out; goto out;
status = nfserr_inval; status = nfserr_inval;
if (!test_access(od->od_share_access, stp)) { if (!test_access(od->od_share_access, stp)) {
dprintk("NFSD: access not a subset current bitmap: 0x%lx, input access=%08x\n", dprintk("NFSD: access not a subset of current bitmap: 0x%hhx, input access=%08x\n",
stp->st_access_bmap, od->od_share_access); stp->st_access_bmap, od->od_share_access);
goto out; goto out;
} }
if (!test_deny(od->od_share_deny, stp)) { if (!test_deny(od->od_share_deny, stp)) {
dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n", dprintk("NFSD: deny not a subset of current bitmap: 0x%hhx, input deny=%08x\n",
stp->st_deny_bmap, od->od_share_deny); stp->st_deny_bmap, od->od_share_deny);
goto out; goto out;
} }
......
...@@ -406,8 +406,8 @@ struct nfs4_ol_stateid { ...@@ -406,8 +406,8 @@ struct nfs4_ol_stateid {
struct list_head st_locks; struct list_head st_locks;
struct nfs4_stateowner * st_stateowner; struct nfs4_stateowner * st_stateowner;
struct nfs4_file * st_file; struct nfs4_file * st_file;
unsigned long st_access_bmap; unsigned char st_access_bmap;
unsigned long st_deny_bmap; unsigned char st_deny_bmap;
struct nfs4_ol_stateid * st_openstp; struct nfs4_ol_stateid * st_openstp;
}; };
......
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