]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
NFS: Return the file btime in the statx results when appropriate
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 29 May 2025 10:45:47 +0000 (06:45 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 14 Jul 2025 22:20:02 +0000 (15:20 -0700)
If the server supports the NFSv4.x "create_time" attribute, then return
it as part of the statx results.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://lore.kernel.org/r/eae27d6467e08aaa67e0ac6ae7119263a0f83349.1748515333.git.bcodding@redhat.com
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/inode.c
fs/nfs/nfs4trace.h

index c5462aed6bf5e8fff11665f871228f975155ecbf..4c7fa4f2bd5e27bda380e3bb92bd834e87f6add3 100644 (file)
@@ -937,6 +937,7 @@ static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
 
 static u32 nfs_get_valid_attrmask(struct inode *inode)
 {
+       u64 fattr_valid = NFS_SERVER(inode)->fattr_valid;
        unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
        u32 reply_mask = STATX_INO | STATX_TYPE;
 
@@ -956,6 +957,9 @@ static u32 nfs_get_valid_attrmask(struct inode *inode)
                reply_mask |= STATX_UID | STATX_GID;
        if (!(cache_validity & NFS_INO_INVALID_BLOCKS))
                reply_mask |= STATX_BLOCKS;
+       if (!(cache_validity & NFS_INO_INVALID_BTIME) &&
+           (fattr_valid & NFS_ATTR_FATTR_BTIME))
+               reply_mask |= STATX_BTIME;
        if (!(cache_validity & NFS_INO_INVALID_CHANGE))
                reply_mask |= STATX_CHANGE_COOKIE;
        return reply_mask;
@@ -966,6 +970,7 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
 {
        struct inode *inode = d_inode(path->dentry);
        struct nfs_server *server = NFS_SERVER(inode);
+       u64 fattr_valid = server->fattr_valid;
        unsigned long cache_validity;
        int err = 0;
        bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
@@ -976,9 +981,12 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
 
        request_mask &= STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_UID |
                        STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME |
-                       STATX_INO | STATX_SIZE | STATX_BLOCKS |
+                       STATX_INO | STATX_SIZE | STATX_BLOCKS | STATX_BTIME |
                        STATX_CHANGE_COOKIE;
 
+       if (!(fattr_valid & NFS_ATTR_FATTR_BTIME))
+               request_mask &= ~STATX_BTIME;
+
        if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
                if (readdirplus_enabled)
                        nfs_readdirplus_parent_cache_hit(path->dentry);
@@ -1010,7 +1018,7 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
        /* Is the user requesting attributes that might need revalidation? */
        if (!(request_mask & (STATX_MODE|STATX_NLINK|STATX_ATIME|STATX_CTIME|
                                        STATX_MTIME|STATX_UID|STATX_GID|
-                                       STATX_SIZE|STATX_BLOCKS|
+                                       STATX_SIZE|STATX_BLOCKS|STATX_BTIME|
                                        STATX_CHANGE_COOKIE)))
                goto out_no_revalidate;
 
@@ -1034,6 +1042,8 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
                do_update |= cache_validity & NFS_INO_INVALID_OTHER;
        if (request_mask & STATX_BLOCKS)
                do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
+       if (request_mask & STATX_BTIME)
+               do_update |= cache_validity & NFS_INO_INVALID_BTIME;
 
        if (do_update) {
                if (readdirplus_enabled)
@@ -1055,6 +1065,7 @@ out_no_revalidate:
                stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC;
        if (S_ISDIR(inode->i_mode))
                stat->blksize = NFS_SERVER(inode)->dtsize;
+       stat->btime = NFS_I(inode)->btime;
 out:
        trace_nfs_getattr_exit(inode, err);
        return err;
index deab4c0e21a0642ee97b0b81f8c55812f5028f7c..553e4550258891d5cc43c84056f27992f542824a 100644 (file)
@@ -30,7 +30,8 @@
                { NFS_ATTR_FATTR_CTIME, "CTIME" }, \
                { NFS_ATTR_FATTR_CHANGE, "CHANGE" }, \
                { NFS_ATTR_FATTR_OWNER_NAME, "OWNER_NAME" }, \
-               { NFS_ATTR_FATTR_GROUP_NAME, "GROUP_NAME" })
+               { NFS_ATTR_FATTR_GROUP_NAME, "GROUP_NAME" }, \
+               { NFS_ATTR_FATTR_BTIME, "BTIME" })
 
 DECLARE_EVENT_CLASS(nfs4_clientid_event,
                TP_PROTO(