diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-02-23 10:48:07 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-02-23 10:48:07 -0500 |
commit | ed5bde0bf8995d7d8c0b5a9c33e624a945f333ef (patch) | |
tree | 1e4ba09b0e10860c051ab4eb558b0e58f8037866 /fs/ext4 | |
parent | 722bde6875bfb49a0c84e5601eb82dd7ac02d27c (diff) |
ext4: Simplify delalloc implementation by removing mpd.get_block
This parameter was always set to ext4_da_get_block_write().
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/inode.c | 125 |
1 files changed, 58 insertions, 67 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cd0399db0ef1..924ba8afc227 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1705,7 +1705,6 @@ struct mpage_da_data { | |||
1705 | struct inode *inode; | 1705 | struct inode *inode; |
1706 | struct buffer_head lbh; /* extent of blocks */ | 1706 | struct buffer_head lbh; /* extent of blocks */ |
1707 | unsigned long first_page, next_page; /* extent of pages */ | 1707 | unsigned long first_page, next_page; /* extent of pages */ |
1708 | get_block_t *get_block; | ||
1709 | struct writeback_control *wbc; | 1708 | struct writeback_control *wbc; |
1710 | int io_done; | 1709 | int io_done; |
1711 | int pages_written; | 1710 | int pages_written; |
@@ -1719,7 +1718,6 @@ struct mpage_da_data { | |||
1719 | * @mpd->inode: inode | 1718 | * @mpd->inode: inode |
1720 | * @mpd->first_page: first page of the extent | 1719 | * @mpd->first_page: first page of the extent |
1721 | * @mpd->next_page: page after the last page of the extent | 1720 | * @mpd->next_page: page after the last page of the extent |
1722 | * @mpd->get_block: the filesystem's block mapper function | ||
1723 | * | 1721 | * |
1724 | * By the time mpage_da_submit_io() is called we expect all blocks | 1722 | * By the time mpage_da_submit_io() is called we expect all blocks |
1725 | * to be allocated. this may be wrong if allocation failed. | 1723 | * to be allocated. this may be wrong if allocation failed. |
@@ -1929,16 +1927,60 @@ static void ext4_print_free_blocks(struct inode *inode) | |||
1929 | return; | 1927 | return; |
1930 | } | 1928 | } |
1931 | 1929 | ||
1930 | #define EXT4_DELALLOC_RSVED 1 | ||
1931 | static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, | ||
1932 | struct buffer_head *bh_result, int create) | ||
1933 | { | ||
1934 | int ret; | ||
1935 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; | ||
1936 | loff_t disksize = EXT4_I(inode)->i_disksize; | ||
1937 | handle_t *handle = NULL; | ||
1938 | |||
1939 | handle = ext4_journal_current_handle(); | ||
1940 | BUG_ON(!handle); | ||
1941 | ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, | ||
1942 | bh_result, create, 0, EXT4_DELALLOC_RSVED); | ||
1943 | if (ret <= 0) | ||
1944 | return ret; | ||
1945 | |||
1946 | bh_result->b_size = (ret << inode->i_blkbits); | ||
1947 | |||
1948 | if (ext4_should_order_data(inode)) { | ||
1949 | int retval; | ||
1950 | retval = ext4_jbd2_file_inode(handle, inode); | ||
1951 | if (retval) | ||
1952 | /* | ||
1953 | * Failed to add inode for ordered mode. Don't | ||
1954 | * update file size | ||
1955 | */ | ||
1956 | return retval; | ||
1957 | } | ||
1958 | |||
1959 | /* | ||
1960 | * Update on-disk size along with block allocation we don't | ||
1961 | * use 'extend_disksize' as size may change within already | ||
1962 | * allocated block -bzzz | ||
1963 | */ | ||
1964 | disksize = ((loff_t) iblock + ret) << inode->i_blkbits; | ||
1965 | if (disksize > i_size_read(inode)) | ||
1966 | disksize = i_size_read(inode); | ||
1967 | if (disksize > EXT4_I(inode)->i_disksize) { | ||
1968 | ext4_update_i_disksize(inode, disksize); | ||
1969 | ret = ext4_mark_inode_dirty(handle, inode); | ||
1970 | return ret; | ||
1971 | } | ||
1972 | return 0; | ||
1973 | } | ||
1974 | |||
1932 | /* | 1975 | /* |
1933 | * mpage_da_map_blocks - go through given space | 1976 | * mpage_da_map_blocks - go through given space |
1934 | * | 1977 | * |
1935 | * @mpd->lbh - bh describing space | 1978 | * @mpd->lbh - bh describing space |
1936 | * @mpd->get_block - the filesystem's block mapper function | ||
1937 | * | 1979 | * |
1938 | * The function skips space we know is already mapped to disk blocks. | 1980 | * The function skips space we know is already mapped to disk blocks. |
1939 | * | 1981 | * |
1940 | */ | 1982 | */ |
1941 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) | 1983 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) |
1942 | { | 1984 | { |
1943 | int err = 0; | 1985 | int err = 0; |
1944 | struct buffer_head new; | 1986 | struct buffer_head new; |
@@ -1960,30 +2002,29 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) | |||
1960 | */ | 2002 | */ |
1961 | if (!new.b_size) | 2003 | if (!new.b_size) |
1962 | return 0; | 2004 | return 0; |
1963 | err = mpd->get_block(mpd->inode, next, &new, 1); | ||
1964 | if (err) { | ||
1965 | 2005 | ||
1966 | /* If get block returns with error | 2006 | err = ext4_da_get_block_write(mpd->inode, next, &new, 1); |
1967 | * we simply return. Later writepage | 2007 | if (err) { |
1968 | * will redirty the page and writepages | 2008 | /* |
1969 | * will find the dirty page again | 2009 | * If get block returns with error we simply |
2010 | * return. Later writepage will redirty the page and | ||
2011 | * writepages will find the dirty page again | ||
1970 | */ | 2012 | */ |
1971 | if (err == -EAGAIN) | 2013 | if (err == -EAGAIN) |
1972 | return 0; | 2014 | return 0; |
1973 | 2015 | ||
1974 | if (err == -ENOSPC && | 2016 | if (err == -ENOSPC && |
1975 | ext4_count_free_blocks(mpd->inode->i_sb)) { | 2017 | ext4_count_free_blocks(mpd->inode->i_sb)) { |
1976 | mpd->retval = err; | 2018 | mpd->retval = err; |
1977 | return 0; | 2019 | return 0; |
1978 | } | 2020 | } |
1979 | 2021 | ||
1980 | /* | 2022 | /* |
1981 | * get block failure will cause us | 2023 | * get block failure will cause us to loop in |
1982 | * to loop in writepages. Because | 2024 | * writepages, because a_ops->writepage won't be able |
1983 | * a_ops->writepage won't be able to | 2025 | * to make progress. The page will be redirtied by |
1984 | * make progress. The page will be redirtied | 2026 | * writepage and writepages will again try to write |
1985 | * by writepage and writepages will again | 2027 | * the same. |
1986 | * try to write the same. | ||
1987 | */ | 2028 | */ |
1988 | printk(KERN_EMERG "%s block allocation failed for inode %lu " | 2029 | printk(KERN_EMERG "%s block allocation failed for inode %lu " |
1989 | "at logical offset %llu with max blocks " | 2030 | "at logical offset %llu with max blocks " |
@@ -2212,7 +2253,6 @@ static int __mpage_da_writepage(struct page *page, | |||
2212 | * | 2253 | * |
2213 | * @mapping: address space structure to write | 2254 | * @mapping: address space structure to write |
2214 | * @wbc: subtract the number of written pages from *@wbc->nr_to_write | 2255 | * @wbc: subtract the number of written pages from *@wbc->nr_to_write |
2215 | * @get_block: the filesystem's block mapper function. | ||
2216 | * | 2256 | * |
2217 | * This is a library function, which implements the writepages() | 2257 | * This is a library function, which implements the writepages() |
2218 | * address_space_operation. | 2258 | * address_space_operation. |
@@ -2223,9 +2263,6 @@ static int mpage_da_writepages(struct address_space *mapping, | |||
2223 | { | 2263 | { |
2224 | int ret; | 2264 | int ret; |
2225 | 2265 | ||
2226 | if (!mpd->get_block) | ||
2227 | return generic_writepages(mapping, wbc); | ||
2228 | |||
2229 | mpd->lbh.b_size = 0; | 2266 | mpd->lbh.b_size = 0; |
2230 | mpd->lbh.b_state = 0; | 2267 | mpd->lbh.b_state = 0; |
2231 | mpd->lbh.b_blocknr = 0; | 2268 | mpd->lbh.b_blocknr = 0; |
@@ -2289,51 +2326,6 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, | |||
2289 | 2326 | ||
2290 | return ret; | 2327 | return ret; |
2291 | } | 2328 | } |
2292 | #define EXT4_DELALLOC_RSVED 1 | ||
2293 | static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, | ||
2294 | struct buffer_head *bh_result, int create) | ||
2295 | { | ||
2296 | int ret; | ||
2297 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; | ||
2298 | loff_t disksize = EXT4_I(inode)->i_disksize; | ||
2299 | handle_t *handle = NULL; | ||
2300 | |||
2301 | handle = ext4_journal_current_handle(); | ||
2302 | BUG_ON(!handle); | ||
2303 | ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, | ||
2304 | bh_result, create, 0, EXT4_DELALLOC_RSVED); | ||
2305 | if (ret > 0) { | ||
2306 | |||
2307 | bh_result->b_size = (ret << inode->i_blkbits); | ||
2308 | |||
2309 | if (ext4_should_order_data(inode)) { | ||
2310 | int retval; | ||
2311 | retval = ext4_jbd2_file_inode(handle, inode); | ||
2312 | if (retval) | ||
2313 | /* | ||
2314 | * Failed to add inode for ordered | ||
2315 | * mode. Don't update file size | ||
2316 | */ | ||
2317 | return retval; | ||
2318 | } | ||
2319 | |||
2320 | /* | ||
2321 | * Update on-disk size along with block allocation | ||
2322 | * we don't use 'extend_disksize' as size may change | ||
2323 | * within already allocated block -bzzz | ||
2324 | */ | ||
2325 | disksize = ((loff_t) iblock + ret) << inode->i_blkbits; | ||
2326 | if (disksize > i_size_read(inode)) | ||
2327 | disksize = i_size_read(inode); | ||
2328 | if (disksize > EXT4_I(inode)->i_disksize) { | ||
2329 | ext4_update_i_disksize(inode, disksize); | ||
2330 | ret = ext4_mark_inode_dirty(handle, inode); | ||
2331 | return ret; | ||
2332 | } | ||
2333 | ret = 0; | ||
2334 | } | ||
2335 | return ret; | ||
2336 | } | ||
2337 | 2329 | ||
2338 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) | 2330 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) |
2339 | { | 2331 | { |
@@ -2584,7 +2576,6 @@ retry: | |||
2584 | dump_stack(); | 2576 | dump_stack(); |
2585 | goto out_writepages; | 2577 | goto out_writepages; |
2586 | } | 2578 | } |
2587 | mpd.get_block = ext4_da_get_block_write; | ||
2588 | ret = mpage_da_writepages(mapping, wbc, &mpd); | 2579 | ret = mpage_da_writepages(mapping, wbc, &mpd); |
2589 | 2580 | ||
2590 | ext4_journal_stop(handle); | 2581 | ext4_journal_stop(handle); |