From: Lukas Czerner <lczerner@redhat.com>
To: linux-fsdevel@vger.kernel.org
Cc: linux-ext4@vger.kernel.org, tytso@mit.edu, hughd@google.com,
linux-mmc@vger.kernel.org, Lukas Czerner <lczerner@redhat.com>
Subject: [PATCH 03/15] ext4: implement invalidatepage_range aop
Date: Fri, 27 Jul 2012 10:01:02 +0200 [thread overview]
Message-ID: <1343376074-28034-4-git-send-email-lczerner@redhat.com> (raw)
In-Reply-To: <1343376074-28034-1-git-send-email-lczerner@redhat.com>
mm now supports invalidatepage_range address space operation which is
useful to allow truncating page range which is not aligned to the end of
the page. This will help in punch hole implementation once
truncate_inode_pages_range() is modify to allow this as well.
With this commit ext4 now register only invalidatepage_range. Also
change the respective tracepoint to print length of the range.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
fs/ext4/inode.c | 58 ++++++++++++++++++++++++++++++------------
include/trace/events/ext4.h | 13 ++++++---
2 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 02bc8cb..1b8c317 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -131,7 +131,8 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode,
new_size);
}
-static void ext4_invalidatepage(struct page *page, unsigned long offset);
+static void ext4_invalidatepage_range(struct page *page, unsigned long offset,
+ unsigned long length);
static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);
static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
@@ -1262,20 +1263,28 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
}
static void ext4_da_page_release_reservation(struct page *page,
- unsigned long offset)
+ unsigned long offset,
+ unsigned long length)
{
int to_release = 0;
struct buffer_head *head, *bh;
unsigned int curr_off = 0;
struct inode *inode = page->mapping->host;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ unsigned long stop = offset + length;
int num_clusters;
+ if (stop < length)
+ stop = PAGE_CACHE_SIZE;
+
head = page_buffers(page);
bh = head;
do {
unsigned int next_off = curr_off + bh->b_size;
+ if (next_off > stop)
+ break;
+
if ((offset <= curr_off) && (buffer_delay(bh))) {
to_release++;
clear_buffer_delay(bh);
@@ -2608,7 +2617,9 @@ static int ext4_da_write_end(struct file *file,
return ret ? ret : copied;
}
-static void ext4_da_invalidatepage(struct page *page, unsigned long offset)
+static void ext4_da_invalidatepage_range(struct page *page,
+ unsigned long offset,
+ unsigned long length)
{
/*
* Drop reserved blocks
@@ -2617,10 +2628,10 @@ static void ext4_da_invalidatepage(struct page *page, unsigned long offset)
if (!page_has_buffers(page))
goto out;
- ext4_da_page_release_reservation(page, offset);
+ ext4_da_page_release_reservation(page, offset, length);
out:
- ext4_invalidatepage(page, offset);
+ ext4_invalidatepage_range(page, offset, length);
return;
}
@@ -2746,47 +2757,60 @@ ext4_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
}
-static void ext4_invalidatepage_free_endio(struct page *page, unsigned long offset)
+static void ext4_invalidatepage_free_endio(struct page *page,
+ unsigned long offset,
+ unsigned long length)
{
struct buffer_head *head, *bh;
unsigned int curr_off = 0;
+ unsigned long stop = offset + length;
if (!page_has_buffers(page))
return;
+ if (stop < length)
+ stop = PAGE_CACHE_SIZE;
+
head = bh = page_buffers(page);
do {
+ unsigned int next_off = curr_off + bh->b_size;
+
+ if (next_off > stop)
+ return;
+
if (offset <= curr_off && test_clear_buffer_uninit(bh)
&& bh->b_private) {
ext4_free_io_end(bh->b_private);
bh->b_private = NULL;
bh->b_end_io = NULL;
}
- curr_off = curr_off + bh->b_size;
+ curr_off = next_off;
bh = bh->b_this_page;
} while (bh != head);
}
-static void ext4_invalidatepage(struct page *page, unsigned long offset)
+static void ext4_invalidatepage_range(struct page *page, unsigned long offset,
+ unsigned long length)
{
journal_t *journal = EXT4_JOURNAL(page->mapping->host);
- trace_ext4_invalidatepage(page, offset);
+ trace_ext4_invalidatepage_range(page, offset, length);
/*
* free any io_end structure allocated for buffers to be discarded
*/
if (ext4_should_dioread_nolock(page->mapping->host))
- ext4_invalidatepage_free_endio(page, offset);
+ ext4_invalidatepage_free_endio(page, offset, length);
/*
* If it's a full truncate we just forget about the pending dirtying
*/
- if (offset == 0)
+ if (offset == 0 && length >= PAGE_CACHE_SIZE)
ClearPageChecked(page);
if (journal)
- jbd2_journal_invalidatepage(journal, page, offset);
+ jbd2_journal_invalidatepage_range(journal, page,
+ offset, length);
else
- block_invalidatepage(page, offset);
+ block_invalidatepage_range(page, offset, length);
}
static int ext4_releasepage(struct page *page, gfp_t wait)
@@ -3101,7 +3125,7 @@ static const struct address_space_operations ext4_ordered_aops = {
.write_begin = ext4_write_begin,
.write_end = ext4_ordered_write_end,
.bmap = ext4_bmap,
- .invalidatepage = ext4_invalidatepage,
+ .invalidatepage_range = ext4_invalidatepage_range,
.releasepage = ext4_releasepage,
.direct_IO = ext4_direct_IO,
.migratepage = buffer_migrate_page,
@@ -3116,7 +3140,7 @@ static const struct address_space_operations ext4_writeback_aops = {
.write_begin = ext4_write_begin,
.write_end = ext4_writeback_write_end,
.bmap = ext4_bmap,
- .invalidatepage = ext4_invalidatepage,
+ .invalidatepage_range = ext4_invalidatepage_range,
.releasepage = ext4_releasepage,
.direct_IO = ext4_direct_IO,
.migratepage = buffer_migrate_page,
@@ -3132,7 +3156,7 @@ static const struct address_space_operations ext4_journalled_aops = {
.write_end = ext4_journalled_write_end,
.set_page_dirty = ext4_journalled_set_page_dirty,
.bmap = ext4_bmap,
- .invalidatepage = ext4_invalidatepage,
+ .invalidatepage_range = ext4_invalidatepage_range,
.releasepage = ext4_releasepage,
.direct_IO = ext4_direct_IO,
.is_partially_uptodate = block_is_partially_uptodate,
@@ -3147,7 +3171,7 @@ static const struct address_space_operations ext4_da_aops = {
.write_begin = ext4_da_write_begin,
.write_end = ext4_da_write_end,
.bmap = ext4_bmap,
- .invalidatepage = ext4_da_invalidatepage,
+ .invalidatepage_range = ext4_da_invalidatepage_range,
.releasepage = ext4_releasepage,
.direct_IO = ext4_direct_IO,
.migratepage = buffer_migrate_page,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 69d8a69..30bae72 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -450,14 +450,15 @@ DEFINE_EVENT(ext4__page_op, ext4_releasepage,
TP_ARGS(page)
);
-TRACE_EVENT(ext4_invalidatepage,
- TP_PROTO(struct page *page, unsigned long offset),
+TRACE_EVENT(ext4_invalidatepage_range,
+ TP_PROTO(struct page *page, unsigned long offset, unsigned long length),
- TP_ARGS(page, offset),
+ TP_ARGS(page, offset, length),
TP_STRUCT__entry(
__field( pgoff_t, index )
__field( unsigned long, offset )
+ __field( unsigned long, length )
__field( ino_t, ino )
__field( dev_t, dev )
@@ -466,14 +467,16 @@ TRACE_EVENT(ext4_invalidatepage,
TP_fast_assign(
__entry->index = page->index;
__entry->offset = offset;
+ __entry->length = length;
__entry->ino = page->mapping->host->i_ino;
__entry->dev = page->mapping->host->i_sb->s_dev;
),
- TP_printk("dev %d,%d ino %lu page_index %lu offset %lu",
+ TP_printk("dev %d,%d ino %lu page_index %lu offset %lu length %lu",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- (unsigned long) __entry->index, __entry->offset)
+ (unsigned long) __entry->index,
+ __entry->offset, __entry->length)
);
TRACE_EVENT(ext4_discard_blocks,
--
1.7.7.6
next prev parent reply other threads:[~2012-07-27 8:01 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-27 8:00 Add invalidatepage_range address space operation Lukas Czerner
2012-07-27 8:01 ` [PATCH 01/15] mm: add " Lukas Czerner
2012-08-20 5:24 ` Hugh Dickins
[not found] ` <5033a999.0f403a0a.19c3.ffff95deSMTPIN_ADDED@mx.google.com>
2012-08-21 18:59 ` Hugh Dickins
2012-07-27 8:01 ` [PATCH 02/15] jbd2: implement jbd2_journal_invalidatepage_range Lukas Czerner
2012-07-27 8:01 ` Lukas Czerner [this message]
2012-07-27 8:01 ` [PATCH 04/15] xfs: implement invalidatepage_range aop Lukas Czerner
2012-07-27 8:01 ` [PATCH 05/15] ocfs2: " Lukas Czerner
2012-07-27 8:01 ` [PATCH 06/15] mm: teach truncate_inode_pages_range() to handle non page aligned ranges Lukas Czerner
2012-08-20 4:52 ` Hugh Dickins
2012-08-20 10:26 ` Lukáš Czerner
2012-08-20 15:47 ` Hugh Dickins
[not found] ` <50339e0d.69b2340a.50ba.ffff92bcSMTPIN_ADDED@mx.google.com>
2012-08-21 18:44 ` Hugh Dickins
2012-08-20 15:53 ` Hugh Dickins
2012-07-27 8:01 ` [PATCH 07/15] ext4: Take i_mutex before punching hole Lukas Czerner
2012-07-27 9:04 ` Lukáš Czerner
2012-07-27 12:08 ` Zheng Liu
2012-08-20 5:45 ` Hugh Dickins
2012-07-27 8:01 ` [PATCH 08/15] Revert "ext4: remove no longer used functions in inode.c" Lukas Czerner
2012-07-27 8:01 ` [PATCH 09/15] Revert "ext4: fix fsx truncate failure" Lukas Czerner
2012-07-27 8:01 ` [PATCH 10/15] ext4: use ext4_zero_partial_blocks in punch_hole Lukas Czerner
2012-07-27 8:01 ` [PATCH 11/15] ext4: remove unused discard_partial_page_buffers Lukas Czerner
2012-07-27 8:01 ` [PATCH 12/15] ext4: remove unused code from ext4_remove_blocks() Lukas Czerner
2012-07-27 8:01 ` [PATCH 13/15] ext4: update ext4_ext_remove_space trace point Lukas Czerner
2012-07-27 8:01 ` [PATCH 14/15] ext4: make punch hole code path work with bigalloc Lukas Czerner
2012-07-27 8:01 ` [PATCH 15/15] ext4: Allow punch hole with bigalloc enabled Lukas Czerner
2012-08-19 0:57 ` Add invalidatepage_range address space operation Theodore Ts'o
2012-08-20 4:43 ` Hugh Dickins
2012-08-20 13:23 ` Theodore Ts'o
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343376074-28034-4-git-send-email-lczerner@redhat.com \
--to=lczerner@redhat.com \
--cc=hughd@google.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).