From patchwork Mon Mar 6 12:01:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 13161018 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C64B5C6FD1A for ; Mon, 6 Mar 2023 12:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230161AbjCFMBr (ORCPT ); Mon, 6 Mar 2023 07:01:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229668AbjCFMBo (ORCPT ); Mon, 6 Mar 2023 07:01:44 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A769B298EA for ; Mon, 6 Mar 2023 04:01:40 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 581921FE65; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BcFZu1EKqaMhKwOFz1ZWi9/9YMK4hKcp66uUAYqgWw8=; b=wWLwLMpUaYWu9CcdFNGkbXM6rATq5Or7uwjNNd/hIwu3BqDVeniwXtPPwfhBEHTh/Zx3Yj w4gmwn5OBs0n34IRK2gQ6yBdyivar9V6UZm2zA1JoA8XnHvcEYYwxq4iMG+8PnhnLzELa+ 3fShMlEF0GLQD+4GtuHFLt3sAO6lVkQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BcFZu1EKqaMhKwOFz1ZWi9/9YMK4hKcp66uUAYqgWw8=; b=VjS05isvtMkxkrbjyLsOPy68t54uafJwp0KWzhylE5x9/zvrmVQhUUMnxU+78jjAInCHf0 7iWlRq/mC9AFwwCA== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id 417D02C143; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 3620951BE389; Mon, 6 Mar 2023 13:01:39 +0100 (CET) From: Hannes Reinecke To: Jens Axboe Cc: linux-block@vger.kernel.org, Matthew Wilcox , Luis Chamberlain , Keith Busch , Hannes Reinecke Subject: [PATCH 1/5] brd: convert to folios Date: Mon, 6 Mar 2023 13:01:23 +0100 Message-Id: <20230306120127.21375-2-hare@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230306120127.21375-1-hare@suse.de> References: <20230306120127.21375-1-hare@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Convert the driver to work on folios instead of pages. Signed-off-by: Hannes Reinecke Reviewed-by: Luis Chamberlain --- drivers/block/brd.c | 171 ++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 86 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 34177f1bd97d..7efc276c4963 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -28,8 +28,8 @@ #include /* - * Each block ramdisk device has a radix_tree brd_pages of pages that stores - * the pages containing the block device's contents. A brd page's ->index is + * Each block ramdisk device has a radix_tree brd_folios of folios that stores + * the folios containing the block device's contents. A brd folio's ->index is * its offset in PAGE_SIZE units. This is similar to, but in no way connected * with, the kernel's pagecache or buffer cache (which sit above our block * device). @@ -40,25 +40,25 @@ struct brd_device { struct list_head brd_list; /* - * Backing store of pages and lock to protect it. This is the contents - * of the block device. + * Backing store of folios and lock to protect it. + * This is the contents of the block device. */ spinlock_t brd_lock; - struct radix_tree_root brd_pages; - u64 brd_nr_pages; + struct radix_tree_root brd_folios; + u64 brd_nr_folios; }; /* - * Look up and return a brd's page for a given sector. + * Look up and return a brd's folio for a given sector. */ -static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) +static struct folio *brd_lookup_folio(struct brd_device *brd, sector_t sector) { pgoff_t idx; - struct page *page; + struct folio *folio; /* - * The page lifetime is protected by the fact that we have opened the - * device node -- brd pages will never be deleted under us, so we + * The folio lifetime is protected by the fact that we have opened the + * device node -- brd folios will never be deleted under us, so we * don't need any further locking or refcounting. * * This is strictly true for the radix-tree nodes as well (ie. we @@ -68,49 +68,49 @@ static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) * here, only deletes). */ rcu_read_lock(); - idx = sector >> PAGE_SECTORS_SHIFT; /* sector to page index */ - page = radix_tree_lookup(&brd->brd_pages, idx); + idx = sector >> PAGE_SECTORS_SHIFT; /* sector to folio index */ + folio = radix_tree_lookup(&brd->brd_folios, idx); rcu_read_unlock(); - BUG_ON(page && page->index != idx); + BUG_ON(folio && folio->index != idx); - return page; + return folio; } /* - * Insert a new page for a given sector, if one does not already exist. + * Insert a new folio for a given sector, if one does not already exist. */ -static int brd_insert_page(struct brd_device *brd, sector_t sector, gfp_t gfp) +static int brd_insert_folio(struct brd_device *brd, sector_t sector, gfp_t gfp) { pgoff_t idx; - struct page *page; + struct folio *folio; int ret = 0; - page = brd_lookup_page(brd, sector); - if (page) + folio = brd_lookup_folio(brd, sector); + if (folio) return 0; - page = alloc_page(gfp | __GFP_ZERO | __GFP_HIGHMEM); - if (!page) + folio = folio_alloc(gfp | __GFP_ZERO, 0); + if (!folio) return -ENOMEM; if (radix_tree_maybe_preload(gfp)) { - __free_page(page); + folio_put(folio); return -ENOMEM; } spin_lock(&brd->brd_lock); idx = sector >> PAGE_SECTORS_SHIFT; - page->index = idx; - if (radix_tree_insert(&brd->brd_pages, idx, page)) { - __free_page(page); - page = radix_tree_lookup(&brd->brd_pages, idx); - if (!page) + folio->index = idx; + if (radix_tree_insert(&brd->brd_folios, idx, folio)) { + folio_put(folio); + folio = radix_tree_lookup(&brd->brd_folios, idx); + if (!folio) ret = -ENOMEM; - else if (page->index != idx) + else if (folio->index != idx) ret = -EIO; } else { - brd->brd_nr_pages++; + brd->brd_nr_folios++; } spin_unlock(&brd->brd_lock); @@ -119,30 +119,30 @@ static int brd_insert_page(struct brd_device *brd, sector_t sector, gfp_t gfp) } /* - * Free all backing store pages and radix tree. This must only be called when + * Free all backing store folios and radix tree. This must only be called when * there are no other users of the device. */ #define FREE_BATCH 16 -static void brd_free_pages(struct brd_device *brd) +static void brd_free_folios(struct brd_device *brd) { unsigned long pos = 0; - struct page *pages[FREE_BATCH]; - int nr_pages; + struct folio *folios[FREE_BATCH]; + int nr_folios; do { int i; - nr_pages = radix_tree_gang_lookup(&brd->brd_pages, - (void **)pages, pos, FREE_BATCH); + nr_folios = radix_tree_gang_lookup(&brd->brd_folios, + (void **)folios, pos, FREE_BATCH); - for (i = 0; i < nr_pages; i++) { + for (i = 0; i < nr_folios; i++) { void *ret; - BUG_ON(pages[i]->index < pos); - pos = pages[i]->index; - ret = radix_tree_delete(&brd->brd_pages, pos); - BUG_ON(!ret || ret != pages[i]); - __free_page(pages[i]); + BUG_ON(folios[i]->index < pos); + pos = folios[i]->index; + ret = radix_tree_delete(&brd->brd_folios, pos); + BUG_ON(!ret || ret != folios[i]); + folio_put(folios[i]); } pos++; @@ -155,10 +155,10 @@ static void brd_free_pages(struct brd_device *brd) /* * This assumes radix_tree_gang_lookup always returns as - * many pages as possible. If the radix-tree code changes, + * many folios as possible. If the radix-tree code changes, * so will this have to. */ - } while (nr_pages == FREE_BATCH); + } while (nr_folios == FREE_BATCH); } /* @@ -172,12 +172,12 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, int ret; copy = min_t(size_t, n, PAGE_SIZE - offset); - ret = brd_insert_page(brd, sector, gfp); + ret = brd_insert_folio(brd, sector, gfp); if (ret) return ret; if (copy < n) { sector += copy >> SECTOR_SHIFT; - ret = brd_insert_page(brd, sector, gfp); + ret = brd_insert_folio(brd, sector, gfp); } return ret; } @@ -188,29 +188,29 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, static void copy_to_brd(struct brd_device *brd, const void *src, sector_t sector, size_t n) { - struct page *page; + struct folio *folio; void *dst; unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; size_t copy; copy = min_t(size_t, n, PAGE_SIZE - offset); - page = brd_lookup_page(brd, sector); - BUG_ON(!page); + folio = brd_lookup_folio(brd, sector); + BUG_ON(!folio); - dst = kmap_atomic(page); - memcpy(dst + offset, src, copy); - kunmap_atomic(dst); + dst = kmap_local_folio(folio, offset); + memcpy(dst, src, copy); + kunmap_local(dst); if (copy < n) { src += copy; sector += copy >> SECTOR_SHIFT; copy = n - copy; - page = brd_lookup_page(brd, sector); - BUG_ON(!page); + folio = brd_lookup_folio(brd, sector); + BUG_ON(!folio); - dst = kmap_atomic(page); + dst = kmap_local_folio(folio, 0); memcpy(dst, src, copy); - kunmap_atomic(dst); + kunmap_local(dst); } } @@ -220,17 +220,17 @@ static void copy_to_brd(struct brd_device *brd, const void *src, static void copy_from_brd(void *dst, struct brd_device *brd, sector_t sector, size_t n) { - struct page *page; + struct folio *folio; void *src; unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; size_t copy; copy = min_t(size_t, n, PAGE_SIZE - offset); - page = brd_lookup_page(brd, sector); - if (page) { - src = kmap_atomic(page); - memcpy(dst, src + offset, copy); - kunmap_atomic(src); + folio = brd_lookup_folio(brd, sector); + if (folio) { + src = kmap_local_folio(folio, offset); + memcpy(dst, src, copy); + kunmap_local(src); } else memset(dst, 0, copy); @@ -238,20 +238,20 @@ static void copy_from_brd(void *dst, struct brd_device *brd, dst += copy; sector += copy >> SECTOR_SHIFT; copy = n - copy; - page = brd_lookup_page(brd, sector); - if (page) { - src = kmap_atomic(page); + folio = brd_lookup_folio(brd, sector); + if (folio) { + src = kmap_local_folio(folio, 0); memcpy(dst, src, copy); - kunmap_atomic(src); + kunmap_local(src); } else memset(dst, 0, copy); } } /* - * Process a single bvec of a bio. + * Process a single folio of a bio. */ -static int brd_do_bvec(struct brd_device *brd, struct page *page, +static int brd_do_folio(struct brd_device *brd, struct folio *folio, unsigned int len, unsigned int off, blk_opf_t opf, sector_t sector) { @@ -261,7 +261,7 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page, if (op_is_write(opf)) { /* * Must use NOIO because we don't want to recurse back into the - * block or filesystem layers from page reclaim. + * block or filesystem layers from folio reclaim. */ gfp_t gfp = opf & REQ_NOWAIT ? GFP_NOWAIT : GFP_NOIO; @@ -270,15 +270,15 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page, goto out; } - mem = kmap_atomic(page); + mem = kmap_local_folio(folio, off); if (!op_is_write(opf)) { - copy_from_brd(mem + off, brd, sector, len); - flush_dcache_page(page); + copy_from_brd(mem, brd, sector, len); + flush_dcache_folio(folio); } else { - flush_dcache_page(page); - copy_to_brd(brd, mem + off, sector, len); + flush_dcache_folio(folio); + copy_to_brd(brd, mem, sector, len); } - kunmap_atomic(mem); + kunmap_local(mem); out: return err; @@ -288,19 +288,18 @@ static void brd_submit_bio(struct bio *bio) { struct brd_device *brd = bio->bi_bdev->bd_disk->private_data; sector_t sector = bio->bi_iter.bi_sector; - struct bio_vec bvec; - struct bvec_iter iter; + struct folio_iter iter; - bio_for_each_segment(bvec, bio, iter) { - unsigned int len = bvec.bv_len; + bio_for_each_folio_all(iter, bio) { + unsigned int len = iter.length; int err; /* Don't support un-aligned buffer */ - WARN_ON_ONCE((bvec.bv_offset & (SECTOR_SIZE - 1)) || + WARN_ON_ONCE((iter.offset & (SECTOR_SIZE - 1)) || (len & (SECTOR_SIZE - 1))); - err = brd_do_bvec(brd, bvec.bv_page, len, bvec.bv_offset, - bio->bi_opf, sector); + err = brd_do_folio(brd, iter.folio, len, iter.offset, + bio->bi_opf, sector); if (err) { if (err == -ENOMEM && bio->bi_opf & REQ_NOWAIT) { bio_wouldblock_error(bio); @@ -373,12 +372,12 @@ static int brd_alloc(int i) list_add_tail(&brd->brd_list, &brd_devices); spin_lock_init(&brd->brd_lock); - INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC); + INIT_RADIX_TREE(&brd->brd_folios, GFP_ATOMIC); snprintf(buf, DISK_NAME_LEN, "ram%d", i); if (!IS_ERR_OR_NULL(brd_debugfs_dir)) debugfs_create_u64(buf, 0444, brd_debugfs_dir, - &brd->brd_nr_pages); + &brd->brd_nr_folios); disk = brd->brd_disk = blk_alloc_disk(NUMA_NO_NODE); if (!disk) @@ -434,7 +433,7 @@ static void brd_cleanup(void) list_for_each_entry_safe(brd, next, &brd_devices, brd_list) { del_gendisk(brd->brd_disk); put_disk(brd->brd_disk); - brd_free_pages(brd); + brd_free_folios(brd); list_del(&brd->brd_list); kfree(brd); } @@ -465,7 +464,7 @@ static int __init brd_init(void) brd_check_and_reset_par(); - brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL); + brd_debugfs_dir = debugfs_create_dir("ramdisk_folios", NULL); for (i = 0; i < rd_nr; i++) { err = brd_alloc(i); From patchwork Mon Mar 6 12:01:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 13161017 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 700C2C6FD1B for ; Mon, 6 Mar 2023 12:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230121AbjCFMBs (ORCPT ); Mon, 6 Mar 2023 07:01:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230140AbjCFMBp (ORCPT ); Mon, 6 Mar 2023 07:01:45 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA14B29425 for ; Mon, 6 Mar 2023 04:01:40 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 595071FE6A; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EwWSptgMMFl2hfXaCi3D0muPPjyDoJ1hqU3sgJ2+gbU=; b=ka2vINzbCY05g/ovFgiErOugKL5/doF7R8M/rWAE4CBVJkDuDJiIKe1RRW5hllmyMYoaPx /gJQ9BLZgFirrnZ3Qa9qHwa7dIiYdWLZ+R7Vq+dYywOf64BNoZlRIKn4ggJVfe2j9VtubM TjVzR+1dgwkYv3uFzNwfk6I5v9Y2Ing= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EwWSptgMMFl2hfXaCi3D0muPPjyDoJ1hqU3sgJ2+gbU=; b=znncyqKHFiz607kZw1kho/6kxcNoYrO2gCs+tWehfkMkJ4kXhbcxL0tzjWr8d2TXH/QCiY XoBd9rrO3qKEwhBA== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id 485782C146; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 3E21D51BE38B; Mon, 6 Mar 2023 13:01:39 +0100 (CET) From: Hannes Reinecke To: Jens Axboe Cc: linux-block@vger.kernel.org, Matthew Wilcox , Luis Chamberlain , Keith Busch , Hannes Reinecke Subject: [PATCH 2/5] brd: abstract page_size conventions Date: Mon, 6 Mar 2023 13:01:24 +0100 Message-Id: <20230306120127.21375-3-hare@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230306120127.21375-1-hare@suse.de> References: <20230306120127.21375-1-hare@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org In preparation for changing the block sizes abstract away references to PAGE_SIZE and friends. Signed-off-by: Hannes Reinecke --- drivers/block/brd.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 7efc276c4963..fc41ea641dfb 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -55,6 +55,7 @@ static struct folio *brd_lookup_folio(struct brd_device *brd, sector_t sector) { pgoff_t idx; struct folio *folio; + unsigned int rd_sector_shift = PAGE_SHIFT - SECTOR_SHIFT; /* * The folio lifetime is protected by the fact that we have opened the @@ -68,7 +69,7 @@ static struct folio *brd_lookup_folio(struct brd_device *brd, sector_t sector) * here, only deletes). */ rcu_read_lock(); - idx = sector >> PAGE_SECTORS_SHIFT; /* sector to folio index */ + idx = sector >> rd_sector_shift; /* sector to folio index */ folio = radix_tree_lookup(&brd->brd_folios, idx); rcu_read_unlock(); @@ -84,13 +85,15 @@ static int brd_insert_folio(struct brd_device *brd, sector_t sector, gfp_t gfp) { pgoff_t idx; struct folio *folio; + unsigned int rd_sector_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sector_order = get_order(PAGE_SIZE); int ret = 0; folio = brd_lookup_folio(brd, sector); if (folio) return 0; - folio = folio_alloc(gfp | __GFP_ZERO, 0); + folio = folio_alloc(gfp | __GFP_ZERO, rd_sector_order); if (!folio) return -ENOMEM; @@ -100,7 +103,7 @@ static int brd_insert_folio(struct brd_device *brd, sector_t sector, gfp_t gfp) } spin_lock(&brd->brd_lock); - idx = sector >> PAGE_SECTORS_SHIFT; + idx = sector >> rd_sector_shift; folio->index = idx; if (radix_tree_insert(&brd->brd_folios, idx, folio)) { folio_put(folio); @@ -167,11 +170,14 @@ static void brd_free_folios(struct brd_device *brd) static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, gfp_t gfp) { - unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; + unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors = 1 << rd_sectors_shift; + unsigned int rd_sector_size = PAGE_SIZE; + unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; int ret; - copy = min_t(size_t, n, PAGE_SIZE - offset); + copy = min_t(size_t, n, rd_sector_size - offset); ret = brd_insert_folio(brd, sector, gfp); if (ret) return ret; @@ -190,10 +196,13 @@ static void copy_to_brd(struct brd_device *brd, const void *src, { struct folio *folio; void *dst; - unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; + unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors = 1 << rd_sectors_shift; + unsigned int rd_sector_size = PAGE_SIZE; + unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; - copy = min_t(size_t, n, PAGE_SIZE - offset); + copy = min_t(size_t, n, rd_sector_size - offset); folio = brd_lookup_folio(brd, sector); BUG_ON(!folio); @@ -222,10 +231,13 @@ static void copy_from_brd(void *dst, struct brd_device *brd, { struct folio *folio; void *src; - unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; + unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors = 1 << rd_sectors_shift; + unsigned int rd_sector_size = PAGE_SIZE; + unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; - copy = min_t(size_t, n, PAGE_SIZE - offset); + copy = min_t(size_t, n, rd_sector_size - offset); folio = brd_lookup_folio(brd, sector); if (folio) { src = kmap_local_folio(folio, offset); From patchwork Mon Mar 6 12:01:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 13161020 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7500C61DA4 for ; Mon, 6 Mar 2023 12:01:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230196AbjCFMBv (ORCPT ); Mon, 6 Mar 2023 07:01:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230079AbjCFMBp (ORCPT ); Mon, 6 Mar 2023 07:01:45 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BFBE298F5 for ; Mon, 6 Mar 2023 04:01:41 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 60D7A22027; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UwuiA4ikQa/M46+bw1EkkXbFkC8gprTE2kfTQZ73XFw=; b=yquJMVlt4CzxTKrVf99x2sKeNpSD9Y+InO+7DTBmKXnDQYZPul69F+7e4R+qp+7zQ/hU3L 5PCF/a3hNbsu1ls3j2ETms+pVvtyoRd5avbR3yJ76JXYDn28gQUMTLbUyDvFzh0qWcW4BD L0PBYOeQbXoGRb6BER/oYKL6LXYAksc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UwuiA4ikQa/M46+bw1EkkXbFkC8gprTE2kfTQZ73XFw=; b=WsMuE6ROSyi71alF8Z1Vl+zxJIesnuGxsNbqudo1NyoQJKJxHXMVO4Dz2UL9/+ScAAaOvZ v6AZsbZXHMlsq2DA== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id 50B2A2C149; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 4607B51BE38D; Mon, 6 Mar 2023 13:01:39 +0100 (CET) From: Hannes Reinecke To: Jens Axboe Cc: linux-block@vger.kernel.org, Matthew Wilcox , Luis Chamberlain , Keith Busch , Hannes Reinecke Subject: [PATCH 3/5] brd: make sector size configurable Date: Mon, 6 Mar 2023 13:01:25 +0100 Message-Id: <20230306120127.21375-4-hare@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230306120127.21375-1-hare@suse.de> References: <20230306120127.21375-1-hare@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Add a module option 'rd_blksize' to allow the user to change the sector size of the RAM disks. Signed-off-by: Hannes Reinecke --- drivers/block/brd.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index fc41ea641dfb..11bac3c3f1b6 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -30,7 +30,7 @@ /* * Each block ramdisk device has a radix_tree brd_folios of folios that stores * the folios containing the block device's contents. A brd folio's ->index is - * its offset in PAGE_SIZE units. This is similar to, but in no way connected + * its offset in brd_blksize units. This is similar to, but in no way connected * with, the kernel's pagecache or buffer cache (which sit above our block * device). */ @@ -46,6 +46,8 @@ struct brd_device { spinlock_t brd_lock; struct radix_tree_root brd_folios; u64 brd_nr_folios; + unsigned int brd_sector_shift; + unsigned int brd_sector_size; }; /* @@ -55,7 +57,7 @@ static struct folio *brd_lookup_folio(struct brd_device *brd, sector_t sector) { pgoff_t idx; struct folio *folio; - unsigned int rd_sector_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sector_shift = brd->brd_sector_shift - SECTOR_SHIFT; /* * The folio lifetime is protected by the fact that we have opened the @@ -85,8 +87,8 @@ static int brd_insert_folio(struct brd_device *brd, sector_t sector, gfp_t gfp) { pgoff_t idx; struct folio *folio; - unsigned int rd_sector_shift = PAGE_SHIFT - SECTOR_SHIFT; - unsigned int rd_sector_order = get_order(PAGE_SIZE); + unsigned int rd_sector_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sector_order = get_order(brd->brd_sector_size); int ret = 0; folio = brd_lookup_folio(brd, sector); @@ -170,9 +172,9 @@ static void brd_free_folios(struct brd_device *brd) static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, gfp_t gfp) { - unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; unsigned int rd_sectors = 1 << rd_sectors_shift; - unsigned int rd_sector_size = PAGE_SIZE; + unsigned int rd_sector_size = brd->brd_sector_size; unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; int ret; @@ -196,9 +198,9 @@ static void copy_to_brd(struct brd_device *brd, const void *src, { struct folio *folio; void *dst; - unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; unsigned int rd_sectors = 1 << rd_sectors_shift; - unsigned int rd_sector_size = PAGE_SIZE; + unsigned int rd_sector_size = brd->brd_sector_size; unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; @@ -231,9 +233,9 @@ static void copy_from_brd(void *dst, struct brd_device *brd, { struct folio *folio; void *src; - unsigned int rd_sectors_shift = PAGE_SHIFT - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; unsigned int rd_sectors = 1 << rd_sectors_shift; - unsigned int rd_sector_size = PAGE_SIZE; + unsigned int rd_sector_size = brd->brd_sector_size; unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; size_t copy; @@ -346,6 +348,10 @@ static int max_part = 1; module_param(max_part, int, 0444); MODULE_PARM_DESC(max_part, "Num Minors to reserve between devices"); +static unsigned int rd_blksize = PAGE_SIZE; +module_param(rd_blksize, uint, 0444); +MODULE_PARM_DESC(rd_blksize, "Blocksize of each RAM disk in bytes."); + MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); MODULE_ALIAS("rd"); @@ -382,6 +388,8 @@ static int brd_alloc(int i) return -ENOMEM; brd->brd_number = i; list_add_tail(&brd->brd_list, &brd_devices); + brd->brd_sector_shift = ilog2(rd_blksize); + brd->brd_sector_size = rd_blksize; spin_lock_init(&brd->brd_lock); INIT_RADIX_TREE(&brd->brd_folios, GFP_ATOMIC); @@ -410,7 +418,7 @@ static int brd_alloc(int i) * otherwise fdisk will align on 1M. Regardless this call * is harmless) */ - blk_queue_physical_block_size(disk->queue, PAGE_SIZE); + blk_queue_physical_block_size(disk->queue, rd_blksize); /* Tell the block layer that this is not a rotational device */ blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue); From patchwork Mon Mar 6 12:01:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 13161019 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAD83C678D4 for ; Mon, 6 Mar 2023 12:01:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230079AbjCFMBw (ORCPT ); Mon, 6 Mar 2023 07:01:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230096AbjCFMBp (ORCPT ); Mon, 6 Mar 2023 07:01:45 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BF38298F4 for ; Mon, 6 Mar 2023 04:01:41 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 678B22212D; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vEOtrYMiDN6Nn1CrMt7w5wRmebvrPq2lUJZ1L1Apqoc=; b=sUvzsnb3uOXBctXGslYrrXPb8JQwUlfv5r+nwUG+5dAIyoWlbgBz3mmlz1VCuTJgkIldVG DfBUrFBBAmhw/rOxYpL5BLGR4+Sc87vLVLsVT0ml6CS4KGvxOQ+WaJs6bE5f6PPn+80/+k HBiEK8l2qulP0oEV72Mxz3xvnfDyRZE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vEOtrYMiDN6Nn1CrMt7w5wRmebvrPq2lUJZ1L1Apqoc=; b=7Ng+PaaKg0mGCT4zneq9LOi539yHiuPMLBCkkv1pE9J3x9c5dTdB8GtdK6dwRTucAEKOH8 W2BRHIgmwHMvRQCg== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id 57FB72C14E; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 4DD3151BE38F; Mon, 6 Mar 2023 13:01:39 +0100 (CET) From: Hannes Reinecke To: Jens Axboe Cc: linux-block@vger.kernel.org, Matthew Wilcox , Luis Chamberlain , Keith Busch , Hannes Reinecke Subject: [PATCH 4/5] brd: limit maximal block size to 32M Date: Mon, 6 Mar 2023 13:01:26 +0100 Message-Id: <20230306120127.21375-5-hare@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230306120127.21375-1-hare@suse.de> References: <20230306120127.21375-1-hare@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Use an arbitrary limit of 32M for the maximal blocksize so as not to overflow the page cache. Signed-off-by: Hannes Reinecke --- drivers/block/brd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 11bac3c3f1b6..1ed114cd5cb0 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -348,6 +348,7 @@ static int max_part = 1; module_param(max_part, int, 0444); MODULE_PARM_DESC(max_part, "Num Minors to reserve between devices"); +#define RD_MAX_SECTOR_SIZE 65536 static unsigned int rd_blksize = PAGE_SIZE; module_param(rd_blksize, uint, 0444); MODULE_PARM_DESC(rd_blksize, "Blocksize of each RAM disk in bytes."); @@ -410,15 +411,14 @@ static int brd_alloc(int i) disk->private_data = brd; strscpy(disk->disk_name, buf, DISK_NAME_LEN); set_capacity(disk, rd_size * 2); - - /* - * This is so fdisk will align partitions on 4k, because of - * direct_access API needing 4k alignment, returning a PFN - * (This is only a problem on very small devices <= 4M, - * otherwise fdisk will align on 1M. Regardless this call - * is harmless) - */ + + if (rd_blksize > RD_MAX_SECTOR_SIZE) { + /* Arbitrary limit maximum block size to 32M */ + err = -EINVAL; + goto out_cleanup_disk; + } blk_queue_physical_block_size(disk->queue, rd_blksize); + blk_queue_max_hw_sectors(disk->queue, RD_MAX_SECTOR_SIZE); /* Tell the block layer that this is not a rotational device */ blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue); From patchwork Mon Mar 6 12:01:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 13161016 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC70DC6FD1C for ; Mon, 6 Mar 2023 12:01:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230163AbjCFMBs (ORCPT ); Mon, 6 Mar 2023 07:01:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52576 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230121AbjCFMBo (ORCPT ); Mon, 6 Mar 2023 07:01:44 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA82F298F0 for ; Mon, 6 Mar 2023 04:01:40 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 6D4691FE6B; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=coGGIOogyleEfcue49LqcYBByvDZ9BHmyGsH3i/Pbcs=; b=zFWsoLx0mVATe4BGpb7FEvnV4IJCpbuYCHeZ0TenJvUFiaf6lqkkzNzxxwwRwLzoLt7IYd nklzBLgTyz4Nj9f32Wb09FkNBEEN9GyhKvcCcn5KtQIfHivohQXY1/ex+ZsbGtEtSzGILq U73iZWY2OvjCkr3yjPn90Hnnke7E4q8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1678104099; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=coGGIOogyleEfcue49LqcYBByvDZ9BHmyGsH3i/Pbcs=; b=fTK7QxT0bGb32lRksuApFAWMAD6Wu9QyjaF+XIp5V2f6W7Uh1pA0tqGndHtaHCxbtgsAzw IWtfOVPrNdeSTfAQ== Received: from adalid.arch.suse.de (adalid.arch.suse.de [10.161.8.13]) by relay2.suse.de (Postfix) with ESMTP id 5BE012C14F; Mon, 6 Mar 2023 12:01:39 +0000 (UTC) Received: by adalid.arch.suse.de (Postfix, from userid 16045) id 552D051BE391; Mon, 6 Mar 2023 13:01:39 +0100 (CET) From: Hannes Reinecke To: Jens Axboe Cc: linux-block@vger.kernel.org, Matthew Wilcox , Luis Chamberlain , Keith Busch , Hannes Reinecke Subject: [PATCH 5/5] brd: make logical sector size configurable Date: Mon, 6 Mar 2023 13:01:27 +0100 Message-Id: <20230306120127.21375-6-hare@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230306120127.21375-1-hare@suse.de> References: <20230306120127.21375-1-hare@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Add a module option 'rd_logical_blksize' to allow the user to change the logical sector size of the RAM disks. Signed-off-by: Hannes Reinecke --- drivers/block/brd.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 1ed114cd5cb0..dda791805aba 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -48,6 +48,8 @@ struct brd_device { u64 brd_nr_folios; unsigned int brd_sector_shift; unsigned int brd_sector_size; + unsigned int brd_logical_sector_shift; + unsigned int brd_logical_sector_size; }; /* @@ -57,7 +59,7 @@ static struct folio *brd_lookup_folio(struct brd_device *brd, sector_t sector) { pgoff_t idx; struct folio *folio; - unsigned int rd_sector_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sector_shift = brd->brd_sector_shift - brd->brd_logical_sector_shift; /* * The folio lifetime is protected by the fact that we have opened the @@ -87,7 +89,7 @@ static int brd_insert_folio(struct brd_device *brd, sector_t sector, gfp_t gfp) { pgoff_t idx; struct folio *folio; - unsigned int rd_sector_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sector_shift = brd->brd_sector_shift - brd->brd_logical_sector_shift; unsigned int rd_sector_order = get_order(brd->brd_sector_size); int ret = 0; @@ -172,10 +174,10 @@ static void brd_free_folios(struct brd_device *brd) static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, gfp_t gfp) { - unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - brd->brd_logical_sector_shift; unsigned int rd_sectors = 1 << rd_sectors_shift; unsigned int rd_sector_size = brd->brd_sector_size; - unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; + unsigned int offset = (sector & (rd_sectors - 1)) << brd->brd_logical_sector_shift; size_t copy; int ret; @@ -184,7 +186,7 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n, if (ret) return ret; if (copy < n) { - sector += copy >> SECTOR_SHIFT; + sector += copy >> brd->brd_logical_sector_shift; ret = brd_insert_folio(brd, sector, gfp); } return ret; @@ -198,10 +200,10 @@ static void copy_to_brd(struct brd_device *brd, const void *src, { struct folio *folio; void *dst; - unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - brd->brd_logical_sector_shift; unsigned int rd_sectors = 1 << rd_sectors_shift; unsigned int rd_sector_size = brd->brd_sector_size; - unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; + unsigned int offset = (sector & (rd_sectors - 1)) << brd->brd_logical_sector_shift; size_t copy; copy = min_t(size_t, n, rd_sector_size - offset); @@ -214,7 +216,7 @@ static void copy_to_brd(struct brd_device *brd, const void *src, if (copy < n) { src += copy; - sector += copy >> SECTOR_SHIFT; + sector += copy >> brd->brd_logical_sector_shift; copy = n - copy; folio = brd_lookup_folio(brd, sector); BUG_ON(!folio); @@ -233,10 +235,10 @@ static void copy_from_brd(void *dst, struct brd_device *brd, { struct folio *folio; void *src; - unsigned int rd_sectors_shift = brd->brd_sector_shift - SECTOR_SHIFT; + unsigned int rd_sectors_shift = brd->brd_sector_shift - brd->brd_logical_sector_shift; unsigned int rd_sectors = 1 << rd_sectors_shift; unsigned int rd_sector_size = brd->brd_sector_size; - unsigned int offset = (sector & (rd_sectors - 1)) << SECTOR_SHIFT; + unsigned int offset = (sector & (rd_sectors - 1)) << brd->brd_logical_sector_shift; size_t copy; copy = min_t(size_t, n, rd_sector_size - offset); @@ -250,7 +252,7 @@ static void copy_from_brd(void *dst, struct brd_device *brd, if (copy < n) { dst += copy; - sector += copy >> SECTOR_SHIFT; + sector += copy >> brd->brd_logical_sector_shift; copy = n - copy; folio = brd_lookup_folio(brd, sector); if (folio) { @@ -309,8 +311,8 @@ static void brd_submit_bio(struct bio *bio) int err; /* Don't support un-aligned buffer */ - WARN_ON_ONCE((iter.offset & (SECTOR_SIZE - 1)) || - (len & (SECTOR_SIZE - 1))); + WARN_ON_ONCE((iter.offset & (brd->brd_logical_sector_size - 1)) || + (len & (brd->brd_logical_sector_size - 1))); err = brd_do_folio(brd, iter.folio, len, iter.offset, bio->bi_opf, sector); @@ -322,7 +324,7 @@ static void brd_submit_bio(struct bio *bio) bio_io_error(bio); return; } - sector += len >> SECTOR_SHIFT; + sector += len >> brd->brd_logical_sector_shift; } bio_endio(bio); @@ -353,6 +355,10 @@ static unsigned int rd_blksize = PAGE_SIZE; module_param(rd_blksize, uint, 0444); MODULE_PARM_DESC(rd_blksize, "Blocksize of each RAM disk in bytes."); +static unsigned int rd_logical_blksize = SECTOR_SIZE; +module_param(rd_logical_blksize, uint, 0444); +MODULE_PARM_DESC(rd_logical_blksize, "Logical blocksize of each RAM disk in bytes."); + MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); MODULE_ALIAS("rd"); @@ -391,6 +397,8 @@ static int brd_alloc(int i) list_add_tail(&brd->brd_list, &brd_devices); brd->brd_sector_shift = ilog2(rd_blksize); brd->brd_sector_size = rd_blksize; + brd->brd_logical_sector_shift = ilog2(rd_logical_blksize); + brd->brd_logical_sector_size = rd_logical_blksize; spin_lock_init(&brd->brd_lock); INIT_RADIX_TREE(&brd->brd_folios, GFP_ATOMIC); @@ -418,6 +426,7 @@ static int brd_alloc(int i) goto out_cleanup_disk; } blk_queue_physical_block_size(disk->queue, rd_blksize); + blk_queue_logical_block_size(disk->queue, rd_logical_blksize); blk_queue_max_hw_sectors(disk->queue, RD_MAX_SECTOR_SIZE); /* Tell the block layer that this is not a rotational device */