Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146386
b: refs/heads/master
c: b920c75
h: refs/heads/master
v: v3
  • Loading branch information
Theodore Ts'o committed May 14, 2009
1 parent d4c0dfa commit 2f5c262
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c21770573319922e3f3fcb331cfaa290c49f1c81
refs/heads/master: b920c75502cb2c48654ef196d647c8eb81ab608a
86 changes: 55 additions & 31 deletions trunk/fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,10 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
}

/*
* The ext4_ind_get_blocks() function handles non-extents inodes
* (i.e., using the traditional indirect/double-indirect i_blocks
* scheme) for ext4_get_blocks().
*
* Allocation strategy is simple: if we have to allocate something, we will
* have to go the whole way to leaf. So let's do it before attaching anything
* to tree, set linkage between the newborn blocks, write them if sync is
Expand All @@ -909,10 +913,11 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
* return = 0, if plain lookup failed.
* return < 0, error case.
*
*
* Need to be called with
* down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
* (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
* The ext4_ind_get_blocks() function should be called with
* down_write(&EXT4_I(inode)->i_data_sem) if allocating filesystem
* blocks (i.e., flags has EXT4_GET_BLOCKS_CREATE set) or
* down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system
* blocks.
*/
static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, unsigned int maxblocks,
Expand Down Expand Up @@ -1152,8 +1157,8 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
clear_buffer_unwritten(bh);

/*
* Try to see if we can get the block without requesting
* for new file system block.
* Try to see if we can get the block without requesting a new
* file system block.
*/
down_read((&EXT4_I(inode)->i_data_sem));
if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
Expand Down Expand Up @@ -2000,6 +2005,12 @@ static void ext4_print_free_blocks(struct inode *inode)
return;
}

/*
* This function is used by mpage_da_map_blocks(). We separate it out
* as a separate function just to make life easier, and because
* mpage_da_map_blocks() used to be a generic function that took a
* get_block_t.
*/
static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result)
{
Expand Down Expand Up @@ -2031,8 +2042,8 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,

/*
* Update on-disk size along with block allocation we don't
* use 'extend_disksize' as size may change within already
* allocated block -bzzz
* use EXT4_GET_BLOCKS_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))
Expand Down Expand Up @@ -2338,16 +2349,16 @@ static int __mpage_da_writepage(struct page *page,
}

/*
* this is a special callback for ->write_begin() only
* it's intention is to return mapped block or reserve space
* This is a special get_blocks_t callback which is used by
* ext4_da_write_begin(). It will either return mapped block or
* reserve space for a single block.
*
* For delayed buffer_head we have BH_Mapped, BH_New, BH_Delay set.
* We also have b_blocknr = -1 and b_bdev initialized properly
*
* For unwritten buffer_head we have BH_Mapped, BH_New, BH_Unwritten set.
* We also have b_blocknr = physicalblock mapping unwritten extent and b_bdev
* initialized properly.
*
*/
static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
Expand Down Expand Up @@ -2400,7 +2411,23 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
return ret;
}

static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock,
/*
* This function is used as a standard get_block_t calback function
* when there is no desire to allocate any blocks. It is used as a
* callback function for block_prepare_write(), nobh_writepage(), and
* block_write_full_page(). These functions should only try to map a
* single block at a time.
*
* Since this function doesn't do block allocations even if the caller
* requests it by passing in create=1, it is critically important that
* any caller checks to make sure that any buffer heads are returned
* by this function are either all already mapped or marked for
* delayed allocation before calling nobh_writepage() or
* block_write_full_page(). Otherwise, b_blocknr could be left
* unitialized, and the page write functions will be taken by
* surprise.
*/
static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int ret = 0;
Expand All @@ -2419,10 +2446,11 @@ static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock,
}

/*
* get called vi ext4_da_writepages after taking page lock (have journal handle)
* get called via journal_submit_inode_data_buffers (no journal handle)
* get called via shrink_page_list via pdflush (no journal handle)
* or grab_page_cache when doing write_begin (have journal handle)
* This function can get called via...
* - ext4_da_writepages after taking page lock (have journal handle)
* - journal_submit_inode_data_buffers (no journal handle)
* - shrink_page_list via pdflush (no journal handle)
* - grab_page_cache when doing write_begin (have journal handle)
*/
static int ext4_da_writepage(struct page *page,
struct writeback_control *wbc)
Expand Down Expand Up @@ -2473,7 +2501,7 @@ static int ext4_da_writepage(struct page *page,
* do block allocation here.
*/
ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
ext4_normal_get_block_write);
noalloc_get_block_write);
if (!ret) {
page_bufs = page_buffers(page);
/* check whether all are mapped and non delay */
Expand All @@ -2498,11 +2526,10 @@ static int ext4_da_writepage(struct page *page,
}

if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
ret = nobh_writepage(page, ext4_normal_get_block_write, wbc);
ret = nobh_writepage(page, noalloc_get_block_write, wbc);
else
ret = block_write_full_page(page,
ext4_normal_get_block_write,
wbc);
ret = block_write_full_page(page, noalloc_get_block_write,
wbc);

return ret;
}
Expand Down Expand Up @@ -2814,7 +2841,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
*pagep = page;

ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
ext4_da_get_block_prep);
ext4_da_get_block_prep);
if (ret < 0) {
unlock_page(page);
ext4_journal_stop(handle);
Expand Down Expand Up @@ -3122,12 +3149,10 @@ static int __ext4_normal_writepage(struct page *page,
struct inode *inode = page->mapping->host;

if (test_opt(inode->i_sb, NOBH))
return nobh_writepage(page,
ext4_normal_get_block_write, wbc);
return nobh_writepage(page, noalloc_get_block_write, wbc);
else
return block_write_full_page(page,
ext4_normal_get_block_write,
wbc);
return block_write_full_page(page, noalloc_get_block_write,
wbc);
}

static int ext4_normal_writepage(struct page *page,
Expand Down Expand Up @@ -3179,7 +3204,7 @@ static int __ext4_journalled_writepage(struct page *page,
int err;

ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
ext4_normal_get_block_write);
noalloc_get_block_write);
if (ret != 0)
goto out_unlock;

Expand Down Expand Up @@ -3264,9 +3289,8 @@ static int ext4_journalled_writepage(struct page *page,
* really know unless we go poke around in the buffer_heads.
* But block_write_full_page will do the right thing.
*/
return block_write_full_page(page,
ext4_normal_get_block_write,
wbc);
return block_write_full_page(page, noalloc_get_block_write,
wbc);
}
no_write:
redirty_page_for_writepage(wbc, page);
Expand Down

0 comments on commit 2f5c262

Please sign in to comment.