diff options
author | Yan, Zheng <zyan@redhat.com> | 2015-06-10 05:26:13 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-06-25 04:49:31 -0400 |
commit | f66fd9f0952187d274c13c136b74548f792c1925 (patch) | |
tree | c021f04f69b116f2673fdfb2354a99871f8f03a4 /fs/ceph/caps.c | |
parent | e548e9b93d3e565e42b938a99804114565be1f81 (diff) |
ceph: pre-allocate data structure that tracks caps flushing
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 69a16044ec41..dd7b20adf1d4 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1356,7 +1356,8 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) | |||
1356 | * Caller is then responsible for calling __mark_inode_dirty with the | 1356 | * Caller is then responsible for calling __mark_inode_dirty with the |
1357 | * returned flags value. | 1357 | * returned flags value. |
1358 | */ | 1358 | */ |
1359 | int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | 1359 | int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, |
1360 | struct ceph_cap_flush **pcf) | ||
1360 | { | 1361 | { |
1361 | struct ceph_mds_client *mdsc = | 1362 | struct ceph_mds_client *mdsc = |
1362 | ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc; | 1363 | ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc; |
@@ -1376,6 +1377,9 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |||
1376 | ceph_cap_string(was | mask)); | 1377 | ceph_cap_string(was | mask)); |
1377 | ci->i_dirty_caps |= mask; | 1378 | ci->i_dirty_caps |= mask; |
1378 | if (was == 0) { | 1379 | if (was == 0) { |
1380 | WARN_ON_ONCE(ci->i_prealloc_cap_flush); | ||
1381 | swap(ci->i_prealloc_cap_flush, *pcf); | ||
1382 | |||
1379 | if (!ci->i_head_snapc) { | 1383 | if (!ci->i_head_snapc) { |
1380 | WARN_ON_ONCE(!rwsem_is_locked(&mdsc->snap_rwsem)); | 1384 | WARN_ON_ONCE(!rwsem_is_locked(&mdsc->snap_rwsem)); |
1381 | ci->i_head_snapc = ceph_get_snap_context( | 1385 | ci->i_head_snapc = ceph_get_snap_context( |
@@ -1391,6 +1395,8 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |||
1391 | ihold(inode); | 1395 | ihold(inode); |
1392 | dirty |= I_DIRTY_SYNC; | 1396 | dirty |= I_DIRTY_SYNC; |
1393 | } | 1397 | } |
1398 | } else { | ||
1399 | WARN_ON_ONCE(!ci->i_prealloc_cap_flush); | ||
1394 | } | 1400 | } |
1395 | BUG_ON(list_empty(&ci->i_dirty_item)); | 1401 | BUG_ON(list_empty(&ci->i_dirty_item)); |
1396 | if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && | 1402 | if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && |
@@ -1446,6 +1452,17 @@ static void __add_cap_flushing_to_mdsc(struct ceph_mds_client *mdsc, | |||
1446 | rb_insert_color(&cf->g_node, &mdsc->cap_flush_tree); | 1452 | rb_insert_color(&cf->g_node, &mdsc->cap_flush_tree); |
1447 | } | 1453 | } |
1448 | 1454 | ||
1455 | struct ceph_cap_flush *ceph_alloc_cap_flush(void) | ||
1456 | { | ||
1457 | return kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL); | ||
1458 | } | ||
1459 | |||
1460 | void ceph_free_cap_flush(struct ceph_cap_flush *cf) | ||
1461 | { | ||
1462 | if (cf) | ||
1463 | kmem_cache_free(ceph_cap_flush_cachep, cf); | ||
1464 | } | ||
1465 | |||
1449 | static u64 __get_oldest_flush_tid(struct ceph_mds_client *mdsc) | 1466 | static u64 __get_oldest_flush_tid(struct ceph_mds_client *mdsc) |
1450 | { | 1467 | { |
1451 | struct rb_node *n = rb_first(&mdsc->cap_flush_tree); | 1468 | struct rb_node *n = rb_first(&mdsc->cap_flush_tree); |
@@ -1469,11 +1486,12 @@ static int __mark_caps_flushing(struct inode *inode, | |||
1469 | { | 1486 | { |
1470 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | 1487 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
1471 | struct ceph_inode_info *ci = ceph_inode(inode); | 1488 | struct ceph_inode_info *ci = ceph_inode(inode); |
1472 | struct ceph_cap_flush *cf; | 1489 | struct ceph_cap_flush *cf = NULL; |
1473 | int flushing; | 1490 | int flushing; |
1474 | 1491 | ||
1475 | BUG_ON(ci->i_dirty_caps == 0); | 1492 | BUG_ON(ci->i_dirty_caps == 0); |
1476 | BUG_ON(list_empty(&ci->i_dirty_item)); | 1493 | BUG_ON(list_empty(&ci->i_dirty_item)); |
1494 | BUG_ON(!ci->i_prealloc_cap_flush); | ||
1477 | 1495 | ||
1478 | flushing = ci->i_dirty_caps; | 1496 | flushing = ci->i_dirty_caps; |
1479 | dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n", | 1497 | dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n", |
@@ -1484,7 +1502,7 @@ static int __mark_caps_flushing(struct inode *inode, | |||
1484 | ci->i_dirty_caps = 0; | 1502 | ci->i_dirty_caps = 0; |
1485 | dout(" inode %p now !dirty\n", inode); | 1503 | dout(" inode %p now !dirty\n", inode); |
1486 | 1504 | ||
1487 | cf = kmalloc(sizeof(*cf), GFP_ATOMIC); | 1505 | swap(cf, ci->i_prealloc_cap_flush); |
1488 | cf->caps = flushing; | 1506 | cf->caps = flushing; |
1489 | cf->kick = false; | 1507 | cf->kick = false; |
1490 | 1508 | ||
@@ -3075,7 +3093,7 @@ out: | |||
3075 | cf = list_first_entry(&to_remove, | 3093 | cf = list_first_entry(&to_remove, |
3076 | struct ceph_cap_flush, list); | 3094 | struct ceph_cap_flush, list); |
3077 | list_del(&cf->list); | 3095 | list_del(&cf->list); |
3078 | kfree(cf); | 3096 | ceph_free_cap_flush(cf); |
3079 | } | 3097 | } |
3080 | if (drop) | 3098 | if (drop) |
3081 | iput(inode); | 3099 | iput(inode); |