diff --git a/README.md b/README.md index b7b8a2a..810fa4d 100644 --- a/README.md +++ b/README.md @@ -61,9 +61,9 @@ While this is a fork, we try to keep the changes to driver minimal to make syncs | Kernel range | NonRAID module branch | Upstream base | Tested distros | Notes | | ------------- | --------------------- | ------------- | -------------- | ------ | -| 6.1 - 6.4 | [nonraid-6.1](https://github.com/qvr/nonraid/tree/nonraid-6.1) | unRAID 6.12.15 (6.1.126-Unraid) | Debian 12 | Contains fixes backported from 6.6 branch | -| 6.5 - 6.8 | [nonraid-6.6](https://github.com/qvr/nonraid/tree/nonraid-6.6) | unRAID 7.0.1 (6.6.78-Unraid) | Ubuntu 24.04 LTS GA kernel | No functional difference to 6.12 branch | -| 6.11 - 6.18 | [nonraid-6.12](https://github.com/qvr/nonraid/tree/nonraid-6.12) | unRAID 7.1.2 (6.12.24-Unraid) | Ubuntu 24.04 LTS HWE kernel, Debian 13, Arch, Proxmox VE 9 | unRAID 7.2.0 has no changes to the kernel driver | +| 6.1 - 6.4 | [nonraid-6.1](https://github.com/qvr/nonraid/tree/nonraid-6.1) | unRAID 6.12.15 (6.1.126-Unraid) | Debian 12 | Contains fixes backported from 6.6 and 6.18 branch | +| 6.5 - 6.8 | [nonraid-6.6](https://github.com/qvr/nonraid/tree/nonraid-6.6) | unRAID 7.0.1 (6.6.78-Unraid) | Ubuntu 24.04 LTS GA kernel | Contains fixes backported from 6.18 branch | +| 6.11 - 7.0 | [nonraid-6.18](https://github.com/qvr/nonraid/tree/nonraid-6.18) | unRAID 7.3.0 (6.18.29-Unraid) | Ubuntu 24.04 LTS HWE kernel, Debian 13, Arch, Proxmox VE 9 | | The supported kernel version ranges might be inaccurate, the driver has been tested to work on **Ubuntu 24.04 LTS** GA kernel (6.8.0) and HWE kernels (6.11 and 6.14), on **Debian 12** (6.1), on **Debian 13** (6.12), on **Arch Linux** lts kernel (6.12) and stable kernels (6.16, 6.17) and on **Proxmox VE 9** (6.14). Note that kernel versions 6.9 and 6.10 are not supported. You can report other distributions and kernel versions that work in the [discussions](https://github.com/qvr/nonraid/discussions). @@ -276,7 +276,7 @@ BTRFS also works (`sudo mkfs.btrfs /dev/nmd3p1`). For ZFS, name the pools as `diskN` where N is the slot number so that `nmdctl mount` works properly: ```bash -sudo zpool create disk3 /dev/nmd3p1 +sudo zpool create -o ashift=12 disk3 /dev/nmd3p1 ``` You can use any combination of different filesystems based on your needs. diff --git a/dkms.conf b/dkms.conf index f173c1b..33a526d 100644 --- a/dkms.conf +++ b/dkms.conf @@ -8,4 +8,4 @@ BUILT_MODULE_LOCATION[1]=raid6 DEST_MODULE_LOCATION[1]="/updates" AUTOINSTALL="yes" PACKAGE_NAME=nonraid-dkms -PACKAGE_VERSION=1.3.2 +PACKAGE_VERSION=1.3.991 diff --git a/md_nonraid/6.1/md_unraid.c b/md_nonraid/6.1/md_unraid.c index b185ecc..d41fc69 100644 --- a/md_nonraid/6.1/md_unraid.c +++ b/md_nonraid/6.1/md_unraid.c @@ -941,6 +941,8 @@ static void md_submit_bio(struct bio *bi) } bi = bio_split_to_limits(bi); + if (!bi) + return; bi->bi_opf &= ~REQ_NOMERGE; unraid_make_request(mddev, unit, bi); @@ -2249,4 +2251,5 @@ module_exit(md_exit); MODULE_ALIAS("nonraid"); MODULE_ALIAS_BLOCKDEV_MAJOR(MAJOR_NR); +MODULE_DESCRIPTION("NonRAID array stacking driver"); MODULE_LICENSE("GPL"); diff --git a/md_nonraid/6.1/unraid.c b/md_nonraid/6.1/unraid.c index ee08ab5..23ddd42 100644 --- a/md_nonraid/6.1/unraid.c +++ b/md_nonraid/6.1/unraid.c @@ -23,6 +23,11 @@ #include "md_unraid.h" +/* + * The global zero page. + */ +#define raid6_empty_zero_page page_address(ZERO_PAGE(0)) + /* * The following can be used to debug the driver */ @@ -1723,6 +1728,12 @@ void unraid_make_request(mddev_t *mddev, int unit, struct bio *bi) /* check for requests before we're running */ BUG_ON(!conf); + /* check for REQ_OP_DISCARD - shouldn't happen */ + if (unlikely(bio_op(bi) == REQ_OP_DISCARD)) { + /* just ignore it */ + return; + } + /* check for REQ_FLUSH */ if (bi->bi_opf & REQ_PREFLUSH) { dprintk("got a flush: disk: %d\n", unit); @@ -1795,8 +1806,6 @@ static void unraidd(mddev_t *mddev, unsigned long unit) dprintk("nonraidd%d: activated\n", (int)unit); - blk_start_plug(&plug); - spin_lock_irq(&conf->device_lock); while (!list_empty(&conf->handle_list[unit])) { struct list_head *first; @@ -1811,6 +1820,9 @@ static void unraidd(mddev_t *mddev, unsigned long unit) spin_unlock_irq(&conf->device_lock); + if (count == 0) + blk_start_plug(&plug); + handle_stripe(sh); release_stripe(sh); count++; @@ -1819,7 +1831,8 @@ static void unraidd(mddev_t *mddev, unsigned long unit) } spin_unlock_irq(&conf->device_lock); - blk_finish_plug(&plug); + if (count) + blk_finish_plug(&plug); dprintk("nonraidd%d: handled %d stripes\n", (int)unit, count); } diff --git a/md_nonraid/6.12/README.md b/md_nonraid/6.12/README.md deleted file mode 100644 index 55e1dce..0000000 --- a/md_nonraid/6.12/README.md +++ /dev/null @@ -1 +0,0 @@ -These files are copied from [nonraid-6.12 branch](https://github.com/qvr/nonraid/tree/nonraid-6.12) that is used to track upstream changes and rebase nonraid patches on top of them. Check that branch for commit history. diff --git a/md_nonraid/6.18/README.md b/md_nonraid/6.18/README.md new file mode 100644 index 0000000..54bffd1 --- /dev/null +++ b/md_nonraid/6.18/README.md @@ -0,0 +1 @@ +These files are copied from [nonraid-6.18 branch](https://github.com/qvr/nonraid/tree/nonraid-6.18) that is used to track upstream changes and rebase nonraid patches on top of them. Check that branch for commit history. diff --git a/md_nonraid/6.12/md_unraid.c b/md_nonraid/6.18/md_unraid.c similarity index 97% rename from md_nonraid/6.12/md_unraid.c rename to md_nonraid/6.18/md_unraid.c index 8fed951..a3c6bed 100644 --- a/md_nonraid/6.12/md_unraid.c +++ b/md_nonraid/6.18/md_unraid.c @@ -941,6 +941,8 @@ static void md_submit_bio(struct bio *bi) } bi = bio_split_to_limits(bi); + if (!bi) + return; bi->bi_opf &= ~REQ_NOMERGE; unraid_make_request(mddev, unit, bi); @@ -985,6 +987,40 @@ static struct block_device_operations md_fops = // .revalidate_disk= md_revalidate, }; +static struct queue_limits *md_set_queue_limits(struct queue_limits *lim, mdk_rdev_t *rdev) +{ + /* set default stacking limits */ + blk_set_stacking_limits(lim); + lim->features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA | BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT; + + /* merge lower device limits */ + if (!strstr(rdev->status, "DISK_NP")) { + queue_limits_stack_bdev(lim, rdev->bdev, rdev->offset, rdev->name); + } + + /* disk being emulated, set some missing defaults */ + if (strstr(rdev->status, "DISK_NP")) { + lim->max_zone_append_sectors = 0; + } + + /* we must override selected merged limits */ + lim->logical_block_size = 512; + lim->physical_block_size = 4096; + lim->dma_alignment = 511; + lim->io_min = 512; + lim->io_opt = 128 * 1024; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0) + lim->max_hw_wzeroes_unmap_sectors = 0; +#endif + lim->max_secure_erase_sectors = 0; /* disable secure_erase */ + lim->max_write_zeroes_sectors = 0; /* disable write_zeroes */ + lim->max_hw_sectors = 256; /* 256 sectors => 128K */ + lim->max_hw_discard_sectors = 0; /* disable discard */ + lim->max_discard_sectors = 0; + lim->discard_granularity = 0; + return lim; +} + static int do_run(mddev_t *mddev) { mdp_super_t *sb = &mddev->sb; @@ -1017,10 +1053,12 @@ static int do_run(mddev_t *mddev) /* create the md devices */ for (i = 1; i <= 28; i++) { mdp_disk_t *disk = &sb->disks[i]; + struct queue_limits lim; if (disk_active(disk) || disk_enabled(disk)) { - int unit = disk->number; struct gendisk *gd = blk_alloc_disk(NULL,NUMA_NO_NODE); + mdk_rdev_t *rdev = &mddev->rdev[i]; + int unit = disk->number; int ret; mddev->gendisk[unit] = gd; @@ -1032,21 +1070,10 @@ static int do_run(mddev_t *mddev) gd->fops = &md_fops; gd->private_data = mddev; gd->queue->queuedata = mddev; + queue_limits_set(gd->queue, md_set_queue_limits(&lim, rdev)); /* capacity in 512-byte sectors */ set_capacity(gd, disk->size*2); - - blk_set_stacking_limits(&gd->queue->limits); - gd->queue->limits.features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA | - BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT | - BLK_FEAT_ROTATIONAL; - - blk_queue_disable_discard(gd->queue); - blk_queue_disable_secure_erase(gd->queue); - blk_queue_disable_write_zeroes(gd->queue); - - if (md_restrict & 1) - gd->queue->limits.max_hw_sectors = 256; /* 256 sectors => 128K */ ret = add_disk(gd); printk("nmd%dp1: running, size: %llu blocks\n", unit, disk->size); @@ -2249,4 +2276,5 @@ module_exit(md_exit); MODULE_ALIAS("nonraid"); MODULE_ALIAS_BLOCKDEV_MAJOR(MAJOR_NR); +MODULE_DESCRIPTION("NonRAID array stacking driver"); MODULE_LICENSE("GPL"); diff --git a/md_nonraid/6.12/md_unraid.h b/md_nonraid/6.18/md_unraid.h similarity index 99% rename from md_nonraid/6.12/md_unraid.h rename to md_nonraid/6.18/md_unraid.h index f399a90..508231e 100644 --- a/md_nonraid/6.12/md_unraid.h +++ b/md_nonraid/6.18/md_unraid.h @@ -64,7 +64,7 @@ extern void (*raid6_xor_syndrome)(int, int, int, size_t, void **); */ #define MD_MAJOR_VERSION 2 #define MD_MINOR_VERSION 9 -#define MD_PATCHLEVEL_VERSION 35 +#define MD_PATCHLEVEL_VERSION 40 /****************************************************************************/ /* 'md_p.h' holds the 'physical' layout of RAID devices */ diff --git a/md_nonraid/6.12/unraid.c b/md_nonraid/6.18/unraid.c similarity index 99% rename from md_nonraid/6.12/unraid.c rename to md_nonraid/6.18/unraid.c index 706d7f2..6320d86 100644 --- a/md_nonraid/6.12/unraid.c +++ b/md_nonraid/6.18/unraid.c @@ -23,6 +23,11 @@ #include "md_unraid.h" +/* + * The global zero page. + */ +#define raid6_empty_zero_page page_address(ZERO_PAGE(0)) + /* * The following can be used to debug the driver */ @@ -1723,6 +1728,12 @@ void unraid_make_request(mddev_t *mddev, int unit, struct bio *bi) /* check for requests before we're running */ BUG_ON(!conf); + /* check for REQ_OP_DISCARD - shouldn't happen */ + if (unlikely(bio_op(bi) == REQ_OP_DISCARD)) { + /* just ignore it */ + return; + } + /* check for REQ_FLUSH */ if (bi->bi_opf & REQ_PREFLUSH) { dprintk("got a flush: disk: %d\n", unit); @@ -1795,8 +1806,6 @@ static void unraidd(mddev_t *mddev, unsigned long unit) dprintk("nonraidd%d: activated\n", (int)unit); - blk_start_plug(&plug); - spin_lock_irq(&conf->device_lock); while (!list_empty(&conf->handle_list[unit])) { struct list_head *first; @@ -1811,6 +1820,9 @@ static void unraidd(mddev_t *mddev, unsigned long unit) spin_unlock_irq(&conf->device_lock); + if (count == 0) + blk_start_plug(&plug); + handle_stripe(sh); release_stripe(sh); count++; @@ -1819,7 +1831,8 @@ static void unraidd(mddev_t *mddev, unsigned long unit) } spin_unlock_irq(&conf->device_lock); - blk_finish_plug(&plug); + if (count) + blk_finish_plug(&plug); dprintk("nonraidd%d: handled %d stripes\n", (int)unit, count); } diff --git a/md_nonraid/6.6/md_unraid.c b/md_nonraid/6.6/md_unraid.c index 8f350da..7965a71 100644 --- a/md_nonraid/6.6/md_unraid.c +++ b/md_nonraid/6.6/md_unraid.c @@ -941,6 +941,8 @@ static void md_submit_bio(struct bio *bi) } bi = bio_split_to_limits(bi); + if (!bi) + return; bi->bi_opf &= ~REQ_NOMERGE; unraid_make_request(mddev, unit, bi); @@ -2247,4 +2249,5 @@ module_exit(md_exit); MODULE_ALIAS("nonraid"); MODULE_ALIAS_BLOCKDEV_MAJOR(MAJOR_NR); +MODULE_DESCRIPTION("NonRAID array stacking driver"); MODULE_LICENSE("GPL"); diff --git a/md_nonraid/6.6/unraid.c b/md_nonraid/6.6/unraid.c index 706d7f2..6320d86 100644 --- a/md_nonraid/6.6/unraid.c +++ b/md_nonraid/6.6/unraid.c @@ -23,6 +23,11 @@ #include "md_unraid.h" +/* + * The global zero page. + */ +#define raid6_empty_zero_page page_address(ZERO_PAGE(0)) + /* * The following can be used to debug the driver */ @@ -1723,6 +1728,12 @@ void unraid_make_request(mddev_t *mddev, int unit, struct bio *bi) /* check for requests before we're running */ BUG_ON(!conf); + /* check for REQ_OP_DISCARD - shouldn't happen */ + if (unlikely(bio_op(bi) == REQ_OP_DISCARD)) { + /* just ignore it */ + return; + } + /* check for REQ_FLUSH */ if (bi->bi_opf & REQ_PREFLUSH) { dprintk("got a flush: disk: %d\n", unit); @@ -1795,8 +1806,6 @@ static void unraidd(mddev_t *mddev, unsigned long unit) dprintk("nonraidd%d: activated\n", (int)unit); - blk_start_plug(&plug); - spin_lock_irq(&conf->device_lock); while (!list_empty(&conf->handle_list[unit])) { struct list_head *first; @@ -1811,6 +1820,9 @@ static void unraidd(mddev_t *mddev, unsigned long unit) spin_unlock_irq(&conf->device_lock); + if (count == 0) + blk_start_plug(&plug); + handle_stripe(sh); release_stripe(sh); count++; @@ -1819,7 +1831,8 @@ static void unraidd(mddev_t *mddev, unsigned long unit) } spin_unlock_irq(&conf->device_lock); - blk_finish_plug(&plug); + if (count) + blk_finish_plug(&plug); dprintk("nonraidd%d: handled %d stripes\n", (int)unit, count); } diff --git a/md_nonraid/Makefile b/md_nonraid/Makefile index db3a843..881496e 100644 --- a/md_nonraid/Makefile +++ b/md_nonraid/Makefile @@ -8,7 +8,7 @@ K_GT_6_8 := $(shell [ $(K_MAJOR) -gt 6 -o \( $(K_MAJOR) -eq 6 -a $(K_MINOR) -gt K_GE_6_5 := $(shell [ $(K_MAJOR) -gt 6 -o \( $(K_MAJOR) -eq 6 -a $(K_MINOR) -ge 5 \) ] && echo true) ifeq ($(K_GT_6_8),true) -md-nonraid-m += 6.12/md_unraid.o 6.12/unraid.o +md-nonraid-m += 6.18/md_unraid.o 6.18/unraid.o else ifeq ($(K_GE_6_5),true) md-nonraid-m += 6.6/md_unraid.o 6.6/unraid.o else