diff options
author | Yan, Zheng <zyan@redhat.com> | 2019-06-20 00:09:08 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-07-08 08:01:44 -0400 |
commit | 49ada6e8dc9f64ad1e8dd6f7b453c9e584e9f897 (patch) | |
tree | 2a0441ae082748a0ba0a976ca30608037dc1d180 /fs/ceph/caps.c | |
parent | d6cee9dbd8c841795cd672b98069866789916648 (diff) |
ceph: more precise CEPH_CLIENT_CAPS_PENDING_CAPSNAP
Client uses this flag to tell mds if there is more cap snap need to
flush. It's mainly for the case that client needs to re-send cap/snap
flushes after mds failover, but CEPH_CAP_ANY_FILE_WR on corresponding
inodes are all released before mds failover.
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index f9055cdec3c7..d98dcd976c80 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1295,7 +1295,7 @@ void __ceph_remove_caps(struct ceph_inode_info *ci) | |||
1295 | * caller should hold snap_rwsem (read), s_mutex. | 1295 | * caller should hold snap_rwsem (read), s_mutex. |
1296 | */ | 1296 | */ |
1297 | static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | 1297 | static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, |
1298 | int op, bool sync, int used, int want, int retain, | 1298 | int op, int flags, int used, int want, int retain, |
1299 | int flushing, u64 flush_tid, u64 oldest_flush_tid) | 1299 | int flushing, u64 flush_tid, u64 oldest_flush_tid) |
1300 | __releases(cap->ci->i_ceph_lock) | 1300 | __releases(cap->ci->i_ceph_lock) |
1301 | { | 1301 | { |
@@ -1393,12 +1393,19 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1393 | arg.mode = inode->i_mode; | 1393 | arg.mode = inode->i_mode; |
1394 | 1394 | ||
1395 | arg.inline_data = ci->i_inline_version != CEPH_INLINE_NONE; | 1395 | arg.inline_data = ci->i_inline_version != CEPH_INLINE_NONE; |
1396 | if (list_empty(&ci->i_cap_snaps)) | 1396 | if (!(flags & CEPH_CLIENT_CAPS_PENDING_CAPSNAP) && |
1397 | arg.flags = CEPH_CLIENT_CAPS_NO_CAPSNAP; | 1397 | !list_empty(&ci->i_cap_snaps)) { |
1398 | else | 1398 | struct ceph_cap_snap *capsnap; |
1399 | arg.flags = CEPH_CLIENT_CAPS_PENDING_CAPSNAP; | 1399 | list_for_each_entry_reverse(capsnap, &ci->i_cap_snaps, ci_item) { |
1400 | if (sync) | 1400 | if (capsnap->cap_flush.tid) |
1401 | arg.flags |= CEPH_CLIENT_CAPS_SYNC; | 1401 | break; |
1402 | if (capsnap->need_flush) { | ||
1403 | flags |= CEPH_CLIENT_CAPS_PENDING_CAPSNAP; | ||
1404 | break; | ||
1405 | } | ||
1406 | } | ||
1407 | } | ||
1408 | arg.flags = flags; | ||
1402 | 1409 | ||
1403 | spin_unlock(&ci->i_ceph_lock); | 1410 | spin_unlock(&ci->i_ceph_lock); |
1404 | 1411 | ||
@@ -2085,7 +2092,7 @@ ack: | |||
2085 | sent++; | 2092 | sent++; |
2086 | 2093 | ||
2087 | /* __send_cap drops i_ceph_lock */ | 2094 | /* __send_cap drops i_ceph_lock */ |
2088 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, false, | 2095 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, 0, |
2089 | cap_used, want, retain, flushing, | 2096 | cap_used, want, retain, flushing, |
2090 | flush_tid, oldest_flush_tid); | 2097 | flush_tid, oldest_flush_tid); |
2091 | goto retry; /* retake i_ceph_lock and restart our cap scan. */ | 2098 | goto retry; /* retake i_ceph_lock and restart our cap scan. */ |
@@ -2155,7 +2162,8 @@ retry_locked: | |||
2155 | &flush_tid, &oldest_flush_tid); | 2162 | &flush_tid, &oldest_flush_tid); |
2156 | 2163 | ||
2157 | /* __send_cap drops i_ceph_lock */ | 2164 | /* __send_cap drops i_ceph_lock */ |
2158 | delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, true, | 2165 | delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, |
2166 | CEPH_CLIENT_CAPS_SYNC, | ||
2159 | __ceph_caps_used(ci), | 2167 | __ceph_caps_used(ci), |
2160 | __ceph_caps_wanted(ci), | 2168 | __ceph_caps_wanted(ci), |
2161 | (cap->issued | cap->implemented), | 2169 | (cap->issued | cap->implemented), |
@@ -2328,9 +2336,17 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, | |||
2328 | struct ceph_cap_flush *cf; | 2336 | struct ceph_cap_flush *cf; |
2329 | int ret; | 2337 | int ret; |
2330 | u64 first_tid = 0; | 2338 | u64 first_tid = 0; |
2339 | u64 last_snap_flush = 0; | ||
2331 | 2340 | ||
2332 | ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; | 2341 | ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; |
2333 | 2342 | ||
2343 | list_for_each_entry_reverse(cf, &ci->i_cap_flush_list, i_list) { | ||
2344 | if (!cf->caps) { | ||
2345 | last_snap_flush = cf->tid; | ||
2346 | break; | ||
2347 | } | ||
2348 | } | ||
2349 | |||
2334 | list_for_each_entry(cf, &ci->i_cap_flush_list, i_list) { | 2350 | list_for_each_entry(cf, &ci->i_cap_flush_list, i_list) { |
2335 | if (cf->tid < first_tid) | 2351 | if (cf->tid < first_tid) |
2336 | continue; | 2352 | continue; |
@@ -2348,10 +2364,13 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, | |||
2348 | dout("kick_flushing_caps %p cap %p tid %llu %s\n", | 2364 | dout("kick_flushing_caps %p cap %p tid %llu %s\n", |
2349 | inode, cap, cf->tid, ceph_cap_string(cf->caps)); | 2365 | inode, cap, cf->tid, ceph_cap_string(cf->caps)); |
2350 | ci->i_ceph_flags |= CEPH_I_NODELAY; | 2366 | ci->i_ceph_flags |= CEPH_I_NODELAY; |
2367 | |||
2351 | ret = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, | 2368 | ret = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, |
2352 | false, __ceph_caps_used(ci), | 2369 | (cf->tid < last_snap_flush ? |
2370 | CEPH_CLIENT_CAPS_PENDING_CAPSNAP : 0), | ||
2371 | __ceph_caps_used(ci), | ||
2353 | __ceph_caps_wanted(ci), | 2372 | __ceph_caps_wanted(ci), |
2354 | cap->issued | cap->implemented, | 2373 | (cap->issued | cap->implemented), |
2355 | cf->caps, cf->tid, oldest_flush_tid); | 2374 | cf->caps, cf->tid, oldest_flush_tid); |
2356 | if (ret) { | 2375 | if (ret) { |
2357 | pr_err("kick_flushing_caps: error sending " | 2376 | pr_err("kick_flushing_caps: error sending " |