aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/extents.c20
-rw-r--r--fs/ext4/inode.c76
3 files changed, 69 insertions, 30 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index fc1c0375c9f2..5c31d6ac9500 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2602,6 +2602,9 @@ extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
2602 struct ext4_ext_path *); 2602 struct ext4_ext_path *);
2603extern void ext4_ext_drop_refs(struct ext4_ext_path *); 2603extern void ext4_ext_drop_refs(struct ext4_ext_path *);
2604extern int ext4_ext_check_inode(struct inode *inode); 2604extern int ext4_ext_check_inode(struct inode *inode);
2605extern int ext4_find_delalloc_range(struct inode *inode,
2606 ext4_lblk_t lblk_start,
2607 ext4_lblk_t lblk_end);
2605extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk); 2608extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk);
2606extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 2609extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2607 __u64 start, __u64 len); 2610 __u64 start, __u64 len);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index cae8ae3c1746..be0b1b3eed97 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2076,8 +2076,18 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
2076 break; 2076 break;
2077 } 2077 }
2078 2078
2079 /* This is possible iff next == next_del == EXT_MAX_BLOCKS */ 2079 /*
2080 if (next == next_del) { 2080 * This is possible iff next == next_del == EXT_MAX_BLOCKS.
2081 * we need to check next == EXT_MAX_BLOCKS because it is
2082 * possible that an extent is with unwritten and delayed
2083 * status due to when an extent is delayed allocated and
2084 * is allocated by fallocate status tree will track both of
2085 * them in a extent.
2086 *
2087 * So we could return a unwritten and delayed extent, and
2088 * its block is equal to 'next'.
2089 */
2090 if (next == next_del && next == EXT_MAX_BLOCKS) {
2081 flags |= FIEMAP_EXTENT_LAST; 2091 flags |= FIEMAP_EXTENT_LAST;
2082 if (unlikely(next_del != EXT_MAX_BLOCKS || 2092 if (unlikely(next_del != EXT_MAX_BLOCKS ||
2083 next != EXT_MAX_BLOCKS)) { 2093 next != EXT_MAX_BLOCKS)) {
@@ -3522,9 +3532,9 @@ out:
3522 * 3532 *
3523 * Return 1 if there is a delalloc block in the range, otherwise 0. 3533 * Return 1 if there is a delalloc block in the range, otherwise 0.
3524 */ 3534 */
3525static int ext4_find_delalloc_range(struct inode *inode, 3535int ext4_find_delalloc_range(struct inode *inode,
3526 ext4_lblk_t lblk_start, 3536 ext4_lblk_t lblk_start,
3527 ext4_lblk_t lblk_end) 3537 ext4_lblk_t lblk_end)
3528{ 3538{
3529 struct extent_status es; 3539 struct extent_status es;
3530 3540
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 084b8212cf95..576b586b61aa 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -526,20 +526,26 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
526 retval = ext4_ind_map_blocks(handle, inode, map, flags & 526 retval = ext4_ind_map_blocks(handle, inode, map, flags &
527 EXT4_GET_BLOCKS_KEEP_SIZE); 527 EXT4_GET_BLOCKS_KEEP_SIZE);
528 } 528 }
529 if (retval > 0) {
530 int ret;
531 unsigned long long status;
532
533 status = map->m_flags & EXT4_MAP_UNWRITTEN ?
534 EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
535 if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
536 ext4_find_delalloc_range(inode, map->m_lblk,
537 map->m_lblk + map->m_len - 1))
538 status |= EXTENT_STATUS_DELAYED;
539 ret = ext4_es_insert_extent(inode, map->m_lblk,
540 map->m_len, map->m_pblk, status);
541 if (ret < 0)
542 retval = ret;
543 }
529 if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) 544 if (!(flags & EXT4_GET_BLOCKS_NO_LOCK))
530 up_read((&EXT4_I(inode)->i_data_sem)); 545 up_read((&EXT4_I(inode)->i_data_sem));
531 546
532 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { 547 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
533 int ret; 548 int ret = check_block_validity(inode, map);
534 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) {
535 /* delayed alloc may be allocated by fallocate and
536 * coverted to initialized by directIO.
537 * we need to handle delayed extent here.
538 */
539 down_write((&EXT4_I(inode)->i_data_sem));
540 goto delayed_mapped;
541 }
542 ret = check_block_validity(inode, map);
543 if (ret != 0) 549 if (ret != 0)
544 return ret; 550 return ret;
545 } 551 }
@@ -608,18 +614,23 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
608 (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)) 614 (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE))
609 ext4_da_update_reserve_space(inode, retval, 1); 615 ext4_da_update_reserve_space(inode, retval, 1);
610 } 616 }
611 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) { 617 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
612 ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED); 618 ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED);
613 619
614 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { 620 if (retval > 0) {
615 int ret; 621 int ret;
616delayed_mapped: 622 unsigned long long status;
617 /* delayed allocation blocks has been allocated */ 623
618 ret = ext4_es_remove_extent(inode, map->m_lblk, 624 status = map->m_flags & EXT4_MAP_UNWRITTEN ?
619 map->m_len); 625 EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
620 if (ret < 0) 626 if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
621 retval = ret; 627 ext4_find_delalloc_range(inode, map->m_lblk,
622 } 628 map->m_lblk + map->m_len - 1))
629 status |= EXTENT_STATUS_DELAYED;
630 ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
631 map->m_pblk, status);
632 if (ret < 0)
633 retval = ret;
623 } 634 }
624 635
625 up_write((&EXT4_I(inode)->i_data_sem)); 636 up_write((&EXT4_I(inode)->i_data_sem));
@@ -1765,6 +1776,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
1765 retval = ext4_ind_map_blocks(NULL, inode, map, 0); 1776 retval = ext4_ind_map_blocks(NULL, inode, map, 0);
1766 1777
1767 if (retval == 0) { 1778 if (retval == 0) {
1779 int ret;
1768 /* 1780 /*
1769 * XXX: __block_prepare_write() unmaps passed block, 1781 * XXX: __block_prepare_write() unmaps passed block,
1770 * is it OK? 1782 * is it OK?
@@ -1772,16 +1784,20 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
1772 /* If the block was allocated from previously allocated cluster, 1784 /* If the block was allocated from previously allocated cluster,
1773 * then we dont need to reserve it again. */ 1785 * then we dont need to reserve it again. */
1774 if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) { 1786 if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) {
1775 retval = ext4_da_reserve_space(inode, iblock); 1787 ret = ext4_da_reserve_space(inode, iblock);
1776 if (retval) 1788 if (ret) {
1777 /* not enough space to reserve */ 1789 /* not enough space to reserve */
1790 retval = ret;
1778 goto out_unlock; 1791 goto out_unlock;
1792 }
1779 } 1793 }
1780 1794
1781 retval = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, 1795 ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
1782 ~0, EXTENT_STATUS_DELAYED); 1796 ~0, EXTENT_STATUS_DELAYED);
1783 if (retval) 1797 if (ret) {
1798 retval = ret;
1784 goto out_unlock; 1799 goto out_unlock;
1800 }
1785 1801
1786 /* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served 1802 /* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served
1787 * and it should not appear on the bh->b_state. 1803 * and it should not appear on the bh->b_state.
@@ -1791,6 +1807,16 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
1791 map_bh(bh, inode->i_sb, invalid_block); 1807 map_bh(bh, inode->i_sb, invalid_block);
1792 set_buffer_new(bh); 1808 set_buffer_new(bh);
1793 set_buffer_delay(bh); 1809 set_buffer_delay(bh);
1810 } else if (retval > 0) {
1811 int ret;
1812 unsigned long long status;
1813
1814 status = map->m_flags & EXT4_MAP_UNWRITTEN ?
1815 EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
1816 ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
1817 map->m_pblk, status);
1818 if (ret != 0)
1819 retval = ret;
1794 } 1820 }
1795 1821
1796out_unlock: 1822out_unlock: