* [PATCH 01/23] ocfs2: Handle a symlink read error correctly
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 12:03 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 02/23] ocfs2: Convert ocfs2_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
` (21 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely, stable
If we can't read the buffer, be sure to unlock the page before
returning.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: stable@vger.kernel.org
---
fs/ocfs2/symlink.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index d4c5fdcfa1e4..f5cf2255dc09 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
if (status < 0) {
mlog_errno(status);
- return status;
+ goto out;
}
fe = (struct ocfs2_dinode *) bh->b_data;
@@ -76,9 +76,10 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
memcpy(kaddr, link, len + 1);
kunmap_atomic(kaddr);
SetPageUptodate(page);
+out:
unlock_page(page);
brelse(bh);
- return 0;
+ return status;
}
const struct address_space_operations ocfs2_fast_symlink_aops = {
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 01/23] ocfs2: Handle a symlink read error correctly
2024-12-05 17:16 ` [PATCH 01/23] ocfs2: Handle a symlink read error correctly Matthew Wilcox (Oracle)
@ 2024-12-14 12:03 ` Joseph Qi
2024-12-14 15:20 ` Matthew Wilcox
0 siblings, 1 reply; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 12:03 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: ocfs2-devel, Mark Tinguely, stable
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> If we can't read the buffer, be sure to unlock the page before
> returning.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> Cc: stable@vger.kernel.org
> ---
> fs/ocfs2/symlink.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
> index d4c5fdcfa1e4..f5cf2255dc09 100644
> --- a/fs/ocfs2/symlink.c
> +++ b/fs/ocfs2/symlink.c
> @@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
>
Better to move calling ocfs2_read_inode_block() here.
Thanks,
Joseph
> if (status < 0) {
> mlog_errno(status);
> - return status;
> + goto out;
> }
>
> fe = (struct ocfs2_dinode *) bh->b_data;
> @@ -76,9 +76,10 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
> memcpy(kaddr, link, len + 1);
> kunmap_atomic(kaddr);
> SetPageUptodate(page);
> +out:
> unlock_page(page);
> brelse(bh);
> - return 0;
> + return status;
> }
>
> const struct address_space_operations ocfs2_fast_symlink_aops = {
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH 01/23] ocfs2: Handle a symlink read error correctly
2024-12-14 12:03 ` Joseph Qi
@ 2024-12-14 15:20 ` Matthew Wilcox
2024-12-14 15:45 ` Joseph Qi
0 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox @ 2024-12-14 15:20 UTC (permalink / raw)
To: Joseph Qi; +Cc: ocfs2-devel, Mark Tinguely, stable
On Sat, Dec 14, 2024 at 08:03:30PM +0800, Joseph Qi wrote:
> On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> > If we can't read the buffer, be sure to unlock the page before
> > returning.
> >
> > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> > Cc: stable@vger.kernel.org
> > ---
> > fs/ocfs2/symlink.c | 5 +++--
> > 1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
> > index d4c5fdcfa1e4..f5cf2255dc09 100644
> > --- a/fs/ocfs2/symlink.c
> > +++ b/fs/ocfs2/symlink.c
> > @@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
> >
>
> Better to move calling ocfs2_read_inode_block() here.
Hm? This is a bugfix; it should be as small as reasonable. If you want
the code to be moved around, that should be left to a later patch.
> Thanks,
> Joseph
>
> > if (status < 0) {
> > mlog_errno(status);
> > - return status;
> > + goto out;
> > }
> >
> > fe = (struct ocfs2_dinode *) bh->b_data;
> > @@ -76,9 +76,10 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
> > memcpy(kaddr, link, len + 1);
> > kunmap_atomic(kaddr);
> > SetPageUptodate(page);
> > +out:
> > unlock_page(page);
> > brelse(bh);
> > - return 0;
> > + return status;
> > }
> >
> > const struct address_space_operations ocfs2_fast_symlink_aops = {
>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH 01/23] ocfs2: Handle a symlink read error correctly
2024-12-14 15:20 ` Matthew Wilcox
@ 2024-12-14 15:45 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 15:45 UTC (permalink / raw)
To: Matthew Wilcox, akpm; +Cc: ocfs2-devel, Mark Tinguely, stable
On 2024/12/14 23:20, Matthew Wilcox wrote:
> On Sat, Dec 14, 2024 at 08:03:30PM +0800, Joseph Qi wrote:
>> On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
>>> If we can't read the buffer, be sure to unlock the page before
>>> returning.
>>>
>>> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
>>> Cc: stable@vger.kernel.org
>>> ---
>>> fs/ocfs2/symlink.c | 5 +++--
>>> 1 file changed, 3 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
>>> index d4c5fdcfa1e4..f5cf2255dc09 100644
>>> --- a/fs/ocfs2/symlink.c
>>> +++ b/fs/ocfs2/symlink.c
>>> @@ -65,7 +65,7 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
>>>
>>
>> Better to move calling ocfs2_read_inode_block() here.
>
> Hm? This is a bugfix; it should be as small as reasonable. If you want
> the code to be moved around, that should be left to a later patch.
>
Well, either way is fine to me.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 02/23] ocfs2: Convert ocfs2_page_mkwrite() to use a folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
2024-12-05 17:16 ` [PATCH 01/23] ocfs2: Handle a symlink read error correctly Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 12:20 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 03/23] ocfs2: Convert w_target_page to w_target_folio Matthew Wilcox (Oracle)
` (20 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely
Pass the folio into __ocfs2_page_mkwrite() and use it throughout.
Does not attempt to support large folios.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/mmap.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 6ef4cb045ccd..93b886f16c40 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -44,13 +44,13 @@ static vm_fault_t ocfs2_fault(struct vm_fault *vmf)
}
static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
- struct buffer_head *di_bh, struct page *page)
+ struct buffer_head *di_bh, struct folio *folio)
{
int err;
vm_fault_t ret = VM_FAULT_NOPAGE;
struct inode *inode = file_inode(file);
struct address_space *mapping = inode->i_mapping;
- loff_t pos = page_offset(page);
+ loff_t pos = folio_pos(folio);
unsigned int len = PAGE_SIZE;
pgoff_t last_index;
struct folio *locked_folio = NULL;
@@ -72,9 +72,9 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
*
* Let VM retry with these cases.
*/
- if ((page->mapping != inode->i_mapping) ||
- (!PageUptodate(page)) ||
- (page_offset(page) >= size))
+ if ((folio->mapping != inode->i_mapping) ||
+ !folio_test_uptodate(folio) ||
+ (pos >= size))
goto out;
/*
@@ -87,11 +87,11 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
* worry about ocfs2_write_begin() skipping some buffer reads
* because the "write" would invalidate their data.
*/
- if (page->index == last_index)
+ if (folio->index == last_index)
len = ((size - 1) & ~PAGE_MASK) + 1;
err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
- &locked_folio, &fsdata, di_bh, page);
+ &locked_folio, &fsdata, di_bh, &folio->page);
if (err) {
if (err != -ENOSPC)
mlog_errno(err);
@@ -112,7 +112,7 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
static vm_fault_t ocfs2_page_mkwrite(struct vm_fault *vmf)
{
- struct page *page = vmf->page;
+ struct folio *folio = page_folio(vmf->page);
struct inode *inode = file_inode(vmf->vma->vm_file);
struct buffer_head *di_bh = NULL;
sigset_t oldset;
@@ -141,7 +141,7 @@ static vm_fault_t ocfs2_page_mkwrite(struct vm_fault *vmf)
*/
down_write(&OCFS2_I(inode)->ip_alloc_sem);
- ret = __ocfs2_page_mkwrite(vmf->vma->vm_file, di_bh, page);
+ ret = __ocfs2_page_mkwrite(vmf->vma->vm_file, di_bh, folio);
up_write(&OCFS2_I(inode)->ip_alloc_sem);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 02/23] ocfs2: Convert ocfs2_page_mkwrite() to use a folio
2024-12-05 17:16 ` [PATCH 02/23] ocfs2: Convert ocfs2_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-14 12:20 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 12:20 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: ocfs2-devel, Mark Tinguely
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> Pass the folio into __ocfs2_page_mkwrite() and use it throughout.
> Does not attempt to support large folios.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/mmap.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
> index 6ef4cb045ccd..93b886f16c40 100644
> --- a/fs/ocfs2/mmap.c
> +++ b/fs/ocfs2/mmap.c
> @@ -44,13 +44,13 @@ static vm_fault_t ocfs2_fault(struct vm_fault *vmf)
> }
>
> static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
> - struct buffer_head *di_bh, struct page *page)
> + struct buffer_head *di_bh, struct folio *folio)
> {
> int err;
> vm_fault_t ret = VM_FAULT_NOPAGE;
> struct inode *inode = file_inode(file);
> struct address_space *mapping = inode->i_mapping;
> - loff_t pos = page_offset(page);
> + loff_t pos = folio_pos(folio);
> unsigned int len = PAGE_SIZE;
> pgoff_t last_index;
> struct folio *locked_folio = NULL;
> @@ -72,9 +72,9 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
> *
> * Let VM retry with these cases.
> */
> - if ((page->mapping != inode->i_mapping) ||
> - (!PageUptodate(page)) ||
> - (page_offset(page) >= size))
> + if ((folio->mapping != inode->i_mapping) ||
> + !folio_test_uptodate(folio) ||
> + (pos >= size))
> goto out;
>
> /*
> @@ -87,11 +87,11 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
> * worry about ocfs2_write_begin() skipping some buffer reads
> * because the "write" would invalidate their data.
> */
> - if (page->index == last_index)
> + if (folio->index == last_index)
> len = ((size - 1) & ~PAGE_MASK) + 1;
>
> err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
> - &locked_folio, &fsdata, di_bh, page);
> + &locked_folio, &fsdata, di_bh, &folio->page);
> if (err) {
> if (err != -ENOSPC)
> mlog_errno(err);
> @@ -112,7 +112,7 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
>
> static vm_fault_t ocfs2_page_mkwrite(struct vm_fault *vmf)
> {
> - struct page *page = vmf->page;
> + struct folio *folio = page_folio(vmf->page);
> struct inode *inode = file_inode(vmf->vma->vm_file);
> struct buffer_head *di_bh = NULL;
> sigset_t oldset;
> @@ -141,7 +141,7 @@ static vm_fault_t ocfs2_page_mkwrite(struct vm_fault *vmf)
> */
> down_write(&OCFS2_I(inode)->ip_alloc_sem);
>
> - ret = __ocfs2_page_mkwrite(vmf->vma->vm_file, di_bh, page);
> + ret = __ocfs2_page_mkwrite(vmf->vma->vm_file, di_bh, folio);
>
> up_write(&OCFS2_I(inode)->ip_alloc_sem);
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 03/23] ocfs2: Convert w_target_page to w_target_folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
2024-12-05 17:16 ` [PATCH 01/23] ocfs2: Handle a symlink read error correctly Matthew Wilcox (Oracle)
2024-12-05 17:16 ` [PATCH 02/23] ocfs2: Convert ocfs2_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 12:29 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers() Matthew Wilcox (Oracle)
` (19 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Pass a folio around instead of a page. Saves a few hidden calls to
compound_head() and removes a call to kmap_atomic().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 63 ++++++++++++++++++++++++-------------------------
1 file changed, 31 insertions(+), 32 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index db72b3e924b3..5f7a33335385 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -731,22 +731,22 @@ struct ocfs2_write_ctxt {
/*
* Pages involved in this write.
*
- * w_target_page is the page being written to by the user.
+ * w_target_folio is the folio being written to by the user.
*
* w_pages is an array of pages which always contains
- * w_target_page, and in the case of an allocating write with
+ * w_target_folio, and in the case of an allocating write with
* page_size < cluster size, it will contain zero'd and mapped
- * pages adjacent to w_target_page which need to be written
+ * pages adjacent to w_target_folio which need to be written
* out in so that future reads from that region will get
* zero's.
*/
unsigned int w_num_pages;
struct page *w_pages[OCFS2_MAX_CTXT_PAGES];
- struct page *w_target_page;
+ struct folio *w_target_folio;
/*
* w_target_locked is used for page_mkwrite path indicating no unlocking
- * against w_target_page in ocfs2_write_end_nolock.
+ * against w_target_folio in ocfs2_write_end_nolock.
*/
unsigned int w_target_locked:1;
@@ -791,18 +791,18 @@ static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
/*
* w_target_locked is only set to true in the page_mkwrite() case.
* The intent is to allow us to lock the target page from write_begin()
- * to write_end(). The caller must hold a ref on w_target_page.
+ * to write_end(). The caller must hold a ref on w_target_folio.
*/
if (wc->w_target_locked) {
- BUG_ON(!wc->w_target_page);
+ BUG_ON(!wc->w_target_folio);
for (i = 0; i < wc->w_num_pages; i++) {
- if (wc->w_target_page == wc->w_pages[i]) {
+ if (&wc->w_target_folio->page == wc->w_pages[i]) {
wc->w_pages[i] = NULL;
break;
}
}
- mark_page_accessed(wc->w_target_page);
- put_page(wc->w_target_page);
+ folio_mark_accessed(wc->w_target_folio);
+ folio_put(wc->w_target_folio);
}
ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
}
@@ -869,8 +869,9 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
* and dirty so they'll be written out (in order to prevent uninitialised
* block data from leaking). And clear the new bit.
*/
-static void ocfs2_zero_new_buffers(struct page *page, unsigned from, unsigned to)
+static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
{
+ struct page *page = &folio->page;
unsigned int block_start, block_end;
struct buffer_head *head, *bh;
@@ -918,8 +919,8 @@ static void ocfs2_write_failure(struct inode *inode,
to = user_pos + user_len;
struct page *tmppage;
- if (wc->w_target_page)
- ocfs2_zero_new_buffers(wc->w_target_page, from, to);
+ if (wc->w_target_folio)
+ ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
for(i = 0; i < wc->w_num_pages; i++) {
tmppage = wc->w_pages[i];
@@ -954,7 +955,7 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
new = new | ((i_size_read(inode) <= page_offset(page)) &&
(page_offset(page) <= user_pos));
- if (page == wc->w_target_page) {
+ if (page == &wc->w_target_folio->page) {
map_from = user_pos & (PAGE_SIZE - 1);
map_to = map_from + user_len;
@@ -1097,7 +1098,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
wait_for_stable_page(wc->w_pages[i]);
if (index == target_index)
- wc->w_target_page = wc->w_pages[i];
+ wc->w_target_folio = page_folio(wc->w_pages[i]);
}
out:
if (ret)
@@ -1494,7 +1495,8 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
* If we don't set w_num_pages then this page won't get unlocked
* and freed on cleanup of the write context.
*/
- wc->w_pages[0] = wc->w_target_page = page;
+ wc->w_target_folio = page_folio(page);
+ wc->w_pages[0] = page;
wc->w_num_pages = 1;
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
@@ -1803,7 +1805,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
* the operation.
*/
if (type == OCFS2_WRITE_MMAP && ret == -EAGAIN) {
- BUG_ON(wc->w_target_page);
+ BUG_ON(wc->w_target_folio);
ret = 0;
goto out_quota;
}
@@ -1826,7 +1828,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
success:
if (foliop)
- *foliop = page_folio(wc->w_target_page);
+ *foliop = wc->w_target_folio;
*fsdata = wc;
return 0;
out_quota:
@@ -1924,18 +1926,15 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
struct ocfs2_dinode *di,
struct ocfs2_write_ctxt *wc)
{
- void *kaddr;
-
if (unlikely(*copied < len)) {
- if (!PageUptodate(wc->w_target_page)) {
+ if (!folio_test_uptodate(wc->w_target_folio)) {
*copied = 0;
return;
}
}
- kaddr = kmap_atomic(wc->w_target_page);
- memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied);
- kunmap_atomic(kaddr);
+ memcpy_from_folio(di->id2.i_data.id_data + pos, wc->w_target_folio,
+ pos, *copied);
trace_ocfs2_write_end_inline(
(unsigned long long)OCFS2_I(inode)->ip_blkno,
@@ -1973,15 +1972,15 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
goto out_write_size;
}
- if (unlikely(copied < len) && wc->w_target_page) {
+ if (unlikely(copied < len) && wc->w_target_folio) {
loff_t new_isize;
- if (!PageUptodate(wc->w_target_page))
+ if (!folio_test_uptodate(wc->w_target_folio))
copied = 0;
new_isize = max_t(loff_t, i_size_read(inode), pos + copied);
- if (new_isize > page_offset(wc->w_target_page))
- ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
+ if (new_isize > folio_pos(wc->w_target_folio))
+ ocfs2_zero_new_buffers(wc->w_target_folio, start+copied,
start+len);
else {
/*
@@ -1991,12 +1990,12 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
* put page & buffer dirty bits into inconsistent
* state.
*/
- block_invalidate_folio(page_folio(wc->w_target_page),
+ block_invalidate_folio(wc->w_target_folio,
0, PAGE_SIZE);
}
}
- if (wc->w_target_page)
- flush_dcache_page(wc->w_target_page);
+ if (wc->w_target_folio)
+ flush_dcache_folio(wc->w_target_folio);
for(i = 0; i < wc->w_num_pages; i++) {
tmppage = wc->w_pages[i];
@@ -2005,7 +2004,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
if (tmppage == NULL)
continue;
- if (tmppage == wc->w_target_page) {
+ if (tmppage == &wc->w_target_folio->page) {
from = wc->w_target_from;
to = wc->w_target_to;
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 03/23] ocfs2: Convert w_target_page to w_target_folio
2024-12-05 17:16 ` [PATCH 03/23] ocfs2: Convert w_target_page to w_target_folio Matthew Wilcox (Oracle)
@ 2024-12-14 12:29 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 12:29 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Pass a folio around instead of a page. Saves a few hidden calls to
> compound_head() and removes a call to kmap_atomic().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 63 ++++++++++++++++++++++++-------------------------
> 1 file changed, 31 insertions(+), 32 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index db72b3e924b3..5f7a33335385 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -731,22 +731,22 @@ struct ocfs2_write_ctxt {
> /*
> * Pages involved in this write.
> *
> - * w_target_page is the page being written to by the user.
> + * w_target_folio is the folio being written to by the user.
> *
> * w_pages is an array of pages which always contains
> - * w_target_page, and in the case of an allocating write with
> + * w_target_folio, and in the case of an allocating write with
> * page_size < cluster size, it will contain zero'd and mapped
> - * pages adjacent to w_target_page which need to be written
> + * pages adjacent to w_target_folio which need to be written
> * out in so that future reads from that region will get
> * zero's.
> */
> unsigned int w_num_pages;
> struct page *w_pages[OCFS2_MAX_CTXT_PAGES];
> - struct page *w_target_page;
> + struct folio *w_target_folio;
>
> /*
> * w_target_locked is used for page_mkwrite path indicating no unlocking
> - * against w_target_page in ocfs2_write_end_nolock.
> + * against w_target_folio in ocfs2_write_end_nolock.
> */
> unsigned int w_target_locked:1;
>
> @@ -791,18 +791,18 @@ static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
> /*
> * w_target_locked is only set to true in the page_mkwrite() case.
> * The intent is to allow us to lock the target page from write_begin()
> - * to write_end(). The caller must hold a ref on w_target_page.
> + * to write_end(). The caller must hold a ref on w_target_folio.
> */
> if (wc->w_target_locked) {
> - BUG_ON(!wc->w_target_page);
> + BUG_ON(!wc->w_target_folio);
> for (i = 0; i < wc->w_num_pages; i++) {
> - if (wc->w_target_page == wc->w_pages[i]) {
> + if (&wc->w_target_folio->page == wc->w_pages[i]) {
> wc->w_pages[i] = NULL;
> break;
> }
> }
> - mark_page_accessed(wc->w_target_page);
> - put_page(wc->w_target_page);
> + folio_mark_accessed(wc->w_target_folio);
> + folio_put(wc->w_target_folio);
> }
> ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
> }
> @@ -869,8 +869,9 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
> * and dirty so they'll be written out (in order to prevent uninitialised
> * block data from leaking). And clear the new bit.
> */
> -static void ocfs2_zero_new_buffers(struct page *page, unsigned from, unsigned to)
> +static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
> {
> + struct page *page = &folio->page;
> unsigned int block_start, block_end;
> struct buffer_head *head, *bh;
>
> @@ -918,8 +919,8 @@ static void ocfs2_write_failure(struct inode *inode,
> to = user_pos + user_len;
> struct page *tmppage;
>
> - if (wc->w_target_page)
> - ocfs2_zero_new_buffers(wc->w_target_page, from, to);
> + if (wc->w_target_folio)
> + ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
>
> for(i = 0; i < wc->w_num_pages; i++) {
> tmppage = wc->w_pages[i];
> @@ -954,7 +955,7 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
> new = new | ((i_size_read(inode) <= page_offset(page)) &&
> (page_offset(page) <= user_pos));
>
> - if (page == wc->w_target_page) {
> + if (page == &wc->w_target_folio->page) {
> map_from = user_pos & (PAGE_SIZE - 1);
> map_to = map_from + user_len;
>
> @@ -1097,7 +1098,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> wait_for_stable_page(wc->w_pages[i]);
>
> if (index == target_index)
> - wc->w_target_page = wc->w_pages[i];
> + wc->w_target_folio = page_folio(wc->w_pages[i]);
> }
> out:
> if (ret)
> @@ -1494,7 +1495,8 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> * If we don't set w_num_pages then this page won't get unlocked
> * and freed on cleanup of the write context.
> */
> - wc->w_pages[0] = wc->w_target_page = page;
> + wc->w_target_folio = page_folio(page);
> + wc->w_pages[0] = page;
> wc->w_num_pages = 1;
>
> ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
> @@ -1803,7 +1805,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> * the operation.
> */
> if (type == OCFS2_WRITE_MMAP && ret == -EAGAIN) {
> - BUG_ON(wc->w_target_page);
> + BUG_ON(wc->w_target_folio);
> ret = 0;
> goto out_quota;
> }
> @@ -1826,7 +1828,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
>
> success:
> if (foliop)
> - *foliop = page_folio(wc->w_target_page);
> + *foliop = wc->w_target_folio;
> *fsdata = wc;
> return 0;
> out_quota:
> @@ -1924,18 +1926,15 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
> struct ocfs2_dinode *di,
> struct ocfs2_write_ctxt *wc)
> {
> - void *kaddr;
> -
> if (unlikely(*copied < len)) {
> - if (!PageUptodate(wc->w_target_page)) {
> + if (!folio_test_uptodate(wc->w_target_folio)) {
> *copied = 0;
> return;
> }
> }
>
> - kaddr = kmap_atomic(wc->w_target_page);
> - memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied);
> - kunmap_atomic(kaddr);
> + memcpy_from_folio(di->id2.i_data.id_data + pos, wc->w_target_folio,
> + pos, *copied);
>
> trace_ocfs2_write_end_inline(
> (unsigned long long)OCFS2_I(inode)->ip_blkno,
> @@ -1973,15 +1972,15 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> goto out_write_size;
> }
>
> - if (unlikely(copied < len) && wc->w_target_page) {
> + if (unlikely(copied < len) && wc->w_target_folio) {
> loff_t new_isize;
>
> - if (!PageUptodate(wc->w_target_page))
> + if (!folio_test_uptodate(wc->w_target_folio))
> copied = 0;
>
> new_isize = max_t(loff_t, i_size_read(inode), pos + copied);
> - if (new_isize > page_offset(wc->w_target_page))
> - ocfs2_zero_new_buffers(wc->w_target_page, start+copied,
> + if (new_isize > folio_pos(wc->w_target_folio))
> + ocfs2_zero_new_buffers(wc->w_target_folio, start+copied,
> start+len);
> else {
> /*
> @@ -1991,12 +1990,12 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> * put page & buffer dirty bits into inconsistent
> * state.
> */
> - block_invalidate_folio(page_folio(wc->w_target_page),
> + block_invalidate_folio(wc->w_target_folio,
> 0, PAGE_SIZE);
> }
> }
> - if (wc->w_target_page)
> - flush_dcache_page(wc->w_target_page);
> + if (wc->w_target_folio)
> + flush_dcache_folio(wc->w_target_folio);
>
> for(i = 0; i < wc->w_num_pages; i++) {
> tmppage = wc->w_pages[i];
> @@ -2005,7 +2004,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> if (tmppage == NULL)
> continue;
>
> - if (tmppage == wc->w_target_page) {
> + if (tmppage == &wc->w_target_folio->page) {
> from = wc->w_target_from;
> to = wc->w_target_to;
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (2 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 03/23] ocfs2: Convert w_target_page to w_target_folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:01 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 05/23] ocfs2: Use a folio in ocfs2_write_begin_inline() Matthew Wilcox (Oracle)
` (18 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Convert to the new APIs, saving at least one hidden call to
compound_head().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 5f7a33335385..a1fad246765a 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -869,30 +869,30 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
* and dirty so they'll be written out (in order to prevent uninitialised
* block data from leaking). And clear the new bit.
*/
-static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
+static void ocfs2_zero_new_buffers(struct folio *folio, size_t from, size_t to)
{
- struct page *page = &folio->page;
unsigned int block_start, block_end;
struct buffer_head *head, *bh;
- BUG_ON(!PageLocked(page));
- if (!page_has_buffers(page))
+ BUG_ON(!folio_test_locked(folio));
+ head = folio_buffers(folio);
+ if (!head)
return;
- bh = head = page_buffers(page);
+ bh = head;
block_start = 0;
do {
block_end = block_start + bh->b_size;
if (buffer_new(bh)) {
if (block_end > from && block_start < to) {
- if (!PageUptodate(page)) {
+ if (!folio_test_uptodate(folio)) {
unsigned start, end;
start = max(from, block_start);
end = min(to, block_end);
- zero_user_segment(page, start, end);
+ folio_zero_segment(folio, start, end);
set_buffer_uptodate(bh);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers()
2024-12-05 17:16 ` [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers() Matthew Wilcox (Oracle)
@ 2024-12-14 14:01 ` Joseph Qi
2024-12-14 15:32 ` Matthew Wilcox
0 siblings, 1 reply; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:01 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Convert to the new APIs, saving at least one hidden call to
> compound_head().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/ocfs2/aops.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 5f7a33335385..a1fad246765a 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -869,30 +869,30 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
> * and dirty so they'll be written out (in order to prevent uninitialised
> * block data from leaking). And clear the new bit.
> */
> -static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
> +static void ocfs2_zero_new_buffers(struct folio *folio, size_t from, size_t to)
Don't see why we have to change 'unsigned' to 'size_t'.
Thanks,
Joseph
> {
> - struct page *page = &folio->page;
> unsigned int block_start, block_end;
> struct buffer_head *head, *bh;
>
> - BUG_ON(!PageLocked(page));
> - if (!page_has_buffers(page))
> + BUG_ON(!folio_test_locked(folio));
> + head = folio_buffers(folio);
> + if (!head)
> return;
>
> - bh = head = page_buffers(page);
> + bh = head;
> block_start = 0;
> do {
> block_end = block_start + bh->b_size;
>
> if (buffer_new(bh)) {
> if (block_end > from && block_start < to) {
> - if (!PageUptodate(page)) {
> + if (!folio_test_uptodate(folio)) {
> unsigned start, end;
>
> start = max(from, block_start);
> end = min(to, block_end);
>
> - zero_user_segment(page, start, end);
> + folio_zero_segment(folio, start, end);
> set_buffer_uptodate(bh);
> }
>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers()
2024-12-14 14:01 ` Joseph Qi
@ 2024-12-14 15:32 ` Matthew Wilcox
2024-12-14 15:46 ` Joseph Qi
0 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox @ 2024-12-14 15:32 UTC (permalink / raw)
To: Joseph Qi; +Cc: akpm, Mark Tinguely, ocfs2-devel
On Sat, Dec 14, 2024 at 10:01:20PM +0800, Joseph Qi wrote:
> > -static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
> > +static void ocfs2_zero_new_buffers(struct folio *folio, size_t from, size_t to)
>
> Don't see why we have to change 'unsigned' to 'size_t'.
This is just part of the folio conversion process. Three reasons:
1. size_t is an indication to the human reader that this is a count of the
number of bytes in memory, as opposed to anything else that an 'unsigned
int' might be.
2. Prepares us for folios which are larger than 2GB in size. Yes, not
likely to be something that ocfs2 ever supports, but on arm64 with a
16KiB page size, hugetlbfs at the PUD level has folios which are 64GB in
size. So we need to use size_t within the mm & vfs, and we should
continue that into filesystems.
3. It's actually more efficient. The CPU has to insert a lot of
zero-extend instructions when calling core code which is using size_t.
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers()
2024-12-14 15:32 ` Matthew Wilcox
@ 2024-12-14 15:46 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 15:46 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: akpm, Mark Tinguely, ocfs2-devel
On 2024/12/14 23:32, Matthew Wilcox wrote:
> On Sat, Dec 14, 2024 at 10:01:20PM +0800, Joseph Qi wrote:
>>> -static void ocfs2_zero_new_buffers(struct folio *folio, unsigned from, unsigned to)
>>> +static void ocfs2_zero_new_buffers(struct folio *folio, size_t from, size_t to)
>>
>> Don't see why we have to change 'unsigned' to 'size_t'.
>
> This is just part of the folio conversion process. Three reasons:
>
> 1. size_t is an indication to the human reader that this is a count of the
> number of bytes in memory, as opposed to anything else that an 'unsigned
> int' might be.
>
> 2. Prepares us for folios which are larger than 2GB in size. Yes, not
> likely to be something that ocfs2 ever supports, but on arm64 with a
> 16KiB page size, hugetlbfs at the PUD level has folios which are 64GB in
> size. So we need to use size_t within the mm & vfs, and we should
> continue that into filesystems.
>
> 3. It's actually more efficient. The CPU has to insert a lot of
> zero-extend instructions when calling core code which is using size_t.
Thanks for the explanation.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 05/23] ocfs2: Use a folio in ocfs2_write_begin_inline()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (3 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 04/23] ocfs2: Use a folio in ocfs2_zero_new_buffers() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:04 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 06/23] ocfs2: Pass mmap_folio around instead of mmap_page Matthew Wilcox (Oracle)
` (17 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Retrieve a folio from the page cache instead of a page and use that
folio throught the function. Saves a couple of calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index a1fad246765a..c5e9c3462b84 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1473,7 +1473,7 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
{
int ret;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- struct page *page;
+ struct folio *folio;
handle_t *handle;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
@@ -1484,19 +1484,20 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
goto out;
}
- page = find_or_create_page(mapping, 0, GFP_NOFS);
- if (!page) {
+ folio = __filemap_get_folio(mapping, 0,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
+ if (IS_ERR(folio)) {
ocfs2_commit_trans(osb, handle);
- ret = -ENOMEM;
+ ret = PTR_ERR(folio);
mlog_errno(ret);
goto out;
}
/*
- * If we don't set w_num_pages then this page won't get unlocked
+ * If we don't set w_num_pages then this folio won't get unlocked
* and freed on cleanup of the write context.
*/
- wc->w_target_folio = page_folio(page);
- wc->w_pages[0] = page;
+ wc->w_target_folio = folio;
+ wc->w_pages[0] = &folio->page;
wc->w_num_pages = 1;
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
@@ -1511,8 +1512,8 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL))
ocfs2_set_inode_data_inline(inode, di);
- if (!PageUptodate(page)) {
- ret = ocfs2_read_inline_data(inode, page, wc->w_di_bh);
+ if (!folio_test_uptodate(folio)) {
+ ret = ocfs2_read_inline_data(inode, &folio->page, wc->w_di_bh);
if (ret) {
ocfs2_commit_trans(osb, handle);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 05/23] ocfs2: Use a folio in ocfs2_write_begin_inline()
2024-12-05 17:16 ` [PATCH 05/23] ocfs2: Use a folio in ocfs2_write_begin_inline() Matthew Wilcox (Oracle)
@ 2024-12-14 14:04 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:04 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Retrieve a folio from the page cache instead of a page and use that
> folio throught the function. Saves a couple of calls to compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Missing Mark's SOB.
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index a1fad246765a..c5e9c3462b84 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -1473,7 +1473,7 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> {
> int ret;
> struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
> - struct page *page;
> + struct folio *folio;
> handle_t *handle;
> struct ocfs2_dinode *di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
>
> @@ -1484,19 +1484,20 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> goto out;
> }
>
> - page = find_or_create_page(mapping, 0, GFP_NOFS);
> - if (!page) {
> + folio = __filemap_get_folio(mapping, 0,
> + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
> + if (IS_ERR(folio)) {
> ocfs2_commit_trans(osb, handle);
> - ret = -ENOMEM;
> + ret = PTR_ERR(folio);
> mlog_errno(ret);
> goto out;
> }
> /*
> - * If we don't set w_num_pages then this page won't get unlocked
> + * If we don't set w_num_pages then this folio won't get unlocked
> * and freed on cleanup of the write context.
> */
> - wc->w_target_folio = page_folio(page);
> - wc->w_pages[0] = page;
> + wc->w_target_folio = folio;
> + wc->w_pages[0] = &folio->page;
> wc->w_num_pages = 1;
>
> ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
> @@ -1511,8 +1512,8 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL))
> ocfs2_set_inode_data_inline(inode, di);
>
> - if (!PageUptodate(page)) {
> - ret = ocfs2_read_inline_data(inode, page, wc->w_di_bh);
> + if (!folio_test_uptodate(folio)) {
> + ret = ocfs2_read_inline_data(inode, &folio->page, wc->w_di_bh);
> if (ret) {
> ocfs2_commit_trans(osb, handle);
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 06/23] ocfs2: Pass mmap_folio around instead of mmap_page
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (4 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 05/23] ocfs2: Use a folio in ocfs2_write_begin_inline() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:08 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 07/23] ocfs2: Convert ocfs2_readpage_inline() to take a folio Matthew Wilcox (Oracle)
` (16 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely
Saves a few hidden calls to compound_head() and accesses to
page->mapping.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 37 ++++++++++++++++++-------------------
fs/ocfs2/aops.h | 6 +++---
fs/ocfs2/mmap.c | 2 +-
3 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index c5e9c3462b84..aac644a0d25d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1023,7 +1023,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
struct ocfs2_write_ctxt *wc,
u32 cpos, loff_t user_pos,
unsigned user_len, int new,
- struct page *mmap_page)
+ struct folio *mmap_folio)
{
int ret = 0, i;
unsigned long start, target_index, end_index, index;
@@ -1068,18 +1068,18 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
* and wants us to directly use the page
* passed in.
*/
- lock_page(mmap_page);
+ folio_lock(mmap_folio);
/* Exit and let the caller retry */
- if (mmap_page->mapping != mapping) {
- WARN_ON(mmap_page->mapping);
- unlock_page(mmap_page);
+ if (mmap_folio->mapping != mapping) {
+ WARN_ON(mmap_folio->mapping);
+ folio_unlock(mmap_folio);
ret = -EAGAIN;
goto out;
}
- get_page(mmap_page);
- wc->w_pages[i] = mmap_page;
+ folio_get(mmap_folio);
+ wc->w_pages[i] = &mmap_folio->page;
wc->w_target_locked = true;
} else if (index >= target_index && index <= end_index &&
wc->w_type == OCFS2_WRITE_DIRECT) {
@@ -1536,9 +1536,8 @@ int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size)
}
static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
- struct inode *inode, loff_t pos,
- unsigned len, struct page *mmap_page,
- struct ocfs2_write_ctxt *wc)
+ struct inode *inode, loff_t pos, size_t len,
+ struct folio *mmap_folio, struct ocfs2_write_ctxt *wc)
{
int ret, written = 0;
loff_t end = pos + len;
@@ -1553,7 +1552,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
* Handle inodes which already have inline data 1st.
*/
if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
- if (mmap_page == NULL &&
+ if (mmap_folio == NULL &&
ocfs2_size_fits_inline_data(wc->w_di_bh, end))
goto do_inline_write;
@@ -1577,7 +1576,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
* Check whether the write can fit.
*/
di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
- if (mmap_page ||
+ if (mmap_folio ||
end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di))
return 0;
@@ -1644,9 +1643,9 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
}
int ocfs2_write_begin_nolock(struct address_space *mapping,
- loff_t pos, unsigned len, ocfs2_write_type_t type,
- struct folio **foliop, void **fsdata,
- struct buffer_head *di_bh, struct page *mmap_page)
+ loff_t pos, unsigned len, ocfs2_write_type_t type,
+ struct folio **foliop, void **fsdata,
+ struct buffer_head *di_bh, struct folio *mmap_folio)
{
int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0;
@@ -1669,7 +1668,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
if (ocfs2_supports_inline_data(osb)) {
ret = ocfs2_try_to_write_inline_data(mapping, inode, pos, len,
- mmap_page, wc);
+ mmap_folio, wc);
if (ret == 1) {
ret = 0;
goto success;
@@ -1721,7 +1720,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
(unsigned long long)OCFS2_I(inode)->ip_blkno,
(long long)i_size_read(inode),
le32_to_cpu(di->i_clusters),
- pos, len, type, mmap_page,
+ pos, len, type, mmap_folio,
clusters_to_alloc, extents_to_split);
/*
@@ -1797,7 +1796,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
* extent.
*/
ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
- cluster_of_pages, mmap_page);
+ cluster_of_pages, mmap_folio);
if (ret) {
/*
* ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
@@ -1848,7 +1847,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
* to VM code.
*/
if (wc->w_target_locked)
- unlock_page(mmap_page);
+ folio_unlock(mmap_folio);
ocfs2_free_write_ctxt(inode, wc);
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 1d1b4b7edba0..1cb46072ad84 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -37,9 +37,9 @@ typedef enum {
} ocfs2_write_type_t;
int ocfs2_write_begin_nolock(struct address_space *mapping,
- loff_t pos, unsigned len, ocfs2_write_type_t type,
- struct folio **foliop, void **fsdata,
- struct buffer_head *di_bh, struct page *mmap_page);
+ loff_t pos, unsigned len, ocfs2_write_type_t type,
+ struct folio **foliop, void **fsdata,
+ struct buffer_head *di_bh, struct folio *mmap_folio);
int ocfs2_read_inline_data(struct inode *inode, struct page *page,
struct buffer_head *di_bh);
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 93b886f16c40..6a314e9f2b49 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -91,7 +91,7 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
len = ((size - 1) & ~PAGE_MASK) + 1;
err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
- &locked_folio, &fsdata, di_bh, &folio->page);
+ &locked_folio, &fsdata, di_bh, folio);
if (err) {
if (err != -ENOSPC)
mlog_errno(err);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 06/23] ocfs2: Pass mmap_folio around instead of mmap_page
2024-12-05 17:16 ` [PATCH 06/23] ocfs2: Pass mmap_folio around instead of mmap_page Matthew Wilcox (Oracle)
@ 2024-12-14 14:08 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:08 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: ocfs2-devel, Mark Tinguely
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> Saves a few hidden calls to compound_head() and accesses to
> page->mapping.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 37 ++++++++++++++++++-------------------
> fs/ocfs2/aops.h | 6 +++---
> fs/ocfs2/mmap.c | 2 +-
> 3 files changed, 22 insertions(+), 23 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index c5e9c3462b84..aac644a0d25d 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -1023,7 +1023,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> struct ocfs2_write_ctxt *wc,
> u32 cpos, loff_t user_pos,
> unsigned user_len, int new,
> - struct page *mmap_page)
> + struct folio *mmap_folio)
> {
> int ret = 0, i;
> unsigned long start, target_index, end_index, index;
> @@ -1068,18 +1068,18 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> * and wants us to directly use the page
> * passed in.
> */
> - lock_page(mmap_page);
> + folio_lock(mmap_folio);
>
> /* Exit and let the caller retry */
> - if (mmap_page->mapping != mapping) {
> - WARN_ON(mmap_page->mapping);
> - unlock_page(mmap_page);
> + if (mmap_folio->mapping != mapping) {
> + WARN_ON(mmap_folio->mapping);
> + folio_unlock(mmap_folio);
> ret = -EAGAIN;
> goto out;
> }
>
> - get_page(mmap_page);
> - wc->w_pages[i] = mmap_page;
> + folio_get(mmap_folio);
> + wc->w_pages[i] = &mmap_folio->page;
> wc->w_target_locked = true;
> } else if (index >= target_index && index <= end_index &&
> wc->w_type == OCFS2_WRITE_DIRECT) {
> @@ -1536,9 +1536,8 @@ int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size)
> }
>
> static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
> - struct inode *inode, loff_t pos,
> - unsigned len, struct page *mmap_page,
> - struct ocfs2_write_ctxt *wc)
> + struct inode *inode, loff_t pos, size_t len,
> + struct folio *mmap_folio, struct ocfs2_write_ctxt *wc)
> {
> int ret, written = 0;
> loff_t end = pos + len;
> @@ -1553,7 +1552,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
> * Handle inodes which already have inline data 1st.
> */
> if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
> - if (mmap_page == NULL &&
> + if (mmap_folio == NULL &&
> ocfs2_size_fits_inline_data(wc->w_di_bh, end))
> goto do_inline_write;
>
> @@ -1577,7 +1576,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
> * Check whether the write can fit.
> */
> di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
> - if (mmap_page ||
> + if (mmap_folio ||
> end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di))
> return 0;
>
> @@ -1644,9 +1643,9 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
> }
>
> int ocfs2_write_begin_nolock(struct address_space *mapping,
> - loff_t pos, unsigned len, ocfs2_write_type_t type,
> - struct folio **foliop, void **fsdata,
> - struct buffer_head *di_bh, struct page *mmap_page)
> + loff_t pos, unsigned len, ocfs2_write_type_t type,
> + struct folio **foliop, void **fsdata,
> + struct buffer_head *di_bh, struct folio *mmap_folio)
> {
> int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
> unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0;
> @@ -1669,7 +1668,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
>
> if (ocfs2_supports_inline_data(osb)) {
> ret = ocfs2_try_to_write_inline_data(mapping, inode, pos, len,
> - mmap_page, wc);
> + mmap_folio, wc);
> if (ret == 1) {
> ret = 0;
> goto success;
> @@ -1721,7 +1720,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> (unsigned long long)OCFS2_I(inode)->ip_blkno,
> (long long)i_size_read(inode),
> le32_to_cpu(di->i_clusters),
> - pos, len, type, mmap_page,
> + pos, len, type, mmap_folio,
> clusters_to_alloc, extents_to_split);
>
> /*
> @@ -1797,7 +1796,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> * extent.
> */
> ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
> - cluster_of_pages, mmap_page);
> + cluster_of_pages, mmap_folio);
> if (ret) {
> /*
> * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
> @@ -1848,7 +1847,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> * to VM code.
> */
> if (wc->w_target_locked)
> - unlock_page(mmap_page);
> + folio_unlock(mmap_folio);
>
> ocfs2_free_write_ctxt(inode, wc);
>
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index 1d1b4b7edba0..1cb46072ad84 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -37,9 +37,9 @@ typedef enum {
> } ocfs2_write_type_t;
>
> int ocfs2_write_begin_nolock(struct address_space *mapping,
> - loff_t pos, unsigned len, ocfs2_write_type_t type,
> - struct folio **foliop, void **fsdata,
> - struct buffer_head *di_bh, struct page *mmap_page);
> + loff_t pos, unsigned len, ocfs2_write_type_t type,
> + struct folio **foliop, void **fsdata,
> + struct buffer_head *di_bh, struct folio *mmap_folio);
>
> int ocfs2_read_inline_data(struct inode *inode, struct page *page,
> struct buffer_head *di_bh);
> diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
> index 93b886f16c40..6a314e9f2b49 100644
> --- a/fs/ocfs2/mmap.c
> +++ b/fs/ocfs2/mmap.c
> @@ -91,7 +91,7 @@ static vm_fault_t __ocfs2_page_mkwrite(struct file *file,
> len = ((size - 1) & ~PAGE_MASK) + 1;
>
> err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
> - &locked_folio, &fsdata, di_bh, &folio->page);
> + &locked_folio, &fsdata, di_bh, folio);
> if (err) {
> if (err != -ENOSPC)
> mlog_errno(err);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 07/23] ocfs2: Convert ocfs2_readpage_inline() to take a folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (5 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 06/23] ocfs2: Pass mmap_folio around instead of mmap_page Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:08 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 08/23] ocfs2: Convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio() Matthew Wilcox (Oracle)
` (15 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Save a couple of calls to compound_head() by using a folio throughout
this function.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index aac644a0d25d..1896a1d24173 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -252,12 +252,12 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
return 0;
}
-static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
+static int ocfs2_readpage_inline(struct inode *inode, struct folio *folio)
{
int ret;
struct buffer_head *di_bh = NULL;
- BUG_ON(!PageLocked(page));
+ BUG_ON(!folio_test_locked(folio));
BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
ret = ocfs2_read_inode_block(inode, &di_bh);
@@ -266,9 +266,9 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
goto out;
}
- ret = ocfs2_read_inline_data(inode, page, di_bh);
+ ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
out:
- unlock_page(page);
+ folio_unlock(folio);
brelse(di_bh);
return ret;
@@ -322,7 +322,7 @@ static int ocfs2_read_folio(struct file *file, struct folio *folio)
}
if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
- ret = ocfs2_readpage_inline(inode, &folio->page);
+ ret = ocfs2_readpage_inline(inode, folio);
else
ret = block_read_full_folio(folio, ocfs2_get_block);
unlock = 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 07/23] ocfs2: Convert ocfs2_readpage_inline() to take a folio
2024-12-05 17:16 ` [PATCH 07/23] ocfs2: Convert ocfs2_readpage_inline() to take a folio Matthew Wilcox (Oracle)
@ 2024-12-14 14:08 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:08 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Save a couple of calls to compound_head() by using a folio throughout
> this function.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index aac644a0d25d..1896a1d24173 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -252,12 +252,12 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
> return 0;
> }
>
> -static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
> +static int ocfs2_readpage_inline(struct inode *inode, struct folio *folio)
> {
> int ret;
> struct buffer_head *di_bh = NULL;
>
> - BUG_ON(!PageLocked(page));
> + BUG_ON(!folio_test_locked(folio));
> BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
>
> ret = ocfs2_read_inode_block(inode, &di_bh);
> @@ -266,9 +266,9 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
> goto out;
> }
>
> - ret = ocfs2_read_inline_data(inode, page, di_bh);
> + ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
> out:
> - unlock_page(page);
> + folio_unlock(folio);
>
> brelse(di_bh);
> return ret;
> @@ -322,7 +322,7 @@ static int ocfs2_read_folio(struct file *file, struct folio *folio)
> }
>
> if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
> - ret = ocfs2_readpage_inline(inode, &folio->page);
> + ret = ocfs2_readpage_inline(inode, folio);
> else
> ret = block_read_full_folio(folio, ocfs2_get_block);
> unlock = 0;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 08/23] ocfs2: Convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (6 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 07/23] ocfs2: Convert ocfs2_readpage_inline() to take a folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:10 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 09/23] ocfs2: Convert w_pages to w_folios Matthew Wilcox (Oracle)
` (14 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Saves a hidden call to compound_head().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 2 +-
fs/ocfs2/dlmglue.c | 18 ++++++++----------
fs/ocfs2/dlmglue.h | 6 ++----
3 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 1896a1d24173..161f2dc00b00 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -283,7 +283,7 @@ static int ocfs2_read_folio(struct file *file, struct folio *folio)
trace_ocfs2_readpage((unsigned long long)oi->ip_blkno, folio->index);
- ret = ocfs2_inode_lock_with_page(inode, NULL, 0, &folio->page);
+ ret = ocfs2_inode_lock_with_folio(inode, NULL, 0, folio);
if (ret != 0) {
if (ret == AOP_TRUNCATED_PAGE)
unlock = 0;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 60df52e4c1f8..acebfa19ea6f 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2529,30 +2529,28 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
/*
* This is working around a lock inversion between tasks acquiring DLM
- * locks while holding a page lock and the downconvert thread which
- * blocks dlm lock acquiry while acquiring page locks.
+ * locks while holding a folio lock and the downconvert thread which
+ * blocks dlm lock acquiry while acquiring folio locks.
*
- * ** These _with_page variantes are only intended to be called from aop
- * methods that hold page locks and return a very specific *positive* error
+ * ** These _with_folio variantes are only intended to be called from aop
+ * methods that hold folio locks and return a very specific *positive* error
* code that aop methods pass up to the VFS -- test for errors with != 0. **
*
* The DLM is called such that it returns -EAGAIN if it would have
* blocked waiting for the downconvert thread. In that case we unlock
- * our page so the downconvert thread can make progress. Once we've
+ * our folio so the downconvert thread can make progress. Once we've
* done this we have to return AOP_TRUNCATED_PAGE so the aop method
* that called us can bubble that back up into the VFS who will then
* immediately retry the aop call.
*/
-int ocfs2_inode_lock_with_page(struct inode *inode,
- struct buffer_head **ret_bh,
- int ex,
- struct page *page)
+int ocfs2_inode_lock_with_folio(struct inode *inode,
+ struct buffer_head **ret_bh, int ex, struct folio *folio)
{
int ret;
ret = ocfs2_inode_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK);
if (ret == -EAGAIN) {
- unlock_page(page);
+ folio_unlock(folio);
/*
* If we can't get inode lock immediately, we should not return
* directly here, since this will lead to a softlockup problem.
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index e5da5809ed95..a3ebd7303ea2 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -137,10 +137,8 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
int ex,
int arg_flags,
int subclass);
-int ocfs2_inode_lock_with_page(struct inode *inode,
- struct buffer_head **ret_bh,
- int ex,
- struct page *page);
+int ocfs2_inode_lock_with_folio(struct inode *inode,
+ struct buffer_head **ret_bh, int ex, struct folio *folio);
/* Variants without special locking class or flags */
#define ocfs2_inode_lock_full(i, r, e, f)\
ocfs2_inode_lock_full_nested(i, r, e, f, OI_LS_NORMAL)
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 08/23] ocfs2: Convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio()
2024-12-05 17:16 ` [PATCH 08/23] ocfs2: Convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio() Matthew Wilcox (Oracle)
@ 2024-12-14 14:10 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:10 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Saves a hidden call to compound_head().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 2 +-
> fs/ocfs2/dlmglue.c | 18 ++++++++----------
> fs/ocfs2/dlmglue.h | 6 ++----
> 3 files changed, 11 insertions(+), 15 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 1896a1d24173..161f2dc00b00 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -283,7 +283,7 @@ static int ocfs2_read_folio(struct file *file, struct folio *folio)
>
> trace_ocfs2_readpage((unsigned long long)oi->ip_blkno, folio->index);
>
> - ret = ocfs2_inode_lock_with_page(inode, NULL, 0, &folio->page);
> + ret = ocfs2_inode_lock_with_folio(inode, NULL, 0, folio);
> if (ret != 0) {
> if (ret == AOP_TRUNCATED_PAGE)
> unlock = 0;
> diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
> index 60df52e4c1f8..acebfa19ea6f 100644
> --- a/fs/ocfs2/dlmglue.c
> +++ b/fs/ocfs2/dlmglue.c
> @@ -2529,30 +2529,28 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
>
> /*
> * This is working around a lock inversion between tasks acquiring DLM
> - * locks while holding a page lock and the downconvert thread which
> - * blocks dlm lock acquiry while acquiring page locks.
> + * locks while holding a folio lock and the downconvert thread which
> + * blocks dlm lock acquiry while acquiring folio locks.
> *
> - * ** These _with_page variantes are only intended to be called from aop
> - * methods that hold page locks and return a very specific *positive* error
> + * ** These _with_folio variantes are only intended to be called from aop
> + * methods that hold folio locks and return a very specific *positive* error
> * code that aop methods pass up to the VFS -- test for errors with != 0. **
> *
> * The DLM is called such that it returns -EAGAIN if it would have
> * blocked waiting for the downconvert thread. In that case we unlock
> - * our page so the downconvert thread can make progress. Once we've
> + * our folio so the downconvert thread can make progress. Once we've
> * done this we have to return AOP_TRUNCATED_PAGE so the aop method
> * that called us can bubble that back up into the VFS who will then
> * immediately retry the aop call.
> */
> -int ocfs2_inode_lock_with_page(struct inode *inode,
> - struct buffer_head **ret_bh,
> - int ex,
> - struct page *page)
> +int ocfs2_inode_lock_with_folio(struct inode *inode,
> + struct buffer_head **ret_bh, int ex, struct folio *folio)
> {
> int ret;
>
> ret = ocfs2_inode_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK);
> if (ret == -EAGAIN) {
> - unlock_page(page);
> + folio_unlock(folio);
> /*
> * If we can't get inode lock immediately, we should not return
> * directly here, since this will lead to a softlockup problem.
> diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
> index e5da5809ed95..a3ebd7303ea2 100644
> --- a/fs/ocfs2/dlmglue.h
> +++ b/fs/ocfs2/dlmglue.h
> @@ -137,10 +137,8 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
> int ex,
> int arg_flags,
> int subclass);
> -int ocfs2_inode_lock_with_page(struct inode *inode,
> - struct buffer_head **ret_bh,
> - int ex,
> - struct page *page);
> +int ocfs2_inode_lock_with_folio(struct inode *inode,
> + struct buffer_head **ret_bh, int ex, struct folio *folio);
> /* Variants without special locking class or flags */
> #define ocfs2_inode_lock_full(i, r, e, f)\
> ocfs2_inode_lock_full_nested(i, r, e, f, OI_LS_NORMAL)
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 09/23] ocfs2: Convert w_pages to w_folios
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (7 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 08/23] ocfs2: Convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:15 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 10/23] ocfs2: Convert ocfs2_write_failure() to use a folio Matthew Wilcox (Oracle)
` (13 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Pass around an array of folios instead of an array of pages.
Removes a few calls to compound_head().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 118 ++++++++++++++++++++++++++----------------------
fs/ocfs2/aops.h | 1 +
2 files changed, 65 insertions(+), 54 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 161f2dc00b00..afc20ab52b3e 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -729,19 +729,19 @@ struct ocfs2_write_ctxt {
unsigned int w_large_pages;
/*
- * Pages involved in this write.
+ * Folios involved in this write.
*
* w_target_folio is the folio being written to by the user.
*
- * w_pages is an array of pages which always contains
+ * w_folios is an array of folios which always contains
* w_target_folio, and in the case of an allocating write with
* page_size < cluster size, it will contain zero'd and mapped
* pages adjacent to w_target_folio which need to be written
* out in so that future reads from that region will get
* zero's.
*/
- unsigned int w_num_pages;
- struct page *w_pages[OCFS2_MAX_CTXT_PAGES];
+ unsigned int w_num_folios;
+ struct folio *w_folios[OCFS2_MAX_CTXT_PAGES];
struct folio *w_target_folio;
/*
@@ -771,6 +771,19 @@ struct ocfs2_write_ctxt {
unsigned int w_unwritten_count;
};
+void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios)
+{
+ int i;
+
+ for(i = 0; i < num_folios; i++) {
+ if (!folios[i])
+ continue;
+ folio_unlock(folios[i]);
+ folio_mark_accessed(folios[i]);
+ folio_put(folios[i]);
+ }
+}
+
void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
{
int i;
@@ -784,7 +797,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
}
}
-static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
+static void ocfs2_unlock_folios(struct ocfs2_write_ctxt *wc)
{
int i;
@@ -795,16 +808,16 @@ static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
*/
if (wc->w_target_locked) {
BUG_ON(!wc->w_target_folio);
- for (i = 0; i < wc->w_num_pages; i++) {
- if (&wc->w_target_folio->page == wc->w_pages[i]) {
- wc->w_pages[i] = NULL;
+ for (i = 0; i < wc->w_num_folios; i++) {
+ if (wc->w_target_folio == wc->w_folios[i]) {
+ wc->w_folios[i] = NULL;
break;
}
}
folio_mark_accessed(wc->w_target_folio);
folio_put(wc->w_target_folio);
}
- ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
+ ocfs2_unlock_and_free_folios(wc->w_folios, wc->w_num_folios);
}
static void ocfs2_free_unwritten_list(struct inode *inode,
@@ -826,7 +839,7 @@ static void ocfs2_free_write_ctxt(struct inode *inode,
struct ocfs2_write_ctxt *wc)
{
ocfs2_free_unwritten_list(inode, &wc->w_unwritten_list);
- ocfs2_unlock_pages(wc);
+ ocfs2_unlock_folios(wc);
brelse(wc->w_di_bh);
kfree(wc);
}
@@ -922,8 +935,8 @@ static void ocfs2_write_failure(struct inode *inode,
if (wc->w_target_folio)
ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
- for(i = 0; i < wc->w_num_pages; i++) {
- tmppage = wc->w_pages[i];
+ for (i = 0; i < wc->w_num_folios; i++) {
+ tmppage = &wc->w_folios[i]->page;
if (tmppage && page_has_buffers(tmppage)) {
if (ocfs2_should_order_data(inode))
@@ -935,12 +948,11 @@ static void ocfs2_write_failure(struct inode *inode,
}
}
-static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
- struct ocfs2_write_ctxt *wc,
- struct page *page, u32 cpos,
- loff_t user_pos, unsigned user_len,
- int new)
+static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
+ struct ocfs2_write_ctxt *wc, struct folio *folio, u32 cpos,
+ loff_t user_pos, unsigned user_len, int new)
{
+ struct page *page = &folio->page;
int ret;
unsigned int map_from = 0, map_to = 0;
unsigned int cluster_start, cluster_end;
@@ -1019,11 +1031,9 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
/*
* This function will only grab one clusters worth of pages.
*/
-static int ocfs2_grab_pages_for_write(struct address_space *mapping,
- struct ocfs2_write_ctxt *wc,
- u32 cpos, loff_t user_pos,
- unsigned user_len, int new,
- struct folio *mmap_folio)
+static int ocfs2_grab_folios_for_write(struct address_space *mapping,
+ struct ocfs2_write_ctxt *wc, u32 cpos, loff_t user_pos,
+ unsigned user_len, int new, struct folio *mmap_folio)
{
int ret = 0, i;
unsigned long start, target_index, end_index, index;
@@ -1040,7 +1050,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
* last page of the write.
*/
if (new) {
- wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb);
+ wc->w_num_folios = ocfs2_pages_per_cluster(inode->i_sb);
start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos);
/*
* We need the index *past* the last page we could possibly
@@ -1050,15 +1060,15 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
last_byte = max(user_pos + user_len, i_size_read(inode));
BUG_ON(last_byte < 1);
end_index = ((last_byte - 1) >> PAGE_SHIFT) + 1;
- if ((start + wc->w_num_pages) > end_index)
- wc->w_num_pages = end_index - start;
+ if ((start + wc->w_num_folios) > end_index)
+ wc->w_num_folios = end_index - start;
} else {
- wc->w_num_pages = 1;
+ wc->w_num_folios = 1;
start = target_index;
}
end_index = (user_pos + user_len - 1) >> PAGE_SHIFT;
- for(i = 0; i < wc->w_num_pages; i++) {
+ for(i = 0; i < wc->w_num_folios; i++) {
index = start + i;
if (index >= target_index && index <= end_index &&
@@ -1079,26 +1089,27 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
}
folio_get(mmap_folio);
- wc->w_pages[i] = &mmap_folio->page;
+ wc->w_folios[i] = mmap_folio;
wc->w_target_locked = true;
} else if (index >= target_index && index <= end_index &&
wc->w_type == OCFS2_WRITE_DIRECT) {
/* Direct write has no mapping page. */
- wc->w_pages[i] = NULL;
+ wc->w_folios[i] = NULL;
continue;
} else {
- wc->w_pages[i] = find_or_create_page(mapping, index,
- GFP_NOFS);
- if (!wc->w_pages[i]) {
- ret = -ENOMEM;
+ wc->w_folios[i] = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+ GFP_NOFS);
+ if (IS_ERR(wc->w_folios[i])) {
+ ret = PTR_ERR(wc->w_folios[i]);
mlog_errno(ret);
goto out;
}
}
- wait_for_stable_page(wc->w_pages[i]);
+ folio_wait_stable(wc->w_folios[i]);
if (index == target_index)
- wc->w_target_folio = page_folio(wc->w_pages[i]);
+ wc->w_target_folio = wc->w_folios[i];
}
out:
if (ret)
@@ -1182,19 +1193,18 @@ static int ocfs2_write_cluster(struct address_space *mapping,
if (!should_zero)
p_blkno += (user_pos >> inode->i_sb->s_blocksize_bits) & (u64)(bpc - 1);
- for(i = 0; i < wc->w_num_pages; i++) {
+ for (i = 0; i < wc->w_num_folios; i++) {
int tmpret;
/* This is the direct io target page. */
- if (wc->w_pages[i] == NULL) {
+ if (wc->w_folios[i] == NULL) {
p_blkno += (1 << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits));
continue;
}
- tmpret = ocfs2_prepare_page_for_write(inode, &p_blkno, wc,
- wc->w_pages[i], cpos,
- user_pos, user_len,
- should_zero);
+ tmpret = ocfs2_prepare_folio_for_write(inode, &p_blkno, wc,
+ wc->w_folios[i], cpos, user_pos, user_len,
+ should_zero);
if (tmpret) {
mlog_errno(tmpret);
if (ret == 0)
@@ -1493,12 +1503,12 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
goto out;
}
/*
- * If we don't set w_num_pages then this folio won't get unlocked
+ * If we don't set w_num_folios then this folio won't get unlocked
* and freed on cleanup of the write context.
*/
wc->w_target_folio = folio;
- wc->w_pages[0] = &folio->page;
- wc->w_num_pages = 1;
+ wc->w_folios[0] = folio;
+ wc->w_num_folios = 1;
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
@@ -1791,18 +1801,18 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
}
/*
- * Fill our page array first. That way we've grabbed enough so
+ * Fill our folio array first. That way we've grabbed enough so
* that we can zero and flush if we error after adding the
* extent.
*/
- ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
- cluster_of_pages, mmap_folio);
+ ret = ocfs2_grab_folios_for_write(mapping, wc, wc->w_cpos, pos, len,
+ cluster_of_pages, mmap_folio);
if (ret) {
/*
- * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
- * the target page. In this case, we exit with no error and no target
- * page. This will trigger the caller, page_mkwrite(), to re-try
- * the operation.
+ * ocfs2_grab_folios_for_write() returns -EAGAIN if it
+ * could not lock the target folio. In this case, we exit
+ * with no error and no target folio. This will trigger
+ * the caller, page_mkwrite(), to re-try the operation.
*/
if (type == OCFS2_WRITE_MMAP && ret == -EAGAIN) {
BUG_ON(wc->w_target_folio);
@@ -1997,8 +2007,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
if (wc->w_target_folio)
flush_dcache_folio(wc->w_target_folio);
- for(i = 0; i < wc->w_num_pages; i++) {
- tmppage = wc->w_pages[i];
+ for (i = 0; i < wc->w_num_folios; i++) {
+ tmppage = &wc->w_folios[i]->page;
/* This is the direct io target page. */
if (tmppage == NULL)
@@ -2059,7 +2069,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
* this lock and will ask for the page lock when flushing the data.
* put it here to preserve the unlock order.
*/
- ocfs2_unlock_pages(wc);
+ ocfs2_unlock_folios(wc);
if (handle)
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 1cb46072ad84..dcf4b0dc82c4 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -17,6 +17,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
struct inode *inode, unsigned int from,
unsigned int to, int new);
+void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios);
void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages);
int walk_page_buffers( handle_t *handle,
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 09/23] ocfs2: Convert w_pages to w_folios
2024-12-05 17:16 ` [PATCH 09/23] ocfs2: Convert w_pages to w_folios Matthew Wilcox (Oracle)
@ 2024-12-14 14:15 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:15 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Pass around an array of folios instead of an array of pages.
> Removes a few calls to compound_head().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 118 ++++++++++++++++++++++++++----------------------
> fs/ocfs2/aops.h | 1 +
> 2 files changed, 65 insertions(+), 54 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 161f2dc00b00..afc20ab52b3e 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -729,19 +729,19 @@ struct ocfs2_write_ctxt {
> unsigned int w_large_pages;
>
> /*
> - * Pages involved in this write.
> + * Folios involved in this write.
> *
> * w_target_folio is the folio being written to by the user.
> *
> - * w_pages is an array of pages which always contains
> + * w_folios is an array of folios which always contains
> * w_target_folio, and in the case of an allocating write with
> * page_size < cluster size, it will contain zero'd and mapped
> * pages adjacent to w_target_folio which need to be written
> * out in so that future reads from that region will get
> * zero's.
> */
> - unsigned int w_num_pages;
> - struct page *w_pages[OCFS2_MAX_CTXT_PAGES];
> + unsigned int w_num_folios;
> + struct folio *w_folios[OCFS2_MAX_CTXT_PAGES];
> struct folio *w_target_folio;
>
> /*
> @@ -771,6 +771,19 @@ struct ocfs2_write_ctxt {
> unsigned int w_unwritten_count;
> };
>
> +void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios)
> +{
> + int i;
> +
> + for(i = 0; i < num_folios; i++) {
> + if (!folios[i])
> + continue;
> + folio_unlock(folios[i]);
> + folio_mark_accessed(folios[i]);
> + folio_put(folios[i]);
> + }
> +}
> +
> void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
> {
> int i;
> @@ -784,7 +797,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
> }
> }
>
> -static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
> +static void ocfs2_unlock_folios(struct ocfs2_write_ctxt *wc)
> {
> int i;
>
> @@ -795,16 +808,16 @@ static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
> */
> if (wc->w_target_locked) {
> BUG_ON(!wc->w_target_folio);
> - for (i = 0; i < wc->w_num_pages; i++) {
> - if (&wc->w_target_folio->page == wc->w_pages[i]) {
> - wc->w_pages[i] = NULL;
> + for (i = 0; i < wc->w_num_folios; i++) {
> + if (wc->w_target_folio == wc->w_folios[i]) {
> + wc->w_folios[i] = NULL;
> break;
> }
> }
> folio_mark_accessed(wc->w_target_folio);
> folio_put(wc->w_target_folio);
> }
> - ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
> + ocfs2_unlock_and_free_folios(wc->w_folios, wc->w_num_folios);
> }
>
> static void ocfs2_free_unwritten_list(struct inode *inode,
> @@ -826,7 +839,7 @@ static void ocfs2_free_write_ctxt(struct inode *inode,
> struct ocfs2_write_ctxt *wc)
> {
> ocfs2_free_unwritten_list(inode, &wc->w_unwritten_list);
> - ocfs2_unlock_pages(wc);
> + ocfs2_unlock_folios(wc);
> brelse(wc->w_di_bh);
> kfree(wc);
> }
> @@ -922,8 +935,8 @@ static void ocfs2_write_failure(struct inode *inode,
> if (wc->w_target_folio)
> ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
>
> - for(i = 0; i < wc->w_num_pages; i++) {
> - tmppage = wc->w_pages[i];
> + for (i = 0; i < wc->w_num_folios; i++) {
> + tmppage = &wc->w_folios[i]->page;
>
> if (tmppage && page_has_buffers(tmppage)) {
> if (ocfs2_should_order_data(inode))
> @@ -935,12 +948,11 @@ static void ocfs2_write_failure(struct inode *inode,
> }
> }
>
> -static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
> - struct ocfs2_write_ctxt *wc,
> - struct page *page, u32 cpos,
> - loff_t user_pos, unsigned user_len,
> - int new)
> +static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> + struct ocfs2_write_ctxt *wc, struct folio *folio, u32 cpos,
> + loff_t user_pos, unsigned user_len, int new)
> {
> + struct page *page = &folio->page;
> int ret;
> unsigned int map_from = 0, map_to = 0;
> unsigned int cluster_start, cluster_end;
> @@ -1019,11 +1031,9 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
> /*
> * This function will only grab one clusters worth of pages.
> */
> -static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> - struct ocfs2_write_ctxt *wc,
> - u32 cpos, loff_t user_pos,
> - unsigned user_len, int new,
> - struct folio *mmap_folio)
> +static int ocfs2_grab_folios_for_write(struct address_space *mapping,
> + struct ocfs2_write_ctxt *wc, u32 cpos, loff_t user_pos,
> + unsigned user_len, int new, struct folio *mmap_folio)
> {
> int ret = 0, i;
> unsigned long start, target_index, end_index, index;
> @@ -1040,7 +1050,7 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> * last page of the write.
> */
> if (new) {
> - wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb);
> + wc->w_num_folios = ocfs2_pages_per_cluster(inode->i_sb);
> start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos);
> /*
> * We need the index *past* the last page we could possibly
> @@ -1050,15 +1060,15 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> last_byte = max(user_pos + user_len, i_size_read(inode));
> BUG_ON(last_byte < 1);
> end_index = ((last_byte - 1) >> PAGE_SHIFT) + 1;
> - if ((start + wc->w_num_pages) > end_index)
> - wc->w_num_pages = end_index - start;
> + if ((start + wc->w_num_folios) > end_index)
> + wc->w_num_folios = end_index - start;
> } else {
> - wc->w_num_pages = 1;
> + wc->w_num_folios = 1;
> start = target_index;
> }
> end_index = (user_pos + user_len - 1) >> PAGE_SHIFT;
>
> - for(i = 0; i < wc->w_num_pages; i++) {
> + for(i = 0; i < wc->w_num_folios; i++) {
> index = start + i;
>
> if (index >= target_index && index <= end_index &&
> @@ -1079,26 +1089,27 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
> }
>
> folio_get(mmap_folio);
> - wc->w_pages[i] = &mmap_folio->page;
> + wc->w_folios[i] = mmap_folio;
> wc->w_target_locked = true;
> } else if (index >= target_index && index <= end_index &&
> wc->w_type == OCFS2_WRITE_DIRECT) {
> /* Direct write has no mapping page. */
> - wc->w_pages[i] = NULL;
> + wc->w_folios[i] = NULL;
> continue;
> } else {
> - wc->w_pages[i] = find_or_create_page(mapping, index,
> - GFP_NOFS);
> - if (!wc->w_pages[i]) {
> - ret = -ENOMEM;
> + wc->w_folios[i] = __filemap_get_folio(mapping, index,
> + FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
> + GFP_NOFS);
> + if (IS_ERR(wc->w_folios[i])) {
> + ret = PTR_ERR(wc->w_folios[i]);
> mlog_errno(ret);
> goto out;
> }
> }
> - wait_for_stable_page(wc->w_pages[i]);
> + folio_wait_stable(wc->w_folios[i]);
>
> if (index == target_index)
> - wc->w_target_folio = page_folio(wc->w_pages[i]);
> + wc->w_target_folio = wc->w_folios[i];
> }
> out:
> if (ret)
> @@ -1182,19 +1193,18 @@ static int ocfs2_write_cluster(struct address_space *mapping,
> if (!should_zero)
> p_blkno += (user_pos >> inode->i_sb->s_blocksize_bits) & (u64)(bpc - 1);
>
> - for(i = 0; i < wc->w_num_pages; i++) {
> + for (i = 0; i < wc->w_num_folios; i++) {
> int tmpret;
>
> /* This is the direct io target page. */
> - if (wc->w_pages[i] == NULL) {
> + if (wc->w_folios[i] == NULL) {
> p_blkno += (1 << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits));
> continue;
> }
>
> - tmpret = ocfs2_prepare_page_for_write(inode, &p_blkno, wc,
> - wc->w_pages[i], cpos,
> - user_pos, user_len,
> - should_zero);
> + tmpret = ocfs2_prepare_folio_for_write(inode, &p_blkno, wc,
> + wc->w_folios[i], cpos, user_pos, user_len,
> + should_zero);
> if (tmpret) {
> mlog_errno(tmpret);
> if (ret == 0)
> @@ -1493,12 +1503,12 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> goto out;
> }
> /*
> - * If we don't set w_num_pages then this folio won't get unlocked
> + * If we don't set w_num_folios then this folio won't get unlocked
> * and freed on cleanup of the write context.
> */
> wc->w_target_folio = folio;
> - wc->w_pages[0] = &folio->page;
> - wc->w_num_pages = 1;
> + wc->w_folios[0] = folio;
> + wc->w_num_folios = 1;
>
> ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
> OCFS2_JOURNAL_ACCESS_WRITE);
> @@ -1791,18 +1801,18 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> }
>
> /*
> - * Fill our page array first. That way we've grabbed enough so
> + * Fill our folio array first. That way we've grabbed enough so
> * that we can zero and flush if we error after adding the
> * extent.
> */
> - ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
> - cluster_of_pages, mmap_folio);
> + ret = ocfs2_grab_folios_for_write(mapping, wc, wc->w_cpos, pos, len,
> + cluster_of_pages, mmap_folio);
> if (ret) {
> /*
> - * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
> - * the target page. In this case, we exit with no error and no target
> - * page. This will trigger the caller, page_mkwrite(), to re-try
> - * the operation.
> + * ocfs2_grab_folios_for_write() returns -EAGAIN if it
> + * could not lock the target folio. In this case, we exit
> + * with no error and no target folio. This will trigger
> + * the caller, page_mkwrite(), to re-try the operation.
> */
> if (type == OCFS2_WRITE_MMAP && ret == -EAGAIN) {
> BUG_ON(wc->w_target_folio);
> @@ -1997,8 +2007,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> if (wc->w_target_folio)
> flush_dcache_folio(wc->w_target_folio);
>
> - for(i = 0; i < wc->w_num_pages; i++) {
> - tmppage = wc->w_pages[i];
> + for (i = 0; i < wc->w_num_folios; i++) {
> + tmppage = &wc->w_folios[i]->page;
>
> /* This is the direct io target page. */
> if (tmppage == NULL)
> @@ -2059,7 +2069,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> * this lock and will ask for the page lock when flushing the data.
> * put it here to preserve the unlock order.
> */
> - ocfs2_unlock_pages(wc);
> + ocfs2_unlock_folios(wc);
>
> if (handle)
> ocfs2_commit_trans(osb, handle);
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index 1cb46072ad84..dcf4b0dc82c4 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -17,6 +17,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
> struct inode *inode, unsigned int from,
> unsigned int to, int new);
>
> +void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios);
> void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages);
>
> int walk_page_buffers( handle_t *handle,
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 10/23] ocfs2: Convert ocfs2_write_failure() to use a folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (8 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 09/23] ocfs2: Convert w_pages to w_folios Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:16 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 11/23] ocfs2: Use a folio in ocfs2_write_end_nolock() Matthew Wilcox (Oracle)
` (12 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Remove the folio->page conversion and just use the folio.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index afc20ab52b3e..8dda080743b7 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -930,20 +930,19 @@ static void ocfs2_write_failure(struct inode *inode,
int i;
unsigned from = user_pos & (PAGE_SIZE - 1),
to = user_pos + user_len;
- struct page *tmppage;
if (wc->w_target_folio)
ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
for (i = 0; i < wc->w_num_folios; i++) {
- tmppage = &wc->w_folios[i]->page;
+ struct folio *folio = wc->w_folios[i];
- if (tmppage && page_has_buffers(tmppage)) {
+ if (folio && folio_buffers(folio)) {
if (ocfs2_should_order_data(inode))
ocfs2_jbd2_inode_add_write(wc->w_handle, inode,
user_pos, user_len);
- block_commit_write(tmppage, from, to);
+ block_commit_write(&folio->page, from, to);
}
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 10/23] ocfs2: Convert ocfs2_write_failure() to use a folio
2024-12-05 17:16 ` [PATCH 10/23] ocfs2: Convert ocfs2_write_failure() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-14 14:16 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:16 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Remove the folio->page conversion and just use the folio.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index afc20ab52b3e..8dda080743b7 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -930,20 +930,19 @@ static void ocfs2_write_failure(struct inode *inode,
> int i;
> unsigned from = user_pos & (PAGE_SIZE - 1),
> to = user_pos + user_len;
> - struct page *tmppage;
>
> if (wc->w_target_folio)
> ocfs2_zero_new_buffers(wc->w_target_folio, from, to);
>
> for (i = 0; i < wc->w_num_folios; i++) {
> - tmppage = &wc->w_folios[i]->page;
> + struct folio *folio = wc->w_folios[i];
>
> - if (tmppage && page_has_buffers(tmppage)) {
> + if (folio && folio_buffers(folio)) {
> if (ocfs2_should_order_data(inode))
> ocfs2_jbd2_inode_add_write(wc->w_handle, inode,
> user_pos, user_len);
>
> - block_commit_write(tmppage, from, to);
> + block_commit_write(&folio->page, from, to);
> }
> }
> }
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 11/23] ocfs2: Use a folio in ocfs2_write_end_nolock()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (9 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 10/23] ocfs2: Convert ocfs2_write_failure() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:18 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 12/23] ocfs2: Use a folio in ocfs2_prepare_page_for_write() Matthew Wilcox (Oracle)
` (11 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Remove an access to page->index. Remove some PAGE_SIZE assumptions.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8dda080743b7..cc252a1170ad 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1952,17 +1952,16 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
le16_to_cpu(di->i_dyn_features));
}
-int ocfs2_write_end_nolock(struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied, void *fsdata)
+int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos,
+ unsigned len, unsigned copied, void *fsdata)
{
int i, ret;
- unsigned from, to, start = pos & (PAGE_SIZE - 1);
+ size_t from, to, start = pos & (PAGE_SIZE - 1);
struct inode *inode = mapping->host;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct ocfs2_write_ctxt *wc = fsdata;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
handle_t *handle = wc->w_handle;
- struct page *tmppage;
BUG_ON(!list_empty(&wc->w_unwritten_list));
@@ -1993,32 +1992,32 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
start+len);
else {
/*
- * When page is fully beyond new isize (data copy
- * failed), do not bother zeroing the page. Invalidate
+ * When folio is fully beyond new isize (data copy
+ * failed), do not bother zeroing the folio. Invalidate
* it instead so that writeback does not get confused
* put page & buffer dirty bits into inconsistent
* state.
*/
- block_invalidate_folio(wc->w_target_folio,
- 0, PAGE_SIZE);
+ block_invalidate_folio(wc->w_target_folio, 0,
+ folio_size(wc->w_target_folio));
}
}
if (wc->w_target_folio)
flush_dcache_folio(wc->w_target_folio);
for (i = 0; i < wc->w_num_folios; i++) {
- tmppage = &wc->w_folios[i]->page;
+ struct folio *folio = wc->w_folios[i];
- /* This is the direct io target page. */
- if (tmppage == NULL)
+ /* This is the direct io target folio */
+ if (folio == NULL)
continue;
- if (tmppage == &wc->w_target_folio->page) {
+ if (folio == wc->w_target_folio) {
from = wc->w_target_from;
to = wc->w_target_to;
- BUG_ON(from > PAGE_SIZE ||
- to > PAGE_SIZE ||
+ BUG_ON(from > folio_size(folio) ||
+ to > folio_size(folio) ||
to < from);
} else {
/*
@@ -2027,19 +2026,17 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
* to flush their entire range.
*/
from = 0;
- to = PAGE_SIZE;
+ to = folio_size(folio);
}
- if (page_has_buffers(tmppage)) {
+ if (folio_buffers(folio)) {
if (handle && ocfs2_should_order_data(inode)) {
- loff_t start_byte =
- ((loff_t)tmppage->index << PAGE_SHIFT) +
- from;
+ loff_t start_byte = folio_pos(folio) + from;
loff_t length = to - from;
ocfs2_jbd2_inode_add_write(handle, inode,
start_byte, length);
}
- block_commit_write(tmppage, from, to);
+ block_commit_write(&folio->page, from, to);
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 11/23] ocfs2: Use a folio in ocfs2_write_end_nolock()
2024-12-05 17:16 ` [PATCH 11/23] ocfs2: Use a folio in ocfs2_write_end_nolock() Matthew Wilcox (Oracle)
@ 2024-12-14 14:18 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:18 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Remove an access to page->index. Remove some PAGE_SIZE assumptions.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 37 +++++++++++++++++--------------------
> 1 file changed, 17 insertions(+), 20 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 8dda080743b7..cc252a1170ad 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -1952,17 +1952,16 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
> le16_to_cpu(di->i_dyn_features));
> }
>
> -int ocfs2_write_end_nolock(struct address_space *mapping,
> - loff_t pos, unsigned len, unsigned copied, void *fsdata)
> +int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos,
> + unsigned len, unsigned copied, void *fsdata)
> {
> int i, ret;
> - unsigned from, to, start = pos & (PAGE_SIZE - 1);
> + size_t from, to, start = pos & (PAGE_SIZE - 1);
> struct inode *inode = mapping->host;
> struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
> struct ocfs2_write_ctxt *wc = fsdata;
> struct ocfs2_dinode *di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
> handle_t *handle = wc->w_handle;
> - struct page *tmppage;
>
> BUG_ON(!list_empty(&wc->w_unwritten_list));
>
> @@ -1993,32 +1992,32 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> start+len);
> else {
> /*
> - * When page is fully beyond new isize (data copy
> - * failed), do not bother zeroing the page. Invalidate
> + * When folio is fully beyond new isize (data copy
> + * failed), do not bother zeroing the folio. Invalidate
> * it instead so that writeback does not get confused
> * put page & buffer dirty bits into inconsistent
> * state.
> */
> - block_invalidate_folio(wc->w_target_folio,
> - 0, PAGE_SIZE);
> + block_invalidate_folio(wc->w_target_folio, 0,
> + folio_size(wc->w_target_folio));
> }
> }
> if (wc->w_target_folio)
> flush_dcache_folio(wc->w_target_folio);
>
> for (i = 0; i < wc->w_num_folios; i++) {
> - tmppage = &wc->w_folios[i]->page;
> + struct folio *folio = wc->w_folios[i];
>
> - /* This is the direct io target page. */
> - if (tmppage == NULL)
> + /* This is the direct io target folio */
> + if (folio == NULL)
> continue;
>
> - if (tmppage == &wc->w_target_folio->page) {
> + if (folio == wc->w_target_folio) {
> from = wc->w_target_from;
> to = wc->w_target_to;
>
> - BUG_ON(from > PAGE_SIZE ||
> - to > PAGE_SIZE ||
> + BUG_ON(from > folio_size(folio) ||
> + to > folio_size(folio) ||
> to < from);
> } else {
> /*
> @@ -2027,19 +2026,17 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
> * to flush their entire range.
> */
> from = 0;
> - to = PAGE_SIZE;
> + to = folio_size(folio);
> }
>
> - if (page_has_buffers(tmppage)) {
> + if (folio_buffers(folio)) {
> if (handle && ocfs2_should_order_data(inode)) {
> - loff_t start_byte =
> - ((loff_t)tmppage->index << PAGE_SHIFT) +
> - from;
> + loff_t start_byte = folio_pos(folio) + from;
> loff_t length = to - from;
> ocfs2_jbd2_inode_add_write(handle, inode,
> start_byte, length);
> }
> - block_commit_write(tmppage, from, to);
> + block_commit_write(&folio->page, from, to);
> }
> }
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 12/23] ocfs2: Use a folio in ocfs2_prepare_page_for_write()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (10 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 11/23] ocfs2: Use a folio in ocfs2_write_end_nolock() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:26 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 13/23] ocfs2: Use a folio in ocfs2_map_and_dirty_page() Matthew Wilcox (Oracle)
` (10 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Update to the new APIs. Removes a few page->folio conversions.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index cc252a1170ad..9ce8debbd282 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -963,10 +963,10 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
/* treat the write as new if the a hole/lseek spanned across
* the page boundary.
*/
- new = new | ((i_size_read(inode) <= page_offset(page)) &&
- (page_offset(page) <= user_pos));
+ new = new | ((i_size_read(inode) <= folio_pos(folio)) &&
+ (folio_pos(folio) <= user_pos));
- if (page == &wc->w_target_folio->page) {
+ if (folio == wc->w_target_folio) {
map_from = user_pos & (PAGE_SIZE - 1);
map_to = map_from + user_len;
@@ -990,7 +990,7 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
}
} else {
/*
- * If we haven't allocated the new page yet, we
+ * If we haven't allocated the new folio yet, we
* shouldn't be writing it out without copying user
* data. This is likely a math error from the caller.
*/
@@ -1008,20 +1008,20 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
}
/*
- * Parts of newly allocated pages need to be zero'd.
+ * Parts of newly allocated folios need to be zero'd.
*
* Above, we have also rewritten 'to' and 'from' - as far as
* the rest of the function is concerned, the entire cluster
- * range inside of a page needs to be written.
+ * range inside of a folio needs to be written.
*
- * We can skip this if the page is up to date - it's already
+ * We can skip this if the folio is uptodate - it's already
* been zero'd from being read in as a hole.
*/
- if (new && !PageUptodate(page))
+ if (new && !folio_test_uptodate(folio))
ocfs2_clear_page_regions(page, OCFS2_SB(inode->i_sb),
cpos, user_data_from, user_data_to);
- flush_dcache_page(page);
+ flush_dcache_folio(folio);
out:
return ret;
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 12/23] ocfs2: Use a folio in ocfs2_prepare_page_for_write()
2024-12-05 17:16 ` [PATCH 12/23] ocfs2: Use a folio in ocfs2_prepare_page_for_write() Matthew Wilcox (Oracle)
@ 2024-12-14 14:26 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:26 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Update to the new APIs. Removes a few page->folio conversions.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index cc252a1170ad..9ce8debbd282 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -963,10 +963,10 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> /* treat the write as new if the a hole/lseek spanned across
> * the page boundary.
> */
> - new = new | ((i_size_read(inode) <= page_offset(page)) &&
> - (page_offset(page) <= user_pos));
> + new = new | ((i_size_read(inode) <= folio_pos(folio)) &&
> + (folio_pos(folio) <= user_pos));
>
> - if (page == &wc->w_target_folio->page) {
> + if (folio == wc->w_target_folio) {
> map_from = user_pos & (PAGE_SIZE - 1);
> map_to = map_from + user_len;
>
> @@ -990,7 +990,7 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> }
> } else {
> /*
> - * If we haven't allocated the new page yet, we
> + * If we haven't allocated the new folio yet, we
> * shouldn't be writing it out without copying user
> * data. This is likely a math error from the caller.
> */
> @@ -1008,20 +1008,20 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> }
>
> /*
> - * Parts of newly allocated pages need to be zero'd.
> + * Parts of newly allocated folios need to be zero'd.
> *
> * Above, we have also rewritten 'to' and 'from' - as far as
> * the rest of the function is concerned, the entire cluster
> - * range inside of a page needs to be written.
> + * range inside of a folio needs to be written.
> *
> - * We can skip this if the page is up to date - it's already
> + * We can skip this if the folio is uptodate - it's already
> * been zero'd from being read in as a hole.
> */
> - if (new && !PageUptodate(page))
> + if (new && !folio_test_uptodate(folio))
> ocfs2_clear_page_regions(page, OCFS2_SB(inode->i_sb),
> cpos, user_data_from, user_data_to);
>
> - flush_dcache_page(page);
> + flush_dcache_folio(folio);
>
> out:
> return ret;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 13/23] ocfs2: Use a folio in ocfs2_map_and_dirty_page()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (11 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 12/23] ocfs2: Use a folio in ocfs2_prepare_page_for_write() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:27 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 14/23] ocfs2: Convert ocfs2_map_page_blocks() to ocfs2_map_folio_blocks() Matthew Wilcox (Oracle)
` (9 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Convert the incoming page to a folio and use it throughout the
function. Removes a couple of calls to compound_head().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 395e23920632..e95fe65b6a74 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6812,8 +6812,9 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
unsigned int from, unsigned int to,
struct page *page, int zero, u64 *phys)
{
+ struct folio *folio = page_folio(page);
int ret, partial = 0;
- loff_t start_byte = ((loff_t)page->index << PAGE_SHIFT) + from;
+ loff_t start_byte = folio_pos(folio) + from;
loff_t length = to - from;
ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0);
@@ -6821,14 +6822,14 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
mlog_errno(ret);
if (zero)
- zero_user_segment(page, from, to);
+ folio_zero_segment(folio, from, to);
/*
* Need to set the buffers we zero'd into uptodate
* here if they aren't - ocfs2_map_page_blocks()
* might've skipped some
*/
- ret = walk_page_buffers(handle, page_buffers(page),
+ ret = walk_page_buffers(handle, folio_buffers(folio),
from, to, &partial,
ocfs2_zero_func);
if (ret < 0)
@@ -6841,9 +6842,9 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
}
if (!partial)
- SetPageUptodate(page);
+ folio_mark_uptodate(folio);
- flush_dcache_page(page);
+ flush_dcache_folio(folio);
}
static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start,
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 13/23] ocfs2: Use a folio in ocfs2_map_and_dirty_page()
2024-12-05 17:16 ` [PATCH 13/23] ocfs2: Use a folio in ocfs2_map_and_dirty_page() Matthew Wilcox (Oracle)
@ 2024-12-14 14:27 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:27 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Convert the incoming page to a folio and use it throughout the
> function. Removes a couple of calls to compound_head().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index 395e23920632..e95fe65b6a74 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -6812,8 +6812,9 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> unsigned int from, unsigned int to,
> struct page *page, int zero, u64 *phys)
> {
> + struct folio *folio = page_folio(page);
> int ret, partial = 0;
> - loff_t start_byte = ((loff_t)page->index << PAGE_SHIFT) + from;
> + loff_t start_byte = folio_pos(folio) + from;
> loff_t length = to - from;
>
> ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0);
> @@ -6821,14 +6822,14 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> mlog_errno(ret);
>
> if (zero)
> - zero_user_segment(page, from, to);
> + folio_zero_segment(folio, from, to);
>
> /*
> * Need to set the buffers we zero'd into uptodate
> * here if they aren't - ocfs2_map_page_blocks()
> * might've skipped some
> */
> - ret = walk_page_buffers(handle, page_buffers(page),
> + ret = walk_page_buffers(handle, folio_buffers(folio),
> from, to, &partial,
> ocfs2_zero_func);
> if (ret < 0)
> @@ -6841,9 +6842,9 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> }
>
> if (!partial)
> - SetPageUptodate(page);
> + folio_mark_uptodate(folio);
>
> - flush_dcache_page(page);
> + flush_dcache_folio(folio);
> }
>
> static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start,
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 14/23] ocfs2: Convert ocfs2_map_page_blocks() to ocfs2_map_folio_blocks()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (12 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 13/23] ocfs2: Use a folio in ocfs2_map_and_dirty_page() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:28 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 15/23] ocfs2: Convert ocfs2_clear_page_regions() to ocfs2_clear_folio_regions() Matthew Wilcox (Oracle)
` (8 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
All callers now have a folio, so pass it in instead of converting
folio->page->folio.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 2 +-
fs/ocfs2/aops.c | 18 ++++++++----------
fs/ocfs2/aops.h | 2 +-
3 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index e95fe65b6a74..cfe9535a27f9 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6817,7 +6817,7 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
loff_t start_byte = folio_pos(folio) + from;
loff_t length = to - from;
- ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0);
+ ret = ocfs2_map_folio_blocks(folio, phys, inode, from, to, 0);
if (ret)
mlog_errno(ret);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 9ce8debbd282..cbc8bc6d95f3 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -560,7 +560,7 @@ static void ocfs2_clear_page_regions(struct page *page,
/*
* Nonsparse file systems fully allocate before we get to the write
* code. This prevents ocfs2_write() from tagging the write as an
- * allocating one, which means ocfs2_map_page_blocks() might try to
+ * allocating one, which means ocfs2_map_folio_blocks() might try to
* read-in the blocks at the tail of our file. Avoid reading them by
* testing i_size against each block offset.
*/
@@ -585,11 +585,10 @@ static int ocfs2_should_read_blk(struct inode *inode, struct folio *folio,
*
* This will also skip zeroing, which is handled externally.
*/
-int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
+int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
struct inode *inode, unsigned int from,
unsigned int to, int new)
{
- struct folio *folio = page_folio(page);
int ret = 0;
struct buffer_head *head, *bh, *wait[2], **wait_bh = wait;
unsigned int block_end, block_start;
@@ -971,12 +970,11 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
map_to = map_from + user_len;
if (new)
- ret = ocfs2_map_page_blocks(page, p_blkno, inode,
- cluster_start, cluster_end,
- new);
+ ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
+ cluster_start, cluster_end, new);
else
- ret = ocfs2_map_page_blocks(page, p_blkno, inode,
- map_from, map_to, new);
+ ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
+ map_from, map_to, new);
if (ret) {
mlog_errno(ret);
goto out;
@@ -999,8 +997,8 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
map_from = cluster_start;
map_to = cluster_end;
- ret = ocfs2_map_page_blocks(page, p_blkno, inode,
- cluster_start, cluster_end, new);
+ ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
+ cluster_start, cluster_end, new);
if (ret) {
mlog_errno(ret);
goto out;
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index dcf4b0dc82c4..17ca359c6051 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -13,7 +13,7 @@ handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
unsigned from,
unsigned to);
-int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
+int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
struct inode *inode, unsigned int from,
unsigned int to, int new);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 14/23] ocfs2: Convert ocfs2_map_page_blocks() to ocfs2_map_folio_blocks()
2024-12-05 17:16 ` [PATCH 14/23] ocfs2: Convert ocfs2_map_page_blocks() to ocfs2_map_folio_blocks() Matthew Wilcox (Oracle)
@ 2024-12-14 14:28 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:28 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> All callers now have a folio, so pass it in instead of converting
> folio->page->folio.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 2 +-
> fs/ocfs2/aops.c | 18 ++++++++----------
> fs/ocfs2/aops.h | 2 +-
> 3 files changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index e95fe65b6a74..cfe9535a27f9 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -6817,7 +6817,7 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> loff_t start_byte = folio_pos(folio) + from;
> loff_t length = to - from;
>
> - ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0);
> + ret = ocfs2_map_folio_blocks(folio, phys, inode, from, to, 0);
> if (ret)
> mlog_errno(ret);
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 9ce8debbd282..cbc8bc6d95f3 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -560,7 +560,7 @@ static void ocfs2_clear_page_regions(struct page *page,
> /*
> * Nonsparse file systems fully allocate before we get to the write
> * code. This prevents ocfs2_write() from tagging the write as an
> - * allocating one, which means ocfs2_map_page_blocks() might try to
> + * allocating one, which means ocfs2_map_folio_blocks() might try to
> * read-in the blocks at the tail of our file. Avoid reading them by
> * testing i_size against each block offset.
> */
> @@ -585,11 +585,10 @@ static int ocfs2_should_read_blk(struct inode *inode, struct folio *folio,
> *
> * This will also skip zeroing, which is handled externally.
> */
> -int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
> +int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
> struct inode *inode, unsigned int from,
> unsigned int to, int new)
> {
> - struct folio *folio = page_folio(page);
> int ret = 0;
> struct buffer_head *head, *bh, *wait[2], **wait_bh = wait;
> unsigned int block_end, block_start;
> @@ -971,12 +970,11 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> map_to = map_from + user_len;
>
> if (new)
> - ret = ocfs2_map_page_blocks(page, p_blkno, inode,
> - cluster_start, cluster_end,
> - new);
> + ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
> + cluster_start, cluster_end, new);
> else
> - ret = ocfs2_map_page_blocks(page, p_blkno, inode,
> - map_from, map_to, new);
> + ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
> + map_from, map_to, new);
> if (ret) {
> mlog_errno(ret);
> goto out;
> @@ -999,8 +997,8 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> map_from = cluster_start;
> map_to = cluster_end;
>
> - ret = ocfs2_map_page_blocks(page, p_blkno, inode,
> - cluster_start, cluster_end, new);
> + ret = ocfs2_map_folio_blocks(folio, p_blkno, inode,
> + cluster_start, cluster_end, new);
> if (ret) {
> mlog_errno(ret);
> goto out;
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index dcf4b0dc82c4..17ca359c6051 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -13,7 +13,7 @@ handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
> unsigned from,
> unsigned to);
>
> -int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
> +int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
> struct inode *inode, unsigned int from,
> unsigned int to, int new);
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 15/23] ocfs2: Convert ocfs2_clear_page_regions() to ocfs2_clear_folio_regions()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (13 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 14/23] ocfs2: Convert ocfs2_map_page_blocks() to ocfs2_map_folio_blocks() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:29 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 16/23] ocfs2: Use an array of folios instead of an array of pages Matthew Wilcox (Oracle)
` (7 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Pass in and use the folio instead of its page.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index cbc8bc6d95f3..644680ac1414 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -534,7 +534,7 @@ static void ocfs2_figure_cluster_boundaries(struct ocfs2_super *osb,
*
* from == to == 0 is code for "zero the entire cluster region"
*/
-static void ocfs2_clear_page_regions(struct page *page,
+static void ocfs2_clear_folio_regions(struct folio *folio,
struct ocfs2_super *osb, u32 cpos,
unsigned from, unsigned to)
{
@@ -543,7 +543,7 @@ static void ocfs2_clear_page_regions(struct page *page,
ocfs2_figure_cluster_boundaries(osb, cpos, &cluster_start, &cluster_end);
- kaddr = kmap_atomic(page);
+ kaddr = kmap_local_folio(folio, 0);
if (from || to) {
if (from > cluster_start)
@@ -554,7 +554,7 @@ static void ocfs2_clear_page_regions(struct page *page,
memset(kaddr + cluster_start, 0, cluster_end - cluster_start);
}
- kunmap_atomic(kaddr);
+ kunmap_local(kaddr);
}
/*
@@ -950,7 +950,6 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
struct ocfs2_write_ctxt *wc, struct folio *folio, u32 cpos,
loff_t user_pos, unsigned user_len, int new)
{
- struct page *page = &folio->page;
int ret;
unsigned int map_from = 0, map_to = 0;
unsigned int cluster_start, cluster_end;
@@ -1016,7 +1015,7 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
* been zero'd from being read in as a hole.
*/
if (new && !folio_test_uptodate(folio))
- ocfs2_clear_page_regions(page, OCFS2_SB(inode->i_sb),
+ ocfs2_clear_folio_regions(folio, OCFS2_SB(inode->i_sb),
cpos, user_data_from, user_data_to);
flush_dcache_folio(folio);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 15/23] ocfs2: Convert ocfs2_clear_page_regions() to ocfs2_clear_folio_regions()
2024-12-05 17:16 ` [PATCH 15/23] ocfs2: Convert ocfs2_clear_page_regions() to ocfs2_clear_folio_regions() Matthew Wilcox (Oracle)
@ 2024-12-14 14:29 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:29 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Pass in and use the folio instead of its page.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index cbc8bc6d95f3..644680ac1414 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -534,7 +534,7 @@ static void ocfs2_figure_cluster_boundaries(struct ocfs2_super *osb,
> *
> * from == to == 0 is code for "zero the entire cluster region"
> */
> -static void ocfs2_clear_page_regions(struct page *page,
> +static void ocfs2_clear_folio_regions(struct folio *folio,
> struct ocfs2_super *osb, u32 cpos,
> unsigned from, unsigned to)
> {
> @@ -543,7 +543,7 @@ static void ocfs2_clear_page_regions(struct page *page,
>
> ocfs2_figure_cluster_boundaries(osb, cpos, &cluster_start, &cluster_end);
>
> - kaddr = kmap_atomic(page);
> + kaddr = kmap_local_folio(folio, 0);
>
> if (from || to) {
> if (from > cluster_start)
> @@ -554,7 +554,7 @@ static void ocfs2_clear_page_regions(struct page *page,
> memset(kaddr + cluster_start, 0, cluster_end - cluster_start);
> }
>
> - kunmap_atomic(kaddr);
> + kunmap_local(kaddr);
> }
>
> /*
> @@ -950,7 +950,6 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> struct ocfs2_write_ctxt *wc, struct folio *folio, u32 cpos,
> loff_t user_pos, unsigned user_len, int new)
> {
> - struct page *page = &folio->page;
> int ret;
> unsigned int map_from = 0, map_to = 0;
> unsigned int cluster_start, cluster_end;
> @@ -1016,7 +1015,7 @@ static int ocfs2_prepare_folio_for_write(struct inode *inode, u64 *p_blkno,
> * been zero'd from being read in as a hole.
> */
> if (new && !folio_test_uptodate(folio))
> - ocfs2_clear_page_regions(page, OCFS2_SB(inode->i_sb),
> + ocfs2_clear_folio_regions(folio, OCFS2_SB(inode->i_sb),
> cpos, user_data_from, user_data_to);
>
> flush_dcache_folio(folio);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 16/23] ocfs2: Use an array of folios instead of an array of pages
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (14 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 15/23] ocfs2: Convert ocfs2_clear_page_regions() to ocfs2_clear_folio_regions() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:34 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 17/23] ocfs2: Convert ocfs2_duplicate_clusters_by_page() to use a folio Matthew Wilcox (Oracle)
` (6 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
The ocfs2_zero_cluster_folios() / ocfs2_grab_folios() /
ocfs2_grab_eof_folios() family of functions pass around an array of
pages. Convert them to pass around an array of folios. This removes
the last caller of ocfs2_unlock_and_free_pages(), so delete it.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 98 ++++++++++++++++++++++++------------------------
fs/ocfs2/alloc.h | 2 -
fs/ocfs2/aops.c | 13 -------
fs/ocfs2/aops.h | 1 -
4 files changed, 49 insertions(+), 65 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index cfe9535a27f9..dfcdafc11377 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6847,87 +6847,87 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
flush_dcache_folio(folio);
}
-static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start,
- loff_t end, struct page **pages,
- int numpages, u64 phys, handle_t *handle)
+static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
+ loff_t end, struct folio **folios, int numfolios,
+ u64 phys, handle_t *handle)
{
int i;
- struct page *page;
unsigned int from, to = PAGE_SIZE;
struct super_block *sb = inode->i_sb;
BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb)));
- if (numpages == 0)
+ if (numfolios == 0)
goto out;
to = PAGE_SIZE;
- for(i = 0; i < numpages; i++) {
- page = pages[i];
+ for (i = 0; i < numfolios; i++) {
+ struct folio *folio = folios[i];
from = start & (PAGE_SIZE - 1);
- if ((end >> PAGE_SHIFT) == page->index)
+ if ((end >> PAGE_SHIFT) == folio->index)
to = end & (PAGE_SIZE - 1);
BUG_ON(from > PAGE_SIZE);
BUG_ON(to > PAGE_SIZE);
- ocfs2_map_and_dirty_page(inode, handle, from, to, page, 1,
+ ocfs2_map_and_dirty_page(inode, handle, from, to, &folio->page, 1,
&phys);
- start = (page->index + 1) << PAGE_SHIFT;
+ start = (folio->index + 1) << PAGE_SHIFT;
}
out:
- if (pages)
- ocfs2_unlock_and_free_pages(pages, numpages);
+ if (folios)
+ ocfs2_unlock_and_free_folios(folios, numfolios);
}
-int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
- struct page **pages, int *num)
+static int ocfs2_grab_folios(struct inode *inode, loff_t start, loff_t end,
+ struct folio **folios, int *num)
{
- int numpages, ret = 0;
+ int numfolios, ret = 0;
struct address_space *mapping = inode->i_mapping;
unsigned long index;
loff_t last_page_bytes;
BUG_ON(start > end);
- numpages = 0;
+ numfolios = 0;
last_page_bytes = PAGE_ALIGN(end);
index = start >> PAGE_SHIFT;
do {
- pages[numpages] = find_or_create_page(mapping, index, GFP_NOFS);
- if (!pages[numpages]) {
- ret = -ENOMEM;
+ folios[numfolios] = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
+ if (IS_ERR(folios[numfolios])) {
+ ret = PTR_ERR(folios[numfolios]);
mlog_errno(ret);
goto out;
}
- numpages++;
- index++;
+ index = folio_next_index(folios[numfolios]);
+ numfolios++;
} while (index < (last_page_bytes >> PAGE_SHIFT));
out:
if (ret != 0) {
- if (pages)
- ocfs2_unlock_and_free_pages(pages, numpages);
- numpages = 0;
+ if (folios)
+ ocfs2_unlock_and_free_folios(folios, numfolios);
+ numfolios = 0;
}
- *num = numpages;
+ *num = numfolios;
return ret;
}
-static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
- struct page **pages, int *num)
+static int ocfs2_grab_eof_folios(struct inode *inode, loff_t start, loff_t end,
+ struct folio **folios, int *num)
{
struct super_block *sb = inode->i_sb;
BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits !=
(end - 1) >> OCFS2_SB(sb)->s_clustersize_bits);
- return ocfs2_grab_pages(inode, start, end, pages, num);
+ return ocfs2_grab_folios(inode, start, end, folios, num);
}
/*
@@ -6941,8 +6941,8 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
u64 range_start, u64 range_end)
{
- int ret = 0, numpages;
- struct page **pages = NULL;
+ int ret = 0, numfolios;
+ struct folio **folios = NULL;
u64 phys;
unsigned int ext_flags;
struct super_block *sb = inode->i_sb;
@@ -6955,17 +6955,17 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
return 0;
/*
- * Avoid zeroing pages fully beyond current i_size. It is pointless as
- * underlying blocks of those pages should be already zeroed out and
+ * Avoid zeroing folios fully beyond current i_size. It is pointless as
+ * underlying blocks of those folios should be already zeroed out and
* page writeback will skip them anyway.
*/
range_end = min_t(u64, range_end, i_size_read(inode));
if (range_start >= range_end)
return 0;
- pages = kcalloc(ocfs2_pages_per_cluster(sb),
- sizeof(struct page *), GFP_NOFS);
- if (pages == NULL) {
+ folios = kcalloc(ocfs2_pages_per_cluster(sb),
+ sizeof(struct folio *), GFP_NOFS);
+ if (folios == NULL) {
ret = -ENOMEM;
mlog_errno(ret);
goto out;
@@ -6986,18 +6986,18 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
if (phys == 0 || ext_flags & OCFS2_EXT_UNWRITTEN)
goto out;
- ret = ocfs2_grab_eof_pages(inode, range_start, range_end, pages,
- &numpages);
+ ret = ocfs2_grab_eof_folios(inode, range_start, range_end, folios,
+ &numfolios);
if (ret) {
mlog_errno(ret);
goto out;
}
- ocfs2_zero_cluster_pages(inode, range_start, range_end, pages,
- numpages, phys, handle);
+ ocfs2_zero_cluster_folios(inode, range_start, range_end, folios,
+ numfolios, phys, handle);
/*
- * Initiate writeout of the pages we zero'd here. We don't
+ * Initiate writeout of the folios we zero'd here. We don't
* wait on them - the truncate_inode_pages() call later will
* do that for us.
*/
@@ -7007,7 +7007,7 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
mlog_errno(ret);
out:
- kfree(pages);
+ kfree(folios);
return ret;
}
@@ -7060,7 +7060,7 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
int ocfs2_convert_inline_data_to_extents(struct inode *inode,
struct buffer_head *di_bh)
{
- int ret, has_data, num_pages = 0;
+ int ret, has_data, num_folios = 0;
int need_free = 0;
u32 bit_off, num;
handle_t *handle;
@@ -7069,7 +7069,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
struct ocfs2_alloc_context *data_ac = NULL;
- struct page *page = NULL;
+ struct folio *folio = NULL;
struct ocfs2_extent_tree et;
int did_quota = 0;
@@ -7124,8 +7124,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
*/
block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
- ret = ocfs2_grab_eof_pages(inode, 0, page_end, &page,
- &num_pages);
+ ret = ocfs2_grab_eof_folios(inode, 0, page_end, &folio,
+ &num_folios);
if (ret) {
mlog_errno(ret);
need_free = 1;
@@ -7136,14 +7136,14 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
* This should populate the 1st page for us and mark
* it up to date.
*/
- ret = ocfs2_read_inline_data(inode, page, di_bh);
+ ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
if (ret) {
mlog_errno(ret);
need_free = 1;
goto out_unlock;
}
- ocfs2_map_and_dirty_page(inode, handle, 0, page_end, page, 0,
+ ocfs2_map_and_dirty_page(inode, handle, 0, page_end, &folio->page, 0,
&phys);
}
@@ -7175,8 +7175,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
}
out_unlock:
- if (page)
- ocfs2_unlock_and_free_pages(&page, num_pages);
+ if (folio)
+ ocfs2_unlock_and_free_folios(&folio, num_folios);
out_commit:
if (ret < 0 && did_quota)
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 4af7abaa6e40..6a2aca1a062e 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -254,8 +254,6 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec)
return !rec->e_leaf_clusters;
}
-int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
- struct page **pages, int *num);
void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
unsigned int from, unsigned int to,
struct page *page, int zero, u64 *phys);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 644680ac1414..f1eba968563f 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -783,19 +783,6 @@ void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios)
}
}
-void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
-{
- int i;
-
- for(i = 0; i < num_pages; i++) {
- if (pages[i]) {
- unlock_page(pages[i]);
- mark_page_accessed(pages[i]);
- put_page(pages[i]);
- }
- }
-}
-
static void ocfs2_unlock_folios(struct ocfs2_write_ctxt *wc)
{
int i;
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 17ca359c6051..cf8d202d9a8b 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -18,7 +18,6 @@ int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
unsigned int to, int new);
void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios);
-void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages);
int walk_page_buffers( handle_t *handle,
struct buffer_head *head,
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 16/23] ocfs2: Use an array of folios instead of an array of pages
2024-12-05 17:16 ` [PATCH 16/23] ocfs2: Use an array of folios instead of an array of pages Matthew Wilcox (Oracle)
@ 2024-12-14 14:34 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:34 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> The ocfs2_zero_cluster_folios() / ocfs2_grab_folios() /
> ocfs2_grab_eof_folios() family of functions pass around an array of
> pages. Convert them to pass around an array of folios. This removes
> the last caller of ocfs2_unlock_and_free_pages(), so delete it.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 98 ++++++++++++++++++++++++------------------------
> fs/ocfs2/alloc.h | 2 -
> fs/ocfs2/aops.c | 13 -------
> fs/ocfs2/aops.h | 1 -
> 4 files changed, 49 insertions(+), 65 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index cfe9535a27f9..dfcdafc11377 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -6847,87 +6847,87 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> flush_dcache_folio(folio);
> }
>
> -static void ocfs2_zero_cluster_pages(struct inode *inode, loff_t start,
> - loff_t end, struct page **pages,
> - int numpages, u64 phys, handle_t *handle)
> +static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
> + loff_t end, struct folio **folios, int numfolios,
> + u64 phys, handle_t *handle)
> {
> int i;
> - struct page *page;
> unsigned int from, to = PAGE_SIZE;
> struct super_block *sb = inode->i_sb;
>
> BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb)));
>
> - if (numpages == 0)
> + if (numfolios == 0)
> goto out;
>
> to = PAGE_SIZE;
> - for(i = 0; i < numpages; i++) {
> - page = pages[i];
> + for (i = 0; i < numfolios; i++) {
> + struct folio *folio = folios[i];
>
> from = start & (PAGE_SIZE - 1);
> - if ((end >> PAGE_SHIFT) == page->index)
> + if ((end >> PAGE_SHIFT) == folio->index)
> to = end & (PAGE_SIZE - 1);
>
> BUG_ON(from > PAGE_SIZE);
> BUG_ON(to > PAGE_SIZE);
>
> - ocfs2_map_and_dirty_page(inode, handle, from, to, page, 1,
> + ocfs2_map_and_dirty_page(inode, handle, from, to, &folio->page, 1,
> &phys);
>
> - start = (page->index + 1) << PAGE_SHIFT;
> + start = (folio->index + 1) << PAGE_SHIFT;
> }
> out:
> - if (pages)
> - ocfs2_unlock_and_free_pages(pages, numpages);
> + if (folios)
> + ocfs2_unlock_and_free_folios(folios, numfolios);
> }
>
> -int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
> - struct page **pages, int *num)
> +static int ocfs2_grab_folios(struct inode *inode, loff_t start, loff_t end,
> + struct folio **folios, int *num)
> {
> - int numpages, ret = 0;
> + int numfolios, ret = 0;
> struct address_space *mapping = inode->i_mapping;
> unsigned long index;
> loff_t last_page_bytes;
>
> BUG_ON(start > end);
>
> - numpages = 0;
> + numfolios = 0;
> last_page_bytes = PAGE_ALIGN(end);
> index = start >> PAGE_SHIFT;
> do {
> - pages[numpages] = find_or_create_page(mapping, index, GFP_NOFS);
> - if (!pages[numpages]) {
> - ret = -ENOMEM;
> + folios[numfolios] = __filemap_get_folio(mapping, index,
> + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
> + if (IS_ERR(folios[numfolios])) {
> + ret = PTR_ERR(folios[numfolios]);
> mlog_errno(ret);
> goto out;
> }
>
> - numpages++;
> - index++;
> + index = folio_next_index(folios[numfolios]);
> + numfolios++;
> } while (index < (last_page_bytes >> PAGE_SHIFT));
>
> out:
> if (ret != 0) {
> - if (pages)
> - ocfs2_unlock_and_free_pages(pages, numpages);
> - numpages = 0;
> + if (folios)
> + ocfs2_unlock_and_free_folios(folios, numfolios);
> + numfolios = 0;
> }
>
> - *num = numpages;
> + *num = numfolios;
>
> return ret;
> }
>
> -static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
> - struct page **pages, int *num)
> +static int ocfs2_grab_eof_folios(struct inode *inode, loff_t start, loff_t end,
> + struct folio **folios, int *num)
> {
> struct super_block *sb = inode->i_sb;
>
> BUG_ON(start >> OCFS2_SB(sb)->s_clustersize_bits !=
> (end - 1) >> OCFS2_SB(sb)->s_clustersize_bits);
>
> - return ocfs2_grab_pages(inode, start, end, pages, num);
> + return ocfs2_grab_folios(inode, start, end, folios, num);
> }
>
> /*
> @@ -6941,8 +6941,8 @@ static int ocfs2_grab_eof_pages(struct inode *inode, loff_t start, loff_t end,
> int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
> u64 range_start, u64 range_end)
> {
> - int ret = 0, numpages;
> - struct page **pages = NULL;
> + int ret = 0, numfolios;
> + struct folio **folios = NULL;
> u64 phys;
> unsigned int ext_flags;
> struct super_block *sb = inode->i_sb;
> @@ -6955,17 +6955,17 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
> return 0;
>
> /*
> - * Avoid zeroing pages fully beyond current i_size. It is pointless as
> - * underlying blocks of those pages should be already zeroed out and
> + * Avoid zeroing folios fully beyond current i_size. It is pointless as
> + * underlying blocks of those folios should be already zeroed out and
> * page writeback will skip them anyway.
> */
> range_end = min_t(u64, range_end, i_size_read(inode));
> if (range_start >= range_end)
> return 0;
>
> - pages = kcalloc(ocfs2_pages_per_cluster(sb),
> - sizeof(struct page *), GFP_NOFS);
> - if (pages == NULL) {
> + folios = kcalloc(ocfs2_pages_per_cluster(sb),
> + sizeof(struct folio *), GFP_NOFS);
> + if (folios == NULL) {
> ret = -ENOMEM;
> mlog_errno(ret);
> goto out;
> @@ -6986,18 +6986,18 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
> if (phys == 0 || ext_flags & OCFS2_EXT_UNWRITTEN)
> goto out;
>
> - ret = ocfs2_grab_eof_pages(inode, range_start, range_end, pages,
> - &numpages);
> + ret = ocfs2_grab_eof_folios(inode, range_start, range_end, folios,
> + &numfolios);
> if (ret) {
> mlog_errno(ret);
> goto out;
> }
>
> - ocfs2_zero_cluster_pages(inode, range_start, range_end, pages,
> - numpages, phys, handle);
> + ocfs2_zero_cluster_folios(inode, range_start, range_end, folios,
> + numfolios, phys, handle);
>
> /*
> - * Initiate writeout of the pages we zero'd here. We don't
> + * Initiate writeout of the folios we zero'd here. We don't
> * wait on them - the truncate_inode_pages() call later will
> * do that for us.
> */
> @@ -7007,7 +7007,7 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
> mlog_errno(ret);
>
> out:
> - kfree(pages);
> + kfree(folios);
>
> return ret;
> }
> @@ -7060,7 +7060,7 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
> int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> struct buffer_head *di_bh)
> {
> - int ret, has_data, num_pages = 0;
> + int ret, has_data, num_folios = 0;
> int need_free = 0;
> u32 bit_off, num;
> handle_t *handle;
> @@ -7069,7 +7069,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
> struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
> struct ocfs2_alloc_context *data_ac = NULL;
> - struct page *page = NULL;
> + struct folio *folio = NULL;
> struct ocfs2_extent_tree et;
> int did_quota = 0;
>
> @@ -7124,8 +7124,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> */
> block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
>
> - ret = ocfs2_grab_eof_pages(inode, 0, page_end, &page,
> - &num_pages);
> + ret = ocfs2_grab_eof_folios(inode, 0, page_end, &folio,
> + &num_folios);
> if (ret) {
> mlog_errno(ret);
> need_free = 1;
> @@ -7136,14 +7136,14 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> * This should populate the 1st page for us and mark
> * it up to date.
> */
> - ret = ocfs2_read_inline_data(inode, page, di_bh);
> + ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
> if (ret) {
> mlog_errno(ret);
> need_free = 1;
> goto out_unlock;
> }
>
> - ocfs2_map_and_dirty_page(inode, handle, 0, page_end, page, 0,
> + ocfs2_map_and_dirty_page(inode, handle, 0, page_end, &folio->page, 0,
> &phys);
> }
>
> @@ -7175,8 +7175,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> }
>
> out_unlock:
> - if (page)
> - ocfs2_unlock_and_free_pages(&page, num_pages);
> + if (folio)
> + ocfs2_unlock_and_free_folios(&folio, num_folios);
>
> out_commit:
> if (ret < 0 && did_quota)
> diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
> index 4af7abaa6e40..6a2aca1a062e 100644
> --- a/fs/ocfs2/alloc.h
> +++ b/fs/ocfs2/alloc.h
> @@ -254,8 +254,6 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec)
> return !rec->e_leaf_clusters;
> }
>
> -int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end,
> - struct page **pages, int *num);
> void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> unsigned int from, unsigned int to,
> struct page *page, int zero, u64 *phys);
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index 644680ac1414..f1eba968563f 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -783,19 +783,6 @@ void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios)
> }
> }
>
> -void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
> -{
> - int i;
> -
> - for(i = 0; i < num_pages; i++) {
> - if (pages[i]) {
> - unlock_page(pages[i]);
> - mark_page_accessed(pages[i]);
> - put_page(pages[i]);
> - }
> - }
> -}
> -
> static void ocfs2_unlock_folios(struct ocfs2_write_ctxt *wc)
> {
> int i;
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index 17ca359c6051..cf8d202d9a8b 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -18,7 +18,6 @@ int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
> unsigned int to, int new);
>
> void ocfs2_unlock_and_free_folios(struct folio **folios, int num_folios);
> -void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages);
>
> int walk_page_buffers( handle_t *handle,
> struct buffer_head *head,
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 17/23] ocfs2: Convert ocfs2_duplicate_clusters_by_page() to use a folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (15 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 16/23] ocfs2: Use an array of folios instead of an array of pages Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:36 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 18/23] ocfs2: Convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio() Matthew Wilcox (Oracle)
` (5 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Retrieve folios from the page cache, not pages, and use a folio
throughout this function. Removes seven calls to compound_head().
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/refcounttree.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 004393b13c0a..68e0339690e9 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -2902,7 +2902,6 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
int ret = 0, partial;
struct super_block *sb = inode->i_sb;
u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
- struct page *page;
pgoff_t page_index;
unsigned int from, to;
loff_t offset, end, map_end;
@@ -2921,6 +2920,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
end = i_size_read(inode);
while (offset < end) {
+ struct folio *folio;
page_index = offset >> PAGE_SHIFT;
map_end = ((loff_t)page_index + 1) << PAGE_SHIFT;
if (map_end > end)
@@ -2933,9 +2933,10 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
to = map_end & (PAGE_SIZE - 1);
retry:
- page = find_or_create_page(mapping, page_index, GFP_NOFS);
- if (!page) {
- ret = -ENOMEM;
+ folio = __filemap_get_folio(mapping, page_index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
+ if (IS_ERR(folio)) {
+ ret = PTR_ERR(folio);
mlog_errno(ret);
break;
}
@@ -2945,9 +2946,9 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
* page, so write it back.
*/
if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) {
- if (PageDirty(page)) {
- unlock_page(page);
- put_page(page);
+ if (folio_test_dirty(folio)) {
+ folio_unlock(folio);
+ folio_put(folio);
ret = filemap_write_and_wait_range(mapping,
offset, map_end - 1);
@@ -2955,9 +2956,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
}
}
- if (!PageUptodate(page)) {
- struct folio *folio = page_folio(page);
-
+ if (!folio_test_uptodate(folio)) {
ret = block_read_full_folio(folio, ocfs2_get_block);
if (ret) {
mlog_errno(ret);
@@ -2966,8 +2965,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
folio_lock(folio);
}
- if (page_has_buffers(page)) {
- ret = walk_page_buffers(handle, page_buffers(page),
+ if (folio_buffers(folio)) {
+ ret = walk_page_buffers(handle, folio_buffers(folio),
from, to, &partial,
ocfs2_clear_cow_buffer);
if (ret) {
@@ -2978,12 +2977,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
ocfs2_map_and_dirty_page(inode,
handle, from, to,
- page, 0, &new_block);
- mark_page_accessed(page);
+ &folio->page, 0, &new_block);
+ folio_mark_accessed(folio);
unlock:
- unlock_page(page);
- put_page(page);
- page = NULL;
+ folio_unlock(folio);
+ folio_put(folio);
offset = map_end;
if (ret)
break;
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 17/23] ocfs2: Convert ocfs2_duplicate_clusters_by_page() to use a folio
2024-12-05 17:16 ` [PATCH 17/23] ocfs2: Convert ocfs2_duplicate_clusters_by_page() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-14 14:36 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:36 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Retrieve folios from the page cache, not pages, and use a folio
> throughout this function. Removes seven calls to compound_head().
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/refcounttree.c | 32 +++++++++++++++-----------------
> 1 file changed, 15 insertions(+), 17 deletions(-)
>
> diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
> index 004393b13c0a..68e0339690e9 100644
> --- a/fs/ocfs2/refcounttree.c
> +++ b/fs/ocfs2/refcounttree.c
> @@ -2902,7 +2902,6 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> int ret = 0, partial;
> struct super_block *sb = inode->i_sb;
> u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
> - struct page *page;
> pgoff_t page_index;
> unsigned int from, to;
> loff_t offset, end, map_end;
> @@ -2921,6 +2920,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> end = i_size_read(inode);
>
> while (offset < end) {
> + struct folio *folio;
> page_index = offset >> PAGE_SHIFT;
> map_end = ((loff_t)page_index + 1) << PAGE_SHIFT;
> if (map_end > end)
> @@ -2933,9 +2933,10 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> to = map_end & (PAGE_SIZE - 1);
>
> retry:
> - page = find_or_create_page(mapping, page_index, GFP_NOFS);
> - if (!page) {
> - ret = -ENOMEM;
> + folio = __filemap_get_folio(mapping, page_index,
> + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_NOFS);
> + if (IS_ERR(folio)) {
> + ret = PTR_ERR(folio);
> mlog_errno(ret);
> break;
> }
> @@ -2945,9 +2946,9 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> * page, so write it back.
> */
> if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) {
> - if (PageDirty(page)) {
> - unlock_page(page);
> - put_page(page);
> + if (folio_test_dirty(folio)) {
> + folio_unlock(folio);
> + folio_put(folio);
>
> ret = filemap_write_and_wait_range(mapping,
> offset, map_end - 1);
> @@ -2955,9 +2956,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> }
> }
>
> - if (!PageUptodate(page)) {
> - struct folio *folio = page_folio(page);
> -
> + if (!folio_test_uptodate(folio)) {
> ret = block_read_full_folio(folio, ocfs2_get_block);
> if (ret) {
> mlog_errno(ret);
> @@ -2966,8 +2965,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> folio_lock(folio);
> }
>
> - if (page_has_buffers(page)) {
> - ret = walk_page_buffers(handle, page_buffers(page),
> + if (folio_buffers(folio)) {
> + ret = walk_page_buffers(handle, folio_buffers(folio),
> from, to, &partial,
> ocfs2_clear_cow_buffer);
> if (ret) {
> @@ -2978,12 +2977,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
>
> ocfs2_map_and_dirty_page(inode,
> handle, from, to,
> - page, 0, &new_block);
> - mark_page_accessed(page);
> + &folio->page, 0, &new_block);
> + folio_mark_accessed(folio);
> unlock:
> - unlock_page(page);
> - put_page(page);
> - page = NULL;
> + folio_unlock(folio);
> + folio_put(folio);
> offset = map_end;
> if (ret)
> break;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 18/23] ocfs2: Convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (16 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 17/23] ocfs2: Convert ocfs2_duplicate_clusters_by_page() to use a folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:36 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 19/23] ocfs2: Convert ocfs2_read_inline_data() to take a folio Matthew Wilcox (Oracle)
` (4 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
All callers now have a folio, so skip the folio->page->folio conversion.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 17 ++++++++---------
fs/ocfs2/alloc.h | 6 +++---
fs/ocfs2/refcounttree.c | 5 ++---
3 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index dfcdafc11377..c8d9d5e9a7fd 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6808,11 +6808,10 @@ static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh)
return 0;
}
-void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
- unsigned int from, unsigned int to,
- struct page *page, int zero, u64 *phys)
+void ocfs2_map_and_dirty_folio(struct inode *inode, handle_t *handle,
+ size_t from, size_t to, struct folio *folio, int zero,
+ u64 *phys)
{
- struct folio *folio = page_folio(page);
int ret, partial = 0;
loff_t start_byte = folio_pos(folio) + from;
loff_t length = to - from;
@@ -6871,8 +6870,8 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
BUG_ON(from > PAGE_SIZE);
BUG_ON(to > PAGE_SIZE);
- ocfs2_map_and_dirty_page(inode, handle, from, to, &folio->page, 1,
- &phys);
+ ocfs2_map_and_dirty_folio(inode, handle, from, to, folio, 1,
+ &phys);
start = (folio->index + 1) << PAGE_SHIFT;
}
@@ -7120,7 +7119,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
/*
* Save two copies, one for insert, and one that can
- * be changed by ocfs2_map_and_dirty_page() below.
+ * be changed by ocfs2_map_and_dirty_folio() below.
*/
block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
@@ -7143,8 +7142,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
goto out_unlock;
}
- ocfs2_map_and_dirty_page(inode, handle, 0, page_end, &folio->page, 0,
- &phys);
+ ocfs2_map_and_dirty_folio(inode, handle, 0, page_end, folio, 0,
+ &phys);
}
spin_lock(&oi->ip_lock);
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 6a2aca1a062e..1c0c83362904 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -254,9 +254,9 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec)
return !rec->e_leaf_clusters;
}
-void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
- unsigned int from, unsigned int to,
- struct page *page, int zero, u64 *phys);
+void ocfs2_map_and_dirty_folio(struct inode *inode, handle_t *handle,
+ size_t from, size_t to, struct folio *folio, int zero,
+ u64 *phys);
/*
* Structures which describe a path through a btree, and functions to
* manipulate them.
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 68e0339690e9..693665a36855 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -2975,9 +2975,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
}
}
- ocfs2_map_and_dirty_page(inode,
- handle, from, to,
- &folio->page, 0, &new_block);
+ ocfs2_map_and_dirty_folio(inode, handle, from, to,
+ folio, 0, &new_block);
folio_mark_accessed(folio);
unlock:
folio_unlock(folio);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 18/23] ocfs2: Convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio()
2024-12-05 17:16 ` [PATCH 18/23] ocfs2: Convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio() Matthew Wilcox (Oracle)
@ 2024-12-14 14:36 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:36 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> All callers now have a folio, so skip the folio->page->folio conversion.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 17 ++++++++---------
> fs/ocfs2/alloc.h | 6 +++---
> fs/ocfs2/refcounttree.c | 5 ++---
> 3 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index dfcdafc11377..c8d9d5e9a7fd 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -6808,11 +6808,10 @@ static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh)
> return 0;
> }
>
> -void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> - unsigned int from, unsigned int to,
> - struct page *page, int zero, u64 *phys)
> +void ocfs2_map_and_dirty_folio(struct inode *inode, handle_t *handle,
> + size_t from, size_t to, struct folio *folio, int zero,
> + u64 *phys)
> {
> - struct folio *folio = page_folio(page);
> int ret, partial = 0;
> loff_t start_byte = folio_pos(folio) + from;
> loff_t length = to - from;
> @@ -6871,8 +6870,8 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
> BUG_ON(from > PAGE_SIZE);
> BUG_ON(to > PAGE_SIZE);
>
> - ocfs2_map_and_dirty_page(inode, handle, from, to, &folio->page, 1,
> - &phys);
> + ocfs2_map_and_dirty_folio(inode, handle, from, to, folio, 1,
> + &phys);
>
> start = (folio->index + 1) << PAGE_SHIFT;
> }
> @@ -7120,7 +7119,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
>
> /*
> * Save two copies, one for insert, and one that can
> - * be changed by ocfs2_map_and_dirty_page() below.
> + * be changed by ocfs2_map_and_dirty_folio() below.
> */
> block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
>
> @@ -7143,8 +7142,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> goto out_unlock;
> }
>
> - ocfs2_map_and_dirty_page(inode, handle, 0, page_end, &folio->page, 0,
> - &phys);
> + ocfs2_map_and_dirty_folio(inode, handle, 0, page_end, folio, 0,
> + &phys);
> }
>
> spin_lock(&oi->ip_lock);
> diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
> index 6a2aca1a062e..1c0c83362904 100644
> --- a/fs/ocfs2/alloc.h
> +++ b/fs/ocfs2/alloc.h
> @@ -254,9 +254,9 @@ static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec)
> return !rec->e_leaf_clusters;
> }
>
> -void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle,
> - unsigned int from, unsigned int to,
> - struct page *page, int zero, u64 *phys);
> +void ocfs2_map_and_dirty_folio(struct inode *inode, handle_t *handle,
> + size_t from, size_t to, struct folio *folio, int zero,
> + u64 *phys);
> /*
> * Structures which describe a path through a btree, and functions to
> * manipulate them.
> diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
> index 68e0339690e9..693665a36855 100644
> --- a/fs/ocfs2/refcounttree.c
> +++ b/fs/ocfs2/refcounttree.c
> @@ -2975,9 +2975,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
> }
> }
>
> - ocfs2_map_and_dirty_page(inode,
> - handle, from, to,
> - &folio->page, 0, &new_block);
> + ocfs2_map_and_dirty_folio(inode, handle, from, to,
> + folio, 0, &new_block);
> folio_mark_accessed(folio);
> unlock:
> folio_unlock(folio);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 19/23] ocfs2: Convert ocfs2_read_inline_data() to take a folio
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (17 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 18/23] ocfs2: Convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:39 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 20/23] ocfs2: Use a folio in ocfs2_fast_symlink_read_folio() Matthew Wilcox (Oracle)
` (3 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely
All callers now have a folio, so pass it in. We can use
folio_fill_tail() instead of open-coding it. Saves a call to
compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 2 +-
fs/ocfs2/aops.c | 20 ++++++--------------
fs/ocfs2/aops.h | 2 +-
3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index c8d9d5e9a7fd..36b536b54a2d 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -7135,7 +7135,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
* This should populate the 1st page for us and mark
* it up to date.
*/
- ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
+ ret = ocfs2_read_inline_data(inode, folio, di_bh);
if (ret) {
mlog_errno(ret);
need_free = 1;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f1eba968563f..80fe7a68cbcc 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -215,10 +215,9 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
return err;
}
-int ocfs2_read_inline_data(struct inode *inode, struct page *page,
+int ocfs2_read_inline_data(struct inode *inode, struct folio *folio,
struct buffer_head *di_bh)
{
- void *kaddr;
loff_t size;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
@@ -230,7 +229,7 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
size = i_size_read(inode);
- if (size > PAGE_SIZE ||
+ if (size > folio_size(folio) ||
size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) {
ocfs2_error(inode->i_sb,
"Inode %llu has with inline data has bad size: %Lu\n",
@@ -239,15 +238,8 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
return -EROFS;
}
- kaddr = kmap_atomic(page);
- if (size)
- memcpy(kaddr, di->id2.i_data.id_data, size);
- /* Clear the remaining part of the page */
- memset(kaddr + size, 0, PAGE_SIZE - size);
- flush_dcache_page(page);
- kunmap_atomic(kaddr);
-
- SetPageUptodate(page);
+ folio_fill_tail(folio, 0, di->id2.i_data.id_data, size);
+ folio_mark_uptodate(folio);
return 0;
}
@@ -266,7 +258,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct folio *folio)
goto out;
}
- ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
+ ret = ocfs2_read_inline_data(inode, folio, di_bh);
out:
folio_unlock(folio);
@@ -1506,7 +1498,7 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
ocfs2_set_inode_data_inline(inode, di);
if (!folio_test_uptodate(folio)) {
- ret = ocfs2_read_inline_data(inode, &folio->page, wc->w_di_bh);
+ ret = ocfs2_read_inline_data(inode, folio, wc->w_di_bh);
if (ret) {
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index cf8d202d9a8b..6f25066e5756 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -41,7 +41,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
struct folio **foliop, void **fsdata,
struct buffer_head *di_bh, struct folio *mmap_folio);
-int ocfs2_read_inline_data(struct inode *inode, struct page *page,
+int ocfs2_read_inline_data(struct inode *inode, struct folio *folio,
struct buffer_head *di_bh);
int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 19/23] ocfs2: Convert ocfs2_read_inline_data() to take a folio
2024-12-05 17:16 ` [PATCH 19/23] ocfs2: Convert ocfs2_read_inline_data() to take a folio Matthew Wilcox (Oracle)
@ 2024-12-14 14:39 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:39 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: ocfs2-devel, Mark Tinguely
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> All callers now have a folio, so pass it in. We can use
> folio_fill_tail() instead of open-coding it. Saves a call to
> compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 2 +-
> fs/ocfs2/aops.c | 20 ++++++--------------
> fs/ocfs2/aops.h | 2 +-
> 3 files changed, 8 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index c8d9d5e9a7fd..36b536b54a2d 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -7135,7 +7135,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
> * This should populate the 1st page for us and mark
> * it up to date.
> */
> - ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
> + ret = ocfs2_read_inline_data(inode, folio, di_bh);
> if (ret) {
> mlog_errno(ret);
> need_free = 1;
> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
> index f1eba968563f..80fe7a68cbcc 100644
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -215,10 +215,9 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
> return err;
> }
>
> -int ocfs2_read_inline_data(struct inode *inode, struct page *page,
> +int ocfs2_read_inline_data(struct inode *inode, struct folio *folio,
> struct buffer_head *di_bh)
> {
> - void *kaddr;
> loff_t size;
> struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
>
> @@ -230,7 +229,7 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
>
> size = i_size_read(inode);
>
> - if (size > PAGE_SIZE ||
> + if (size > folio_size(folio) ||
> size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) {
> ocfs2_error(inode->i_sb,
> "Inode %llu has with inline data has bad size: %Lu\n",
> @@ -239,15 +238,8 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
> return -EROFS;
> }
>
> - kaddr = kmap_atomic(page);
> - if (size)
> - memcpy(kaddr, di->id2.i_data.id_data, size);
> - /* Clear the remaining part of the page */
> - memset(kaddr + size, 0, PAGE_SIZE - size);
> - flush_dcache_page(page);
> - kunmap_atomic(kaddr);
> -
> - SetPageUptodate(page);
> + folio_fill_tail(folio, 0, di->id2.i_data.id_data, size);
> + folio_mark_uptodate(folio);
>
> return 0;
> }
> @@ -266,7 +258,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct folio *folio)
> goto out;
> }
>
> - ret = ocfs2_read_inline_data(inode, &folio->page, di_bh);
> + ret = ocfs2_read_inline_data(inode, folio, di_bh);
> out:
> folio_unlock(folio);
>
> @@ -1506,7 +1498,7 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
> ocfs2_set_inode_data_inline(inode, di);
>
> if (!folio_test_uptodate(folio)) {
> - ret = ocfs2_read_inline_data(inode, &folio->page, wc->w_di_bh);
> + ret = ocfs2_read_inline_data(inode, folio, wc->w_di_bh);
> if (ret) {
> ocfs2_commit_trans(osb, handle);
>
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index cf8d202d9a8b..6f25066e5756 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -41,7 +41,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
> struct folio **foliop, void **fsdata,
> struct buffer_head *di_bh, struct folio *mmap_folio);
>
> -int ocfs2_read_inline_data(struct inode *inode, struct page *page,
> +int ocfs2_read_inline_data(struct inode *inode, struct folio *folio,
> struct buffer_head *di_bh);
> int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 20/23] ocfs2: Use a folio in ocfs2_fast_symlink_read_folio()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (18 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 19/23] ocfs2: Convert ocfs2_read_inline_data() to take a folio Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:43 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 21/23] ocfs2: Remove ocfs2_start_walk_page_trans() prototype Matthew Wilcox (Oracle)
` (2 subsequent siblings)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely
Use folio_end_read() instead of SetPageUptodate() and unlock_page().
Use memcpy_to_folio() instead of open-coding a kmap_atomic() sequence.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/symlink.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index f5cf2255dc09..ad8be3300b49 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -54,13 +54,11 @@
static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
{
- struct page *page = &folio->page;
- struct inode *inode = page->mapping->host;
+ struct inode *inode = folio->mapping->host;
struct buffer_head *bh = NULL;
int status = ocfs2_read_inode_block(inode, &bh);
struct ocfs2_dinode *fe;
const char *link;
- void *kaddr;
size_t len;
if (status < 0) {
@@ -72,12 +70,9 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
link = (char *) fe->id2.i_symlink;
/* will be less than a page size */
len = strnlen(link, ocfs2_fast_symlink_chars(inode->i_sb));
- kaddr = kmap_atomic(page);
- memcpy(kaddr, link, len + 1);
- kunmap_atomic(kaddr);
- SetPageUptodate(page);
+ memcpy_to_folio(folio, 0, link, len + 1);
out:
- unlock_page(page);
+ folio_end_read(folio, status == 0);
brelse(bh);
return status;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 20/23] ocfs2: Use a folio in ocfs2_fast_symlink_read_folio()
2024-12-05 17:16 ` [PATCH 20/23] ocfs2: Use a folio in ocfs2_fast_symlink_read_folio() Matthew Wilcox (Oracle)
@ 2024-12-14 14:43 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:43 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: ocfs2-devel, Mark Tinguely
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> Use folio_end_read() instead of SetPageUptodate() and unlock_page().
> Use memcpy_to_folio() instead of open-coding a kmap_atomic() sequence.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/symlink.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
> index f5cf2255dc09..ad8be3300b49 100644
> --- a/fs/ocfs2/symlink.c
> +++ b/fs/ocfs2/symlink.c
> @@ -54,13 +54,11 @@
>
> static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
> {
> - struct page *page = &folio->page;
> - struct inode *inode = page->mapping->host;
> + struct inode *inode = folio->mapping->host;
> struct buffer_head *bh = NULL;
> int status = ocfs2_read_inode_block(inode, &bh);
> struct ocfs2_dinode *fe;
> const char *link;
> - void *kaddr;
> size_t len;
>
> if (status < 0) {
> @@ -72,12 +70,9 @@ static int ocfs2_fast_symlink_read_folio(struct file *f, struct folio *folio)
> link = (char *) fe->id2.i_symlink;
> /* will be less than a page size */
> len = strnlen(link, ocfs2_fast_symlink_chars(inode->i_sb));
> - kaddr = kmap_atomic(page);
> - memcpy(kaddr, link, len + 1);
> - kunmap_atomic(kaddr);
> - SetPageUptodate(page);
> + memcpy_to_folio(folio, 0, link, len + 1);
> out:
> - unlock_page(page);
> + folio_end_read(folio, status == 0);
> brelse(bh);
> return status;
> }
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 21/23] ocfs2: Remove ocfs2_start_walk_page_trans() prototype
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (19 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 20/23] ocfs2: Use a folio in ocfs2_fast_symlink_read_folio() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:44 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 22/23] ocfs2: Support large folios in ocfs2_zero_cluster_folios() Matthew Wilcox (Oracle)
2024-12-05 17:16 ` [PATCH 23/23] ocfs2: Support large folios in ocfs2_write_zero_page() Matthew Wilcox (Oracle)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Matthew Wilcox (Oracle), ocfs2-devel, Mark Tinguely
This function no longer exists.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/aops.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 6f25066e5756..114efc9111e4 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -8,11 +8,6 @@
#include <linux/fs.h>
-handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
- struct page *page,
- unsigned from,
- unsigned to);
-
int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
struct inode *inode, unsigned int from,
unsigned int to, int new);
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 21/23] ocfs2: Remove ocfs2_start_walk_page_trans() prototype
2024-12-05 17:16 ` [PATCH 21/23] ocfs2: Remove ocfs2_start_walk_page_trans() prototype Matthew Wilcox (Oracle)
@ 2024-12-14 14:44 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:44 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: ocfs2-devel, Mark Tinguely
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> This function no longer exists.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/aops.h | 5 -----
> 1 file changed, 5 deletions(-)
>
> diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
> index 6f25066e5756..114efc9111e4 100644
> --- a/fs/ocfs2/aops.h
> +++ b/fs/ocfs2/aops.h
> @@ -8,11 +8,6 @@
>
> #include <linux/fs.h>
>
> -handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
> - struct page *page,
> - unsigned from,
> - unsigned to);
> -
> int ocfs2_map_folio_blocks(struct folio *folio, u64 *p_blkno,
> struct inode *inode, unsigned int from,
> unsigned int to, int new);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 22/23] ocfs2: Support large folios in ocfs2_zero_cluster_folios()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (20 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 21/23] ocfs2: Remove ocfs2_start_walk_page_trans() prototype Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:50 ` Joseph Qi
2024-12-05 17:16 ` [PATCH 23/23] ocfs2: Support large folios in ocfs2_write_zero_page() Matthew Wilcox (Oracle)
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Remove assumptions that a folio is one page in size.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/alloc.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 36b536b54a2d..3bff9314f8e0 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6851,7 +6851,6 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
u64 phys, handle_t *handle)
{
int i;
- unsigned int from, to = PAGE_SIZE;
struct super_block *sb = inode->i_sb;
BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb)));
@@ -6859,21 +6858,18 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
if (numfolios == 0)
goto out;
- to = PAGE_SIZE;
for (i = 0; i < numfolios; i++) {
struct folio *folio = folios[i];
+ size_t to = folio_size(folio);
+ size_t from = offset_in_folio(folio, start);
- from = start & (PAGE_SIZE - 1);
- if ((end >> PAGE_SHIFT) == folio->index)
- to = end & (PAGE_SIZE - 1);
-
- BUG_ON(from > PAGE_SIZE);
- BUG_ON(to > PAGE_SIZE);
+ if (to > end - folio_pos(folio))
+ to = end - folio_pos(folio);
ocfs2_map_and_dirty_folio(inode, handle, from, to, folio, 1,
&phys);
- start = (folio->index + 1) << PAGE_SHIFT;
+ start = folio_next_index(folio) << PAGE_SHIFT;
}
out:
if (folios)
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 22/23] ocfs2: Support large folios in ocfs2_zero_cluster_folios()
2024-12-05 17:16 ` [PATCH 22/23] ocfs2: Support large folios in ocfs2_zero_cluster_folios() Matthew Wilcox (Oracle)
@ 2024-12-14 14:50 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:50 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Remove assumptions that a folio is one page in size.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/alloc.c | 14 +++++---------
> 1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
> index 36b536b54a2d..3bff9314f8e0 100644
> --- a/fs/ocfs2/alloc.c
> +++ b/fs/ocfs2/alloc.c
> @@ -6851,7 +6851,6 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
> u64 phys, handle_t *handle)
> {
> int i;
> - unsigned int from, to = PAGE_SIZE;
> struct super_block *sb = inode->i_sb;
>
> BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(sb)));
> @@ -6859,21 +6858,18 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
> if (numfolios == 0)
> goto out;
>
> - to = PAGE_SIZE;
> for (i = 0; i < numfolios; i++) {
> struct folio *folio = folios[i];
> + size_t to = folio_size(folio);
> + size_t from = offset_in_folio(folio, start);
>
> - from = start & (PAGE_SIZE - 1);
> - if ((end >> PAGE_SHIFT) == folio->index)
> - to = end & (PAGE_SIZE - 1);
> -
> - BUG_ON(from > PAGE_SIZE);
> - BUG_ON(to > PAGE_SIZE);
> + if (to > end - folio_pos(folio))
> + to = end - folio_pos(folio);
>
> ocfs2_map_and_dirty_folio(inode, handle, from, to, folio, 1,
> &phys);
>
> - start = (folio->index + 1) << PAGE_SHIFT;
> + start = folio_next_index(folio) << PAGE_SHIFT;
> }
> out:
> if (folios)
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 23/23] ocfs2: Support large folios in ocfs2_write_zero_page()
2024-12-05 17:16 [PATCH 00/23] Convert ocfs2 to use folios Matthew Wilcox (Oracle)
` (21 preceding siblings ...)
2024-12-05 17:16 ` [PATCH 22/23] ocfs2: Support large folios in ocfs2_zero_cluster_folios() Matthew Wilcox (Oracle)
@ 2024-12-05 17:16 ` Matthew Wilcox (Oracle)
2024-12-14 14:51 ` Joseph Qi
22 siblings, 1 reply; 51+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-12-05 17:16 UTC (permalink / raw)
To: Joseph Qi; +Cc: Mark Tinguely, ocfs2-devel, Matthew Wilcox (Oracle)
From: Mark Tinguely <mark.tinguely@oracle.com>
Remove assumptions that a folio is PAGE_SIZE.
Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ocfs2/file.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 957ced628eb1..e54f2c4b5a90 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -782,11 +782,11 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from,
goto out_commit_trans;
}
- /* Get the offsets within the page that we want to zero */
- zero_from = abs_from & (PAGE_SIZE - 1);
- zero_to = abs_to & (PAGE_SIZE - 1);
+ /* Get the offsets within the folio that we want to zero */
+ zero_from = offset_in_folio(folio, abs_from);
+ zero_to = offset_in_folio(folio, abs_to);
if (!zero_to)
- zero_to = PAGE_SIZE;
+ zero_to = folio_size(folio);
trace_ocfs2_write_zero_page(
(unsigned long long)OCFS2_I(inode)->ip_blkno,
--
2.45.2
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH 23/23] ocfs2: Support large folios in ocfs2_write_zero_page()
2024-12-05 17:16 ` [PATCH 23/23] ocfs2: Support large folios in ocfs2_write_zero_page() Matthew Wilcox (Oracle)
@ 2024-12-14 14:51 ` Joseph Qi
0 siblings, 0 replies; 51+ messages in thread
From: Joseph Qi @ 2024-12-14 14:51 UTC (permalink / raw)
To: Matthew Wilcox (Oracle), akpm; +Cc: Mark Tinguely, ocfs2-devel
On 2024/12/6 01:16, Matthew Wilcox (Oracle) wrote:
> From: Mark Tinguely <mark.tinguely@oracle.com>
>
> Remove assumptions that a folio is PAGE_SIZE.
>
> Signed-off-by: Mark Tinguely <mark.tinguely@oracle.com>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Looks good.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/file.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
> index 957ced628eb1..e54f2c4b5a90 100644
> --- a/fs/ocfs2/file.c
> +++ b/fs/ocfs2/file.c
> @@ -782,11 +782,11 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from,
> goto out_commit_trans;
> }
>
> - /* Get the offsets within the page that we want to zero */
> - zero_from = abs_from & (PAGE_SIZE - 1);
> - zero_to = abs_to & (PAGE_SIZE - 1);
> + /* Get the offsets within the folio that we want to zero */
> + zero_from = offset_in_folio(folio, abs_from);
> + zero_to = offset_in_folio(folio, abs_to);
> if (!zero_to)
> - zero_to = PAGE_SIZE;
> + zero_to = folio_size(folio);
>
> trace_ocfs2_write_zero_page(
> (unsigned long long)OCFS2_I(inode)->ip_blkno,
^ permalink raw reply [flat|nested] 51+ messages in thread