diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-12-23 14:55:18 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-12-30 13:14:11 -0500 |
commit | 2aadac085cf0ca3e0295988d4d1dbdeafc15a9f6 (patch) | |
tree | e37aaaf635cec58b923b33b80cc2e4b968237b05 | |
parent | fba48a8b14f405afc5c80a93ed64a12607dd52c4 (diff) |
f2fs: introduce prepare_write_begin to clean up
This patch adds prepare_write_begin to clean f2fs_write_begin.
The major role of this function is to convert any inline_data and allocate
or find block address.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fs/f2fs/data.c | 92 |
1 files changed, 54 insertions, 38 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 958d8261b258..d4839fc2b4ca 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -1410,6 +1410,51 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) | |||
1410 | } | 1410 | } |
1411 | } | 1411 | } |
1412 | 1412 | ||
1413 | static int prepare_write_begin(struct f2fs_sb_info *sbi, | ||
1414 | struct page *page, loff_t pos, unsigned len, | ||
1415 | block_t *blk_addr, bool *node_changed) | ||
1416 | { | ||
1417 | struct inode *inode = page->mapping->host; | ||
1418 | pgoff_t index = page->index; | ||
1419 | struct dnode_of_data dn; | ||
1420 | struct page *ipage; | ||
1421 | int err = 0; | ||
1422 | |||
1423 | f2fs_lock_op(sbi); | ||
1424 | |||
1425 | /* check inline_data */ | ||
1426 | ipage = get_node_page(sbi, inode->i_ino); | ||
1427 | if (IS_ERR(ipage)) { | ||
1428 | err = PTR_ERR(ipage); | ||
1429 | goto unlock_out; | ||
1430 | } | ||
1431 | |||
1432 | set_new_dnode(&dn, inode, ipage, ipage, 0); | ||
1433 | |||
1434 | if (f2fs_has_inline_data(inode)) { | ||
1435 | if (pos + len <= MAX_INLINE_DATA) { | ||
1436 | read_inline_data(page, ipage); | ||
1437 | set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); | ||
1438 | sync_inode_page(&dn); | ||
1439 | goto done; | ||
1440 | } else { | ||
1441 | err = f2fs_convert_inline_page(&dn, page); | ||
1442 | if (err) | ||
1443 | goto err_out; | ||
1444 | } | ||
1445 | } | ||
1446 | err = f2fs_get_block(&dn, index); | ||
1447 | done: | ||
1448 | /* convert_inline_page can make node_changed */ | ||
1449 | *blk_addr = dn.data_blkaddr; | ||
1450 | *node_changed = dn.node_changed; | ||
1451 | err_out: | ||
1452 | f2fs_put_dnode(&dn); | ||
1453 | unlock_out: | ||
1454 | f2fs_unlock_op(sbi); | ||
1455 | return err; | ||
1456 | } | ||
1457 | |||
1413 | static int f2fs_write_begin(struct file *file, struct address_space *mapping, | 1458 | static int f2fs_write_begin(struct file *file, struct address_space *mapping, |
1414 | loff_t pos, unsigned len, unsigned flags, | 1459 | loff_t pos, unsigned len, unsigned flags, |
1415 | struct page **pagep, void **fsdata) | 1460 | struct page **pagep, void **fsdata) |
@@ -1417,9 +1462,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, | |||
1417 | struct inode *inode = mapping->host; | 1462 | struct inode *inode = mapping->host; |
1418 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 1463 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
1419 | struct page *page = NULL; | 1464 | struct page *page = NULL; |
1420 | struct page *ipage; | ||
1421 | pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; | 1465 | pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; |
1422 | struct dnode_of_data dn; | 1466 | bool need_balance = false; |
1467 | block_t blkaddr = NULL_ADDR; | ||
1423 | int err = 0; | 1468 | int err = 0; |
1424 | 1469 | ||
1425 | trace_f2fs_write_begin(inode, pos, len, flags); | 1470 | trace_f2fs_write_begin(inode, pos, len, flags); |
@@ -1443,37 +1488,12 @@ repeat: | |||
1443 | 1488 | ||
1444 | *pagep = page; | 1489 | *pagep = page; |
1445 | 1490 | ||
1446 | f2fs_lock_op(sbi); | 1491 | err = prepare_write_begin(sbi, page, pos, len, |
1447 | 1492 | &blkaddr, &need_balance); | |
1448 | /* check inline_data */ | ||
1449 | ipage = get_node_page(sbi, inode->i_ino); | ||
1450 | if (IS_ERR(ipage)) { | ||
1451 | err = PTR_ERR(ipage); | ||
1452 | goto unlock_fail; | ||
1453 | } | ||
1454 | |||
1455 | set_new_dnode(&dn, inode, ipage, ipage, 0); | ||
1456 | |||
1457 | if (f2fs_has_inline_data(inode)) { | ||
1458 | if (pos + len <= MAX_INLINE_DATA) { | ||
1459 | read_inline_data(page, ipage); | ||
1460 | set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); | ||
1461 | sync_inode_page(&dn); | ||
1462 | goto put_next; | ||
1463 | } | ||
1464 | err = f2fs_convert_inline_page(&dn, page); | ||
1465 | if (err) | ||
1466 | goto put_fail; | ||
1467 | } | ||
1468 | |||
1469 | err = f2fs_get_block(&dn, index); | ||
1470 | if (err) | 1493 | if (err) |
1471 | goto put_fail; | 1494 | goto fail; |
1472 | put_next: | ||
1473 | f2fs_put_dnode(&dn); | ||
1474 | f2fs_unlock_op(sbi); | ||
1475 | 1495 | ||
1476 | if (dn.node_changed && has_not_enough_free_secs(sbi, 0)) { | 1496 | if (need_balance && has_not_enough_free_secs(sbi, 0)) { |
1477 | unlock_page(page); | 1497 | unlock_page(page); |
1478 | f2fs_balance_fs(sbi); | 1498 | f2fs_balance_fs(sbi); |
1479 | lock_page(page); | 1499 | lock_page(page); |
@@ -1488,7 +1508,7 @@ put_next: | |||
1488 | 1508 | ||
1489 | /* wait for GCed encrypted page writeback */ | 1509 | /* wait for GCed encrypted page writeback */ |
1490 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) | 1510 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) |
1491 | f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); | 1511 | f2fs_wait_on_encrypted_page_writeback(sbi, blkaddr); |
1492 | 1512 | ||
1493 | if (len == PAGE_CACHE_SIZE) | 1513 | if (len == PAGE_CACHE_SIZE) |
1494 | goto out_update; | 1514 | goto out_update; |
@@ -1504,14 +1524,14 @@ put_next: | |||
1504 | goto out_update; | 1524 | goto out_update; |
1505 | } | 1525 | } |
1506 | 1526 | ||
1507 | if (dn.data_blkaddr == NEW_ADDR) { | 1527 | if (blkaddr == NEW_ADDR) { |
1508 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); | 1528 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); |
1509 | } else { | 1529 | } else { |
1510 | struct f2fs_io_info fio = { | 1530 | struct f2fs_io_info fio = { |
1511 | .sbi = sbi, | 1531 | .sbi = sbi, |
1512 | .type = DATA, | 1532 | .type = DATA, |
1513 | .rw = READ_SYNC, | 1533 | .rw = READ_SYNC, |
1514 | .blk_addr = dn.data_blkaddr, | 1534 | .blk_addr = blkaddr, |
1515 | .page = page, | 1535 | .page = page, |
1516 | .encrypted_page = NULL, | 1536 | .encrypted_page = NULL, |
1517 | }; | 1537 | }; |
@@ -1542,10 +1562,6 @@ out_clear: | |||
1542 | clear_cold_data(page); | 1562 | clear_cold_data(page); |
1543 | return 0; | 1563 | return 0; |
1544 | 1564 | ||
1545 | put_fail: | ||
1546 | f2fs_put_dnode(&dn); | ||
1547 | unlock_fail: | ||
1548 | f2fs_unlock_op(sbi); | ||
1549 | fail: | 1565 | fail: |
1550 | f2fs_put_page(page, 1); | 1566 | f2fs_put_page(page, 1); |
1551 | f2fs_write_failed(mapping, pos + len); | 1567 | f2fs_write_failed(mapping, pos + len); |