mm: tidy vmtruncate_range and related functions

Use consistent variable names in truncate_pagecache(), truncate_setsize(),
vmtruncate() and vmtruncate_range().

unmap_mapping_range() and vmtruncate_range() have mismatched interfaces:
don't change either, but make the vmtruncates more precise about what they
expect unmap_mapping_range() to do.

vmtruncate_range() is currently called only with page-aligned start and
end+1: can handle unaligned start, but unaligned end+1 would hit BUG_ON in
truncate_inode_pages_range() (lacks partial clearing of the end page).

Signed-off-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Hugh Dickins 2011-07-25 17:12:24 -07:00 committed by Linus Torvalds
parent 85821aab39
commit 8a549bea51

View File

@ -531,8 +531,8 @@ EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
/** /**
* truncate_pagecache - unmap and remove pagecache that has been truncated * truncate_pagecache - unmap and remove pagecache that has been truncated
* @inode: inode * @inode: inode
* @old: old file offset * @oldsize: old file size
* @new: new file offset * @newsize: new file size
* *
* inode's new i_size must already be written before truncate_pagecache * inode's new i_size must already be written before truncate_pagecache
* is called. * is called.
@ -544,9 +544,10 @@ EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
* situations such as writepage being called for a page that has already * situations such as writepage being called for a page that has already
* had its underlying blocks deallocated. * had its underlying blocks deallocated.
*/ */
void truncate_pagecache(struct inode *inode, loff_t old, loff_t new) void truncate_pagecache(struct inode *inode, loff_t oldsize, loff_t newsize)
{ {
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = inode->i_mapping;
loff_t holebegin = round_up(newsize, PAGE_SIZE);
/* /*
* unmap_mapping_range is called twice, first simply for * unmap_mapping_range is called twice, first simply for
@ -557,9 +558,9 @@ void truncate_pagecache(struct inode *inode, loff_t old, loff_t new)
* truncate_inode_pages finishes, hence the second * truncate_inode_pages finishes, hence the second
* unmap_mapping_range call must be made for correctness. * unmap_mapping_range call must be made for correctness.
*/ */
unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1); unmap_mapping_range(mapping, holebegin, 0, 1);
truncate_inode_pages(mapping, new); truncate_inode_pages(mapping, newsize);
unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1); unmap_mapping_range(mapping, holebegin, 0, 1);
} }
EXPORT_SYMBOL(truncate_pagecache); EXPORT_SYMBOL(truncate_pagecache);
@ -589,29 +590,31 @@ EXPORT_SYMBOL(truncate_setsize);
/** /**
* vmtruncate - unmap mappings "freed" by truncate() syscall * vmtruncate - unmap mappings "freed" by truncate() syscall
* @inode: inode of the file used * @inode: inode of the file used
* @offset: file offset to start truncating * @newsize: file offset to start truncating
* *
* This function is deprecated and truncate_setsize or truncate_pagecache * This function is deprecated and truncate_setsize or truncate_pagecache
* should be used instead, together with filesystem specific block truncation. * should be used instead, together with filesystem specific block truncation.
*/ */
int vmtruncate(struct inode *inode, loff_t offset) int vmtruncate(struct inode *inode, loff_t newsize)
{ {
int error; int error;
error = inode_newsize_ok(inode, offset); error = inode_newsize_ok(inode, newsize);
if (error) if (error)
return error; return error;
truncate_setsize(inode, offset); truncate_setsize(inode, newsize);
if (inode->i_op->truncate) if (inode->i_op->truncate)
inode->i_op->truncate(inode); inode->i_op->truncate(inode);
return 0; return 0;
} }
EXPORT_SYMBOL(vmtruncate); EXPORT_SYMBOL(vmtruncate);
int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end) int vmtruncate_range(struct inode *inode, loff_t lstart, loff_t lend)
{ {
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = inode->i_mapping;
loff_t holebegin = round_up(lstart, PAGE_SIZE);
loff_t holelen = 1 + lend - holebegin;
/* /*
* If the underlying filesystem is not going to provide * If the underlying filesystem is not going to provide
@ -623,10 +626,10 @@ int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end)
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
inode_dio_wait(inode); inode_dio_wait(inode);
unmap_mapping_range(mapping, offset, (end - offset), 1); unmap_mapping_range(mapping, holebegin, holelen, 1);
inode->i_op->truncate_range(inode, offset, end); inode->i_op->truncate_range(inode, lstart, lend);
/* unmap again to remove racily COWed private pages */ /* unmap again to remove racily COWed private pages */
unmap_mapping_range(mapping, offset, (end - offset), 1); unmap_mapping_range(mapping, holebegin, holelen, 1);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
return 0; return 0;