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>
This commit is contained in:
parent
722bde6875
commit
ed5bde0bf8
125
fs/ext4/inode.c
125
fs/ext4/inode.c
@ -1705,7 +1705,6 @@ struct mpage_da_data {
|
|||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct buffer_head lbh; /* extent of blocks */
|
struct buffer_head lbh; /* extent of blocks */
|
||||||
unsigned long first_page, next_page; /* extent of pages */
|
unsigned long first_page, next_page; /* extent of pages */
|
||||||
get_block_t *get_block;
|
|
||||||
struct writeback_control *wbc;
|
struct writeback_control *wbc;
|
||||||
int io_done;
|
int io_done;
|
||||||
int pages_written;
|
int pages_written;
|
||||||
@ -1719,7 +1718,6 @@ struct mpage_da_data {
|
|||||||
* @mpd->inode: inode
|
* @mpd->inode: inode
|
||||||
* @mpd->first_page: first page of the extent
|
* @mpd->first_page: first page of the extent
|
||||||
* @mpd->next_page: page after the last page of the extent
|
* @mpd->next_page: page after the last page of the extent
|
||||||
* @mpd->get_block: the filesystem's block mapper function
|
|
||||||
*
|
*
|
||||||
* By the time mpage_da_submit_io() is called we expect all blocks
|
* By the time mpage_da_submit_io() is called we expect all blocks
|
||||||
* to be allocated. this may be wrong if allocation failed.
|
* to be allocated. this may be wrong if allocation failed.
|
||||||
@ -1929,16 +1927,60 @@ static void ext4_print_free_blocks(struct inode *inode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXT4_DELALLOC_RSVED 1
|
||||||
|
static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
|
||||||
|
struct buffer_head *bh_result, int create)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
|
||||||
|
loff_t disksize = EXT4_I(inode)->i_disksize;
|
||||||
|
handle_t *handle = NULL;
|
||||||
|
|
||||||
|
handle = ext4_journal_current_handle();
|
||||||
|
BUG_ON(!handle);
|
||||||
|
ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks,
|
||||||
|
bh_result, create, 0, EXT4_DELALLOC_RSVED);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bh_result->b_size = (ret << inode->i_blkbits);
|
||||||
|
|
||||||
|
if (ext4_should_order_data(inode)) {
|
||||||
|
int retval;
|
||||||
|
retval = ext4_jbd2_file_inode(handle, inode);
|
||||||
|
if (retval)
|
||||||
|
/*
|
||||||
|
* Failed to add inode for ordered mode. Don't
|
||||||
|
* update file size
|
||||||
|
*/
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update on-disk size along with block allocation we don't
|
||||||
|
* use 'extend_disksize' as size may change within already
|
||||||
|
* allocated block -bzzz
|
||||||
|
*/
|
||||||
|
disksize = ((loff_t) iblock + ret) << inode->i_blkbits;
|
||||||
|
if (disksize > i_size_read(inode))
|
||||||
|
disksize = i_size_read(inode);
|
||||||
|
if (disksize > EXT4_I(inode)->i_disksize) {
|
||||||
|
ext4_update_i_disksize(inode, disksize);
|
||||||
|
ret = ext4_mark_inode_dirty(handle, inode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mpage_da_map_blocks - go through given space
|
* mpage_da_map_blocks - go through given space
|
||||||
*
|
*
|
||||||
* @mpd->lbh - bh describing space
|
* @mpd->lbh - bh describing space
|
||||||
* @mpd->get_block - the filesystem's block mapper function
|
|
||||||
*
|
*
|
||||||
* The function skips space we know is already mapped to disk blocks.
|
* The function skips space we know is already mapped to disk blocks.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int mpage_da_map_blocks(struct mpage_da_data *mpd)
|
static int mpage_da_map_blocks(struct mpage_da_data *mpd)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct buffer_head new;
|
struct buffer_head new;
|
||||||
@ -1960,30 +2002,29 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
|
|||||||
*/
|
*/
|
||||||
if (!new.b_size)
|
if (!new.b_size)
|
||||||
return 0;
|
return 0;
|
||||||
err = mpd->get_block(mpd->inode, next, &new, 1);
|
|
||||||
if (err) {
|
|
||||||
|
|
||||||
/* If get block returns with error
|
err = ext4_da_get_block_write(mpd->inode, next, &new, 1);
|
||||||
* we simply return. Later writepage
|
if (err) {
|
||||||
* will redirty the page and writepages
|
/*
|
||||||
* will find the dirty page again
|
* If get block returns with error we simply
|
||||||
|
* return. Later writepage will redirty the page and
|
||||||
|
* writepages will find the dirty page again
|
||||||
*/
|
*/
|
||||||
if (err == -EAGAIN)
|
if (err == -EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (err == -ENOSPC &&
|
if (err == -ENOSPC &&
|
||||||
ext4_count_free_blocks(mpd->inode->i_sb)) {
|
ext4_count_free_blocks(mpd->inode->i_sb)) {
|
||||||
mpd->retval = err;
|
mpd->retval = err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get block failure will cause us
|
* get block failure will cause us to loop in
|
||||||
* to loop in writepages. Because
|
* writepages, because a_ops->writepage won't be able
|
||||||
* a_ops->writepage won't be able to
|
* to make progress. The page will be redirtied by
|
||||||
* make progress. The page will be redirtied
|
* writepage and writepages will again try to write
|
||||||
* by writepage and writepages will again
|
* the same.
|
||||||
* try to write the same.
|
|
||||||
*/
|
*/
|
||||||
printk(KERN_EMERG "%s block allocation failed for inode %lu "
|
printk(KERN_EMERG "%s block allocation failed for inode %lu "
|
||||||
"at logical offset %llu with max blocks "
|
"at logical offset %llu with max blocks "
|
||||||
@ -2212,7 +2253,6 @@ static int __mpage_da_writepage(struct page *page,
|
|||||||
*
|
*
|
||||||
* @mapping: address space structure to write
|
* @mapping: address space structure to write
|
||||||
* @wbc: subtract the number of written pages from *@wbc->nr_to_write
|
* @wbc: subtract the number of written pages from *@wbc->nr_to_write
|
||||||
* @get_block: the filesystem's block mapper function.
|
|
||||||
*
|
*
|
||||||
* This is a library function, which implements the writepages()
|
* This is a library function, which implements the writepages()
|
||||||
* address_space_operation.
|
* address_space_operation.
|
||||||
@ -2223,9 +2263,6 @@ static int mpage_da_writepages(struct address_space *mapping,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!mpd->get_block)
|
|
||||||
return generic_writepages(mapping, wbc);
|
|
||||||
|
|
||||||
mpd->lbh.b_size = 0;
|
mpd->lbh.b_size = 0;
|
||||||
mpd->lbh.b_state = 0;
|
mpd->lbh.b_state = 0;
|
||||||
mpd->lbh.b_blocknr = 0;
|
mpd->lbh.b_blocknr = 0;
|
||||||
@ -2289,51 +2326,6 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#define EXT4_DELALLOC_RSVED 1
|
|
||||||
static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
|
|
||||||
struct buffer_head *bh_result, int create)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
|
|
||||||
loff_t disksize = EXT4_I(inode)->i_disksize;
|
|
||||||
handle_t *handle = NULL;
|
|
||||||
|
|
||||||
handle = ext4_journal_current_handle();
|
|
||||||
BUG_ON(!handle);
|
|
||||||
ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks,
|
|
||||||
bh_result, create, 0, EXT4_DELALLOC_RSVED);
|
|
||||||
if (ret > 0) {
|
|
||||||
|
|
||||||
bh_result->b_size = (ret << inode->i_blkbits);
|
|
||||||
|
|
||||||
if (ext4_should_order_data(inode)) {
|
|
||||||
int retval;
|
|
||||||
retval = ext4_jbd2_file_inode(handle, inode);
|
|
||||||
if (retval)
|
|
||||||
/*
|
|
||||||
* Failed to add inode for ordered
|
|
||||||
* mode. Don't update file size
|
|
||||||
*/
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update on-disk size along with block allocation
|
|
||||||
* we don't use 'extend_disksize' as size may change
|
|
||||||
* within already allocated block -bzzz
|
|
||||||
*/
|
|
||||||
disksize = ((loff_t) iblock + ret) << inode->i_blkbits;
|
|
||||||
if (disksize > i_size_read(inode))
|
|
||||||
disksize = i_size_read(inode);
|
|
||||||
if (disksize > EXT4_I(inode)->i_disksize) {
|
|
||||||
ext4_update_i_disksize(inode, disksize);
|
|
||||||
ret = ext4_mark_inode_dirty(handle, inode);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
|
static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
|
||||||
{
|
{
|
||||||
@ -2584,7 +2576,6 @@ static int ext4_da_writepages(struct address_space *mapping,
|
|||||||
dump_stack();
|
dump_stack();
|
||||||
goto out_writepages;
|
goto out_writepages;
|
||||||
}
|
}
|
||||||
mpd.get_block = ext4_da_get_block_write;
|
|
||||||
ret = mpage_da_writepages(mapping, wbc, &mpd);
|
ret = mpage_da_writepages(mapping, wbc, &mpd);
|
||||||
|
|
||||||
ext4_journal_stop(handle);
|
ext4_journal_stop(handle);
|
||||||
|
Loading…
Reference in New Issue
Block a user