diff options
-rw-r--r-- | fs/f2fs/data.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 292a06cbea07..e34b1bdfc995 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -573,6 +573,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, | |||
573 | int err = 0, ofs = 1; | 573 | int err = 0, ofs = 1; |
574 | struct extent_info ei; | 574 | struct extent_info ei; |
575 | bool allocated = false; | 575 | bool allocated = false; |
576 | block_t blkaddr; | ||
576 | 577 | ||
577 | map->m_len = 0; | 578 | map->m_len = 0; |
578 | map->m_flags = 0; | 579 | map->m_flags = 0; |
@@ -636,6 +637,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, | |||
636 | pgofs++; | 637 | pgofs++; |
637 | 638 | ||
638 | get_next: | 639 | get_next: |
640 | if (map->m_len >= maxblocks) | ||
641 | goto sync_out; | ||
642 | |||
639 | if (dn.ofs_in_node >= end_offset) { | 643 | if (dn.ofs_in_node >= end_offset) { |
640 | if (allocated) | 644 | if (allocated) |
641 | sync_inode_page(&dn); | 645 | sync_inode_page(&dn); |
@@ -653,44 +657,43 @@ get_next: | |||
653 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); | 657 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); |
654 | } | 658 | } |
655 | 659 | ||
656 | if (maxblocks > map->m_len) { | 660 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
657 | block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); | ||
658 | 661 | ||
659 | if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { | 662 | if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { |
660 | if (create) { | 663 | if (create) { |
661 | if (unlikely(f2fs_cp_error(sbi))) { | 664 | if (unlikely(f2fs_cp_error(sbi))) { |
662 | err = -EIO; | 665 | err = -EIO; |
663 | goto sync_out; | 666 | goto sync_out; |
664 | } | ||
665 | err = __allocate_data_block(&dn); | ||
666 | if (err) | ||
667 | goto sync_out; | ||
668 | allocated = true; | ||
669 | map->m_flags |= F2FS_MAP_NEW; | ||
670 | blkaddr = dn.data_blkaddr; | ||
671 | } else { | ||
672 | /* | ||
673 | * we only merge preallocated unwritten blocks | ||
674 | * for fiemap. | ||
675 | */ | ||
676 | if (flag != F2FS_GET_BLOCK_FIEMAP || | ||
677 | blkaddr != NEW_ADDR) | ||
678 | goto sync_out; | ||
679 | } | 667 | } |
668 | err = __allocate_data_block(&dn); | ||
669 | if (err) | ||
670 | goto sync_out; | ||
671 | allocated = true; | ||
672 | map->m_flags |= F2FS_MAP_NEW; | ||
673 | blkaddr = dn.data_blkaddr; | ||
674 | } else { | ||
675 | /* | ||
676 | * we only merge preallocated unwritten blocks | ||
677 | * for fiemap. | ||
678 | */ | ||
679 | if (flag != F2FS_GET_BLOCK_FIEMAP || | ||
680 | blkaddr != NEW_ADDR) | ||
681 | goto sync_out; | ||
680 | } | 682 | } |
683 | } | ||
681 | 684 | ||
682 | /* Give more consecutive addresses for the readahead */ | 685 | /* Give more consecutive addresses for the readahead */ |
683 | if ((map->m_pblk != NEW_ADDR && | 686 | if ((map->m_pblk != NEW_ADDR && |
684 | blkaddr == (map->m_pblk + ofs)) || | 687 | blkaddr == (map->m_pblk + ofs)) || |
685 | (map->m_pblk == NEW_ADDR && | 688 | (map->m_pblk == NEW_ADDR && |
686 | blkaddr == NEW_ADDR)) { | 689 | blkaddr == NEW_ADDR)) { |
687 | ofs++; | 690 | ofs++; |
688 | dn.ofs_in_node++; | 691 | dn.ofs_in_node++; |
689 | pgofs++; | 692 | pgofs++; |
690 | map->m_len++; | 693 | map->m_len++; |
691 | goto get_next; | 694 | goto get_next; |
692 | } | ||
693 | } | 695 | } |
696 | |||
694 | sync_out: | 697 | sync_out: |
695 | if (allocated) | 698 | if (allocated) |
696 | sync_inode_page(&dn); | 699 | sync_inode_page(&dn); |