This patch adds support for dax zero_page_range operation to dm targets.
Unified · Split
| @@ -201,10 +201,27 @@ static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff, · 200 unmodified lines | |||
| 201 | return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i); | 201 | return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i); |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 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 | |||
| 204 | #else | 220 | #else |
| 205 | #define linear_dax_direct_access NULL | 221 | #define linear_dax_direct_access NULL |
| 206 | #define linear_dax_copy_from_iter NULL | 222 | #define linear_dax_copy_from_iter NULL |
| 207 | #define linear_dax_copy_to_iter NULL | 223 | #define linear_dax_copy_to_iter NULL |
| 224 | #define linear_dax_zero_page_range NULL | ||
| 208 | #endif | 225 | #endif |
| 209 | 226 | ||
| 210 | static struct target_type linear_target = { | 227 | static struct target_type linear_target = { |
| @@ -226,6 +243,7 @@ static struct target_type linear_target = { · 15 unmodified lines | |||
| 226 | .direct_access = linear_dax_direct_access, | 243 | .direct_access = linear_dax_direct_access, |
| 227 | .dax_copy_from_iter = linear_dax_copy_from_iter, | 244 | .dax_copy_from_iter = linear_dax_copy_from_iter, |
| 228 | .dax_copy_to_iter = linear_dax_copy_to_iter, | 245 | .dax_copy_to_iter = linear_dax_copy_to_iter, |
| 246 | .dax_zero_page_range = linear_dax_zero_page_range, | ||
| 229 | }; | 247 | }; |
| 230 | 248 | ||
| 231 | int __init dm_linear_init(void) | 249 | int __init dm_linear_init(void) |
| @@ -994,10 +994,26 @@ static size_t log_writes_dax_copy_to_iter(struct dm_target *ti, · 993 unmodified lines | |||
| 994 | return dax_copy_to_iter(lc->dev->dax_dev, pgoff, addr, bytes, i); | 994 | return dax_copy_to_iter(lc->dev->dax_dev, pgoff, addr, bytes, i); |
| 995 | } | 995 | } |
| 996 | 996 | ||
| 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 | |||
| 997 | #else | 1012 | #else |
| 998 | #define log_writes_dax_direct_access NULL | 1013 | #define log_writes_dax_direct_access NULL |
| 999 | #define log_writes_dax_copy_from_iter NULL | 1014 | #define log_writes_dax_copy_from_iter NULL |
| 1000 | #define log_writes_dax_copy_to_iter NULL | 1015 | #define log_writes_dax_copy_to_iter NULL |
| 1016 | #define log_writes_dax_zero_page_range NULL | ||
| 1001 | #endif | 1017 | #endif |
| 1002 | 1018 | ||
| 1003 | static struct target_type log_writes_target = { | 1019 | static struct target_type log_writes_target = { |
| @@ -1016,6 +1032,7 @@ static struct target_type log_writes_target = { · 12 unmodified lines | |||
| 1016 | .direct_access = log_writes_dax_direct_access, | 1032 | .direct_access = log_writes_dax_direct_access, |
| 1017 | .dax_copy_from_iter = log_writes_dax_copy_from_iter, | 1033 | .dax_copy_from_iter = log_writes_dax_copy_from_iter, |
| 1018 | .dax_copy_to_iter = log_writes_dax_copy_to_iter, | 1034 | .dax_copy_to_iter = log_writes_dax_copy_to_iter, |
| 1035 | .dax_zero_page_range = log_writes_dax_zero_page_range, | ||
| 1019 | }; | 1036 | }; |
| 1020 | 1037 | ||
| 1021 | static int __init dm_log_writes_init(void) | 1038 | static int __init dm_log_writes_init(void) |
| @@ -360,10 +360,32 @@ static size_t stripe_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff, · 359 unmodified lines | |||
| 360 | return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i); | 360 | return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i); |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 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 | |||
| 363 | #else | 384 | #else |
| 364 | #define stripe_dax_direct_access NULL | 385 | #define stripe_dax_direct_access NULL |
| 365 | #define stripe_dax_copy_from_iter NULL | 386 | #define stripe_dax_copy_from_iter NULL |
| 366 | #define stripe_dax_copy_to_iter NULL | 387 | #define stripe_dax_copy_to_iter NULL |
| 388 | #define stripe_dax_zero_page_range NULL | ||
| 367 | #endif | 389 | #endif |
| 368 | 390 | ||
| 369 | /* | 391 | /* |
| @@ -486,6 +508,7 @@ static struct target_type stripe_target = { · 116 unmodified lines | |||
| 486 | .direct_access = stripe_dax_direct_access, | 508 | .direct_access = stripe_dax_direct_access, |
| 487 | .dax_copy_from_iter = stripe_dax_copy_from_iter, | 509 | .dax_copy_from_iter = stripe_dax_copy_from_iter, |
| 488 | .dax_copy_to_iter = stripe_dax_copy_to_iter, | 510 | .dax_copy_to_iter = stripe_dax_copy_to_iter, |
| 511 | .dax_zero_page_range = stripe_dax_zero_page_range, | ||
| 489 | }; | 512 | }; |
| 490 | 513 | ||
| 491 | int __init dm_stripe_init(void) | 514 | int __init dm_stripe_init(void) |
| @@ -1198,6 +1198,35 @@ static size_t dm_dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, · 1197 unmodified lines | |||
| 1198 | return ret; | 1198 | return ret; |
| 1199 | } | 1199 | } |
| 1200 | 1200 | ||
| 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 | |||
| 1201 | /* | 1230 | /* |
| 1202 | * A target may call dm_accept_partial_bio only from the map routine. It is | 1231 | * A target may call dm_accept_partial_bio only from the map routine. It is |
| 1203 | * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_RESET, | 1232 | * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_RESET, |
| @@ -3199,6 +3228,7 @@ static const struct dax_operations dm_dax_ops = { · 1995 unmodified lines | |||
| 3199 | .dax_supported = dm_dax_supported, | 3228 | .dax_supported = dm_dax_supported, |
| 3200 | .copy_from_iter = dm_dax_copy_from_iter, | 3229 | .copy_from_iter = dm_dax_copy_from_iter, |
| 3201 | .copy_to_iter = dm_dax_copy_to_iter, | 3230 | .copy_to_iter = dm_dax_copy_to_iter, |
| 3231 | .zero_page_range = dm_dax_zero_page_range, | ||
| 3202 | }; | 3232 | }; |
| 3203 | 3233 | ||
| 3204 | /* | 3234 | /* |
| @@ -141,6 +141,8 @@ typedef long (*dm_dax_direct_access_fn) (struct dm_target *ti, pgoff_t pgoff, · 140 unmodified lines | |||
| 141 | long nr_pages, void **kaddr, pfn_t *pfn); | 141 | long nr_pages, void **kaddr, pfn_t *pfn); |
| 142 | typedef size_t (*dm_dax_copy_iter_fn)(struct dm_target *ti, pgoff_t pgoff, | 142 | typedef size_t (*dm_dax_copy_iter_fn)(struct dm_target *ti, pgoff_t pgoff, |
| 143 | void *addr, size_t bytes, struct iov_iter *i); | 143 | 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); | ||
| 144 | #define PAGE_SECTORS (PAGE_SIZE / 512) | 146 | #define PAGE_SECTORS (PAGE_SIZE / 512) |
| 145 | 147 | ||
| 146 | void dm_error(const char *message); | 148 | void dm_error(const char *message); |
| @@ -195,6 +197,7 @@ struct target_type { · 48 unmodified lines | |||
| 195 | dm_dax_direct_access_fn direct_access; | 197 | dm_dax_direct_access_fn direct_access; |
| 196 | dm_dax_copy_iter_fn dax_copy_from_iter; | 198 | dm_dax_copy_iter_fn dax_copy_from_iter; |
| 197 | dm_dax_copy_iter_fn dax_copy_to_iter; | 199 | dm_dax_copy_iter_fn dax_copy_to_iter; |
| 200 | dm_dax_zero_page_range_fn dax_zero_page_range; | ||
| 198 | 201 | ||
| 199 | /* For internal device-mapper use. */ | 202 | /* For internal device-mapper use. */ |
| 200 | struct list_head list; | 203 | struct list_head list; |