Blob Blame History Raw
From: Jeff Layton <jlayton@kernel.org>
Date: Thu, 6 Jun 2019 08:06:40 -0400
Subject: ceph: handle change_attr in cap messages
Git-commit: 176c77c9c9b1f843332496a28f4545eb96d5dab9
Patch-mainline: v5.3-rc1
References: bsc#1148133 bsc#1136682

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Acked-by: Luis Henriques <lhenriques@suse.com>
[luis: s/timespec64/timespec]
---
 fs/ceph/caps.c  |   19 ++++++++++---------
 fs/ceph/snap.c  |    2 ++
 fs/ceph/super.h |    1 +
 3 files changed, 13 insertions(+), 9 deletions(-)

--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -7,6 +7,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/writeback.h>
+#include <linux/iversion.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -1114,6 +1115,7 @@ struct cap_msg_args {
 	u64			ino, cid, follows;
 	u64			flush_tid, oldest_flush_tid, size, max_size;
 	u64			xattr_version;
+	u64			change_attr;
 	struct ceph_buffer	*xattr_buf;
 	struct timespec		atime, mtime, ctime, btime;
 	int			op, caps, wanted, dirty;
@@ -1220,15 +1222,10 @@ static int send_cap_msg(struct cap_msg_a
 	/* pool namespace (version 8) (mds always ignores this) */
 	ceph_encode_32(&p, 0);
 
-	/*
-	 * btime and change_attr (version 9)
-	 *
-	 * We just zero these out for now, as the MDS ignores them unless
-	 * the requisite feature flags are set (which we don't do yet).
-	 */
+	/* btime and change_attr (version 9) */
 	ceph_encode_timespec(p, &arg->btime);
 	p += sizeof(struct ceph_timespec);
-	ceph_encode_64(&p, 0);
+	ceph_encode_64(&p, arg->change_attr);
 
 	/* Advisory flags (version 10) */
 	ceph_encode_32(&p, arg->flags);
@@ -1356,6 +1353,7 @@ static int __send_cap(struct ceph_mds_cl
 	arg.atime = inode->i_atime;
 	arg.ctime = inode->i_ctime;
 	arg.btime = ci->i_btime;
+	arg.change_attr = inode_peek_iversion_raw(inode);
 
 	arg.op = op;
 	arg.caps = cap->implemented;
@@ -1416,6 +1414,7 @@ static inline int __send_flush_snap(stru
 	arg.mtime = capsnap->mtime;
 	arg.ctime = capsnap->ctime;
 	arg.btime = capsnap->btime;
+	arg.change_attr = capsnap->change_attr;
 
 	arg.op = CEPH_CAP_OP_FLUSHSNAP;
 	arg.caps = capsnap->issued;
@@ -3030,6 +3029,7 @@ struct cap_extra_info {
 	bool dirstat_valid;
 	u64 nfiles;
 	u64 nsubdirs;
+	u64 change_attr;
 	/* currently issued */
 	int issued;
 	struct timespec btime;
@@ -3114,6 +3114,8 @@ static void handle_cap_grant(struct inod
 
 	__check_cap_issue(ci, cap, newcaps);
 
+	inode_set_max_iversion_raw(inode, extra_info->change_attr);
+
 	if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
 	    (extra_info->issued & CEPH_CAP_AUTH_EXCL) == 0) {
 		inode->i_mode = le32_to_cpu(grant->mode);
@@ -3842,14 +3844,13 @@ void ceph_handle_caps(struct ceph_mds_se
 
 	if (msg_version >= 9) {
 		struct ceph_timespec *btime;
-		u64 change_attr;
 
 		if (p + sizeof(*btime) > end)
 			goto bad;
 		btime = p;
 		ceph_decode_timespec(&extra_info.btime, btime);
 		p += sizeof(*btime);
-		ceph_decode_64_safe(&p, end, change_attr, bad);
+		ceph_decode_64_safe(&p, end, extra_info.change_attr, bad);
 	}
 
 	if (msg_version >= 11) {
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -2,6 +2,7 @@
 
 #include <linux/sort.h>
 #include <linux/slab.h>
+#include <linux/iversion.h>
 #include "super.h"
 #include "mds_client.h"
 #include <linux/ceph/decode.h>
@@ -603,6 +604,7 @@ int __ceph_finish_cap_snap(struct ceph_i
 	capsnap->atime = inode->i_atime;
 	capsnap->ctime = inode->i_ctime;
 	capsnap->btime = ci->i_btime;
+	capsnap->change_attr = inode_peek_iversion_raw(inode);
 	capsnap->time_warp_seq = ci->i_time_warp_seq;
 	capsnap->truncate_size = ci->i_truncate_size;
 	capsnap->truncate_seq = ci->i_truncate_seq;
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -193,6 +193,7 @@ struct ceph_cap_snap {
 	u64 xattr_version;
 
 	u64 size;
+	u64 change_attr;
 	struct timespec mtime, atime, ctime, btime;
 	u64 time_warp_seq;
 	u64 truncate_size;