mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 01:21:58 +00:00
mm: change invalidatepage prototype to accept length
Currently there is no way to truncate partial page where the end truncate point is not at the end of the page. This is because it was not needed and the functionality was enough for file system truncate operation to work properly. However more file systems now support punch hole feature and it can benefit from mm supporting truncating page just up to the certain point. Specifically, with this functionality truncate_inode_pages_range() can be changed so it supports truncating partial page at the end of the range (currently it will BUG_ON() if 'end' is not at the end of the page). This commit changes the invalidatepage() address space operation prototype to accept range to be invalidated and update all the instances for it. We also change the block_invalidatepage() in the same way and actually make a use of the new length argument implementing range invalidation. Actual file system implementations will follow except the file systems where the changes are really simple and should not change the behaviour in any way .Implementation for truncate_page_range() which will be able to accept page unaligned ranges will follow as well. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Hugh Dickins <hughd@google.com>
This commit is contained in:
parent
c7788792a5
commit
d47992f86b
30 changed files with 116 additions and 69 deletions
21
fs/buffer.c
21
fs/buffer.c
|
@ -1454,7 +1454,8 @@ static void discard_buffer(struct buffer_head * bh)
|
|||
* block_invalidatepage - invalidate part or all of a buffer-backed page
|
||||
*
|
||||
* @page: the page which is affected
|
||||
* @offset: the index of the truncation point
|
||||
* @offset: start of the range to invalidate
|
||||
* @length: length of the range to invalidate
|
||||
*
|
||||
* block_invalidatepage() is called when all or part of the page has become
|
||||
* invalidated by a truncate operation.
|
||||
|
@ -1465,21 +1466,34 @@ static void discard_buffer(struct buffer_head * bh)
|
|||
* point. Because the caller is about to free (and possibly reuse) those
|
||||
* blocks on-disk.
|
||||
*/
|
||||
void block_invalidatepage(struct page *page, unsigned long offset)
|
||||
void block_invalidatepage(struct page *page, unsigned int offset,
|
||||
unsigned int length)
|
||||
{
|
||||
struct buffer_head *head, *bh, *next;
|
||||
unsigned int curr_off = 0;
|
||||
unsigned int stop = length + offset;
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
if (!page_has_buffers(page))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Check for overflow
|
||||
*/
|
||||
BUG_ON(stop > PAGE_CACHE_SIZE || stop < length);
|
||||
|
||||
head = page_buffers(page);
|
||||
bh = head;
|
||||
do {
|
||||
unsigned int next_off = curr_off + bh->b_size;
|
||||
next = bh->b_this_page;
|
||||
|
||||
/*
|
||||
* Are we still fully in range ?
|
||||
*/
|
||||
if (next_off > stop)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* is this block fully invalidated?
|
||||
*/
|
||||
|
@ -1501,6 +1515,7 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(block_invalidatepage);
|
||||
|
||||
|
||||
/*
|
||||
* We attach and possibly dirty the buffers atomically wrt
|
||||
* __set_page_dirty_buffers() via private_lock. try_to_free_buffers
|
||||
|
@ -2841,7 +2856,7 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
|
|||
* they may have been added in ext3_writepage(). Make them
|
||||
* freeable here, so the page does not leak.
|
||||
*/
|
||||
do_invalidatepage(page, 0);
|
||||
do_invalidatepage(page, 0, PAGE_CACHE_SIZE);
|
||||
unlock_page(page);
|
||||
return 0; /* don't care */
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue