aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/transaction.c
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2013-05-21 23:20:03 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-05-21 23:20:03 -0400
commit259709b07da103edc40b8c5bdb2d5c0e77374f94 (patch)
tree358bb3da52897264271a9ff45dd5869f2056aa39 /fs/jbd2/transaction.c
parentd47992f86b307985b3215bcf141d56d1849d71df (diff)
jbd2: change jbd2_journal_invalidatepage to accept length
invalidatepage now accepts range to invalidate and there are two file system using jbd2 also implementing punch hole feature which can benefit from this. We need to implement the same thing for jbd2 layer in order to allow those file system take benefit of this functionality. This commit adds length argument to the jbd2_journal_invalidatepage() and updates all instances in ext4 and ocfs2. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/jbd2/transaction.c')
-rw-r--r--fs/jbd2/transaction.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 10f524c59ea8..5d8268ad364a 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -2034,18 +2034,23 @@ zap_buffer_unlocked:
2034 * void jbd2_journal_invalidatepage() 2034 * void jbd2_journal_invalidatepage()
2035 * @journal: journal to use for flush... 2035 * @journal: journal to use for flush...
2036 * @page: page to flush 2036 * @page: page to flush
2037 * @offset: length of page to invalidate. 2037 * @offset: start of the range to invalidate
2038 * @length: length of the range to invalidate
2038 * 2039 *
2039 * Reap page buffers containing data after offset in page. Can return -EBUSY 2040 * Reap page buffers containing data after in the specified range in page.
2040 * if buffers are part of the committing transaction and the page is straddling 2041 * Can return -EBUSY if buffers are part of the committing transaction and
2041 * i_size. Caller then has to wait for current commit and try again. 2042 * the page is straddling i_size. Caller then has to wait for current commit
2043 * and try again.
2042 */ 2044 */
2043int jbd2_journal_invalidatepage(journal_t *journal, 2045int jbd2_journal_invalidatepage(journal_t *journal,
2044 struct page *page, 2046 struct page *page,
2045 unsigned long offset) 2047 unsigned int offset,
2048 unsigned int length)
2046{ 2049{
2047 struct buffer_head *head, *bh, *next; 2050 struct buffer_head *head, *bh, *next;
2051 unsigned int stop = offset + length;
2048 unsigned int curr_off = 0; 2052 unsigned int curr_off = 0;
2053 int partial_page = (offset || length < PAGE_CACHE_SIZE);
2049 int may_free = 1; 2054 int may_free = 1;
2050 int ret = 0; 2055 int ret = 0;
2051 2056
@@ -2054,6 +2059,8 @@ int jbd2_journal_invalidatepage(journal_t *journal,
2054 if (!page_has_buffers(page)) 2059 if (!page_has_buffers(page))
2055 return 0; 2060 return 0;
2056 2061
2062 BUG_ON(stop > PAGE_CACHE_SIZE || stop < length);
2063
2057 /* We will potentially be playing with lists other than just the 2064 /* We will potentially be playing with lists other than just the
2058 * data lists (especially for journaled data mode), so be 2065 * data lists (especially for journaled data mode), so be
2059 * cautious in our locking. */ 2066 * cautious in our locking. */
@@ -2063,10 +2070,13 @@ int jbd2_journal_invalidatepage(journal_t *journal,
2063 unsigned int next_off = curr_off + bh->b_size; 2070 unsigned int next_off = curr_off + bh->b_size;
2064 next = bh->b_this_page; 2071 next = bh->b_this_page;
2065 2072
2073 if (next_off > stop)
2074 return 0;
2075
2066 if (offset <= curr_off) { 2076 if (offset <= curr_off) {
2067 /* This block is wholly outside the truncation point */ 2077 /* This block is wholly outside the truncation point */
2068 lock_buffer(bh); 2078 lock_buffer(bh);
2069 ret = journal_unmap_buffer(journal, bh, offset > 0); 2079 ret = journal_unmap_buffer(journal, bh, partial_page);
2070 unlock_buffer(bh); 2080 unlock_buffer(bh);
2071 if (ret < 0) 2081 if (ret < 0)
2072 return ret; 2082 return ret;
@@ -2077,7 +2087,7 @@ int jbd2_journal_invalidatepage(journal_t *journal,
2077 2087
2078 } while (bh != head); 2088 } while (bh != head);
2079 2089
2080 if (!offset) { 2090 if (!partial_page) {
2081 if (may_free && try_to_free_buffers(page)) 2091 if (may_free && try_to_free_buffers(page))
2082 J_ASSERT(!page_has_buffers(page)); 2092 J_ASSERT(!page_has_buffers(page));
2083 } 2093 }