Skip to content

Commit 2f12d44

Browse files
committed
Merge tag 'for-5.9/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - DM multipath locking fixes around m->flags tests and improvements to bio-based code so that it follows patterns established by request-based code. - Request-based DM core improvement to eliminate unnecessary call to blk_mq_queue_stopped(). - Add "panic_on_corruption" error handling mode to DM verity target. - DM bufio fix to to perform buffer cleanup from a workqueue rather than wait for IO in reclaim context from shrinker. - DM crypt improvement to optionally avoid async processing via workqueues for reads and/or writes -- via "no_read_workqueue" and "no_write_workqueue" features. This more direct IO processing improves latency and throughput with faster storage. Avoiding workqueue IO submission for writes (DM_CRYPT_NO_WRITE_WORKQUEUE) is a requirement for adding zoned block device support to DM crypt. - Add zoned block device support to DM crypt. Makes use of DM_CRYPT_NO_WRITE_WORKQUEUE and a new optional feature (DM_CRYPT_WRITE_INLINE) that allows write completion to wait for encryption to complete. This allows write ordering to be preserved, which is needed for zoned block devices. - Fix DM ebs target's check for REQ_OP_FLUSH. - Fix DM core's report zones support to not report more zones than were requested. - A few small compiler warning fixes. - DM dust improvements to return output directly to the user rather than require they scrape the system log for output. * tag 'for-5.9/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm: don't call report zones for more than the user requested dm ebs: Fix incorrect checking for REQ_OP_FLUSH dm init: Set file local variable static dm ioctl: Fix compilation warning dm raid: Remove empty if statement dm verity: Fix compilation warning dm crypt: Enable zoned block device support dm crypt: add flags to optionally bypass kcryptd workqueues dm bufio: do buffer cleanup from a workqueue dm rq: don't call blk_mq_queue_stopped() in dm_stop_queue() dm dust: add interface to list all badblocks dm dust: report some message results directly back to user dm verity: add "panic_on_corruption" error handling mode dm mpath: use double checked locking in fast path dm mpath: rename current_pgpath to pgpath in multipath_prepare_ioctl dm mpath: rework __map_bio() dm mpath: factor out multipath_queue_bio dm mpath: push locking down to must_push_back_rq() dm mpath: take m->lock spinlock when testing QUEUE_IF_NO_PATH dm mpath: changes from initial m->flags locking audit
2 parents fa73e21 + a9cb9f4 commit 2f12d44

File tree

15 files changed

+355
-118
lines changed

15 files changed

+355
-118
lines changed

Documentation/admin-guide/device-mapper/dm-dust.rst

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ Create the dm-dust device:
6969
$ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096'
7070

7171
Check the status of the read behavior ("bypass" indicates that all I/O
72-
will be passed through to the underlying device)::
72+
will be passed through to the underlying device; "verbose" indicates that
73+
bad block additions, removals, and remaps will be verbosely logged)::
7374

7475
$ sudo dmsetup status dust1
75-
0 33552384 dust 252:17 bypass
76+
0 33552384 dust 252:17 bypass verbose
7677

7778
$ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct
7879
128+0 records in
@@ -164,7 +165,7 @@ following message command::
164165
A message will print with the number of bad blocks currently
165166
configured on the device::
166167

167-
kernel: device-mapper: dust: countbadblocks: 895 badblock(s) found
168+
countbadblocks: 895 badblock(s) found
168169

169170
Querying for specific bad blocks
170171
--------------------------------
@@ -176,11 +177,11 @@ following message command::
176177

177178
The following message will print if the block is in the list::
178179

179-
device-mapper: dust: queryblock: block 72 found in badblocklist
180+
dust_query_block: block 72 found in badblocklist
180181

181182
The following message will print if the block is not in the list::
182183

183-
device-mapper: dust: queryblock: block 72 not found in badblocklist
184+
dust_query_block: block 72 not found in badblocklist
184185

185186
The "queryblock" message command will work in both the "enabled"
186187
and "disabled" modes, allowing the verification of whether a block
@@ -198,12 +199,28 @@ following message command::
198199

199200
After clearing the bad block list, the following message will appear::
200201

201-
kernel: device-mapper: dust: clearbadblocks: badblocks cleared
202+
dust_clear_badblocks: badblocks cleared
202203

203204
If there were no bad blocks to clear, the following message will
204205
appear::
205206

206-
kernel: device-mapper: dust: clearbadblocks: no badblocks found
207+
dust_clear_badblocks: no badblocks found
208+
209+
Listing the bad block list
210+
--------------------------
211+
212+
To list all bad blocks in the bad block list (using an example device
213+
with blocks 1 and 2 in the bad block list), run the following message
214+
command::
215+
216+
$ sudo dmsetup message dust1 0 listbadblocks
217+
1
218+
2
219+
220+
If there are no bad blocks in the bad block list, the command will
221+
execute with no output::
222+
223+
$ sudo dmsetup message dust1 0 listbadblocks
207224

208225
Message commands list
209226
---------------------
@@ -223,6 +240,7 @@ Single argument message commands::
223240

224241
countbadblocks
225242
clearbadblocks
243+
listbadblocks
226244
disable
227245
enable
228246
quiet

Documentation/admin-guide/device-mapper/verity.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ restart_on_corruption
8383
not compatible with ignore_corruption and requires user space support to
8484
avoid restart loops.
8585

86+
panic_on_corruption
87+
Panic the device when a corrupted block is discovered. This option is
88+
not compatible with ignore_corruption and restart_on_corruption.
89+
8690
ignore_zero_blocks
8791
Do not verify blocks that are expected to contain zeroes and always return
8892
zeroes instead. This may be useful if the partition contains unused blocks

drivers/md/dm-bufio.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ struct dm_bufio_client {
108108
int async_write_error;
109109

110110
struct list_head client_list;
111+
111112
struct shrinker shrinker;
113+
struct work_struct shrink_work;
114+
atomic_long_t need_shrink;
112115
};
113116

114117
/*
@@ -1634,8 +1637,7 @@ static unsigned long get_retain_buffers(struct dm_bufio_client *c)
16341637
return retain_bytes;
16351638
}
16361639

1637-
static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
1638-
gfp_t gfp_mask)
1640+
static void __scan(struct dm_bufio_client *c)
16391641
{
16401642
int l;
16411643
struct dm_buffer *b, *tmp;
@@ -1646,42 +1648,58 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
16461648

16471649
for (l = 0; l < LIST_SIZE; l++) {
16481650
list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) {
1649-
if (__try_evict_buffer(b, gfp_mask))
1651+
if (count - freed <= retain_target)
1652+
atomic_long_set(&c->need_shrink, 0);
1653+
if (!atomic_long_read(&c->need_shrink))
1654+
return;
1655+
if (__try_evict_buffer(b, GFP_KERNEL)) {
1656+
atomic_long_dec(&c->need_shrink);
16501657
freed++;
1651-
if (!--nr_to_scan || ((count - freed) <= retain_target))
1652-
return freed;
1658+
}
16531659
cond_resched();
16541660
}
16551661
}
1656-
return freed;
16571662
}
16581663

1659-
static unsigned long
1660-
dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
1664+
static void shrink_work(struct work_struct *w)
1665+
{
1666+
struct dm_bufio_client *c = container_of(w, struct dm_bufio_client, shrink_work);
1667+
1668+
dm_bufio_lock(c);
1669+
__scan(c);
1670+
dm_bufio_unlock(c);
1671+
}
1672+
1673+
static unsigned long dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
16611674
{
16621675
struct dm_bufio_client *c;
1663-
unsigned long freed;
16641676

16651677
c = container_of(shrink, struct dm_bufio_client, shrinker);
1666-
if (sc->gfp_mask & __GFP_FS)
1667-
dm_bufio_lock(c);
1668-
else if (!dm_bufio_trylock(c))
1669-
return SHRINK_STOP;
1678+
atomic_long_add(sc->nr_to_scan, &c->need_shrink);
1679+
queue_work(dm_bufio_wq, &c->shrink_work);
16701680

1671-
freed = __scan(c, sc->nr_to_scan, sc->gfp_mask);
1672-
dm_bufio_unlock(c);
1673-
return freed;
1681+
return sc->nr_to_scan;
16741682
}
16751683

1676-
static unsigned long
1677-
dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
1684+
static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
16781685
{
16791686
struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker);
16801687
unsigned long count = READ_ONCE(c->n_buffers[LIST_CLEAN]) +
16811688
READ_ONCE(c->n_buffers[LIST_DIRTY]);
16821689
unsigned long retain_target = get_retain_buffers(c);
1690+
unsigned long queued_for_cleanup = atomic_long_read(&c->need_shrink);
1691+
1692+
if (unlikely(count < retain_target))
1693+
count = 0;
1694+
else
1695+
count -= retain_target;
16831696

1684-
return (count < retain_target) ? 0 : (count - retain_target);
1697+
if (unlikely(count < queued_for_cleanup))
1698+
count = 0;
1699+
else
1700+
count -= queued_for_cleanup;
1701+
1702+
return count;
16851703
}
16861704

16871705
/*
@@ -1772,6 +1790,9 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
17721790
__free_buffer_wake(b);
17731791
}
17741792

1793+
INIT_WORK(&c->shrink_work, shrink_work);
1794+
atomic_long_set(&c->need_shrink, 0);
1795+
17751796
c->shrinker.count_objects = dm_bufio_shrink_count;
17761797
c->shrinker.scan_objects = dm_bufio_shrink_scan;
17771798
c->shrinker.seeks = 1;
@@ -1817,6 +1838,7 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c)
18171838
drop_buffers(c);
18181839

18191840
unregister_shrinker(&c->shrinker);
1841+
flush_work(&c->shrink_work);
18201842

18211843
mutex_lock(&dm_bufio_clients_lock);
18221844

0 commit comments

Comments
 (0)