History

libnvdimm: add dax_dev sync flag

This patch adds 'DAXDEV_SYNC' flag which is set for nd_region doing synchronous flush. This later is used to disable MAP_SYNC functionality for ext4 & xfs filesystem for devices don't support synchronous flush.

Pankaj Gupta committed 7 years ago

Commit fefc1d91 parent 6e842008 files · +56 −7Browse files

Unified · Split

8 files
  1. drivers/dax/bus.c +1 −1
  2. drivers/dax/super.c +18 −1
  3. drivers/md/dm.c +2 −1
  4. drivers/nvdimm/pmem.c +4 −1
  5. drivers/nvdimm/region_devs.c +7 −0
  6. drivers/s390/block/dcssblk.c +1 −1
  7. include/linux/dax.h +22 −2
  8. include/linux/libnvdimm.h +1 −0
drivers/dax/bus.c+1−1
@@ -388,7 +388,7 @@ struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id, · 387 unmodified lines
388 * No 'host' or dax_operations since there is no access to this388 * No 'host' or dax_operations since there is no access to this
389 * device outside of mmap of the resulting character device.389 * device outside of mmap of the resulting character device.
390 */390 */
391 dax_dev = alloc_dax(dev_dax, NULL, NULL);391 dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC);
392 if (!dax_dev)392 if (!dax_dev)
393 goto err;393 goto err;
394 394
drivers/dax/super.c+18−1
@@ -195,6 +195,8 @@ enum dax_device_flags { · 194 unmodified lines
195 DAXDEV_ALIVE,195 DAXDEV_ALIVE,
196 /* gate whether dax_flush() calls the low level flush routine */196 /* gate whether dax_flush() calls the low level flush routine */
197 DAXDEV_WRITE_CACHE,197 DAXDEV_WRITE_CACHE,
198 /* flag to check if device supports synchronous flush */
199 DAXDEV_SYNC,
198};200};
199 201
200/**202/**
@@ -372,6 +374,18 @@ bool dax_write_cache_enabled(struct dax_device *dax_dev) · 171 unmodified lines
372}374}
373EXPORT_SYMBOL_GPL(dax_write_cache_enabled);375EXPORT_SYMBOL_GPL(dax_write_cache_enabled);
374 376
377bool __dax_synchronous(struct dax_device *dax_dev)
378{
379 return test_bit(DAXDEV_SYNC, &dax_dev->flags);
380}
381EXPORT_SYMBOL_GPL(__dax_synchronous);
382
383void __set_dax_synchronous(struct dax_device *dax_dev)
384{
385 set_bit(DAXDEV_SYNC, &dax_dev->flags);
386}
387EXPORT_SYMBOL_GPL(__set_dax_synchronous);
388
375bool dax_alive(struct dax_device *dax_dev)389bool dax_alive(struct dax_device *dax_dev)
376{390{
377 lockdep_assert_held(&dax_srcu);391 lockdep_assert_held(&dax_srcu);
@@ -526,7 +540,7 @@ static void dax_add_host(struct dax_device *dax_dev, const char *host) · 148 unmodified lines
526}540}
527 541
528struct dax_device *alloc_dax(void *private, const char *__host,542struct dax_device *alloc_dax(void *private, const char *__host,
529 const struct dax_operations *ops)543 const struct dax_operations *ops, unsigned long flags)
530{544{
531 struct dax_device *dax_dev;545 struct dax_device *dax_dev;
532 const char *host;546 const char *host;
@@ -549,6 +563,9 @@ struct dax_device *alloc_dax(void *private, const char *__host, · 16 unmodified lines
549 dax_add_host(dax_dev, host);563 dax_add_host(dax_dev, host);
550 dax_dev->ops = ops;564 dax_dev->ops = ops;
551 dax_dev->private = private;565 dax_dev->private = private;
566 if (flags & DAXDEV_F_SYNC)
567 set_dax_synchronous(dax_dev);
568
552 return dax_dev;569 return dax_dev;
553 570
554 err_dev:571 err_dev:
drivers/md/dm.c+2−1
@@ -1991,7 +1991,8 @@ static struct mapped_device *alloc_dev(int minor) · 1990 unmodified lines
1991 sprintf(md->disk->disk_name, "dm-%d", minor);1991 sprintf(md->disk->disk_name, "dm-%d", minor);
1992 1992
1993 if (IS_ENABLED(CONFIG_DAX_DRIVER)) {1993 if (IS_ENABLED(CONFIG_DAX_DRIVER)) {
1994 md->dax_dev = alloc_dax(md, md->disk->disk_name, &dm_dax_ops);1994 md->dax_dev = alloc_dax(md, md->disk->disk_name,
1995 &dm_dax_ops, 0);
1995 if (!md->dax_dev)1996 if (!md->dax_dev)
1996 goto bad;1997 goto bad;
1997 }1998 }
drivers/nvdimm/pmem.c+4−1
@@ -376,6 +376,7 @@ static int pmem_attach_disk(struct device *dev, · 375 unmodified lines
376 struct gendisk *disk;376 struct gendisk *disk;
377 void *addr;377 void *addr;
378 int rc;378 int rc;
379 unsigned long flags = 0UL;
379 380
380 pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);381 pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
381 if (!pmem)382 if (!pmem)
@@ -474,7 +475,9 @@ static int pmem_attach_disk(struct device *dev, · 92 unmodified lines
474 nvdimm_badblocks_populate(nd_region, &pmem->bb, &bb_res);475 nvdimm_badblocks_populate(nd_region, &pmem->bb, &bb_res);
475 disk->bb = &pmem->bb;476 disk->bb = &pmem->bb;
476 477
477 dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops);478 if (is_nvdimm_sync(nd_region))
479 flags = DAXDEV_F_SYNC;
480 dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags);
478 if (!dax_dev) {481 if (!dax_dev) {
479 put_disk(disk);482 put_disk(disk);
480 return -ENOMEM;483 return -ENOMEM;
drivers/nvdimm/region_devs.c+7−0
@@ -1211,6 +1211,13 @@ int nvdimm_has_cache(struct nd_region *nd_region) · 1210 unmodified lines
1211}1211}
1212EXPORT_SYMBOL_GPL(nvdimm_has_cache);1212EXPORT_SYMBOL_GPL(nvdimm_has_cache);
1213 1213
1214bool is_nvdimm_sync(struct nd_region *nd_region)
1215{
1216 return is_nd_pmem(&nd_region->dev) &&
1217 !test_bit(ND_REGION_ASYNC, &nd_region->flags);
1218}
1219EXPORT_SYMBOL_GPL(is_nvdimm_sync);
1220
1214struct conflict_context {1221struct conflict_context {
1215 struct nd_region *nd_region;1222 struct nd_region *nd_region;
1216 resource_size_t start, size;1223 resource_size_t start, size;
drivers/s390/block/dcssblk.c+1−1
@@ -679,7 +679,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char · 678 unmodified lines
679 goto put_dev;679 goto put_dev;
680 680
681 dev_info->dax_dev = alloc_dax(dev_info, dev_info->gd->disk_name,681 dev_info->dax_dev = alloc_dax(dev_info, dev_info->gd->disk_name,
682 &dcssblk_dax_ops);682 &dcssblk_dax_ops, DAXDEV_F_SYNC);
683 if (!dev_info->dax_dev) {683 if (!dev_info->dax_dev) {
684 rc = -ENOMEM;684 rc = -ENOMEM;
685 goto put_dev;685 goto put_dev;
include/linux/dax.h+22−2
@@ -7,6 +7,9 @@ · 6 unmodified lines
7#include <linux/radix-tree.h>7#include <linux/radix-tree.h>
8#include <asm/pgtable.h>8#include <asm/pgtable.h>
9 9
10/* Flag for synchronous flush */
11#define DAXDEV_F_SYNC (1UL << 0)
12
10typedef unsigned long dax_entry_t;13typedef unsigned long dax_entry_t;
11 14
12struct iomap_ops;15struct iomap_ops;
@@ -38,18 +41,28 @@ extern struct attribute_group dax_attribute_group; · 25 unmodified lines
38#if IS_ENABLED(CONFIG_DAX)41#if IS_ENABLED(CONFIG_DAX)
39struct dax_device *dax_get_by_host(const char *host);42struct dax_device *dax_get_by_host(const char *host);
40struct dax_device *alloc_dax(void *private, const char *host,43struct dax_device *alloc_dax(void *private, const char *host,
41 const struct dax_operations *ops);44 const struct dax_operations *ops, unsigned long flags);
42void put_dax(struct dax_device *dax_dev);45void put_dax(struct dax_device *dax_dev);
43void kill_dax(struct dax_device *dax_dev);46void kill_dax(struct dax_device *dax_dev);
44void dax_write_cache(struct dax_device *dax_dev, bool wc);47void dax_write_cache(struct dax_device *dax_dev, bool wc);
45bool dax_write_cache_enabled(struct dax_device *dax_dev);48bool dax_write_cache_enabled(struct dax_device *dax_dev);
49bool __dax_synchronous(struct dax_device *dax_dev);
50static inline bool dax_synchronous(struct dax_device *dax_dev)
51{
52 return __dax_synchronous(dax_dev);
53}
54void __set_dax_synchronous(struct dax_device *dax_dev);
55static inline void set_dax_synchronous(struct dax_device *dax_dev)
56{
57 __set_dax_synchronous(dax_dev);
58}
46#else59#else
47static inline struct dax_device *dax_get_by_host(const char *host)60static inline struct dax_device *dax_get_by_host(const char *host)
48{61{
49 return NULL;62 return NULL;
50}63}
51static inline struct dax_device *alloc_dax(void *private, const char *host,64static inline struct dax_device *alloc_dax(void *private, const char *host,
52 const struct dax_operations *ops)65 const struct dax_operations *ops, unsigned long flags)
53{66{
54 /*67 /*
55 * Callers should check IS_ENABLED(CONFIG_DAX) to know if this68 * Callers should check IS_ENABLED(CONFIG_DAX) to know if this
@@ -70,6 +83,13 @@ static inline bool dax_write_cache_enabled(struct dax_device *dax_dev) · 14 unmodified lines
70{83{
71 return false;84 return false;
72}85}
86static inline bool dax_synchronous(struct dax_device *dax_dev)
87{
88 return true;
89}
90static inline void set_dax_synchronous(struct dax_device *dax_dev)
91{
92}
73#endif93#endif
74 94
75struct writeback_control;95struct writeback_control;
include/linux/libnvdimm.h+1−0
@@ -263,6 +263,7 @@ int generic_nvdimm_flush(struct nd_region *nd_region); · 262 unmodified lines
263int nvdimm_has_flush(struct nd_region *nd_region);263int nvdimm_has_flush(struct nd_region *nd_region);
264int nvdimm_has_cache(struct nd_region *nd_region);264int nvdimm_has_cache(struct nd_region *nd_region);
265int nvdimm_in_overwrite(struct nvdimm *nvdimm);265int nvdimm_in_overwrite(struct nvdimm *nvdimm);
266bool is_nvdimm_sync(struct nd_region *nd_region);
266 267
267static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void *buf,268static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void *buf,
268 unsigned int buf_len, int *cmd_rc)269 unsigned int buf_len, int *cmd_rc)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t