ceph: report the inode version in getattr if requested
authorJeff Layton <jlayton@kernel.org>
Fri, 5 Aug 2022 17:50:02 +0000 (13:50 -0400)
committerJeff Layton <jlayton@kernel.org>
Thu, 26 Jan 2023 12:00:06 +0000 (07:00 -0500)
When getattr requests the STX_CHANGE_COOKIE, request the full gamut of
caps (similarly to how ctime is handled). When the change attribute
seems to be valid, return it in the change_cookie field and set the flag
in the reply mask. Also, unconditionally enable
STATX_ATTR_CHANGE_MONOTONIC.

Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
fs/ceph/inode.c

index 23d05ec..e22e631 100644 (file)
@@ -2417,10 +2417,10 @@ static int statx_to_caps(u32 want, umode_t mode)
 {
        int mask = 0;
 
-       if (want & (STATX_MODE|STATX_UID|STATX_GID|STATX_CTIME|STATX_BTIME))
+       if (want & (STATX_MODE|STATX_UID|STATX_GID|STATX_CTIME|STATX_BTIME|STATX_CHANGE_COOKIE))
                mask |= CEPH_CAP_AUTH_SHARED;
 
-       if (want & (STATX_NLINK|STATX_CTIME)) {
+       if (want & (STATX_NLINK|STATX_CTIME|STATX_CHANGE_COOKIE)) {
                /*
                 * The link count for directories depends on inode->i_subdirs,
                 * and that is only updated when Fs caps are held.
@@ -2431,11 +2431,10 @@ static int statx_to_caps(u32 want, umode_t mode)
                        mask |= CEPH_CAP_LINK_SHARED;
        }
 
-       if (want & (STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_SIZE|
-                   STATX_BLOCKS))
+       if (want & (STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_SIZE|STATX_BLOCKS|STATX_CHANGE_COOKIE))
                mask |= CEPH_CAP_FILE_SHARED;
 
-       if (want & (STATX_CTIME))
+       if (want & (STATX_CTIME|STATX_CHANGE_COOKIE))
                mask |= CEPH_CAP_XATTR_SHARED;
 
        return mask;
@@ -2478,6 +2477,11 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
                valid_mask |= STATX_BTIME;
        }
 
+       if (request_mask & STATX_CHANGE_COOKIE) {
+               stat->change_cookie = inode_peek_iversion_raw(inode);
+               valid_mask |= STATX_CHANGE_COOKIE;
+       }
+
        if (ceph_snap(inode) == CEPH_NOSNAP)
                stat->dev = sb->s_dev;
        else
@@ -2519,6 +2523,8 @@ int ceph_getattr(struct user_namespace *mnt_userns, const struct path *path,
                        stat->nlink = 1 + 1 + ci->i_subdirs;
        }
 
+       stat->attributes_mask |= STATX_ATTR_CHANGE_MONOTONIC;
+       stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC;
        stat->result_mask = request_mask & valid_mask;
        return err;
 }