From patchwork Tue Nov 7 19:41:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13449245 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CAE1315A6 for ; Tue, 7 Nov 2023 19:42:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="VkTFI7X6" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C763184 for ; Tue, 7 Nov 2023 11:42:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=HAzpO5vddckPLZx1GWapozUSPOMMErgj8L/dgMSKhKw=; b=VkTFI7X63TSu1cZJo7Df9ZDuTr 7tI5aMqYBN5e7UjerMZUWu/NaUabLqwTv/W7foixuIV1el3zdNnikBM926bDYuinrPNEOIAKdPJJY e9kynsCFDMERMvEoZhosBPTsofG6NGgSa9aer3B/zjE7e52H8PybCrWbZsCjJ3auKHrX3U7NsOShE 3L5+ZFKLH2XkMcvdt1YwJRbHjXDDbqTpk0lNcwCFK2ZnIDn/49nE8hjMzqT/hd/7IoBmCkbkcIxy2 1XBstEKxXBRZ0B1Y59vcjz7HW8D964BR+xTPQnkZBAjXvnBZ8HFelYOYRC+FXaluefnMUus9Frcqu +Jv58Y1A==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r0RxT-00E9kz-Ot; Tue, 07 Nov 2023 19:41:55 +0000 From: "Matthew Wilcox (Oracle)" To: Andrew Morton Cc: "Matthew Wilcox (Oracle)" , Hannes Reinecke , Luis Chamberlain , Pankaj Raghav , linux-fsdevel@vger.kernel.org Subject: [PATCH 1/5] buffer: Return bool from grow_dev_folio() Date: Tue, 7 Nov 2023 19:41:48 +0000 Message-Id: <20231107194152.3374087-2-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231107194152.3374087-1-willy@infradead.org> References: <20231107194152.3374087-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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) --- 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; } } From patchwork Tue Nov 7 19:41:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13449246 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9636F36B03 for ; Tue, 7 Nov 2023 19:42:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="QNYYV5S6" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4E7F184 for ; Tue, 7 Nov 2023 11:42:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=di9cP0sWSVGFPXpf5mG5HSbfipSWo6tzMdD/guucQIE=; b=QNYYV5S69yIS/x6nNFyk6Ly6xu I5i7KYGYIFVnNvTKXVs80gHR+MoGim7F+8O33ufaxAEJsi0+gukY62ykhX22MPSHKEYYHgStmEKuJ xXP2MaZEqabXg/atiBJ1OvwUVR8jfd4+aMW/msCfaUpinnlq42giVHxYV3wA+z6xwtQClquSR21SO 18pwxTP3UjFKFJkoqeEW4gIhWzOU5yIRb8n98xorYPOykUvfeJiFmcpDYgTqAmZO4TiIbxasonT5O F+17b9U/umem4VywdB02QseSuMP5QlKzTKq12ncPphxSPOXvgxApeGzhvWM+CrEPUl3ddxnArMKMK ZCeheHGg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r0RxT-00E9l1-RX; Tue, 07 Nov 2023 19:41:55 +0000 From: "Matthew Wilcox (Oracle)" To: Andrew Morton Cc: "Matthew Wilcox (Oracle)" , Hannes Reinecke , Luis Chamberlain , Pankaj Raghav , linux-fsdevel@vger.kernel.org Subject: [PATCH 2/5] buffer: Calculate block number inside folio_init_buffers() Date: Tue, 7 Nov 2023 19:41:49 +0000 Message-Id: <20231107194152.3374087-3-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231107194152.3374087-1-willy@infradead.org> References: <20231107194152.3374087-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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) Reviewed-by: Pankaj Raghav --- 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 * From patchwork Tue Nov 7 19:41:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13449249 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E65CF36AFE for ; Tue, 7 Nov 2023 19:42:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="q0e34h02" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51D8D184 for ; Tue, 7 Nov 2023 11:42:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=xfASZ8VSwupG8W8xOo2oafiHbZVPBxsrX/jji6c7RCA=; b=q0e34h02PybsihRcKWPK2JfGhP rRGN+p37Avy6kDYRbaYLagB1eGsZSxBEhGBGVcEgid5a2l/r4XGH98kFm4HgoiL4sztmK0xw4Mbs/ pRF4wTnHuBZwFBhmDnAX7SqG7I1RSDLBy8idnylhEtvhyXTr3ds/7zrJUzUA4R6/8zMl9shlScFqo mxnvaDdIuoy4QVWvKIl9mPQz6HW5ndOqiQ2LsL0yGt49KVV2lF3IISOe8tC5o2rRiPaBpJF5JB2nk 7wuexuV9jZWCbmNkMVetkgp9sUvWSY6p463YCrPQaD7PkydxcfaCEBmzYUFJKKJ1tI8ITJ8MOMvrF gV34sxYg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r0RxT-00E9l3-Ti; Tue, 07 Nov 2023 19:41:55 +0000 From: "Matthew Wilcox (Oracle)" To: Andrew Morton Cc: "Matthew Wilcox (Oracle)" , Hannes Reinecke , Luis Chamberlain , Pankaj Raghav , linux-fsdevel@vger.kernel.org Subject: [PATCH 3/5] buffer: Fix grow_buffers() for block size > PAGE_SIZE Date: Tue, 7 Nov 2023 19:41:50 +0000 Message-Id: <20231107194152.3374087-4-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231107194152.3374087-1-willy@infradead.org> References: <20231107194152.3374087-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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) --- 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 * From patchwork Tue Nov 7 19:41:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13449248 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ACBB636AFE for ; Tue, 7 Nov 2023 19:42:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="pyFIZPDq" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3537D184 for ; Tue, 7 Nov 2023 11:42:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=mtzc42jL92/A9PanSigtfnK/05Wkzw2xa6Ym8wnoe4o=; b=pyFIZPDqctPbt7Katju0AIszWP NJd1Sq4rnvUhPffnwpknxn2EQQrIUmp4mHxyzHhQfwL/c/XSxnqW7/ZjOTy5Y+PgIJO3Qysm7lvOn A/vCwRHWN1VNp0moP0OuzzHytuT1ir7EMFSkC3SLGFtyVdPp4mwCqOhawQFyPW5oqweM1ESq77DQ6 FgrkP4vBD9bZ4NIPFCrXkIhXqyubxD9Uci0ql6d7NcSMoeQnhjDm/5FkQg70QlcRZ5uCrR5vjFGoZ StxoJtg8y4XxUxVugVylTKtPji0tzZL9r3xcfc5X5R06UGs1PuO1fOeGjlHcg8+tO/YHmKPzOB/jL BmvFpAKg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r0RxU-00E9l5-0C; Tue, 07 Nov 2023 19:41:56 +0000 From: "Matthew Wilcox (Oracle)" To: Andrew Morton Cc: "Matthew Wilcox (Oracle)" , Hannes Reinecke , Luis Chamberlain , Pankaj Raghav , linux-fsdevel@vger.kernel.org Subject: [PATCH 4/5] buffer: Cast block to loff_t before shifting it Date: Tue, 7 Nov 2023 19:41:51 +0000 Message-Id: <20231107194152.3374087-5-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231107194152.3374087-1-willy@infradead.org> References: <20231107194152.3374087-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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) --- 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; From patchwork Tue Nov 7 19:41:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13449250 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 503A736AFE for ; Tue, 7 Nov 2023 19:42:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="TjRa542P" Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF2DB10C1 for ; Tue, 7 Nov 2023 11:42:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=Laz2KCiz/PqdHbx5lJ7LK8+snbPmisFVR4K15bIR380=; b=TjRa542PWstspcQhwbJZkkAO2O U3Q2oSpJZ1aJronnqjSRtG0YlXUadAkrtyBJ3bbJs0l66AfCN0aN8XHe1giUBnVHS128014pkLL2S xLRzdVEa6P1q4oc8tAbTsipWHiHq55XXSwfyV6LGiX2bVN/makgTNieuW+gJO3Hto1baxpt6Y6TCv /PGpLMu3a0Fx1h/gY/zTItqAZAQTCpRGbgdlditReeKQa6C1vLjmp1cIefiJcM2m8fn1jVCe9gx7H b/WyTB+FJqRWJWPrMlFr1oxeqOJj1kDaTeyCD/yqzDqCEb3ZUnVLZVFrtqhEkYFs3l0PIpwK241iq Zx8Pjv7Q==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r0RxU-00E9l7-CE; Tue, 07 Nov 2023 19:41:56 +0000 From: "Matthew Wilcox (Oracle)" To: Andrew Morton Cc: "Matthew Wilcox (Oracle)" , Hannes Reinecke , Luis Chamberlain , Pankaj Raghav , linux-fsdevel@vger.kernel.org Subject: [PATCH 5/5] buffer: Fix various functions for block size > PAGE_SIZE Date: Tue, 7 Nov 2023 19:41:52 +0000 Message-Id: <20231107194152.3374087-6-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231107194152.3374087-1-willy@infradead.org> References: <20231107194152.3374087-1-willy@infradead.org> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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) Reviewed-by: Pankaj Raghav --- 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);