projects/linux·commit f3e3dbce

Merge tag 'block-7.1-20260424' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

f3e3dbce · Linus Torvalds <[email protected]> · 2026-04-24 15:06:55 -07:00

Pull block fixes from Jens Axboe:

 - Series for zloop, fixing a variety of issues

 - t10-pi code cleanup

 - Fix for a merge window regression with the bio memory allocation mask

 - Fix for a merge window regression in ublk, caused by an issue with
   the maple tree iteration code at teardown

 - ublk self tests additions

 - Zoned device pgmap fixes

 - Various little cleanups and fixes

* tag 'block-7.1-20260424' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (21 commits)
  Revert "floppy: fix reference leak on platform_device_register() failure"
  ublk: avoid unpinning pages under maple tree spinlock
  ublk: refactor common helper ublk_shmem_remove_ranges()
  ublk: fix maple tree lockdep warning in ublk_buf_cleanup
  selftests: ublk: add ublk auto integrity test
  selftests: ublk: enable test_integrity_02.sh on fio 3.42
  selftests: ublk: remove unused argument to _cleanup
  block: only restrict bio allocation gfp mask asked to block
  block/blk-throttle: Add WQ_PERCPU to alloc_workqueue users
  block: Add WQ_PERCPU to alloc_workqueue users
  block: relax pgmap check in bio_add_page for compatible zone device pages
  block: add pgmap check to biovec_phys_mergeable
  floppy: fix reference leak on platform_device_register() failure
  ublk: use unchecked copy helpers for bio page data
  t10-pi: reduce ref tag code duplication
  zloop: remove irq-safe locking
  zloop: factor out zloop_mark_{full,empty} helpers
  zloop: set RQF_QUIET when completing requests on deleted devices
  zloop: improve the unaligned write pointer warning
  zloop: use vfs_truncate
  ...
Commit
f3e3dbcea15e20f7413afd8c791a496f0b80e80b
Parents
fa58e6e9 · 895a9b37

Merge commit. Changes below are compared with the first parent: fa58e6e9.

Changes

61 files changed · +347 −187

FileStatusAddDelContent
block/bio-integrity-auto.cmodified+1−1View file
block/bio-integrity.cmodified+3−3View file
block/bio.cmodified+6−5View file
block/blk-core.cmodified+1−1View file
block/blk-throttle.cmodified+1−1View file
block/blk.hmodified+21−0View file
drivers/block/ublk_drv.cmodified+80−43View file
drivers/block/zloop.cmodified+59−64View file
include/linux/t10-pi.hmodified+13−12View file
tools/testing/selftests/ublk/Makefilemodified+1−0View file
tools/testing/selftests/ublk/test_batch_01.shmodified+2−2View file
tools/testing/selftests/ublk/test_batch_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_batch_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_02.shmodified+2−2View file
tools/testing/selftests/ublk/test_generic_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_06.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_07.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_08.shmodified+2−2View file
tools/testing/selftests/ublk/test_generic_09.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_10.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_12.shmodified+2−2View file
tools/testing/selftests/ublk/test_generic_13.shmodified+1−1View file
tools/testing/selftests/ublk/test_generic_16.shmodified+2−2View file
tools/testing/selftests/ublk/test_generic_17.shmodified+1−1View file
tools/testing/selftests/ublk/test_integrity_02.shmodified+3−2View file
tools/testing/selftests/ublk/test_integrity_03.shadded+103−0View file
tools/testing/selftests/ublk/test_loop_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_04.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_05.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_06.shmodified+1−1View file
tools/testing/selftests/ublk/test_loop_07.shmodified+1−1View file
tools/testing/selftests/ublk/test_null_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_null_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_null_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_part_01.shmodified+2−2View file
tools/testing/selftests/ublk/test_part_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_recover_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_recover_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_recover_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_recover_04.shmodified+1−1View file
tools/testing/selftests/ublk/test_shmemzc_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_shmemzc_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_shmemzc_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_shmemzc_04.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_04.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_05.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_06.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_07.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_08.shmodified+1−1View file
tools/testing/selftests/ublk/test_stress_09.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_01.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_02.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_03.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_04.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_05.shmodified+1−1View file
tools/testing/selftests/ublk/test_stripe_06.shmodified+1−1View file

Only the first 600 diff lines are shown. Download the complete patch.

block/bio-integrity-auto.c

View file
diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c
index ebd17f4..353eed6 100644
--- a/block/bio-integrity-auto.c
+++ b/block/bio-integrity-auto.c
@@ -125,7 +125,7 @@ static int __init blk_integrity_auto_init(void)
* Make it highpri CPU intensive wq with max concurrency of 1.
*/
kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
- WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
+ WQ_HIGHPRI | WQ_CPU_INTENSIVE | WQ_PERCPU, 1);
if (!kintegrityd_wq)
panic("Failed to create kintegrityd\n");
return 0;

block/bio-integrity.c

View file
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index e79eaf0..e54c6e0 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -231,10 +231,10 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
if (bip->bip_vcnt > 0) {
struct bio_vec *bv = &bip->bip_vec[bip->bip_vcnt - 1];
- if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
+ if (!zone_device_pages_compatible(bv->bv_page, page))
return 0;
-
- if (bvec_try_merge_hw_page(q, bv, page, len, offset)) {
+ if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
+ bvec_try_merge_hw_page(q, bv, page, len, offset)) {
bip->bip_iter.bi_size += len;
return len;
}

block/bio.c

View file
diff --git a/block/bio.c b/block/bio.c
index 641ef09..b8972db 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -544,7 +544,8 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
return NULL;
- gfp = try_alloc_gfp(gfp);
+ if (saved_gfp & __GFP_DIRECT_RECLAIM)
+ gfp = try_alloc_gfp(gfp);
if (bs->cache && nr_vecs <= BIO_INLINE_VECS) {
/*
* Set REQ_ALLOC_CACHE even if no cached bio is available to
@@ -1048,10 +1049,10 @@ int bio_add_page(struct bio *bio, struct page *page,
if (bio->bi_vcnt > 0) {
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
- if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
+ if (!zone_device_pages_compatible(bv->bv_page, page))
return 0;
-
- if (bvec_try_merge_page(bv, page, len, offset)) {
+ if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
+ bvec_try_merge_page(bv, page, len, offset)) {
bio->bi_iter.bi_size += len;
return len;
}
@@ -1958,7 +1959,7 @@ int bioset_init(struct bio_set *bs,
if (flags & BIOSET_NEED_RESCUER) {
bs->rescue_workqueue = alloc_workqueue("bioset",
- WQ_MEM_RECLAIM, 0);
+ WQ_MEM_RECLAIM | WQ_PERCPU, 0);
if (!bs->rescue_workqueue)
goto bad;
}

block/blk-core.c

View file
diff --git a/block/blk-core.c b/block/blk-core.c
index 474700f..1745005 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1282,7 +1282,7 @@ int __init blk_dev_init(void)
/* used for unplugging and affects IO latency/throughput - HIGHPRI */
kblockd_workqueue = alloc_workqueue("kblockd",
- WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+ WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_PERCPU, 0);
if (!kblockd_workqueue)
panic("Failed to create kblockd\n");

block/blk-throttle.c

View file
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 97188a7..cabf91f 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1839,7 +1839,7 @@ void blk_throtl_exit(struct gendisk *disk)
static int __init throtl_init(void)
{
- kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM, 0);
+ kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM | WQ_PERCPU, 0);
if (!kthrotld_workqueue)
panic("Failed to create kthrotld\n");

block/blk.h

View file
diff --git a/block/blk.h b/block/blk.h
index ec4674c..b998a77 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -127,6 +127,8 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
if (addr1 + vec1->bv_len != addr2)
return false;
+ if (!zone_device_pages_have_same_pgmap(vec1->bv_page, vec2->bv_page))
+ return false;
if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))
return false;
if ((addr1 | mask) != ((addr2 + vec2->bv_len - 1) | mask))
@@ -134,6 +136,25 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
return true;
}
+/*
+ * Check if two pages from potentially different zone device pgmaps can
+ * coexist as separate bvec entries in the same bio.
+ *
+ * The block DMA iterator (blk_dma_map_iter_start) caches the P2PDMA mapping
+ * state from the first segment and applies it to all subsequent segments, so
+ * P2PDMA pages from different pgmaps must not be mixed in the same bio.
+ *
+ * Other zone device types (FS_DAX, GENERIC) use the same dma_map_phys() path
+ * as normal RAM. PRIVATE and COHERENT pages never appear in bios.
+ */
+static inline bool zone_device_pages_compatible(const struct page *a,
+ const struct page *b)
+{
+ if (is_pci_p2pdma_page(a) || is_pci_p2pdma_page(b))
+ return zone_device_pages_have_same_pgmap(a, b);
+ return true;
+}
+
static inline bool __bvec_gap_to_prev(const struct queue_limits *lim,
struct bio_vec *bprv, unsigned int offset)
{

drivers/block/ublk_drv.c

View file
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 603a98a..8e5f373 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1319,10 +1319,18 @@ static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
len = bv->bv_len - *offset;
bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
+ /*
+ * Bio pages may originate from slab caches without a usercopy region
+ * (e.g. jbd2 frozen metadata buffers). This is the same data that
+ * the loop driver writes to its backing file — no exposure risk.
+ * The bvec length is always trusted, so the size check in
+ * check_copy_size() is not needed either. Use the unchecked
+ * helpers to avoid false positives on slab pages.
+ */
if (dir == ITER_DEST)
- copied = copy_to_iter(bv_buf, len, uiter);
+ copied = _copy_to_iter(bv_buf, len, uiter);
else
- copied = copy_from_iter(bv_buf, len, uiter);
+ copied = _copy_from_iter(bv_buf, len, uiter);
kunmap_local(bv_buf);
@@ -5413,39 +5421,88 @@ err_free_pages:
return ret;
}
-static int __ublk_ctrl_unreg_buf(struct ublk_device *ub, int buf_index)
+static void ublk_unpin_range_pages(unsigned long base_pfn,
+ unsigned long nr_pages)
+{
+#define UBLK_UNPIN_BATCH 32
+ struct page *pages[UBLK_UNPIN_BATCH];
+ unsigned long off;
+
+ for (off = 0; off < nr_pages; ) {
+ unsigned int batch = min_t(unsigned long,
+ nr_pages - off, UBLK_UNPIN_BATCH);
+ unsigned int j;
+
+ for (j = 0; j < batch; j++)
+ pages[j] = pfn_to_page(base_pfn + off + j);
+ unpin_user_pages(pages, batch);
+ off += batch;
+ }
+}
+
+/*
+ * Inner loop: erase up to UBLK_REMOVE_BATCH matching ranges under
+ * mas_lock, collecting them into an xarray. Then drop the lock and
+ * unpin pages + free ranges outside spinlock context.
+ *
+ * Returns true if the tree walk completed, false if more ranges remain.
+ * Xarray key is the base PFN, value encodes nr_pages via xa_mk_value().
+ */
+#define UBLK_REMOVE_BATCH 64
+
+static bool __ublk_shmem_remove_ranges(struct ublk_device *ub,
+ int buf_index, int *ret)
{
MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
struct ublk_buf_range *range;
- struct page *pages[32];
- int ret = -ENOENT;
+ struct xarray to_unpin;
+ unsigned long idx;
+ unsigned int count = 0;
+ bool done = false;
+ void *entry;
+
+ xa_init(&to_unpin);
mas_lock(&mas);
mas_for_each(&mas, range, ULONG_MAX) {
- unsigned long base, nr, off;
+ unsigned long nr;
- if (range->buf_index != buf_index)
+ if (buf_index >= 0 && range->buf_index != buf_index)
continue;
- ret = 0;
- base = mas.index;
- nr = mas.last - base + 1;
+ *ret = 0;
+ nr = mas.last - mas.index + 1;
+ if (xa_err(xa_store(&to_unpin, mas.index,
+ xa_mk_value(nr), GFP_ATOMIC)))
+ goto unlock;
mas_erase(&mas);
-
- for (off = 0; off < nr; ) {
- unsigned int batch = min_t(unsigned long,
- nr - off, 32);
- unsigned int j;
-
- for (j = 0; j < batch; j++)
- pages[j] = pfn_to_page(base + off + j);
- unpin_user_pages(pages, batch);
- off += batch;
- }
kfree(range);
+ if (++count >= UBLK_REMOVE_BATCH)
+ goto unlock;
}
+ done = true;
+unlock:
mas_unlock(&mas);
+ xa_for_each(&to_unpin, idx, entry)
+ ublk_unpin_range_pages(idx, xa_to_value(entry));
+ xa_destroy(&to_unpin);
+
+ return done;
+}
+
+/*
+ * Remove ranges from the maple tree matching buf_index, unpin pages
+ * and free range structs. If buf_index < 0, remove all ranges.
+ * Processes ranges in batches to avoid holding the maple tree spinlock
+ * across potentially expensive page unpinning.
+ */
+static int ublk_shmem_remove_ranges(struct ublk_device *ub, int buf_index)
+{
+ int ret = -ENOENT;
+
+ while (!__ublk_shmem_remove_ranges(ub, buf_index, &ret))
+ cond_resched();
return ret;
}
@@ -5464,7 +5521,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
memflags = ublk_lock_buf_tree(ub);
- ret = __ublk_ctrl_unreg_buf(ub, index);
+ ret = ublk_shmem_remove_ranges(ub, index);
if (!ret)
ida_free(&ub->buf_ida, index);
@@ -5474,27 +5531,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
static void ublk_buf_cleanup(struct ublk_device *ub)
{
- MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
- struct ublk_buf_range *range;
- struct page *pages[32];
-
- mas_for_each(&mas, range, ULONG_MAX) {
- unsigned long base = mas.index;
- unsigned long nr = mas.last - base + 1;
- unsigned long off;
-
- for (off = 0; off < nr; ) {
- unsigned int batch = min_t(unsigned long,
- nr - off, 32);
- unsigned int j;
-
- for (j = 0; j < batch; j++)
- pages[j] = pfn_to_page(base + off + j);
- unpin_user_pages(pages, batch);
- off += batch;
- }
- kfree(range);
- }
+ ublk_shmem_remove_ranges(ub, -1);
mtree_destroy(&ub->buf_tree);
ida_destroy(&ub->buf_ida);
}

drivers/block/zloop.c

View file
diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c
index 8baf642..55eeb6a 100644
--- a/drivers/block/zloop.c
+++ b/drivers/block/zloop.c
@@ -288,12 +288,29 @@ static bool zloop_do_open_zone(struct zloop_device *zlo,
}
}
+static void zloop_mark_full(struct zloop_device *zlo, struct zloop_zone *zone)
+{
+ lockdep_assert_held(&zone->wp_lock);
+
+ zloop_lru_remove_open_zone(zlo, zone);
+ zone->cond = BLK_ZONE_COND_FULL;
+ zone->wp = ULLONG_MAX;
+}
+
+static void zloop_mark_empty(struct zloop_device *zlo, struct zloop_zone *zone)
+{
+ lockdep_assert_held(&zone->wp_lock);
+
+ zloop_lru_remove_open_zone(zlo, zone);
+ zone->cond = BLK_ZONE_COND_EMPTY;
+ zone->wp = zone->start;
+}
+
static int zloop_update_seq_zone(struct zloop_device *zlo, unsigned int zone_no)
{
struct zloop_zone *zone = &zlo->zones[zone_no];
struct kstat stat;
sector_t file_sectors;
- unsigned long flags;
int ret;
lockdep_assert_held(&zone->lock);
@@ -313,28 +330,24 @@ static int zloop_update_seq_zone(struct zloop_device *zlo, unsigned int zone_no)
return -EINVAL;
}
- if (file_sectors & ((zlo->block_size >> SECTOR_SHIFT) - 1)) {
- pr_err("Zone %u file size not aligned to block size %u\n",
- zone_no, zlo->block_size);
+ if (!IS_ALIGNED(stat.size, zlo->block_size)) {
+ pr_err("Zone %u file size (%llu) not aligned to block size %u\n",
+ zone_no, stat.size, zlo->block_size);
return -EINVAL;
}
- spin_lock_irqsave(&zone->wp_lock, flags);
+ spin_lock(&zone->wp_lock);
if (!file_sectors) {
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_EMPTY;
- zone->wp = zone->start;
+ zloop_mark_empty(zlo, zone);
} else if (file_sectors == zlo->zone_capacity) {
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_FULL;
- zone->wp = ULLONG_MAX;
+ zloop_mark_full(zlo, zone);
} else {
if (zone->cond != BLK_ZONE_COND_IMP_OPEN &&
zone->cond != BLK_ZONE_COND_EXP_OPEN)
zone->cond = BLK_ZONE_COND_CLOSED;
zone->wp = zone->start + file_sectors;
}
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
return 0;
}
@@ -367,7 +380,6 @@ unlock:
static int zloop_close_zone(struct zloop_device *zlo, unsigned int zone_no)
{
struct zloop_zone *zone = &zlo->zones[zone_no];
- unsigned long flags;
int ret = 0;
if (test_bit(ZLOOP_ZONE_CONV, &zone->flags))
@@ -386,13 +398,13 @@ static int zloop_close_zone(struct zloop_device *zlo, unsigned int zone_no)
break;
case BLK_ZONE_COND_IMP_OPEN:
case BLK_ZONE_COND_EXP_OPEN:
- spin_lock_irqsave(&zone->wp_lock, flags);
+ spin_lock(&zone->wp_lock);
zloop_lru_remove_open_zone(zlo, zone);
if (zone->wp == zone->start)
zone->cond = BLK_ZONE_COND_EMPTY;
else
zone->cond = BLK_ZONE_COND_CLOSED;
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
break;
case BLK_ZONE_COND_EMPTY:
case BLK_ZONE_COND_FULL:
@@ -410,7 +422,6 @@ unlock:
static int zloop_reset_zone(struct zloop_device *zlo, unsigned int zone_no)
{
struct zloop_zone *zone = &zlo->zones[zone_no];
- unsigned long flags;
int ret = 0;
if (test_bit(ZLOOP_ZONE_CONV, &zone->flags))
@@ -428,12 +439,10 @@ static int zloop_reset_zone(struct zloop_device *zlo, unsigned int zone_no)
goto unlock;
}
- spin_lock_irqsave(&zone->wp_lock, flags);
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_EMPTY;
- zone->wp = zone->start;
+ spin_lock(&zone->wp_lock);
+ zloop_mark_empty(zlo, zone);
clear_bit(ZLOOP_ZONE_SEQ_ERROR, &zone->flags);
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
unlock:
mutex_unlock(&zone->lock);
@@ -458,7 +467,6 @@ static int zloop_reset_all_zones(struct zloop_device *zlo)
static int zloop_finish_zone(struct zloop_device *zlo, unsigned int zone_no)
{
struct zloop_zone *zone = &zlo->zones[zone_no];
- unsigned long flags;
int ret = 0;
if (test_bit(ZLOOP_ZONE_CONV, &zone->flags))
@@ -476,12 +484,10 @@ static int zloop_finish_zone(struct zloop_device *zlo, unsigned int zone_no)
goto unlock;
}
- spin_lock_irqsave(&zone->wp_lock, flags);
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_FULL;
- zone->wp = ULLONG_MAX;
+ spin_lock(&zone->wp_lock);
+ zloop_mark_full(zlo, zone);
clear_bit(ZLOOP_ZONE_SEQ_ERROR, &zone->flags);
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
unlock:
mutex_unlock(&zone->lock);
@@ -571,10 +577,9 @@ static int zloop_seq_write_prep(struct zloop_cmd *cmd)
bool is_append = req_op(rq) == REQ_OP_ZONE_APPEND;
struct zloop_zone *zone = &zlo->zones[zone_no];
sector_t zone_end = zone->start + zlo->zone_capacity;
- unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&zone->wp_lock, flags);
+ spin_lock(&zone->wp_lock);
/*
* Zone append operations always go at the current write pointer, but
@@ -616,14 +621,11 @@ static int zloop_seq_write_prep(struct zloop_cmd *cmd)
*/
if (!is_append || !zlo->ordered_zone_append) {
zone->wp += nr_sectors;
- if (zone->wp == zone_end) {
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_FULL;
- zone->wp = ULLONG_MAX;
- }
+ if (zone->wp == zone_end)
+ zloop_mark_full(zlo, zone);
}
out_unlock:
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
return ret;
}
@@ -861,25 +863,21 @@ static bool zloop_set_zone_append_sector(struct request *rq)
struct zloop_zone *zone = &zlo->zones[zone_no];
sector_t zone_end = zone->start + zlo->zone_capacity;
sector_t nr_sectors = blk_rq_sectors(rq);
- unsigned long flags;
- spin_lock_irqsave(&zone->wp_lock, flags);
+ spin_lock(&zone->wp_lock);
if (zone->cond == BLK_ZONE_COND_FULL ||
zone->wp + nr_sectors > zone_end) {
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
return false;
}
rq->__sector = zone->wp;
zone->wp += blk_rq_sectors(rq);
- if (zone->wp >= zone_end) {
- zloop_lru_remove_open_zone(zlo, zone);
- zone->cond = BLK_ZONE_COND_FULL;
- zone->wp = ULLONG_MAX;
- }
+ if (zone->wp >= zone_end)
+ zloop_mark_full(zlo, zone);
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
return true;
}
@@ -891,8 +889,10 @@ static blk_status_t zloop_queue_rq(struct blk_mq_hw_ctx *hctx,
struct zloop_cmd *cmd = blk_mq_rq_to_pdu(rq);
struct zloop_device *zlo = rq->q->queuedata;
- if (data_race(READ_ONCE(zlo->state)) == Zlo_deleting)
+ if (data_race(READ_ONCE(zlo->state)) == Zlo_deleting) {
+ rq->rq_flags |= RQF_QUIET;
return BLK_STS_IOERR;
+ }
/*
* If we need to strongly order zone append operations, set the request
@@ -938,7 +938,6 @@ static int zloop_report_zones(struct gendisk *disk, sector_t sector,
struct zloop_device *zlo = disk->private_data;
struct blk_zone blkz = {};
unsigned int first, i;
- unsigned long flags;
int ret;
first = disk_zone_no(disk, sector);
@@ -962,9 +961,9 @@ static int zloop_report_zones(struct gendisk *disk, sector_t sector,
blkz.start = zone->start;
blkz.len = zlo->zone_size;
- spin_lock_irqsave(&zone->wp_lock, flags);
+ spin_lock(&zone->wp_lock);
blkz.wp = zone->wp;
- spin_unlock_irqrestore(&zone->wp_lock, flags);
+ spin_unlock(&zone->wp_lock);
blkz.cond = zone->cond;
if (test_bit(ZLOOP_ZONE_CONV, &zone->flags)) {
blkz.type = BLK_ZONE_TYPE_CONVENTIONAL;
@@ -1363,20 +1362,6 @@ out:
return ret;
}
-static void zloop_truncate(struct file *file, loff_t pos)
-{
- struct mnt_idmap *idmap = file_mnt_idmap(file);
- struct dentry *dentry = file_dentry(file);
- struct iattr newattrs;
-
- newattrs.ia_size = pos;
- newattrs.ia_valid = ATTR_SIZE;
-
- inode_lock(dentry->d_inode);
- notify_change(idmap, dentry, &newattrs, NULL);
- inode_unlock(dentry->d_inode);
-}
-
static void zloop_forget_cache(struct zloop_device *zlo)
{
unsigned int i;
@@ -1401,8 +1386,18 @@ static void zloop_forget_cache(struct zloop_device *zlo)
zlo->disk->part0, ret);
continue;
}
- if (old_wp < zone->wp)
- zloop_truncate(file, old_wp);
+
+ if (old_wp > zone->wp)
+ continue;
+ /*
+ * This should not happen, if we recored a full zone, it can't
+ * be active.
+ */
+ if (WARN_ON_ONCE(old_wp == ULLONG_MAX))
+ continue;
+
+ vfs_truncate(&file->f_path,
+ (old_wp - zone->start) << SECTOR_SHIFT);
}
}

include/linux/t10-pi.h

View file
diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h
index 2c59fe3..b6c2496 100644
--- a/include/linux/t10-pi.h
+++ b/include/linux/t10-pi.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/blk-mq.h>
+#include <linux/wordpart.h>
/*
* A T10 PI-capable target device can be formatted with different
@@ -25,6 +26,16 @@ enum t10_dif_type {
T10_PI_TYPE3_PROTECTION = 0x3,
};
+static inline u64 full_pi_ref_tag(const struct request *rq)
+{

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/Makefile

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_batch_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_batch_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_batch_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_06.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_07.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_08.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_09.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_10.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_12.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_13.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_16.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_generic_17.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_integrity_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_integrity_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_04.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_05.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_06.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_loop_07.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_null_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_null_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_null_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_part_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_part_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_recover_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_recover_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_recover_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_recover_04.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_shmemzc_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_shmemzc_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_shmemzc_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_shmemzc_04.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_04.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_05.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_06.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_07.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_08.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stress_09.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_01.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_02.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_03.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_04.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_05.sh

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/ublk/test_stripe_06.sh

View file

This diff is incomplete. Download the complete patch.