Skip to content

Commit

Permalink
get rid of block_write_begin_newtrunc
Browse files Browse the repository at this point in the history
Move the call to vmtruncate to get rid of accessive blocks to the callers
in preparation of the new truncate sequence and rename the non-truncating
version to block_write_begin.

While we're at it also remove several unused arguments to block_write_begin.

Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Aug 9, 2010
1 parent 6e1db88 commit 155130a
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 91 deletions.
14 changes: 11 additions & 3 deletions fs/bfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,17 @@ static int bfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags,
pagep, fsdata, bfs_get_block);
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep,
bfs_get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
Expand Down
5 changes: 2 additions & 3 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,8 @@ static int blkdev_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin_newtrunc(file, mapping, pos, len, flags,
pagep, fsdata, blkdev_get_block);
return block_write_begin(mapping, pos, len, flags, pagep,
blkdev_get_block);
}

static int blkdev_write_end(struct file *file, struct address_space *mapping,
Expand Down
61 changes: 9 additions & 52 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1962,14 +1962,13 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
EXPORT_SYMBOL(__block_write_begin);

/*
* Filesystems implementing the new truncate sequence should use the
* _newtrunc postfix variant which won't incorrectly call vmtruncate.
* block_write_begin takes care of the basic task of block allocation and
* bringing partial write blocks uptodate first.
*
* The filesystem needs to handle block truncation upon failure.
*/
int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
get_block_t *get_block)
int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
unsigned flags, struct page **pagep, get_block_t *get_block)
{
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
struct page *page;
Expand All @@ -1989,44 +1988,6 @@ int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
*pagep = page;
return status;
}
EXPORT_SYMBOL(block_write_begin_newtrunc);

/*
* block_write_begin takes care of the basic task of block allocation and
* bringing partial write blocks uptodate first.
*
* If *pagep is not NULL, then block_write_begin uses the locked page
* at *pagep rather than allocating its own. In this case, the page will
* not be unlocked or deallocated on failure.
*/
int block_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
get_block_t *get_block)
{
int ret;

ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
pagep, fsdata, get_block);

/*
* prepare_write() may have instantiated a few blocks
* outside i_size. Trim these off again. Don't need
* i_size_read because we hold i_mutex.
*
* Filesystems which pass down their own page also cannot
* call into vmtruncate here because it would lead to lock
* inversion problems (*pagep is locked). This is a further
* example of where the old truncate sequence is inadequate.
*/
if (unlikely(ret) && *pagep == NULL) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}
EXPORT_SYMBOL(block_write_begin);

int block_write_end(struct file *file, struct address_space *mapping,
Expand Down Expand Up @@ -2357,19 +2318,15 @@ int cont_write_begin(struct file *file, struct address_space *mapping,

err = cont_expand_zero(file, mapping, pos, bytes);
if (err)
goto out;
return err;

zerofrom = *bytes & ~PAGE_CACHE_MASK;
if (pos+len > *bytes && zerofrom & (blocksize-1)) {
*bytes |= (blocksize-1);
(*bytes)++;
}

*pagep = NULL;
err = block_write_begin_newtrunc(file, mapping, pos, len,
flags, pagep, fsdata, get_block);
out:
return err;
return block_write_begin(mapping, pos, len, flags, pagep, get_block);
}
EXPORT_SYMBOL(cont_write_begin);

Expand Down Expand Up @@ -2511,8 +2468,8 @@ int nobh_write_begin(struct address_space *mapping,
unlock_page(page);
page_cache_release(page);
*pagep = NULL;
return block_write_begin_newtrunc(NULL, mapping, pos, len,
flags, pagep, fsdata, get_block);
return block_write_begin(mapping, pos, len, flags, pagep,
get_block);
}

if (PageMappedToDisk(page))
Expand Down
5 changes: 2 additions & 3 deletions fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,9 +772,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
{
int ret;

*pagep = NULL;
ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
pagep, fsdata, ext2_get_block);
ret = block_write_begin(mapping, pos, len, flags, pagep,
ext2_get_block);
if (ret < 0)
ext2_write_failed(mapping, pos + len);
return ret;
Expand Down
12 changes: 10 additions & 2 deletions fs/minix/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,17 @@ static int minix_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep,
minix_get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t minix_bmap(struct address_space *mapping, sector_t block)
Expand Down
12 changes: 8 additions & 4 deletions fs/nilfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,15 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,
if (unlikely(err))
return err;

*pagep = NULL;
err = block_write_begin(file, mapping, pos, len, flags, pagep,
fsdata, nilfs_get_block);
if (unlikely(err))
err = block_write_begin(mapping, pos, len, flags, pagep,
nilfs_get_block);
if (unlikely(err)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);

nilfs_transaction_abort(inode->i_sb);
}
return err;
}

Expand Down
11 changes: 7 additions & 4 deletions fs/nilfs2/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,14 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
}

pos = rb->blkoff << inode->i_blkbits;
page = NULL;
err = block_write_begin(NULL, inode->i_mapping, pos, blocksize,
0, &page, NULL, nilfs_get_block);
if (unlikely(err))
err = block_write_begin(inode->i_mapping, pos, blocksize,
0, &page, nilfs_get_block);
if (unlikely(err)) {
loff_t isize = inode->i_size;
if (pos + blocksize > isize)
vmtruncate(inode, isize);
goto failed_inode;
}

err = nilfs_recovery_copy_block(sbi, rb, page);
if (unlikely(err))
Expand Down
14 changes: 11 additions & 3 deletions fs/omfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,17 @@ static int omfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags,
pagep, fsdata, omfs_get_block);
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep,
omfs_get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
Expand Down
13 changes: 10 additions & 3 deletions fs/sysv/itree.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,16 @@ static int sysv_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
get_block);
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep, get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
Expand Down
13 changes: 10 additions & 3 deletions fs/udf/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,16 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
udf_get_block);
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t udf_bmap(struct address_space *mapping, sector_t block)
Expand Down
12 changes: 10 additions & 2 deletions fs/ufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,17 @@ static int ufs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
int ret;

ret = block_write_begin(mapping, pos, len, flags, pagep,
ufs_getfrag_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
Expand Down
14 changes: 11 additions & 3 deletions fs/xfs/linux-2.6/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1504,9 +1504,17 @@ xfs_vm_write_begin(
struct page **pagep,
void **fsdata)
{
*pagep = NULL;
return block_write_begin(file, mapping, pos, len, flags | AOP_FLAG_NOFS,
pagep, fsdata, xfs_get_blocks);
int ret;

ret = block_write_begin(mapping, pos, len, flags | AOP_FLAG_NOFS,
pagep, xfs_get_blocks);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}

return ret;
}

STATIC sector_t
Expand Down
8 changes: 2 additions & 6 deletions include/linux/buffer_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,8 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
int block_read_full_page(struct page*, get_block_t*);
int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
unsigned long from);
int block_write_begin_newtrunc(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
struct page **, void **, get_block_t*);
int block_write_begin(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
struct page **, void **, get_block_t*);
int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
unsigned flags, struct page **pagep, get_block_t *get_block);
int __block_write_begin(struct page *page, loff_t pos, unsigned len,
get_block_t *get_block);
int block_write_end(struct file *, struct address_space *,
Expand Down

0 comments on commit 155130a

Please sign in to comment.