aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2016-01-26 02:37:38 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2016-02-22 19:07:23 -0500
commit4fe71e88bf681359fdbc99dc74920b38f018f89d (patch)
tree09d3ae4c5b9f0171e5a88314661945a94cf8a2ce
parent8f1dbbbbdfe9bada7e2f8041e07c6373f787c043 (diff)
f2fs: simplify f2fs_map_blocks
In f2fs_map_blocks, we use duplicated codes to handle first block mapping and the following blocks mapping, it's unnecessary. This patch simplifies f2fs_map_blocks to avoid using copied codes. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c101
1 files changed, 32 insertions, 69 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 90b3a3726d80..bd49a02dfa11 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -631,6 +631,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
631 goto out; 631 goto out;
632 } 632 }
633 633
634next_dnode:
634 if (create) 635 if (create)
635 f2fs_lock_op(sbi); 636 f2fs_lock_op(sbi);
636 637
@@ -643,47 +644,57 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
643 goto unlock_out; 644 goto unlock_out;
644 } 645 }
645 646
646 if (dn.data_blkaddr == NEW_ADDR || dn.data_blkaddr == NULL_ADDR) { 647 end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
648
649next_block:
650 blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
651
652 if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) {
647 if (create) { 653 if (create) {
648 if (unlikely(f2fs_cp_error(sbi))) { 654 if (unlikely(f2fs_cp_error(sbi))) {
649 err = -EIO; 655 err = -EIO;
650 goto put_out; 656 goto sync_out;
651 } 657 }
652 err = __allocate_data_block(&dn); 658 err = __allocate_data_block(&dn);
653 if (err) 659 if (err)
654 goto put_out; 660 goto sync_out;
655 allocated = true; 661 allocated = true;
656 map->m_flags = F2FS_MAP_NEW; 662 map->m_flags = F2FS_MAP_NEW;
663 blkaddr = dn.data_blkaddr;
657 } else { 664 } else {
658 if (flag != F2FS_GET_BLOCK_FIEMAP || 665 if (flag != F2FS_GET_BLOCK_FIEMAP ||
659 dn.data_blkaddr != NEW_ADDR) { 666 blkaddr != NEW_ADDR) {
660 if (flag == F2FS_GET_BLOCK_BMAP) 667 if (flag == F2FS_GET_BLOCK_BMAP)
661 err = -ENOENT; 668 err = -ENOENT;
662 goto put_out; 669 goto sync_out;
663 } 670 }
664
665 /*
666 * preallocated unwritten block should be mapped
667 * for fiemap.
668 */
669 if (dn.data_blkaddr == NEW_ADDR)
670 map->m_flags = F2FS_MAP_UNWRITTEN;
671 } 671 }
672 } 672 }
673 673
674 map->m_flags |= F2FS_MAP_MAPPED; 674 if (map->m_len == 0) {
675 map->m_pblk = dn.data_blkaddr; 675 /* preallocated unwritten block should be mapped for fiemap. */
676 map->m_len = 1; 676 if (blkaddr == NEW_ADDR)
677 map->m_flags |= F2FS_MAP_UNWRITTEN;
678 map->m_flags |= F2FS_MAP_MAPPED;
679
680 map->m_pblk = blkaddr;
681 map->m_len = 1;
682 } else if ((map->m_pblk != NEW_ADDR &&
683 blkaddr == (map->m_pblk + ofs)) ||
684 (map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR)) {
685 ofs++;
686 map->m_len++;
687 } else {
688 goto sync_out;
689 }
677 690
678 end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
679 dn.ofs_in_node++; 691 dn.ofs_in_node++;
680 pgofs++; 692 pgofs++;
681 693
682get_next: 694 if (map->m_len < maxblocks) {
683 if (map->m_len >= maxblocks) 695 if (dn.ofs_in_node < end_offset)
684 goto sync_out; 696 goto next_block;
685 697
686 if (dn.ofs_in_node >= end_offset) {
687 if (allocated) 698 if (allocated)
688 sync_inode_page(&dn); 699 sync_inode_page(&dn);
689 f2fs_put_dnode(&dn); 700 f2fs_put_dnode(&dn);
@@ -691,62 +702,14 @@ get_next:
691 if (create) { 702 if (create) {
692 f2fs_unlock_op(sbi); 703 f2fs_unlock_op(sbi);
693 f2fs_balance_fs(sbi, allocated); 704 f2fs_balance_fs(sbi, allocated);
694 f2fs_lock_op(sbi);
695 } 705 }
696 allocated = false; 706 allocated = false;
697 707 goto next_dnode;
698 set_new_dnode(&dn, inode, NULL, NULL, 0);
699 err = get_dnode_of_data(&dn, pgofs, mode);
700 if (err) {
701 if (err == -ENOENT)
702 err = 0;
703 goto unlock_out;
704 }
705
706 end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
707 }
708
709 blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
710
711 if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) {
712 if (create) {
713 if (unlikely(f2fs_cp_error(sbi))) {
714 err = -EIO;
715 goto sync_out;
716 }
717 err = __allocate_data_block(&dn);
718 if (err)
719 goto sync_out;
720 allocated = true;
721 map->m_flags |= F2FS_MAP_NEW;
722 blkaddr = dn.data_blkaddr;
723 } else {
724 /*
725 * we only merge preallocated unwritten blocks
726 * for fiemap.
727 */
728 if (flag != F2FS_GET_BLOCK_FIEMAP ||
729 blkaddr != NEW_ADDR)
730 goto sync_out;
731 }
732 }
733
734 /* Give more consecutive addresses for the readahead */
735 if ((map->m_pblk != NEW_ADDR &&
736 blkaddr == (map->m_pblk + ofs)) ||
737 (map->m_pblk == NEW_ADDR &&
738 blkaddr == NEW_ADDR)) {
739 ofs++;
740 dn.ofs_in_node++;
741 pgofs++;
742 map->m_len++;
743 goto get_next;
744 } 708 }
745 709
746sync_out: 710sync_out:
747 if (allocated) 711 if (allocated)
748 sync_inode_page(&dn); 712 sync_inode_page(&dn);
749put_out:
750 f2fs_put_dnode(&dn); 713 f2fs_put_dnode(&dn);
751unlock_out: 714unlock_out:
752 if (create) { 715 if (create) {