Skip to content

Commit cdf6cdc

Browse files
rhvgoyaldjbw
authored andcommitted
dm,dax: Add dax zero_page_range operation
This patch adds support for dax zero_page_range operation to dm targets. Signed-off-by: Vivek Goyal <[email protected]> Acked-by: Mike Snitzer <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent 79fa974 commit cdf6cdc

File tree

5 files changed

+91
-0
lines changed

5 files changed

+91
-0
lines changed

drivers/md/dm-linear.c

+18
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,27 @@ static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
201201
return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
202202
}
203203

204+
static int linear_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
205+
size_t nr_pages)
206+
{
207+
int ret;
208+
struct linear_c *lc = ti->private;
209+
struct block_device *bdev = lc->dev->bdev;
210+
struct dax_device *dax_dev = lc->dev->dax_dev;
211+
sector_t dev_sector, sector = pgoff * PAGE_SECTORS;
212+
213+
dev_sector = linear_map_sector(ti, sector);
214+
ret = bdev_dax_pgoff(bdev, dev_sector, nr_pages << PAGE_SHIFT, &pgoff);
215+
if (ret)
216+
return ret;
217+
return dax_zero_page_range(dax_dev, pgoff, nr_pages);
218+
}
219+
204220
#else
205221
#define linear_dax_direct_access NULL
206222
#define linear_dax_copy_from_iter NULL
207223
#define linear_dax_copy_to_iter NULL
224+
#define linear_dax_zero_page_range NULL
208225
#endif
209226

210227
static struct target_type linear_target = {
@@ -226,6 +243,7 @@ static struct target_type linear_target = {
226243
.direct_access = linear_dax_direct_access,
227244
.dax_copy_from_iter = linear_dax_copy_from_iter,
228245
.dax_copy_to_iter = linear_dax_copy_to_iter,
246+
.dax_zero_page_range = linear_dax_zero_page_range,
229247
};
230248

231249
int __init dm_linear_init(void)

drivers/md/dm-log-writes.c

+17
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,26 @@ static size_t log_writes_dax_copy_to_iter(struct dm_target *ti,
994994
return dax_copy_to_iter(lc->dev->dax_dev, pgoff, addr, bytes, i);
995995
}
996996

997+
static int log_writes_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
998+
size_t nr_pages)
999+
{
1000+
int ret;
1001+
struct log_writes_c *lc = ti->private;
1002+
sector_t sector = pgoff * PAGE_SECTORS;
1003+
1004+
ret = bdev_dax_pgoff(lc->dev->bdev, sector, nr_pages << PAGE_SHIFT,
1005+
&pgoff);
1006+
if (ret)
1007+
return ret;
1008+
return dax_zero_page_range(lc->dev->dax_dev, pgoff,
1009+
nr_pages << PAGE_SHIFT);
1010+
}
1011+
9971012
#else
9981013
#define log_writes_dax_direct_access NULL
9991014
#define log_writes_dax_copy_from_iter NULL
10001015
#define log_writes_dax_copy_to_iter NULL
1016+
#define log_writes_dax_zero_page_range NULL
10011017
#endif
10021018

10031019
static struct target_type log_writes_target = {
@@ -1016,6 +1032,7 @@ static struct target_type log_writes_target = {
10161032
.direct_access = log_writes_dax_direct_access,
10171033
.dax_copy_from_iter = log_writes_dax_copy_from_iter,
10181034
.dax_copy_to_iter = log_writes_dax_copy_to_iter,
1035+
.dax_zero_page_range = log_writes_dax_zero_page_range,
10191036
};
10201037

10211038
static int __init dm_log_writes_init(void)

drivers/md/dm-stripe.c

+23
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,32 @@ static size_t stripe_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
360360
return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
361361
}
362362

363+
static int stripe_dax_zero_page_range(struct dm_target *ti, pgoff_t pgoff,
364+
size_t nr_pages)
365+
{
366+
int ret;
367+
sector_t dev_sector, sector = pgoff * PAGE_SECTORS;
368+
struct stripe_c *sc = ti->private;
369+
struct dax_device *dax_dev;
370+
struct block_device *bdev;
371+
uint32_t stripe;
372+
373+
stripe_map_sector(sc, sector, &stripe, &dev_sector);
374+
dev_sector += sc->stripe[stripe].physical_start;
375+
dax_dev = sc->stripe[stripe].dev->dax_dev;
376+
bdev = sc->stripe[stripe].dev->bdev;
377+
378+
ret = bdev_dax_pgoff(bdev, dev_sector, nr_pages << PAGE_SHIFT, &pgoff);
379+
if (ret)
380+
return ret;
381+
return dax_zero_page_range(dax_dev, pgoff, nr_pages);
382+
}
383+
363384
#else
364385
#define stripe_dax_direct_access NULL
365386
#define stripe_dax_copy_from_iter NULL
366387
#define stripe_dax_copy_to_iter NULL
388+
#define stripe_dax_zero_page_range NULL
367389
#endif
368390

369391
/*
@@ -486,6 +508,7 @@ static struct target_type stripe_target = {
486508
.direct_access = stripe_dax_direct_access,
487509
.dax_copy_from_iter = stripe_dax_copy_from_iter,
488510
.dax_copy_to_iter = stripe_dax_copy_to_iter,
511+
.dax_zero_page_range = stripe_dax_zero_page_range,
489512
};
490513

491514
int __init dm_stripe_init(void)

drivers/md/dm.c

+30
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,35 @@ static size_t dm_dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
11981198
return ret;
11991199
}
12001200

1201+
static int dm_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
1202+
size_t nr_pages)
1203+
{
1204+
struct mapped_device *md = dax_get_private(dax_dev);
1205+
sector_t sector = pgoff * PAGE_SECTORS;
1206+
struct dm_target *ti;
1207+
int ret = -EIO;
1208+
int srcu_idx;
1209+
1210+
ti = dm_dax_get_live_target(md, sector, &srcu_idx);
1211+
1212+
if (!ti)
1213+
goto out;
1214+
if (WARN_ON(!ti->type->dax_zero_page_range)) {
1215+
/*
1216+
* ->zero_page_range() is mandatory dax operation. If we are
1217+
* here, something is wrong.
1218+
*/
1219+
dm_put_live_table(md, srcu_idx);
1220+
goto out;
1221+
}
1222+
ret = ti->type->dax_zero_page_range(ti, pgoff, nr_pages);
1223+
1224+
out:
1225+
dm_put_live_table(md, srcu_idx);
1226+
1227+
return ret;
1228+
}
1229+
12011230
/*
12021231
* A target may call dm_accept_partial_bio only from the map routine. It is
12031232
* allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_RESET,
@@ -3199,6 +3228,7 @@ static const struct dax_operations dm_dax_ops = {
31993228
.dax_supported = dm_dax_supported,
32003229
.copy_from_iter = dm_dax_copy_from_iter,
32013230
.copy_to_iter = dm_dax_copy_to_iter,
3231+
.zero_page_range = dm_dax_zero_page_range,
32023232
};
32033233

32043234
/*

include/linux/device-mapper.h

+3
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff,
141141
long nr_pages, void **kaddr, pfn_t *pfn);
142142
typedef size_t (*dm_dax_copy_iter_fn)(struct dm_target *ti, pgoff_t pgoff,
143143
void *addr, size_t bytes, struct iov_iter *i);
144+
typedef int (*dm_dax_zero_page_range_fn)(struct dm_target *ti, pgoff_t pgoff,
145+
size_t nr_pages);
144146
#define PAGE_SECTORS (PAGE_SIZE / 512)
145147

146148
void dm_error(const char *message);
@@ -195,6 +197,7 @@ struct target_type {
195197
dm_dax_direct_access_fn direct_access;
196198
dm_dax_copy_iter_fn dax_copy_from_iter;
197199
dm_dax_copy_iter_fn dax_copy_to_iter;
200+
dm_dax_zero_page_range_fn dax_zero_page_range;
198201

199202
/* For internal device-mapper use. */
200203
struct list_head list;

0 commit comments

Comments
 (0)