aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHou Pengyang <houpengyang@huawei.com>2017-04-26 12:17:21 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2017-05-03 13:04:54 -0400
commit279d6df20c94079d35e012f1602d40c42632e8f3 (patch)
tree2570480070d63ca08bf3f99cbdb0330e7622ee00
parent9a744b92da6eacea33dec1e9280fd324736bfe81 (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.c39
-rw-r--r--fs/f2fs/f2fs.h2
-rw-r--r--fs/f2fs/gc.c1
-rw-r--r--fs/f2fs/segment.c1
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);
1411out_writepage: 1417out_writepage:
1412 f2fs_put_dnode(&dn); 1418 f2fs_put_dnode(&dn);
1419out:
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);
1497done: 1506done:
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);