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:
parent
4e9906e798
commit
49a9f4f671
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 | \
|
||||||
|
|
Loading…
Reference in New Issue