|
@@ -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,
|
|
&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,
|
|
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,
|
|
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,
|
|
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,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- 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,
|
|
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,
|
|
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,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ 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);
|