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: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Yan, Zheng 2018-04-25 17:30:23 +08:00 committed by Ilya Dryomov
parent 4e9906e798
commit 49a9f4f671
4 changed files with 36 additions and 18 deletions

View File

@ -69,6 +69,8 @@ static char *gcap_string(char *s, int c)
*s++ = 'w'; *s++ = 'w';
if (c & CEPH_CAP_GBUFFER) if (c & CEPH_CAP_GBUFFER)
*s++ = 'b'; *s++ = 'b';
if (c & CEPH_CAP_GWREXTEND)
*s++ = 'a';
if (c & CEPH_CAP_GLAZYIO) if (c & CEPH_CAP_GLAZYIO)
*s++ = 'l'; *s++ = 'l';
return s; return s;

View File

@ -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 */ /* xattrs */
/* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */ /* 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)) && 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_op = &ceph_dir_iops;
inode->i_fop = &ceph_dir_fops; inode->i_fop = &ceph_dir_fops;
ci->i_dir_layout = iinfo->dir_layout;
ci->i_files = le64_to_cpu(info->files); ci->i_files = le64_to_cpu(info->files);
ci->i_subdirs = le64_to_cpu(info->subdirs); 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; break;
default: default:
pr_err("fill_inode %llx.%llx BAD mode 0%o\n", 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_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
struct ceph_mds_client *mdsc = fsc->mdsc; struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_mds_request *req; struct ceph_mds_request *req;
int mode;
int err; int err;
if (ceph_snap(inode) == CEPH_SNAPDIR) { 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)) if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
return 0; 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)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = inode; req->r_inode = inode;

View File

@ -56,6 +56,7 @@ struct ceph_vxattr {
#define VXATTR_FLAG_READONLY (1<<0) #define VXATTR_FLAG_READONLY (1<<0)
#define VXATTR_FLAG_HIDDEN (1<<1) #define VXATTR_FLAG_HIDDEN (1<<1)
#define VXATTR_FLAG_RSTAT (1<<2)
/* layouts */ /* 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) \ #define CEPH_XATTR_NAME2(_type, _name, _name2) \
XATTR_CEPH_PREFIX #_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 = CEPH_XATTR_NAME(_type, _name), \
.name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \ .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
.getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \ .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
.exists_cb = NULL, \ .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) \ #define XATTR_LAYOUT_FIELD(_type, _name, _field) \
{ \ { \
.name = CEPH_XATTR_NAME2(_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, object_size),
XATTR_LAYOUT_FIELD(dir, layout, pool), XATTR_LAYOUT_FIELD(dir, layout, pool),
XATTR_LAYOUT_FIELD(dir, layout, pool_namespace), XATTR_LAYOUT_FIELD(dir, layout, pool_namespace),
XATTR_NAME_CEPH(dir, entries), XATTR_NAME_CEPH(dir, entries, 0),
XATTR_NAME_CEPH(dir, files), XATTR_NAME_CEPH(dir, files, 0),
XATTR_NAME_CEPH(dir, subdirs), XATTR_NAME_CEPH(dir, subdirs, 0),
XATTR_NAME_CEPH(dir, rentries), XATTR_RSTAT_FIELD(dir, rentries),
XATTR_NAME_CEPH(dir, rfiles), XATTR_RSTAT_FIELD(dir, rfiles),
XATTR_NAME_CEPH(dir, rsubdirs), XATTR_RSTAT_FIELD(dir, rsubdirs),
XATTR_NAME_CEPH(dir, rbytes), XATTR_RSTAT_FIELD(dir, rbytes),
XATTR_NAME_CEPH(dir, rctime), XATTR_RSTAT_FIELD(dir, rctime),
{ {
.name = "ceph.quota", .name = "ceph.quota",
.name_size = sizeof("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 */ /* let's see if a virtual xattr was requested */
vxattr = ceph_match_vxattr(inode, name); vxattr = ceph_match_vxattr(inode, name);
if (vxattr) { 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) if (err)
return err; return err;
err = -ENODATA; err = -ENODATA;

View File

@ -628,6 +628,7 @@ int ceph_flags_to_mode(int flags);
CEPH_CAP_XATTR_SHARED) CEPH_CAP_XATTR_SHARED)
#define CEPH_STAT_CAP_INLINE_DATA (CEPH_CAP_FILE_SHARED | \ #define CEPH_STAT_CAP_INLINE_DATA (CEPH_CAP_FILE_SHARED | \
CEPH_CAP_FILE_RD) CEPH_CAP_FILE_RD)
#define CEPH_STAT_RSTAT CEPH_CAP_FILE_WREXTEND
#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED | \ #define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED | \
CEPH_CAP_LINK_SHARED | \ CEPH_CAP_LINK_SHARED | \