NFS: Don't compare apples to elephants to determine access bits
authorAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 26 Jul 2017 16:00:21 +0000 (12:00 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 16 Oct 2017 17:51:27 +0000 (13:51 -0400)
The NFS_ACCESS_* flags aren't a 1:1 mapping to the MAY_* flags, so
checking for MAY_WHATEVER might have surprising results in
nfs*_proc_access().  Let's simplify this check when determining which
bits to ask for, and do it in a generic place instead of copying code
for each NFS version.

Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/dir.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c

index 80f397dc96bbc9e701013afb66a825f71fa47d0c..db482d4c15d593cffea4e0ef312348dfbcc84b0c 100644 (file)
@@ -2425,9 +2425,14 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
        if (!may_block)
                goto out;
 
-       /* Be clever: ask server to check for all possible rights */
-       cache.mask = NFS_MAY_LOOKUP | NFS_MAY_EXECUTE
-                    | NFS_MAY_WRITE | NFS_MAY_READ;
+       /*
+        * Determine which access bits we want to ask for...
+        */
+       cache.mask = NFS_ACCESS_READ | NFS_ACCESS_MODIFY | NFS_ACCESS_EXTEND;
+       if (S_ISDIR(inode->i_mode))
+               cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
+       else
+               cache.mask |= NFS_ACCESS_EXECUTE;
        cache.cred = cred;
        status = NFS_PROTO(inode)->access(inode, &cache);
        if (status != 0) {
index d1e87ec0df8482d272b2a2c481b0eb3d76401ebd..44bf961d581253b47a6d7662f16c06db2a4309b6 100644 (file)
@@ -187,6 +187,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
        struct nfs3_accessargs  arg = {
                .fh             = NFS_FH(inode),
+               .access         = entry->mask,
        };
        struct nfs3_accessres   res;
        struct rpc_message msg = {
@@ -195,25 +196,9 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
                .rpc_resp       = &res,
                .rpc_cred       = entry->cred,
        };
-       int mode = entry->mask;
        int status = -ENOMEM;
 
        dprintk("NFS call  access\n");
-
-       if (mode & MAY_READ)
-               arg.access |= NFS3_ACCESS_READ;
-       if (S_ISDIR(inode->i_mode)) {
-               if (mode & MAY_WRITE)
-                       arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
-               if (mode & MAY_EXEC)
-                       arg.access |= NFS3_ACCESS_LOOKUP;
-       } else {
-               if (mode & MAY_WRITE)
-                       arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
-               if (mode & MAY_EXEC)
-                       arg.access |= NFS3_ACCESS_EXECUTE;
-       }
-
        res.fattr = nfs_alloc_fattr();
        if (res.fattr == NULL)
                goto out;
index f90090e8c959b14346baf76ac7eaefed7ae30f82..7fd6423031043b933cb0d113ad24ebb5619fc11b 100644 (file)
@@ -3889,6 +3889,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
        struct nfs4_accessargs args = {
                .fh = NFS_FH(inode),
                .bitmask = server->cache_consistency_bitmask,
+               .access = entry->mask,
        };
        struct nfs4_accessres res = {
                .server = server,
@@ -3899,26 +3900,8 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
                .rpc_resp = &res,
                .rpc_cred = entry->cred,
        };
-       int mode = entry->mask;
        int status = 0;
 
-       /*
-        * Determine which access bits we want to ask for...
-        */
-       if (mode & MAY_READ)
-               args.access |= NFS4_ACCESS_READ;
-       if (S_ISDIR(inode->i_mode)) {
-               if (mode & MAY_WRITE)
-                       args.access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE;
-               if (mode & MAY_EXEC)
-                       args.access |= NFS4_ACCESS_LOOKUP;
-       } else {
-               if (mode & MAY_WRITE)
-                       args.access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND;
-               if (mode & MAY_EXEC)
-                       args.access |= NFS4_ACCESS_EXECUTE;
-       }
-
        res.fattr = nfs_alloc_fattr();
        if (res.fattr == NULL)
                return -ENOMEM;