diff mbox series

[12/16] romfs: Convert romfs_read_folio() to use a folio

Message ID 20240530202110.2653630-13-willy@infradead.org (mailing list archive)
State New
Headers show
Series Prepare to remove PG_error | expand

Commit Message

Matthew Wilcox May 30, 2024, 8:21 p.m. UTC
Remove the conversion back to struct page and use the folio APIs instead
of the page APIs.  It's probably more trouble than it's worth to support
large folios in romfs, so there are still PAGE_SIZE assumptions in
this function.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/romfs/super.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

Comments

Greg Ungerer Aug. 12, 2024, 1:46 a.m. UTC | #1
Hi Mathew,

On 31/5/24 06:21, Matthew Wilcox (Oracle) wrote:
> Remove the conversion back to struct page and use the folio APIs instead
> of the page APIs.  It's probably more trouble than it's worth to support
> large folios in romfs, so there are still PAGE_SIZE assumptions in
> this function.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

This is breaking for me on my m68k/ColdFire 5475 target. That is a full
MMU CPU. The usual test build I do (m5475evb_defconfig) fails to boot,
not being able to load and start init or sh at startup from a ROMfs
resident in RAM within the uclinux MTD mapper:

...
Freeing unused kernel image (initmem) memory: 80K
This architecture does not have kernel memory protection.
Run /sbin/init as init process
Run /etc/init as init process
Run /bin/init as init process
Starting init: /bin/init exists but couldn't execute it (error -13)
Run /bin/sh as init process
Starting init: /bin/sh exists but couldn't execute it (error -13)
Kernel panic - not syncing: No working init found.  Try passing init= option to
kernel. See Linux Documentation/admin-guide/init.rst for guidance.
CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.11.0-rc3 #4
Stack from 00829f74:
         00829f74 003d8508 003d8508 00000000 0000000a 00000003 0032b864 003d8508
         00325126 00000001 00002700 00000003 00829fb0 00324e9e 00000000 00000000
         00000000 0032ba9a 003ce1bd 0032b9b8 000218a4 00000000 00000000 00000000
         00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
         00000000 00002000 00000000
Call Trace: [<0032b864>] dump_stack+0xc/0x10
  [<00325126>] panic+0xca/0x236
  [<00324e9e>] try_to_run_init_process+0x0/0x36
  [<0032ba9a>] kernel_init+0xe2/0xe8
  [<0032b9b8>] kernel_init+0x0/0xe8
  [<000218a4>] ret_from_kernel_thread+0xc/0x14

Reverting this change gets it going again.

Any idea what might be going on?

Regards
Greg


> ---
>   fs/romfs/super.c | 22 ++++++----------------
>   1 file changed, 6 insertions(+), 16 deletions(-)
> 
> diff --git a/fs/romfs/super.c b/fs/romfs/super.c
> index 2cbb92462074..68758b6fed94 100644
> --- a/fs/romfs/super.c
> +++ b/fs/romfs/super.c
> @@ -101,19 +101,15 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos);
>    */
>   static int romfs_read_folio(struct file *file, struct folio *folio)
>   {
> -	struct page *page = &folio->page;
> -	struct inode *inode = page->mapping->host;
> +	struct inode *inode = folio->mapping->host;
>   	loff_t offset, size;
>   	unsigned long fillsize, pos;
>   	void *buf;
>   	int ret;
>   
> -	buf = kmap(page);
> -	if (!buf)
> -		return -ENOMEM;
> +	buf = kmap_local_folio(folio, 0);
>   
> -	/* 32 bit warning -- but not for us :) */
> -	offset = page_offset(page);
> +	offset = folio_pos(folio);
>   	size = i_size_read(inode);
>   	fillsize = 0;
>   	ret = 0;
> @@ -125,20 +121,14 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
>   
>   		ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize);
>   		if (ret < 0) {
> -			SetPageError(page);
>   			fillsize = 0;
>   			ret = -EIO;
>   		}
>   	}
>   
> -	if (fillsize < PAGE_SIZE)
> -		memset(buf + fillsize, 0, PAGE_SIZE - fillsize);
> -	if (ret == 0)
> -		SetPageUptodate(page);
> -
> -	flush_dcache_page(page);
> -	kunmap(page);
> -	unlock_page(page);
> +	buf = folio_zero_tail(folio, fillsize, buf);
> +	kunmap_local(buf);
> +	folio_end_read(folio, ret == 0);
>   	return ret;
>   }
>
Matthew Wilcox Aug. 12, 2024, 3:30 a.m. UTC | #2
On Mon, Aug 12, 2024 at 11:46:34AM +1000, Greg Ungerer wrote:
> > @@ -125,20 +121,14 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
> >   		ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize);
> >   		if (ret < 0) {
> > -			SetPageError(page);
> >   			fillsize = 0;
> >   			ret = -EIO;
> >   		}
> >   	}
> > -	if (fillsize < PAGE_SIZE)
> > -		memset(buf + fillsize, 0, PAGE_SIZE - fillsize);
> > -	if (ret == 0)
> > -		SetPageUptodate(page);
> > -
> > -	flush_dcache_page(page);
> > -	kunmap(page);
> > -	unlock_page(page);
> > +	buf = folio_zero_tail(folio, fillsize, buf);

I think this should have been:

	buf = folio_zero_tail(folio, fillsize, buf + fillsize);

Can you give that a try?
Greg Ungerer Aug. 12, 2024, 4:36 a.m. UTC | #3
On 12/8/24 13:30, Matthew Wilcox wrote:
> On Mon, Aug 12, 2024 at 11:46:34AM +1000, Greg Ungerer wrote:
>>> @@ -125,20 +121,14 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
>>>    		ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize);
>>>    		if (ret < 0) {
>>> -			SetPageError(page);
>>>    			fillsize = 0;
>>>    			ret = -EIO;
>>>    		}
>>>    	}
>>> -	if (fillsize < PAGE_SIZE)
>>> -		memset(buf + fillsize, 0, PAGE_SIZE - fillsize);
>>> -	if (ret == 0)
>>> -		SetPageUptodate(page);
>>> -
>>> -	flush_dcache_page(page);
>>> -	kunmap(page);
>>> -	unlock_page(page);
>>> +	buf = folio_zero_tail(folio, fillsize, buf);
> 
> I think this should have been:
> 
> 	buf = folio_zero_tail(folio, fillsize, buf + fillsize);
> 
> Can you give that a try?

Yep, that fixes it.

Thanks
Greg
Matthew Wilcox Aug. 14, 2024, 7:32 p.m. UTC | #4
On Mon, Aug 12, 2024 at 02:36:57PM +1000, Greg Ungerer wrote:
> Yep, that fixes it.

Christian, can you apply this fix, please?

diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 68758b6fed94..0addcc849ff2 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -126,7 +126,7 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
 		}
 	}
 
-	buf = folio_zero_tail(folio, fillsize, buf);
+	buf = folio_zero_tail(folio, fillsize, buf + fillsize);
 	kunmap_local(buf);
 	folio_end_read(folio, ret == 0);
 	return ret;
Christian Brauner Aug. 15, 2024, 12:42 p.m. UTC | #5
On Wed, Aug 14, 2024 at 08:32:30PM GMT, Matthew Wilcox wrote:
> On Mon, Aug 12, 2024 at 02:36:57PM +1000, Greg Ungerer wrote:
> > Yep, that fixes it.
> 
> Christian, can you apply this fix, please?
> 
> diff --git a/fs/romfs/super.c b/fs/romfs/super.c
> index 68758b6fed94..0addcc849ff2 100644
> --- a/fs/romfs/super.c
> +++ b/fs/romfs/super.c
> @@ -126,7 +126,7 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
>  		}
>  	}
>  
> -	buf = folio_zero_tail(folio, fillsize, buf);
> +	buf = folio_zero_tail(folio, fillsize, buf + fillsize);
>  	kunmap_local(buf);
>  	folio_end_read(folio, ret == 0);
>  	return ret;

Yep, please see #vfs.fixes. The whole series is already upstream.
Greg Ungerer Aug. 26, 2024, 1:34 a.m. UTC | #6
On 15/8/24 22:42, Christian Brauner wrote:
> On Wed, Aug 14, 2024 at 08:32:30PM GMT, Matthew Wilcox wrote:
>> On Mon, Aug 12, 2024 at 02:36:57PM +1000, Greg Ungerer wrote:
>>> Yep, that fixes it.
>>
>> Christian, can you apply this fix, please?
>>
>> diff --git a/fs/romfs/super.c b/fs/romfs/super.c
>> index 68758b6fed94..0addcc849ff2 100644
>> --- a/fs/romfs/super.c
>> +++ b/fs/romfs/super.c
>> @@ -126,7 +126,7 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
>>   		}
>>   	}
>>   
>> -	buf = folio_zero_tail(folio, fillsize, buf);
>> +	buf = folio_zero_tail(folio, fillsize, buf + fillsize);
>>   	kunmap_local(buf);
>>   	folio_end_read(folio, ret == 0);
>>   	return ret;
> 
> Yep, please see #vfs.fixes. The whole series is already upstream.

Just a heads up, this is still broken in 6.11-rc5.
Christian Brauner Aug. 26, 2024, 10:42 a.m. UTC | #7
On Mon, Aug 26, 2024 at 11:34:21AM GMT, Greg Ungerer wrote:
> 
> On 15/8/24 22:42, Christian Brauner wrote:
> > On Wed, Aug 14, 2024 at 08:32:30PM GMT, Matthew Wilcox wrote:
> > > On Mon, Aug 12, 2024 at 02:36:57PM +1000, Greg Ungerer wrote:
> > > > Yep, that fixes it.
> > > 
> > > Christian, can you apply this fix, please?
> > > 
> > > diff --git a/fs/romfs/super.c b/fs/romfs/super.c
> > > index 68758b6fed94..0addcc849ff2 100644
> > > --- a/fs/romfs/super.c
> > > +++ b/fs/romfs/super.c
> > > @@ -126,7 +126,7 @@ static int romfs_read_folio(struct file *file, struct folio *folio)
> > >   		}
> > >   	}
> > > -	buf = folio_zero_tail(folio, fillsize, buf);
> > > +	buf = folio_zero_tail(folio, fillsize, buf + fillsize);
> > >   	kunmap_local(buf);
> > >   	folio_end_read(folio, ret == 0);
> > >   	return ret;
> > 
> > Yep, please see #vfs.fixes. The whole series is already upstream.
> 
> Just a heads up, this is still broken in 6.11-rc5.

Pull request will be becoming today. Some fixes in the netfs library
caused some delays because they had to be redone a few times.
diff mbox series

Patch

diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 2cbb92462074..68758b6fed94 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -101,19 +101,15 @@  static struct inode *romfs_iget(struct super_block *sb, unsigned long pos);
  */
 static int romfs_read_folio(struct file *file, struct folio *folio)
 {
-	struct page *page = &folio->page;
-	struct inode *inode = page->mapping->host;
+	struct inode *inode = folio->mapping->host;
 	loff_t offset, size;
 	unsigned long fillsize, pos;
 	void *buf;
 	int ret;
 
-	buf = kmap(page);
-	if (!buf)
-		return -ENOMEM;
+	buf = kmap_local_folio(folio, 0);
 
-	/* 32 bit warning -- but not for us :) */
-	offset = page_offset(page);
+	offset = folio_pos(folio);
 	size = i_size_read(inode);
 	fillsize = 0;
 	ret = 0;
@@ -125,20 +121,14 @@  static int romfs_read_folio(struct file *file, struct folio *folio)
 
 		ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize);
 		if (ret < 0) {
-			SetPageError(page);
 			fillsize = 0;
 			ret = -EIO;
 		}
 	}
 
-	if (fillsize < PAGE_SIZE)
-		memset(buf + fillsize, 0, PAGE_SIZE - fillsize);
-	if (ret == 0)
-		SetPageUptodate(page);
-
-	flush_dcache_page(page);
-	kunmap(page);
-	unlock_page(page);
+	buf = folio_zero_tail(folio, fillsize, buf);
+	kunmap_local(buf);
+	folio_end_read(folio, ret == 0);
 	return ret;
 }