]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
NFSv4: Add CB_GETATTR support for delegated attributes
authorTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 17 Jun 2024 01:21:23 +0000 (21:21 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 8 Jul 2024 17:47:25 +0000 (13:47 -0400)
When the client holds an attribute delegation, the server may retrieve
all the timestamps through a CB_GETATTR callback.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c

index 650758ee0d5fe24bb0be7b67c4ccb8eb17f35b0d..154a6ed1299f8556cb26e9011d07bf2e1d31f300 100644 (file)
@@ -46,14 +46,15 @@ struct cb_compound_hdr_res {
 
 struct cb_getattrargs {
        struct nfs_fh fh;
-       uint32_t bitmap[2];
+       uint32_t bitmap[3];
 };
 
 struct cb_getattrres {
        __be32 status;
-       uint32_t bitmap[2];
+       uint32_t bitmap[3];
        uint64_t size;
        uint64_t change_attr;
+       struct timespec64 atime;
        struct timespec64 ctime;
        struct timespec64 mtime;
 };
index 76cea34477ae6fde32e99c277df8eea7526bd484..199c527886405f6eecbd097dae40a079cf73d7cb 100644 (file)
@@ -37,7 +37,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
        if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
                goto out;
 
-       res->bitmap[0] = res->bitmap[1] = 0;
+       memset(res->bitmap, 0, sizeof(res->bitmap));
        res->status = htonl(NFS4ERR_BADHANDLE);
 
        dprintk_rcu("NFS: GETATTR callback request from %s\n",
@@ -59,12 +59,16 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
        res->change_attr = delegation->change_attr;
        if (nfs_have_writebacks(inode))
                res->change_attr++;
+       res->atime = inode_get_atime(inode);
        res->ctime = inode_get_ctime(inode);
        res->mtime = inode_get_mtime(inode);
-       res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
-               args->bitmap[0];
-       res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
-               args->bitmap[1];
+       res->bitmap[0] = (FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE) &
+                        args->bitmap[0];
+       res->bitmap[1] = (FATTR4_WORD1_TIME_ACCESS |
+                         FATTR4_WORD1_TIME_METADATA |
+                         FATTR4_WORD1_TIME_MODIFY) & args->bitmap[1];
+       res->bitmap[2] = (FATTR4_WORD2_TIME_DELEG_ACCESS |
+                         FATTR4_WORD2_TIME_DELEG_MODIFY) & args->bitmap[2];
        res->status = 0;
 out_iput:
        rcu_read_unlock();
index 9369488f2ed453068b19bd505801c1debb811af1..29c49a7e5fe1c10aca0b700d47adfa49c8ffbd86 100644 (file)
@@ -25,8 +25,9 @@
 #define CB_OP_GETATTR_BITMAP_MAXSZ     (4 * 4) // bitmap length, 3 bitmaps
 #define CB_OP_GETATTR_RES_MAXSZ                (CB_OP_HDR_RES_MAXSZ + \
                                         CB_OP_GETATTR_BITMAP_MAXSZ + \
-                                        /* change, size, ctime, mtime */\
-                                        (2 + 2 + 3 + 3) * 4)
+                                        /* change, size, atime, ctime,
+                                         * mtime, deleg_atime, deleg_mtime */\
+                                        (2 + 2 + 3 + 3 + 3 + 3 + 3) * 4)
 #define CB_OP_RECALL_RES_MAXSZ         (CB_OP_HDR_RES_MAXSZ)
 
 #if defined(CONFIG_NFS_V4_1)
@@ -635,6 +636,13 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec64 *
        return 0;
 }
 
+static __be32 encode_attr_atime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
+{
+       if (!(bitmap[1] & FATTR4_WORD1_TIME_ACCESS))
+               return 0;
+       return encode_attr_time(xdr,time);
+}
+
 static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec64 *time)
 {
        if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
@@ -649,6 +657,24 @@ static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap,
        return encode_attr_time(xdr,time);
 }
 
+static __be32 encode_attr_delegatime(struct xdr_stream *xdr,
+                                    const uint32_t *bitmap,
+                                    const struct timespec64 *time)
+{
+       if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_ACCESS))
+               return 0;
+       return encode_attr_time(xdr,time);
+}
+
+static __be32 encode_attr_delegmtime(struct xdr_stream *xdr,
+                                    const uint32_t *bitmap,
+                                    const struct timespec64 *time)
+{
+       if (!(bitmap[2] & FATTR4_WORD2_TIME_DELEG_MODIFY))
+               return 0;
+       return encode_attr_time(xdr,time);
+}
+
 static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
 {
        __be32 status;
@@ -697,12 +723,21 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr,
        if (unlikely(status != 0))
                goto out;
        status = encode_attr_size(xdr, res->bitmap, res->size);
+       if (unlikely(status != 0))
+               goto out;
+       status = encode_attr_atime(xdr, res->bitmap, &res->atime);
        if (unlikely(status != 0))
                goto out;
        status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
        if (unlikely(status != 0))
                goto out;
        status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
+       if (unlikely(status != 0))
+               goto out;
+       status = encode_attr_delegatime(xdr, res->bitmap, &res->atime);
+       if (unlikely(status != 0))
+               goto out;
+       status = encode_attr_delegmtime(xdr, res->bitmap, &res->mtime);
        *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
 out:
        return status;