diff options
author | Hou Pengyang <houpengyang@huawei.com> | 2017-04-26 12:17:21 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2017-05-03 13:04:54 -0400 |
commit | 279d6df20c94079d35e012f1602d40c42632e8f3 (patch) | |
tree | 2570480070d63ca08bf3f99cbdb0330e7622ee00 | |
parent | 9a744b92da6eacea33dec1e9280fd324736bfe81 (diff) |
f2fs: release cp and dnode lock before IPU
We don't need to rewrite the page under cp_rwsem and dnode locks.
Signed-off-by: Hou Pengyang <houpengyang@huawei.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/data.c | 39 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 1 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 1 |
4 files changed, 27 insertions, 16 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 2f2de18d24fe..1254986dd6eb 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -1368,12 +1368,17 @@ int do_write_data_page(struct f2fs_io_info *fio) | |||
1368 | 1368 | ||
1369 | if (valid_ipu_blkaddr(fio)) { | 1369 | if (valid_ipu_blkaddr(fio)) { |
1370 | ipu_force = true; | 1370 | ipu_force = true; |
1371 | fio->need_lock = false; | ||
1371 | goto got_it; | 1372 | goto got_it; |
1372 | } | 1373 | } |
1373 | } | 1374 | } |
1375 | |||
1376 | if (fio->need_lock) | ||
1377 | f2fs_lock_op(fio->sbi); | ||
1378 | |||
1374 | err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE); | 1379 | err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE); |
1375 | if (err) | 1380 | if (err) |
1376 | return err; | 1381 | goto out; |
1377 | 1382 | ||
1378 | fio->old_blkaddr = dn.data_blkaddr; | 1383 | fio->old_blkaddr = dn.data_blkaddr; |
1379 | 1384 | ||
@@ -1394,22 +1399,26 @@ got_it: | |||
1394 | * it had better in-place writes for updated data. | 1399 | * it had better in-place writes for updated data. |
1395 | */ | 1400 | */ |
1396 | if (ipu_force || (valid_ipu_blkaddr(fio) && need_inplace_update(fio))) { | 1401 | if (ipu_force || (valid_ipu_blkaddr(fio) && need_inplace_update(fio))) { |
1397 | f2fs_bug_on(fio->sbi, !fio->cp_rwsem_locked); | 1402 | f2fs_put_dnode(&dn); |
1398 | f2fs_unlock_op(fio->sbi); | 1403 | if (fio->need_lock) |
1399 | fio->cp_rwsem_locked = false; | 1404 | f2fs_unlock_op(fio->sbi); |
1400 | |||
1401 | err = rewrite_data_page(fio); | 1405 | err = rewrite_data_page(fio); |
1402 | trace_f2fs_do_write_data_page(fio->page, IPU); | 1406 | trace_f2fs_do_write_data_page(fio->page, IPU); |
1403 | set_inode_flag(inode, FI_UPDATE_WRITE); | 1407 | set_inode_flag(inode, FI_UPDATE_WRITE); |
1404 | } else { | 1408 | return err; |
1405 | write_data_page(&dn, fio); | ||
1406 | trace_f2fs_do_write_data_page(page, OPU); | ||
1407 | set_inode_flag(inode, FI_APPEND_WRITE); | ||
1408 | if (page->index == 0) | ||
1409 | set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); | ||
1410 | } | 1409 | } |
1410 | |||
1411 | /* LFS mode write path */ | ||
1412 | write_data_page(&dn, fio); | ||
1413 | trace_f2fs_do_write_data_page(page, OPU); | ||
1414 | set_inode_flag(inode, FI_APPEND_WRITE); | ||
1415 | if (page->index == 0) | ||
1416 | set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); | ||
1411 | out_writepage: | 1417 | out_writepage: |
1412 | f2fs_put_dnode(&dn); | 1418 | f2fs_put_dnode(&dn); |
1419 | out: | ||
1420 | if (fio->need_lock) | ||
1421 | f2fs_unlock_op(fio->sbi); | ||
1413 | return err; | 1422 | return err; |
1414 | } | 1423 | } |
1415 | 1424 | ||
@@ -1434,7 +1443,7 @@ static int __write_data_page(struct page *page, bool *submitted, | |||
1434 | .page = page, | 1443 | .page = page, |
1435 | .encrypted_page = NULL, | 1444 | .encrypted_page = NULL, |
1436 | .submitted = false, | 1445 | .submitted = false, |
1437 | .cp_rwsem_locked = true, | 1446 | .need_lock = true, |
1438 | }; | 1447 | }; |
1439 | 1448 | ||
1440 | trace_f2fs_writepage(page, DATA); | 1449 | trace_f2fs_writepage(page, DATA); |
@@ -1470,6 +1479,7 @@ write: | |||
1470 | 1479 | ||
1471 | /* Dentry blocks are controlled by checkpoint */ | 1480 | /* Dentry blocks are controlled by checkpoint */ |
1472 | if (S_ISDIR(inode->i_mode)) { | 1481 | if (S_ISDIR(inode->i_mode)) { |
1482 | fio.need_lock = false; | ||
1473 | err = do_write_data_page(&fio); | 1483 | err = do_write_data_page(&fio); |
1474 | goto done; | 1484 | goto done; |
1475 | } | 1485 | } |
@@ -1487,13 +1497,12 @@ write: | |||
1487 | if (!err) | 1497 | if (!err) |
1488 | goto out; | 1498 | goto out; |
1489 | } | 1499 | } |
1490 | f2fs_lock_op(sbi); | 1500 | |
1491 | if (err == -EAGAIN) | 1501 | if (err == -EAGAIN) |
1492 | err = do_write_data_page(&fio); | 1502 | err = do_write_data_page(&fio); |
1493 | if (F2FS_I(inode)->last_disk_size < psize) | 1503 | if (F2FS_I(inode)->last_disk_size < psize) |
1494 | F2FS_I(inode)->last_disk_size = psize; | 1504 | F2FS_I(inode)->last_disk_size = psize; |
1495 | if (fio.cp_rwsem_locked) | 1505 | |
1496 | f2fs_unlock_op(sbi); | ||
1497 | done: | 1506 | done: |
1498 | if (err && err != -ENOENT) | 1507 | if (err && err != -ENOENT) |
1499 | goto redirty_out; | 1508 | goto redirty_out; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6f671c719570..713f072e5fbc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -803,7 +803,7 @@ struct f2fs_io_info { | |||
803 | struct page *page; /* page to be written */ | 803 | struct page *page; /* page to be written */ |
804 | struct page *encrypted_page; /* encrypted page */ | 804 | struct page *encrypted_page; /* encrypted page */ |
805 | bool submitted; /* indicate IO submission */ | 805 | bool submitted; /* indicate IO submission */ |
806 | bool cp_rwsem_locked; /* indicate cp_rwsem is held */ | 806 | bool need_lock; /* indicate we need to lock cp_rwsem */ |
807 | }; | 807 | }; |
808 | 808 | ||
809 | #define is_read_io(rw) ((rw) == READ) | 809 | #define is_read_io(rw) ((rw) == READ) |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index c2a9ae8397d3..026522107ca3 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -717,6 +717,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, | |||
717 | .old_blkaddr = NULL_ADDR, | 717 | .old_blkaddr = NULL_ADDR, |
718 | .page = page, | 718 | .page = page, |
719 | .encrypted_page = NULL, | 719 | .encrypted_page = NULL, |
720 | .need_lock = true, | ||
720 | }; | 721 | }; |
721 | bool is_dirty = PageDirty(page); | 722 | bool is_dirty = PageDirty(page); |
722 | int err; | 723 | int err; |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 656e1515ff56..e302f30ec7fe 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -312,6 +312,7 @@ static int __commit_inmem_pages(struct inode *inode, | |||
312 | fio.page = page; | 312 | fio.page = page; |
313 | fio.old_blkaddr = NULL_ADDR; | 313 | fio.old_blkaddr = NULL_ADDR; |
314 | fio.encrypted_page = NULL; | 314 | fio.encrypted_page = NULL; |
315 | fio.need_lock = false, | ||
315 | err = do_write_data_page(&fio); | 316 | err = do_write_data_page(&fio); |
316 | if (err) { | 317 | if (err) { |
317 | unlock_page(page); | 318 | unlock_page(page); |