NFS: Fix attribute bitmask in _nfs42_proc_fallocate()
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sun, 28 Mar 2021 22:12:03 +0000 (18:12 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 12 Apr 2021 21:14:17 +0000 (17:14 -0400)
We can't use nfs4_fattr_bitmap as a bitmask, because it hasn't been
filtered to represent the attributes supported by the server. Instead,
let's revert to using server->cache_consistency_bitmask after adding in
the missing SPACE_USED attribute.

Fixes: 913eca1aea87 ("NFS: Fallocate should use the nfs4_fattr_bitmap")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs42proc.c

index 094024b..597005b 100644 (file)
@@ -46,11 +46,12 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 {
        struct inode *inode = file_inode(filep);
        struct nfs_server *server = NFS_SERVER(inode);
+       u32 bitmask[3];
        struct nfs42_falloc_args args = {
                .falloc_fh      = NFS_FH(inode),
                .falloc_offset  = offset,
                .falloc_length  = len,
-               .falloc_bitmask = nfs4_fattr_bitmap,
+               .falloc_bitmask = bitmask,
        };
        struct nfs42_falloc_res res = {
                .falloc_server  = server,
@@ -68,6 +69,10 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
                return status;
        }
 
+       memcpy(bitmask, server->cache_consistency_bitmask, sizeof(bitmask));
+       if (server->attr_bitmask[1] & FATTR4_WORD1_SPACE_USED)
+               bitmask[1] |= FATTR4_WORD1_SPACE_USED;
+
        res.falloc_fattr = nfs_alloc_fattr();
        if (!res.falloc_fattr)
                return -ENOMEM;
@@ -75,7 +80,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
        status = nfs4_call_sync(server->client, server, msg,
                                &args.seq_args, &res.seq_res, 0);
        if (status == 0)
-               status = nfs_post_op_update_inode(inode, res.falloc_fattr);
+               status = nfs_post_op_update_inode_force_wcc(inode,
+                                                           res.falloc_fattr);
 
        kfree(res.falloc_fattr);
        return status;