aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-05-14 13:57:08 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-05-14 13:57:08 -0400
commit2ac3b6e00acb46406c993d57921f86a594aafe08 (patch)
tree51f8a245caa53776fb9617973742ffc81023e007
parent2fa3cdfb319055fd8b25abdafa413e16f00ad493 (diff)
ext4: Clean up ext4_get_blocks() so it does not depend on bh_result->b_state
The ext4_get_blocks() function was depending on the value of bh_result->b_state as an input parameter to decide whether or not update the delalloc accounting statistics by calling ext4_da_update_reserve_space(). We now use a separate flag, EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE, to requests this update, so that all callers of ext4_get_blocks() can clear map_bh.b_state before calling ext4_get_blocks() without worrying about any consistency issues. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/ext4.h15
-rw-r--r--fs/ext4/inode.c56
2 files changed, 41 insertions, 30 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 17feb4ac633a..d164f1294e5f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -318,16 +318,21 @@ struct ext4_new_group_data {
318 */ 318 */
319 /* Allocate any needed blocks and/or convert an unitialized 319 /* Allocate any needed blocks and/or convert an unitialized
320 extent to be an initialized ext4 */ 320 extent to be an initialized ext4 */
321#define EXT4_GET_BLOCKS_CREATE 1 321#define EXT4_GET_BLOCKS_CREATE 0x0001
322 /* Request the creation of an unitialized extent */ 322 /* Request the creation of an unitialized extent */
323#define EXT4_GET_BLOCKS_UNINIT_EXT 2 323#define EXT4_GET_BLOCKS_UNINIT_EXT 0x0002
324#define EXT4_GET_BLOCKS_CREATE_UNINIT_EXT (EXT4_GET_BLOCKS_UNINIT_EXT|\ 324#define EXT4_GET_BLOCKS_CREATE_UNINIT_EXT (EXT4_GET_BLOCKS_UNINIT_EXT|\
325 EXT4_GET_BLOCKS_CREATE) 325 EXT4_GET_BLOCKS_CREATE)
326 /* Update the ext4_inode_info i_disksize field */ 326 /* Update the ext4_inode_info i_disksize field */
327#define EXT4_GET_BLOCKS_EXTEND_DISKSIZE 4 327#define EXT4_GET_BLOCKS_EXTEND_DISKSIZE 0x0004
328 /* Caller is from the delayed allocation writeout path, 328 /* Caller is from the delayed allocation writeout path,
329 so the filesystem blocks have already been accounted for */ 329 so set the magic i_delalloc_reserve_flag after taking the
330#define EXT4_GET_BLOCKS_DELALLOC_RESERVE 8 330 inode allocation semaphore for */
331#define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0008
332 /* Call ext4_da_update_reserve_space() after successfully
333 allocating the blocks */
334#define EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE 0x0010
335
331 336
332/* 337/*
333 * ioctl commands 338 * ioctl commands
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index bfe50a22363b..d7b7480682b9 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1234,16 +1234,15 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1234 } 1234 }
1235 } 1235 }
1236 1236
1237 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) { 1237 if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
1238 EXT4_I(inode)->i_delalloc_reserved_flag = 0; 1238 EXT4_I(inode)->i_delalloc_reserved_flag = 0;
1239 /* 1239
1240 * Update reserved blocks/metadata blocks 1240 /*
1241 * after successful block allocation 1241 * Update reserved blocks/metadata blocks after successful
1242 * which were deferred till now 1242 * block allocation which had been deferred till now.
1243 */ 1243 */
1244 if ((retval > 0) && buffer_delay(bh)) 1244 if ((retval > 0) && (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE))
1245 ext4_da_update_reserve_space(inode, retval); 1245 ext4_da_update_reserve_space(inode, retval);
1246 }
1247 1246
1248 up_write((&EXT4_I(inode)->i_data_sem)); 1247 up_write((&EXT4_I(inode)->i_data_sem));
1249 return retval; 1248 return retval;
@@ -2015,7 +2014,7 @@ static void ext4_print_free_blocks(struct inode *inode)
2015 */ 2014 */
2016static int mpage_da_map_blocks(struct mpage_da_data *mpd) 2015static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2017{ 2016{
2018 int err, blks; 2017 int err, blks, get_blocks_flags;
2019 struct buffer_head new; 2018 struct buffer_head new;
2020 sector_t next = mpd->b_blocknr; 2019 sector_t next = mpd->b_blocknr;
2021 unsigned max_blocks = mpd->b_size >> mpd->inode->i_blkbits; 2020 unsigned max_blocks = mpd->b_size >> mpd->inode->i_blkbits;
@@ -2040,23 +2039,30 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2040 BUG_ON(!handle); 2039 BUG_ON(!handle);
2041 2040
2042 /* 2041 /*
2043 * We need to make sure the BH_Delay flag is passed down to 2042 * Call ext4_get_blocks() to allocate any delayed allocation
2044 * ext4_da_get_block_write(), since it calls ext4_get_blocks() 2043 * blocks, or to convert an uninitialized extent to be
2045 * with the EXT4_GET_BLOCKS_DELALLOC_RESERVE flag. This flag 2044 * initialized (in the case where we have written into
2046 * causes ext4_get_blocks() to call 2045 * one or more preallocated blocks).
2047 * ext4_da_update_reserve_space() if the passed buffer head 2046 *
2048 * has the BH_Delay flag set. In the future, once we clean up 2047 * We pass in the magic EXT4_GET_BLOCKS_DELALLOC_RESERVE to
2049 * the interfaces to ext4_get_blocks(), we should pass in a 2048 * indicate that we are on the delayed allocation path. This
2050 * separate flag which requests that the delayed allocation 2049 * affects functions in many different parts of the allocation
2051 * statistics should be updated, instead of depending on the 2050 * call path. This flag exists primarily because we don't
2052 * state information getting passed down via the map_bh's 2051 * want to change *many* call functions, so ext4_get_blocks()
2053 * state bitmasks plus the magic 2052 * will set the magic i_delalloc_reserved_flag once the
2054 * EXT4_GET_BLOCKS_DELALLOC_RESERVE flag. 2053 * inode's allocation semaphore is taken.
2054 *
2055 * If the blocks in questions were delalloc blocks, set
2056 * EXT4_GET_BLOCKS_DELALLOC_RESERVE so the delalloc accounting
2057 * variables are updated after the blocks have been allocated.
2055 */ 2058 */
2056 new.b_state = mpd->b_state & (1 << BH_Delay); 2059 new.b_state = 0;
2060 get_blocks_flags = (EXT4_GET_BLOCKS_CREATE |
2061 EXT4_GET_BLOCKS_DELALLOC_RESERVE);
2062 if (mpd->b_state & (1 << BH_Delay))
2063 get_blocks_flags |= EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE;
2057 blks = ext4_get_blocks(handle, mpd->inode, next, max_blocks, 2064 blks = ext4_get_blocks(handle, mpd->inode, next, max_blocks,
2058 &new, EXT4_GET_BLOCKS_CREATE| 2065 &new, get_blocks_flags);
2059 EXT4_GET_BLOCKS_DELALLOC_RESERVE);
2060 if (blks < 0) { 2066 if (blks < 0) {
2061 err = blks; 2067 err = blks;
2062 /* 2068 /*