Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49a9f4f6 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: always get rstat from auth mds

rstat is not tracked by capability. client can't know if rstat from
non-auth mds is uptodate or not.

Link: http://tracker.ceph.com/issues/23538


Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 4e9906e7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ static char *gcap_string(char *s, int c)
		*s++ = 'w';
	if (c & CEPH_CAP_GBUFFER)
		*s++ = 'b';
	if (c & CEPH_CAP_GWREXTEND)
		*s++ = 'a';
	if (c & CEPH_CAP_GLAZYIO)
		*s++ = 'l';
	return s;
+15 −6
Original line number Diff line number Diff line
@@ -854,6 +854,18 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
		}
	}

	/* layout and rstat are not tracked by capability, update them if
	 * the inode info is from auth mds */
	if (new_version || (info->cap.flags & CEPH_CAP_FLAG_AUTH)) {
		if (S_ISDIR(inode->i_mode)) {
			ci->i_dir_layout = iinfo->dir_layout;
			ci->i_rbytes = le64_to_cpu(info->rbytes);
			ci->i_rfiles = le64_to_cpu(info->rfiles);
			ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
			ceph_decode_timespec(&ci->i_rctime, &info->rctime);
		}
	}

	/* xattrs */
	/* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
	if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))  &&
@@ -919,14 +931,9 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
		inode->i_op = &ceph_dir_iops;
		inode->i_fop = &ceph_dir_fops;

		ci->i_dir_layout = iinfo->dir_layout;

		ci->i_files = le64_to_cpu(info->files);
		ci->i_subdirs = le64_to_cpu(info->subdirs);
		ci->i_rbytes = le64_to_cpu(info->rbytes);
		ci->i_rfiles = le64_to_cpu(info->rfiles);
		ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
		ceph_decode_timespec(&ci->i_rctime, &info->rctime);
		break;
	default:
		pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
@@ -2178,6 +2185,7 @@ int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
	struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
	struct ceph_mds_client *mdsc = fsc->mdsc;
	struct ceph_mds_request *req;
	int mode;
	int err;

	if (ceph_snap(inode) == CEPH_SNAPDIR) {
@@ -2190,7 +2198,8 @@ int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
	if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
		return 0;

	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
	mode = (mask & CEPH_STAT_RSTAT) ? USE_AUTH_MDS : USE_ANY_MDS;
	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, mode);
	if (IS_ERR(req))
		return PTR_ERR(req);
	req->r_inode = inode;
+18 −12
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct ceph_vxattr {

#define VXATTR_FLAG_READONLY		(1<<0)
#define VXATTR_FLAG_HIDDEN		(1<<1)
#define VXATTR_FLAG_RSTAT		(1<<2)

/* layouts */

@@ -265,14 +266,16 @@ static size_t ceph_vxattrcb_quota_max_files(struct ceph_inode_info *ci,
#define CEPH_XATTR_NAME2(_type, _name, _name2)	\
	XATTR_CEPH_PREFIX #_type "." #_name "." #_name2

#define XATTR_NAME_CEPH(_type, _name)					\
#define XATTR_NAME_CEPH(_type, _name, _flags)				\
	{								\
		.name = CEPH_XATTR_NAME(_type, _name),			\
		.name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
		.getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
		.exists_cb = NULL,					\
		.flags = VXATTR_FLAG_READONLY,			\
		.flags = (VXATTR_FLAG_READONLY | _flags),		\
	}
#define XATTR_RSTAT_FIELD(_type, _name)			\
	XATTR_NAME_CEPH(_type, _name, VXATTR_FLAG_RSTAT)
#define XATTR_LAYOUT_FIELD(_type, _name, _field)			\
	{								\
		.name = CEPH_XATTR_NAME2(_type, _name, _field),	\
@@ -303,14 +306,14 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
	XATTR_LAYOUT_FIELD(dir, layout, object_size),
	XATTR_LAYOUT_FIELD(dir, layout, pool),
	XATTR_LAYOUT_FIELD(dir, layout, pool_namespace),
	XATTR_NAME_CEPH(dir, entries),
	XATTR_NAME_CEPH(dir, files),
	XATTR_NAME_CEPH(dir, subdirs),
	XATTR_NAME_CEPH(dir, rentries),
	XATTR_NAME_CEPH(dir, rfiles),
	XATTR_NAME_CEPH(dir, rsubdirs),
	XATTR_NAME_CEPH(dir, rbytes),
	XATTR_NAME_CEPH(dir, rctime),
	XATTR_NAME_CEPH(dir, entries, 0),
	XATTR_NAME_CEPH(dir, files, 0),
	XATTR_NAME_CEPH(dir, subdirs, 0),
	XATTR_RSTAT_FIELD(dir, rentries),
	XATTR_RSTAT_FIELD(dir, rfiles),
	XATTR_RSTAT_FIELD(dir, rsubdirs),
	XATTR_RSTAT_FIELD(dir, rbytes),
	XATTR_RSTAT_FIELD(dir, rctime),
	{
		.name = "ceph.quota",
		.name_size = sizeof("ceph.quota"),
@@ -807,7 +810,10 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
	/* let's see if a virtual xattr was requested */
	vxattr = ceph_match_vxattr(inode, name);
	if (vxattr) {
		err = ceph_do_getattr(inode, 0, true);
		int mask = 0;
		if (vxattr->flags & VXATTR_FLAG_RSTAT)
			mask |= CEPH_STAT_RSTAT;
		err = ceph_do_getattr(inode, mask, true);
		if (err)
			return err;
		err = -ENODATA;
+1 −0
Original line number Diff line number Diff line
@@ -628,6 +628,7 @@ int ceph_flags_to_mode(int flags);
				 CEPH_CAP_XATTR_SHARED)
#define CEPH_STAT_CAP_INLINE_DATA (CEPH_CAP_FILE_SHARED | \
				   CEPH_CAP_FILE_RD)
#define CEPH_STAT_RSTAT CEPH_CAP_FILE_WREXTEND

#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED |			\
			      CEPH_CAP_LINK_SHARED |			\