linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] More buffer_head cleanups
@ 2023-11-07 19:41 Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 1/5] buffer: Return bool from grow_dev_folio() Matthew Wilcox (Oracle)
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

The first patch is a left-over from last cycle.  The rest fix "obvious"
block size > PAGE_SIZE problems.  I haven't tested with a large block
size setup.

Matthew Wilcox (Oracle) (5):
  buffer: Return bool from grow_dev_folio()
  buffer: Calculate block number inside folio_init_buffers()
  buffer: Fix grow_buffers() for block size > PAGE_SIZE
  buffer: Cast block to loff_t before shifting it
  buffer: Fix various functions for block size > PAGE_SIZE

 fs/buffer.c | 86 +++++++++++++++++++++++++----------------------------
 1 file changed, 40 insertions(+), 46 deletions(-)

-- 
2.42.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] buffer: Return bool from grow_dev_folio()
  2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
@ 2023-11-07 19:41 ` Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers() Matthew Wilcox (Oracle)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

Rename grow_dev_page() to grow_dev_folio() and make it return a bool.
Document what that bool means; it's more subtle than it first appears.
Also rename the 'failed' label to 'unlock' beacuse it's not exactly
'failed'.  It just hasn't succeeded.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/buffer.c | 50 +++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index 967f34b70aa8..8dad6c691e14 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1024,40 +1024,43 @@ static sector_t folio_init_buffers(struct folio *folio,
 }
 
 /*
- * Create the page-cache page that contains the requested block.
+ * Create the page-cache folio that contains the requested block.
  *
  * This is used purely for blockdev mappings.
+ *
+ * Returns false if we have a 'permanent' failure.  Returns true if
+ * we succeeded, or the caller should retry.
  */
-static int
-grow_dev_page(struct block_device *bdev, sector_t block,
-	      pgoff_t index, int size, int sizebits, gfp_t gfp)
+static bool grow_dev_folio(struct block_device *bdev, sector_t block,
+		pgoff_t index, unsigned size, int sizebits, gfp_t gfp)
 {
 	struct inode *inode = bdev->bd_inode;
 	struct folio *folio;
 	struct buffer_head *bh;
-	sector_t end_block;
-	int ret = 0;
+	sector_t end_block = 0;
 
 	folio = __filemap_get_folio(inode->i_mapping, index,
 			FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
 	if (IS_ERR(folio))
-		return PTR_ERR(folio);
+		return false;
 
 	bh = folio_buffers(folio);
 	if (bh) {
 		if (bh->b_size == size) {
 			end_block = folio_init_buffers(folio, bdev,
 					(sector_t)index << sizebits, size);
-			goto done;
+			goto unlock;
 		}
+
+		/* Caller should retry if this call fails */
+		end_block = ~0ULL;
 		if (!try_to_free_buffers(folio))
-			goto failed;
+			goto unlock;
 	}
 
-	ret = -ENOMEM;
 	bh = folio_alloc_buffers(folio, size, gfp | __GFP_ACCOUNT);
 	if (!bh)
-		goto failed;
+		goto unlock;
 
 	/*
 	 * Link the folio to the buffers and initialise them.  Take the
@@ -1069,20 +1072,19 @@ grow_dev_page(struct block_device *bdev, sector_t block,
 	end_block = folio_init_buffers(folio, bdev,
 			(sector_t)index << sizebits, size);
 	spin_unlock(&inode->i_mapping->private_lock);
-done:
-	ret = (block < end_block) ? 1 : -ENXIO;
-failed:
+unlock:
 	folio_unlock(folio);
 	folio_put(folio);
-	return ret;
+	return block < end_block;
 }
 
 /*
- * Create buffers for the specified block device block's page.  If
- * that page was dirty, the buffers are set dirty also.
+ * Create buffers for the specified block device block's folio.  If
+ * that folio was dirty, the buffers are set dirty also.  Returns false
+ * if we've hit a permanent error.
  */
-static int
-grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp)
+static bool grow_buffers(struct block_device *bdev, sector_t block,
+		unsigned size, gfp_t gfp)
 {
 	pgoff_t index;
 	int sizebits;
@@ -1099,11 +1101,11 @@ grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp)
 			"device %pg\n",
 			__func__, (unsigned long long)block,
 			bdev);
-		return -EIO;
+		return false;
 	}
 
-	/* Create a page with the proper size buffers.. */
-	return grow_dev_page(bdev, block, index, size, sizebits, gfp);
+	/* Create a folio with the proper size buffers */
+	return grow_dev_folio(bdev, block, index, size, sizebits, gfp);
 }
 
 static struct buffer_head *
@@ -1124,14 +1126,12 @@ __getblk_slow(struct block_device *bdev, sector_t block,
 
 	for (;;) {
 		struct buffer_head *bh;
-		int ret;
 
 		bh = __find_get_block(bdev, block, size);
 		if (bh)
 			return bh;
 
-		ret = grow_buffers(bdev, block, size, gfp);
-		if (ret < 0)
+		if (!grow_buffers(bdev, block, size, gfp))
 			return NULL;
 	}
 }
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers()
  2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 1/5] buffer: Return bool from grow_dev_folio() Matthew Wilcox (Oracle)
@ 2023-11-07 19:41 ` Matthew Wilcox (Oracle)
       [not found]   ` <CGME20231108145953eucas1p2eeaf54e93c10cbf501a43f594e23438a@eucas1p2.samsung.com>
  2023-11-08 17:30   ` kernel test robot
  2023-11-07 19:41 ` [PATCH 3/5] buffer: Fix grow_buffers() for block size > PAGE_SIZE Matthew Wilcox (Oracle)
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

The calculation of block from index doesn't work for devices with a block
size larger than PAGE_SIZE as we end up shifting by a negative number.
Instead, calculate the number of the first block from the folio's
position in the block device.  We no longer need to pass sizebits to
grow_dev_folio().

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

diff --git a/fs/buffer.c b/fs/buffer.c
index 8dad6c691e14..cd114110b27f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -995,11 +995,12 @@ static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
  * Initialise the state of a blockdev folio's buffers.
  */ 
 static sector_t folio_init_buffers(struct folio *folio,
-		struct block_device *bdev, sector_t block, int size)
+		struct block_device *bdev, int size)
 {
 	struct buffer_head *head = folio_buffers(folio);
 	struct buffer_head *bh = head;
 	bool uptodate = folio_test_uptodate(folio);
+	sector_t block = folio_pos(folio) / size;
 	sector_t end_block = blkdev_max_block(bdev, size);
 
 	do {
@@ -1032,7 +1033,7 @@ static sector_t folio_init_buffers(struct folio *folio,
  * we succeeded, or the caller should retry.
  */
 static bool grow_dev_folio(struct block_device *bdev, sector_t block,
-		pgoff_t index, unsigned size, int sizebits, gfp_t gfp)
+		pgoff_t index, unsigned size, gfp_t gfp)
 {
 	struct inode *inode = bdev->bd_inode;
 	struct folio *folio;
@@ -1047,8 +1048,7 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
 	bh = folio_buffers(folio);
 	if (bh) {
 		if (bh->b_size == size) {
-			end_block = folio_init_buffers(folio, bdev,
-					(sector_t)index << sizebits, size);
+			end_block = folio_init_buffers(folio, bdev, size);
 			goto unlock;
 		}
 
@@ -1069,8 +1069,7 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
 	 */
 	spin_lock(&inode->i_mapping->private_lock);
 	link_dev_buffers(folio, bh);
-	end_block = folio_init_buffers(folio, bdev,
-			(sector_t)index << sizebits, size);
+	end_block = folio_init_buffers(folio, bdev, size);
 	spin_unlock(&inode->i_mapping->private_lock);
 unlock:
 	folio_unlock(folio);
@@ -1105,7 +1104,7 @@ static bool grow_buffers(struct block_device *bdev, sector_t block,
 	}
 
 	/* Create a folio with the proper size buffers */
-	return grow_dev_folio(bdev, block, index, size, sizebits, gfp);
+	return grow_dev_folio(bdev, block, index, size, gfp);
 }
 
 static struct buffer_head *
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] buffer: Fix grow_buffers() for block size > PAGE_SIZE
  2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 1/5] buffer: Return bool from grow_dev_folio() Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers() Matthew Wilcox (Oracle)
@ 2023-11-07 19:41 ` Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 4/5] buffer: Cast block to loff_t before shifting it Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE Matthew Wilcox (Oracle)
  4 siblings, 0 replies; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

We must not shift by a negative number so work in terms of a byte
offset to avoid the awkward shift left-or-right-depending-on-sign
option.  This means we need to use check_mul_overflow() to ensure
that a large block number does not result in a wrap.

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

diff --git a/fs/buffer.c b/fs/buffer.c
index cd114110b27f..c83bb89b2e24 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1085,26 +1085,21 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
 static bool grow_buffers(struct block_device *bdev, sector_t block,
 		unsigned size, gfp_t gfp)
 {
-	pgoff_t index;
-	int sizebits;
-
-	sizebits = PAGE_SHIFT - __ffs(size);
-	index = block >> sizebits;
+	loff_t pos;
 
 	/*
-	 * Check for a block which wants to lie outside our maximum possible
-	 * pagecache index.  (this comparison is done using sector_t types).
+	 * Check for a block which lies outside our maximum possible
+	 * pagecache index.
 	 */
-	if (unlikely(index != block >> sizebits)) {
-		printk(KERN_ERR "%s: requested out-of-range block %llu for "
-			"device %pg\n",
+	if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) {
+		printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n",
 			__func__, (unsigned long long)block,
 			bdev);
 		return false;
 	}
 
 	/* Create a folio with the proper size buffers */
-	return grow_dev_folio(bdev, block, index, size, gfp);
+	return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp);
 }
 
 static struct buffer_head *
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] buffer: Cast block to loff_t before shifting it
  2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
                   ` (2 preceding siblings ...)
  2023-11-07 19:41 ` [PATCH 3/5] buffer: Fix grow_buffers() for block size > PAGE_SIZE Matthew Wilcox (Oracle)
@ 2023-11-07 19:41 ` Matthew Wilcox (Oracle)
  2023-11-07 19:41 ` [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE Matthew Wilcox (Oracle)
  4 siblings, 0 replies; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

While sector_t is always defined as a u64 today, that hasn't always been
the case and it might not always be the same size as loff_t in the future.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/buffer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index c83bb89b2e24..2f08af3c47a2 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2008,7 +2008,7 @@ static int
 iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
 		const struct iomap *iomap)
 {
-	loff_t offset = block << inode->i_blkbits;
+	loff_t offset = (loff_t)block << inode->i_blkbits;
 
 	bh->b_bdev = iomap->bdev;
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE
  2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
                   ` (3 preceding siblings ...)
  2023-11-07 19:41 ` [PATCH 4/5] buffer: Cast block to loff_t before shifting it Matthew Wilcox (Oracle)
@ 2023-11-07 19:41 ` Matthew Wilcox (Oracle)
       [not found]   ` <CGME20231108151744eucas1p229d2073ae889eb95caed90b1f83821c3@eucas1p2.samsung.com>
  4 siblings, 1 reply; 10+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-07 19:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

If i_blkbits is larger than PAGE_SHIFT, we shift by a negative number,
which is undefined.  It is safe to shift the block left as a block
device must be smaller than MAX_LFS_FILESIZE, which is guaranteed to
fit in loff_t.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/buffer.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index 2f08af3c47a2..5bdfcf8c6fe6 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -199,7 +199,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block)
 	int all_mapped = 1;
 	static DEFINE_RATELIMIT_STATE(last_warned, HZ, 1);
 
-	index = block >> (PAGE_SHIFT - bd_inode->i_blkbits);
+	index = ((loff_t)block << bd_inode->i_blkbits) / PAGE_SIZE;
 	folio = __filemap_get_folio(bd_mapping, index, FGP_ACCESSED, 0);
 	if (IS_ERR(folio))
 		goto out;
@@ -1693,13 +1693,13 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 	struct inode *bd_inode = bdev->bd_inode;
 	struct address_space *bd_mapping = bd_inode->i_mapping;
 	struct folio_batch fbatch;
-	pgoff_t index = block >> (PAGE_SHIFT - bd_inode->i_blkbits);
+	pgoff_t index = ((loff_t)block << bd_inode->i_blkbits) / PAGE_SIZE;
 	pgoff_t end;
 	int i, count;
 	struct buffer_head *bh;
 	struct buffer_head *head;
 
-	end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits);
+	end = ((loff_t)(block + len - 1) << bd_inode->i_blkbits) / PAGE_SIZE;
 	folio_batch_init(&fbatch);
 	while (filemap_get_folios(bd_mapping, &index, end, &fbatch)) {
 		count = folio_batch_count(&fbatch);
@@ -2660,8 +2660,8 @@ int block_truncate_page(struct address_space *mapping,
 		return 0;
 
 	length = blocksize - length;
-	iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits);
-	
+	iblock = ((loff_t)index * PAGE_SIZE) >> inode->i_blkbits;
+
 	folio = filemap_grab_folio(mapping, index);
 	if (IS_ERR(folio))
 		return PTR_ERR(folio);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers()
       [not found]   ` <CGME20231108145953eucas1p2eeaf54e93c10cbf501a43f594e23438a@eucas1p2.samsung.com>
@ 2023-11-08 14:59     ` Pankaj Raghav
  2023-11-08 15:22       ` Matthew Wilcox
  0 siblings, 1 reply; 10+ messages in thread
From: Pankaj Raghav @ 2023-11-08 14:59 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle)
  Cc: Andrew Morton, Hannes Reinecke, Luis Chamberlain, linux-fsdevel,
	p.raghav

On Tue, Nov 07, 2023 at 07:41:49PM +0000, Matthew Wilcox (Oracle) wrote:
> The calculation of block from index doesn't work for devices with a block
> size larger than PAGE_SIZE as we end up shifting by a negative number.
> Instead, calculate the number of the first block from the folio's
> position in the block device.  We no longer need to pass sizebits to
> grow_dev_folio().
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

Not totally related to the patch but even though the variable "block"
is sector_t type, but it represents the block number in logical block
size unit of the device? My mind directly went to sector_t being 512
bytes blocks.

But the math checks out.
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
> ---
>  fs/buffer.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/buffer.c b/fs/buffer.c
> index 8dad6c691e14..cd114110b27f 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -995,11 +995,12 @@ static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
>   * Initialise the state of a blockdev folio's buffers.
>   */ 
>  static sector_t folio_init_buffers(struct folio *folio,
> -		struct block_device *bdev, sector_t block, int size)
> +		struct block_device *bdev, int size)
>  {
>  	struct buffer_head *head = folio_buffers(folio);
>  	struct buffer_head *bh = head;
>  	bool uptodate = folio_test_uptodate(folio);
> +	sector_t block = folio_pos(folio) / size;
>  	sector_t end_block = blkdev_max_block(bdev, size);
>  
>  	do {
> @@ -1032,7 +1033,7 @@ static sector_t folio_init_buffers(struct folio *folio,
>   * we succeeded, or the caller should retry.
>   */
>  static bool grow_dev_folio(struct block_device *bdev, sector_t block,
> -		pgoff_t index, unsigned size, int sizebits, gfp_t gfp)
> +		pgoff_t index, unsigned size, gfp_t gfp)
>  {
>  	struct inode *inode = bdev->bd_inode;
>  	struct folio *folio;
> @@ -1047,8 +1048,7 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
>  	bh = folio_buffers(folio);
>  	if (bh) {
>  		if (bh->b_size == size) {
> -			end_block = folio_init_buffers(folio, bdev,
> -					(sector_t)index << sizebits, size);
> +			end_block = folio_init_buffers(folio, bdev, size);
>  			goto unlock;
>  		}
>  
> @@ -1069,8 +1069,7 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block,
>  	 */
>  	spin_lock(&inode->i_mapping->private_lock);
>  	link_dev_buffers(folio, bh);
> -	end_block = folio_init_buffers(folio, bdev,
> -			(sector_t)index << sizebits, size);
> +	end_block = folio_init_buffers(folio, bdev, size);
>  	spin_unlock(&inode->i_mapping->private_lock);
>  unlock:
>  	folio_unlock(folio);
> @@ -1105,7 +1104,7 @@ static bool grow_buffers(struct block_device *bdev, sector_t block,
>  	}
>  
>  	/* Create a folio with the proper size buffers */
> -	return grow_dev_folio(bdev, block, index, size, sizebits, gfp);
> +	return grow_dev_folio(bdev, block, index, size, gfp);
>  }
>  
>  static struct buffer_head *
> -- 
> 2.42.0
> 

-- 
Pankaj Raghav

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE
       [not found]   ` <CGME20231108151744eucas1p229d2073ae889eb95caed90b1f83821c3@eucas1p2.samsung.com>
@ 2023-11-08 15:17     ` Pankaj Raghav
  0 siblings, 0 replies; 10+ messages in thread
From: Pankaj Raghav @ 2023-11-08 15:17 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle)
  Cc: Andrew Morton, Hannes Reinecke, Luis Chamberlain, linux-fsdevel,
	p.raghav

On Tue, Nov 07, 2023 at 07:41:52PM +0000, Matthew Wilcox (Oracle) wrote:
> If i_blkbits is larger than PAGE_SHIFT, we shift by a negative number,
> which is undefined.  It is safe to shift the block left as a block
> device must be smaller than MAX_LFS_FILESIZE, which is guaranteed to
> fit in loff_t.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

Looks good,
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>

> ---
>  fs/buffer.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/buffer.c b/fs/buffer.c
> index 2f08af3c47a2..5bdfcf8c6fe6 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -199,7 +199,7 @@ __find_get_block_slow(struct block_device *bdev, sector_t block)
>  	int all_mapped = 1;
>  	static DEFINE_RATELIMIT_STATE(last_warned, HZ, 1);
>  
> -	index = block >> (PAGE_SHIFT - bd_inode->i_blkbits);
> +	index = ((loff_t)block << bd_inode->i_blkbits) / PAGE_SIZE;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers()
  2023-11-08 14:59     ` Pankaj Raghav
@ 2023-11-08 15:22       ` Matthew Wilcox
  0 siblings, 0 replies; 10+ messages in thread
From: Matthew Wilcox @ 2023-11-08 15:22 UTC (permalink / raw)
  To: Pankaj Raghav
  Cc: Andrew Morton, Hannes Reinecke, Luis Chamberlain, linux-fsdevel

On Wed, Nov 08, 2023 at 03:59:51PM +0100, Pankaj Raghav wrote:
> On Tue, Nov 07, 2023 at 07:41:49PM +0000, Matthew Wilcox (Oracle) wrote:
> > The calculation of block from index doesn't work for devices with a block
> > size larger than PAGE_SIZE as we end up shifting by a negative number.
> > Instead, calculate the number of the first block from the folio's
> > position in the block device.  We no longer need to pass sizebits to
> > grow_dev_folio().
> > 
> > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> 
> Not totally related to the patch but even though the variable "block"
> is sector_t type, but it represents the block number in logical block
> size unit of the device? My mind directly went to sector_t being 512
> bytes blocks.

Yes; it's confusing.  buffer_heads are always created for the logical
block size that the filesystem mounted on the device needs.  It's
never for the fixed-size 512 byte sectors (but might happen to be
512 bytes if that's what the fs has set the block device to).

> But the math checks out.
> Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>

Thanks!

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers()
  2023-11-07 19:41 ` [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers() Matthew Wilcox (Oracle)
       [not found]   ` <CGME20231108145953eucas1p2eeaf54e93c10cbf501a43f594e23438a@eucas1p2.samsung.com>
@ 2023-11-08 17:30   ` kernel test robot
  1 sibling, 0 replies; 10+ messages in thread
From: kernel test robot @ 2023-11-08 17:30 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle), Andrew Morton
  Cc: oe-kbuild-all, Linux Memory Management List,
	Matthew Wilcox (Oracle), Hannes Reinecke, Luis Chamberlain,
	Pankaj Raghav, linux-fsdevel

Hi Matthew,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master next-20231108]
[cannot apply to v6.6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Return-bool-from-grow_dev_folio/20231108-035905
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20231107194152.3374087-3-willy%40infradead.org
patch subject: [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers()
config: i386-randconfig-141-20231108 (https://download.01.org/0day-ci/archive/20231109/202311090123.FRvXagQt-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231109/202311090123.FRvXagQt-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311090123.FRvXagQt-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: fs/buffer.o: in function `folio_init_buffers':
>> fs/buffer.c:1003: undefined reference to `__divdi3'


vim +1003 fs/buffer.c

   993	
   994	/*
   995	 * Initialise the state of a blockdev folio's buffers.
   996	 */ 
   997	static sector_t folio_init_buffers(struct folio *folio,
   998			struct block_device *bdev, int size)
   999	{
  1000		struct buffer_head *head = folio_buffers(folio);
  1001		struct buffer_head *bh = head;
  1002		bool uptodate = folio_test_uptodate(folio);
> 1003		sector_t block = folio_pos(folio) / size;
  1004		sector_t end_block = blkdev_max_block(bdev, size);
  1005	
  1006		do {
  1007			if (!buffer_mapped(bh)) {
  1008				bh->b_end_io = NULL;
  1009				bh->b_private = NULL;
  1010				bh->b_bdev = bdev;
  1011				bh->b_blocknr = block;
  1012				if (uptodate)
  1013					set_buffer_uptodate(bh);
  1014				if (block < end_block)
  1015					set_buffer_mapped(bh);
  1016			}
  1017			block++;
  1018			bh = bh->b_this_page;
  1019		} while (bh != head);
  1020	
  1021		/*
  1022		 * Caller needs to validate requested block against end of device.
  1023		 */
  1024		return end_block;
  1025	}
  1026	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-11-08 17:33 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-07 19:41 [PATCH 0/5] More buffer_head cleanups Matthew Wilcox (Oracle)
2023-11-07 19:41 ` [PATCH 1/5] buffer: Return bool from grow_dev_folio() Matthew Wilcox (Oracle)
2023-11-07 19:41 ` [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers() Matthew Wilcox (Oracle)
     [not found]   ` <CGME20231108145953eucas1p2eeaf54e93c10cbf501a43f594e23438a@eucas1p2.samsung.com>
2023-11-08 14:59     ` Pankaj Raghav
2023-11-08 15:22       ` Matthew Wilcox
2023-11-08 17:30   ` kernel test robot
2023-11-07 19:41 ` [PATCH 3/5] buffer: Fix grow_buffers() for block size > PAGE_SIZE Matthew Wilcox (Oracle)
2023-11-07 19:41 ` [PATCH 4/5] buffer: Cast block to loff_t before shifting it Matthew Wilcox (Oracle)
2023-11-07 19:41 ` [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE Matthew Wilcox (Oracle)
     [not found]   ` <CGME20231108151744eucas1p229d2073ae889eb95caed90b1f83821c3@eucas1p2.samsung.com>
2023-11-08 15:17     ` Pankaj Raghav

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).