aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c110
1 files changed, 43 insertions, 67 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e6113c3a126f..bfe50a22363b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2006,57 +2006,6 @@ static void ext4_print_free_blocks(struct inode *inode)
2006} 2006}
2007 2007
2008/* 2008/*
2009 * This function is used by mpage_da_map_blocks(). We separate it out
2010 * as a separate function just to make life easier, and because
2011 * mpage_da_map_blocks() used to be a generic function that took a
2012 * get_block_t.
2013 */
2014static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
2015 struct buffer_head *bh_result)
2016{
2017 int ret;
2018 unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
2019 loff_t disksize = EXT4_I(inode)->i_disksize;
2020 handle_t *handle = NULL;
2021
2022 handle = ext4_journal_current_handle();
2023 BUG_ON(!handle);
2024 ret = ext4_get_blocks(handle, inode, iblock, max_blocks,
2025 bh_result, EXT4_GET_BLOCKS_CREATE|
2026 EXT4_GET_BLOCKS_DELALLOC_RESERVE);
2027 if (ret <= 0)
2028 return ret;
2029
2030 bh_result->b_size = (ret << inode->i_blkbits);
2031
2032 if (ext4_should_order_data(inode)) {
2033 int retval;
2034 retval = ext4_jbd2_file_inode(handle, inode);
2035 if (retval)
2036 /*
2037 * Failed to add inode for ordered mode. Don't
2038 * update file size
2039 */
2040 return retval;
2041 }
2042
2043 /*
2044 * Update on-disk size along with block allocation we don't
2045 * use EXT4_GET_BLOCKS_EXTEND_DISKSIZE as size may change
2046 * within already allocated block -bzzz
2047 */
2048 disksize = ((loff_t) iblock + ret) << inode->i_blkbits;
2049 if (disksize > i_size_read(inode))
2050 disksize = i_size_read(inode);
2051 if (disksize > EXT4_I(inode)->i_disksize) {
2052 ext4_update_i_disksize(inode, disksize);
2053 ret = ext4_mark_inode_dirty(handle, inode);
2054 return ret;
2055 }
2056 return 0;
2057}
2058
2059/*
2060 * mpage_da_map_blocks - go through given space 2009 * mpage_da_map_blocks - go through given space
2061 * 2010 *
2062 * @mpd - bh describing space 2011 * @mpd - bh describing space
@@ -2066,9 +2015,12 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
2066 */ 2015 */
2067static int mpage_da_map_blocks(struct mpage_da_data *mpd) 2016static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2068{ 2017{
2069 int err = 0; 2018 int err, blks;
2070 struct buffer_head new; 2019 struct buffer_head new;
2071 sector_t next; 2020 sector_t next = mpd->b_blocknr;
2021 unsigned max_blocks = mpd->b_size >> mpd->inode->i_blkbits;
2022 loff_t disksize = EXT4_I(mpd->inode)->i_disksize;
2023 handle_t *handle = NULL;
2072 2024
2073 /* 2025 /*
2074 * We consider only non-mapped and non-allocated blocks 2026 * We consider only non-mapped and non-allocated blocks
@@ -2077,6 +2029,16 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2077 !(mpd->b_state & (1 << BH_Delay)) && 2029 !(mpd->b_state & (1 << BH_Delay)) &&
2078 !(mpd->b_state & (1 << BH_Unwritten))) 2030 !(mpd->b_state & (1 << BH_Unwritten)))
2079 return 0; 2031 return 0;
2032
2033 /*
2034 * If we didn't accumulate anything to write simply return
2035 */
2036 if (!mpd->b_size)
2037 return 0;
2038
2039 handle = ext4_journal_current_handle();
2040 BUG_ON(!handle);
2041
2080 /* 2042 /*
2081 * We need to make sure the BH_Delay flag is passed down to 2043 * We need to make sure the BH_Delay flag is passed down to
2082 * ext4_da_get_block_write(), since it calls ext4_get_blocks() 2044 * ext4_da_get_block_write(), since it calls ext4_get_blocks()
@@ -2092,18 +2054,11 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2092 * EXT4_GET_BLOCKS_DELALLOC_RESERVE flag. 2054 * EXT4_GET_BLOCKS_DELALLOC_RESERVE flag.
2093 */ 2055 */
2094 new.b_state = mpd->b_state & (1 << BH_Delay); 2056 new.b_state = mpd->b_state & (1 << BH_Delay);
2095 new.b_blocknr = 0; 2057 blks = ext4_get_blocks(handle, mpd->inode, next, max_blocks,
2096 new.b_size = mpd->b_size; 2058 &new, EXT4_GET_BLOCKS_CREATE|
2097 next = mpd->b_blocknr; 2059 EXT4_GET_BLOCKS_DELALLOC_RESERVE);
2098 /* 2060 if (blks < 0) {
2099 * If we didn't accumulate anything 2061 err = blks;
2100 * to write simply return
2101 */
2102 if (!new.b_size)
2103 return 0;
2104
2105 err = ext4_da_get_block_write(mpd->inode, next, &new);
2106 if (err) {
2107 /* 2062 /*
2108 * If get block returns with error we simply 2063 * If get block returns with error we simply
2109 * return. Later writepage will redirty the page and 2064 * return. Later writepage will redirty the page and
@@ -2136,12 +2091,14 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2136 if (err == -ENOSPC) { 2091 if (err == -ENOSPC) {
2137 ext4_print_free_blocks(mpd->inode); 2092 ext4_print_free_blocks(mpd->inode);
2138 } 2093 }
2139 /* invlaidate all the pages */ 2094 /* invalidate all the pages */
2140 ext4_da_block_invalidatepages(mpd, next, 2095 ext4_da_block_invalidatepages(mpd, next,
2141 mpd->b_size >> mpd->inode->i_blkbits); 2096 mpd->b_size >> mpd->inode->i_blkbits);
2142 return err; 2097 return err;
2143 } 2098 }
2144 BUG_ON(new.b_size == 0); 2099 BUG_ON(blks == 0);
2100
2101 new.b_size = (blks << mpd->inode->i_blkbits);
2145 2102
2146 if (buffer_new(&new)) 2103 if (buffer_new(&new))
2147 __unmap_underlying_blocks(mpd->inode, &new); 2104 __unmap_underlying_blocks(mpd->inode, &new);
@@ -2154,6 +2111,25 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2154 (mpd->b_state & (1 << BH_Unwritten))) 2111 (mpd->b_state & (1 << BH_Unwritten)))
2155 mpage_put_bnr_to_bhs(mpd, next, &new); 2112 mpage_put_bnr_to_bhs(mpd, next, &new);
2156 2113
2114 if (ext4_should_order_data(mpd->inode)) {
2115 err = ext4_jbd2_file_inode(handle, mpd->inode);
2116 if (err)
2117 return err;
2118 }
2119
2120 /*
2121 * Update on-disk size along with block allocation we don't
2122 * use EXT4_GET_BLOCKS_EXTEND_DISKSIZE as size may change
2123 * within already allocated block -bzzz
2124 */
2125 disksize = ((loff_t) next + blks) << mpd->inode->i_blkbits;
2126 if (disksize > i_size_read(mpd->inode))
2127 disksize = i_size_read(mpd->inode);
2128 if (disksize > EXT4_I(mpd->inode)->i_disksize) {
2129 ext4_update_i_disksize(mpd->inode, disksize);
2130 return ext4_mark_inode_dirty(handle, mpd->inode);
2131 }
2132
2157 return 0; 2133 return 0;
2158} 2134}
2159 2135