summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2015-05-01 04:57:16 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-06-25 04:49:28 -0400
commit860560904962d08fd38666207c910065fe53e074 (patch)
tree88a9532f9652a11bb393a4496130c532705282b9 /fs/ceph/caps.c
parent5dda377cf0a6bd43f64a3c1efb670d7c668e7b29 (diff)
ceph: avoid sending unnessesary FLUSHSNAP message
when a snap notification contains no new snapshot, we can avoid sending FLUSHSNAP message to MDS. But we still need to create cap_snap in some case because it's required by write path and page writeback path Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c69
1 files changed, 38 insertions, 31 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index feb8ec92f1b4..f1dbcae7c75c 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1297,11 +1297,8 @@ retry:
1297 if (capsnap->dirty_pages || capsnap->writing) 1297 if (capsnap->dirty_pages || capsnap->writing)
1298 break; 1298 break;
1299 1299
1300 /* 1300 /* should be removed by ceph_try_drop_cap_snap() */
1301 * if cap writeback already occurred, we should have dropped 1301 BUG_ON(!capsnap->need_flush);
1302 * the capsnap in ceph_put_wrbuffer_cap_refs.
1303 */
1304 BUG_ON(capsnap->dirty == 0);
1305 1302
1306 /* pick mds, take s_mutex */ 1303 /* pick mds, take s_mutex */
1307 if (ci->i_auth_cap == NULL) { 1304 if (ci->i_auth_cap == NULL) {
@@ -2347,6 +2344,27 @@ void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
2347 spin_unlock(&ci->i_ceph_lock); 2344 spin_unlock(&ci->i_ceph_lock);
2348} 2345}
2349 2346
2347
2348/*
2349 * drop cap_snap that is not associated with any snapshot.
2350 * we don't need to send FLUSHSNAP message for it.
2351 */
2352static int ceph_try_drop_cap_snap(struct ceph_cap_snap *capsnap)
2353{
2354 if (!capsnap->need_flush &&
2355 !capsnap->writing && !capsnap->dirty_pages) {
2356
2357 dout("dropping cap_snap %p follows %llu\n",
2358 capsnap, capsnap->follows);
2359 ceph_put_snap_context(capsnap->context);
2360 list_del(&capsnap->ci_item);
2361 list_del(&capsnap->flushing_item);
2362 ceph_put_cap_snap(capsnap);
2363 return 1;
2364 }
2365 return 0;
2366}
2367
2350/* 2368/*
2351 * Release cap refs. 2369 * Release cap refs.
2352 * 2370 *
@@ -2360,7 +2378,6 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
2360{ 2378{
2361 struct inode *inode = &ci->vfs_inode; 2379 struct inode *inode = &ci->vfs_inode;
2362 int last = 0, put = 0, flushsnaps = 0, wake = 0; 2380 int last = 0, put = 0, flushsnaps = 0, wake = 0;
2363 struct ceph_cap_snap *capsnap;
2364 2381
2365 spin_lock(&ci->i_ceph_lock); 2382 spin_lock(&ci->i_ceph_lock);
2366 if (had & CEPH_CAP_PIN) 2383 if (had & CEPH_CAP_PIN)
@@ -2382,17 +2399,17 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
2382 if (had & CEPH_CAP_FILE_WR) 2399 if (had & CEPH_CAP_FILE_WR)
2383 if (--ci->i_wr_ref == 0) { 2400 if (--ci->i_wr_ref == 0) {
2384 last++; 2401 last++;
2385 if (!list_empty(&ci->i_cap_snaps)) { 2402 if (__ceph_have_pending_cap_snap(ci)) {
2386 capsnap = list_first_entry(&ci->i_cap_snaps, 2403 struct ceph_cap_snap *capsnap =
2387 struct ceph_cap_snap, 2404 list_last_entry(&ci->i_cap_snaps,
2388 ci_item); 2405 struct ceph_cap_snap,
2389 if (capsnap->writing) { 2406 ci_item);
2390 capsnap->writing = 0; 2407 capsnap->writing = 0;
2391 flushsnaps = 2408 if (ceph_try_drop_cap_snap(capsnap))
2392 __ceph_finish_cap_snap(ci, 2409 put++;
2393 capsnap); 2410 else if (__ceph_finish_cap_snap(ci, capsnap))
2394 wake = 1; 2411 flushsnaps = 1;
2395 } 2412 wake = 1;
2396 } 2413 }
2397 if (ci->i_wrbuffer_ref_head == 0 && 2414 if (ci->i_wrbuffer_ref_head == 0 &&
2398 ci->i_dirty_caps == 0 && 2415 ci->i_dirty_caps == 0 &&
@@ -2416,7 +2433,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
2416 ceph_flush_snaps(ci); 2433 ceph_flush_snaps(ci);
2417 if (wake) 2434 if (wake)
2418 wake_up_all(&ci->i_cap_wq); 2435 wake_up_all(&ci->i_cap_wq);
2419 if (put) 2436 while (put-- > 0)
2420 iput(inode); 2437 iput(inode);
2421} 2438}
2422 2439
@@ -2467,25 +2484,15 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
2467 capsnap->dirty_pages -= nr; 2484 capsnap->dirty_pages -= nr;
2468 if (capsnap->dirty_pages == 0) { 2485 if (capsnap->dirty_pages == 0) {
2469 complete_capsnap = 1; 2486 complete_capsnap = 1;
2470 if (capsnap->dirty == 0) 2487 drop_capsnap = ceph_try_drop_cap_snap(capsnap);
2471 /* cap writeback completed before we created
2472 * the cap_snap; no FLUSHSNAP is needed */
2473 drop_capsnap = 1;
2474 } 2488 }
2475 dout("put_wrbuffer_cap_refs on %p cap_snap %p " 2489 dout("put_wrbuffer_cap_refs on %p cap_snap %p "
2476 " snap %lld %d/%d -> %d/%d %s%s%s\n", 2490 " snap %lld %d/%d -> %d/%d %s%s\n",
2477 inode, capsnap, capsnap->context->seq, 2491 inode, capsnap, capsnap->context->seq,
2478 ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, 2492 ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
2479 ci->i_wrbuffer_ref, capsnap->dirty_pages, 2493 ci->i_wrbuffer_ref, capsnap->dirty_pages,
2480 last ? " (wrbuffer last)" : "", 2494 last ? " (wrbuffer last)" : "",
2481 complete_capsnap ? " (complete capsnap)" : "", 2495 complete_capsnap ? " (complete capsnap)" : "");
2482 drop_capsnap ? " (drop capsnap)" : "");
2483 if (drop_capsnap) {
2484 ceph_put_snap_context(capsnap->context);
2485 list_del(&capsnap->ci_item);
2486 list_del(&capsnap->flushing_item);
2487 ceph_put_cap_snap(capsnap);
2488 }
2489 } 2496 }
2490 2497
2491 spin_unlock(&ci->i_ceph_lock); 2498 spin_unlock(&ci->i_ceph_lock);