提交 4985d6f9 编写于 作者: Y Yan, Zheng 提交者: Ilya Dryomov

ceph: handle the new nfiles/nsubdirs fields in cap message

Without these new fields, stale st_size is returned in following
case.

1. MDS modifies a directory
2. MDS issues CEPH_CAP_ANY_SHARED to client
3. The client satifies stat(2) by its cached metadata. set st_size
   to "i_files + i_subdirs".

Link: http://tracker.ceph.com/issues/23855Signed-off-by: N"Yan, Zheng" <zyan@redhat.com>
Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
上级 a1c6b835
...@@ -3030,6 +3030,10 @@ struct cap_extra_info { ...@@ -3030,6 +3030,10 @@ struct cap_extra_info {
u64 inline_version; u64 inline_version;
void *inline_data; void *inline_data;
u32 inline_len; u32 inline_len;
/* dirstat */
bool dirstat_valid;
u64 nfiles;
u64 nsubdirs;
/* currently issued */ /* currently issued */
int issued; int issued;
}; };
...@@ -3154,6 +3158,11 @@ static void handle_cap_grant(struct inode *inode, ...@@ -3154,6 +3158,11 @@ static void handle_cap_grant(struct inode *inode,
&ctime, &mtime, &atime); &ctime, &mtime, &atime);
} }
if ((newcaps & CEPH_CAP_FILE_SHARED) && extra_info->dirstat_valid) {
ci->i_files = extra_info->nfiles;
ci->i_subdirs = extra_info->nsubdirs;
}
if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) { if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) {
/* file layout may have changed */ /* file layout may have changed */
s64 old_pool = ci->i_layout.pool_id; s64 old_pool = ci->i_layout.pool_id;
...@@ -3741,6 +3750,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3741,6 +3750,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
struct ceph_mds_cap_peer *peer = NULL; struct ceph_mds_cap_peer *peer = NULL;
struct ceph_snap_realm *realm = NULL; struct ceph_snap_realm *realm = NULL;
int op; int op;
int msg_version = le16_to_cpu(msg->hdr.version);
u32 seq, mseq; u32 seq, mseq;
struct ceph_vino vino; struct ceph_vino vino;
void *snaptrace; void *snaptrace;
...@@ -3765,7 +3775,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3765,7 +3775,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
snaptrace_len = le32_to_cpu(h->snap_trace_len); snaptrace_len = le32_to_cpu(h->snap_trace_len);
p = snaptrace + snaptrace_len; p = snaptrace + snaptrace_len;
if (le16_to_cpu(msg->hdr.version) >= 2) { if (msg_version >= 2) {
u32 flock_len; u32 flock_len;
ceph_decode_32_safe(&p, end, flock_len, bad); ceph_decode_32_safe(&p, end, flock_len, bad);
if (p + flock_len > end) if (p + flock_len > end)
...@@ -3773,7 +3783,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3773,7 +3783,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
p += flock_len; p += flock_len;
} }
if (le16_to_cpu(msg->hdr.version) >= 3) { if (msg_version >= 3) {
if (op == CEPH_CAP_OP_IMPORT) { if (op == CEPH_CAP_OP_IMPORT) {
if (p + sizeof(*peer) > end) if (p + sizeof(*peer) > end)
goto bad; goto bad;
...@@ -3785,7 +3795,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3785,7 +3795,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
} }
} }
if (le16_to_cpu(msg->hdr.version) >= 4) { if (msg_version >= 4) {
ceph_decode_64_safe(&p, end, extra_info.inline_version, bad); ceph_decode_64_safe(&p, end, extra_info.inline_version, bad);
ceph_decode_32_safe(&p, end, extra_info.inline_len, bad); ceph_decode_32_safe(&p, end, extra_info.inline_len, bad);
if (p + extra_info.inline_len > end) if (p + extra_info.inline_len > end)
...@@ -3794,7 +3804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3794,7 +3804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
p += extra_info.inline_len; p += extra_info.inline_len;
} }
if (le16_to_cpu(msg->hdr.version) >= 5) { if (msg_version >= 5) {
struct ceph_osd_client *osdc = &mdsc->fsc->client->osdc; struct ceph_osd_client *osdc = &mdsc->fsc->client->osdc;
u32 epoch_barrier; u32 epoch_barrier;
...@@ -3802,7 +3812,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3802,7 +3812,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
ceph_osdc_update_epoch_barrier(osdc, epoch_barrier); ceph_osdc_update_epoch_barrier(osdc, epoch_barrier);
} }
if (le16_to_cpu(msg->hdr.version) >= 8) { if (msg_version >= 8) {
u64 flush_tid; u64 flush_tid;
u32 caller_uid, caller_gid; u32 caller_uid, caller_gid;
u32 pool_ns_len; u32 pool_ns_len;
...@@ -3822,6 +3832,25 @@ void ceph_handle_caps(struct ceph_mds_session *session, ...@@ -3822,6 +3832,25 @@ void ceph_handle_caps(struct ceph_mds_session *session,
} }
} }
if (msg_version >= 11) {
struct ceph_timespec *btime;
u64 change_attr;
u32 flags;
/* version >= 9 */
if (p + sizeof(*btime) > end)
goto bad;
btime = p;
p += sizeof(*btime);
ceph_decode_64_safe(&p, end, change_attr, bad);
/* version >= 10 */
ceph_decode_32_safe(&p, end, flags, bad);
/* version >= 11 */
extra_info.dirstat_valid = true;
ceph_decode_64_safe(&p, end, extra_info.nfiles, bad);
ceph_decode_64_safe(&p, end, extra_info.nsubdirs, bad);
}
/* lookup ino */ /* lookup ino */
inode = ceph_find_inode(mdsc->fsc->sb, vino); inode = ceph_find_inode(mdsc->fsc->sb, vino);
ci = ceph_inode(inode); ci = ceph_inode(inode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册