Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed5bde0b authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4: Simplify delalloc implementation by removing mpd.get_block



This parameter was always set to ext4_da_get_block_write().

Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 722bde68
Loading
Loading
Loading
Loading
+58 −67
Original line number Diff line number Diff line
@@ -1705,7 +1705,6 @@ struct mpage_da_data {
	struct inode *inode;
	struct buffer_head lbh;			/* extent of blocks */
	unsigned long first_page, next_page;	/* extent of pages */
	get_block_t *get_block;
	struct writeback_control *wbc;
	int io_done;
	int pages_written;
@@ -1719,7 +1718,6 @@ struct mpage_da_data {
 * @mpd->inode: inode
 * @mpd->first_page: first 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
 * to be allocated. this may be wrong if allocation failed.
@@ -1929,11 +1927,55 @@ static void ext4_print_free_blocks(struct inode *inode)
	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
 *
 * @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.
 *
@@ -1960,13 +2002,13 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
	 */
	if (!new.b_size)
		return 0;
	err = mpd->get_block(mpd->inode, next, &new, 1);
	if (err) {

		/* If get block returns with error
		 * we simply return. Later writepage
		 * will redirty the page and writepages
		 * will find the dirty page again
	err = ext4_da_get_block_write(mpd->inode, next, &new, 1);
	if (err) {
		/*
		 * 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)
			return 0;
@@ -1978,12 +2020,11 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
		}

		/*
		 * get block failure will cause us
		 * to loop in writepages. Because
		 * a_ops->writepage won't be able to
		 * make progress. The page will be redirtied
		 * by writepage and writepages will again
		 * try to write the same.
		 * get block failure will cause us to loop in
		 * writepages, because a_ops->writepage won't be able
		 * to make progress. The page will be redirtied by
		 * writepage and writepages will again try to write
		 * the same.
		 */
		printk(KERN_EMERG "%s block allocation failed for inode %lu "
				  "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
 * @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()
 * address_space_operation.
@@ -2223,9 +2263,6 @@ static int mpage_da_writepages(struct address_space *mapping,
{
	int ret;

	if (!mpd->get_block)
		return generic_writepages(mapping, wbc);

	mpd->lbh.b_size = 0;
	mpd->lbh.b_state = 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;
}
#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)
{
@@ -2584,7 +2576,6 @@ retry:
			dump_stack();
			goto out_writepages;
		}
		mpd.get_block = ext4_da_get_block_write;
		ret = mpage_da_writepages(mapping, wbc, &mpd);

		ext4_journal_stop(handle);