Skip to content

Commit 2e5fd48

Browse files
committed
Merge tag 'libnvdimm-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams: - Fix a race condition in the teardown path of raw mode pmem namespaces. - Cleanup the code that filesystems use to detect filesystem-dax capabilities of their underlying block device. * tag 'libnvdimm-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: dax: remove bdev_dax_supported xfs: factor out a xfs_buftarg_is_dax helper dax: stub out dax_supported for !CONFIG_FS_DAX dax: remove __generic_fsdax_supported dax: move the dax_read_lock() locking into dax_supported dax: mark dax_get_by_host static dm: use fs_dax_get_by_bdev instead of dax_get_by_host dax: stop using bdevname fsdax: improve the FS_DAX Kconfig description and help text libnvdimm/pmem: Fix crash triggered when I/O in-flight during unbind
2 parents 4b105f4 + 3fc3725 commit 2e5fd48

File tree

10 files changed

+120
-172
lines changed

10 files changed

+120
-172
lines changed

drivers/dax/super.c

Lines changed: 73 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
#include <linux/fs.h>
1818
#include "dax-private.h"
1919

20+
/**
21+
* struct dax_device - anchor object for dax services
22+
* @inode: core vfs
23+
* @cdev: optional character interface for "device dax"
24+
* @host: optional name for lookups where the device path is not available
25+
* @private: dax driver private data
26+
* @flags: state and boolean properties
27+
*/
28+
struct dax_device {
29+
struct hlist_node list;
30+
struct inode inode;
31+
struct cdev cdev;
32+
const char *host;
33+
void *private;
34+
unsigned long flags;
35+
const struct dax_operations *ops;
36+
};
37+
2038
static dev_t dax_devt;
2139
DEFINE_STATIC_SRCU(dax_srcu);
2240
static struct vfsmount *dax_mnt;
@@ -40,6 +58,42 @@ void dax_read_unlock(int id)
4058
}
4159
EXPORT_SYMBOL_GPL(dax_read_unlock);
4260

61+
static int dax_host_hash(const char *host)
62+
{
63+
return hashlen_hash(hashlen_string("DAX", host)) % DAX_HASH_SIZE;
64+
}
65+
66+
/**
67+
* dax_get_by_host() - temporary lookup mechanism for filesystem-dax
68+
* @host: alternate name for the device registered by a dax driver
69+
*/
70+
static struct dax_device *dax_get_by_host(const char *host)
71+
{
72+
struct dax_device *dax_dev, *found = NULL;
73+
int hash, id;
74+
75+
if (!host)
76+
return NULL;
77+
78+
hash = dax_host_hash(host);
79+
80+
id = dax_read_lock();
81+
spin_lock(&dax_host_lock);
82+
hlist_for_each_entry(dax_dev, &dax_host_list[hash], list) {
83+
if (!dax_alive(dax_dev)
84+
|| strcmp(host, dax_dev->host) != 0)
85+
continue;
86+
87+
if (igrab(&dax_dev->inode))
88+
found = dax_dev;
89+
break;
90+
}
91+
spin_unlock(&dax_host_lock);
92+
dax_read_unlock(id);
93+
94+
return found;
95+
}
96+
4397
#ifdef CONFIG_BLOCK
4498
#include <linux/blkdev.h>
4599

@@ -65,45 +119,39 @@ struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
65119
return dax_get_by_host(bdev->bd_disk->disk_name);
66120
}
67121
EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
68-
#endif
69122

70-
bool __generic_fsdax_supported(struct dax_device *dax_dev,
123+
bool generic_fsdax_supported(struct dax_device *dax_dev,
71124
struct block_device *bdev, int blocksize, sector_t start,
72125
sector_t sectors)
73126
{
74127
bool dax_enabled = false;
75128
pgoff_t pgoff, pgoff_end;
76-
char buf[BDEVNAME_SIZE];
77129
void *kaddr, *end_kaddr;
78130
pfn_t pfn, end_pfn;
79131
sector_t last_page;
80132
long len, len2;
81133
int err, id;
82134

83135
if (blocksize != PAGE_SIZE) {
84-
pr_info("%s: error: unsupported blocksize for dax\n",
85-
bdevname(bdev, buf));
136+
pr_info("%pg: error: unsupported blocksize for dax\n", bdev);
86137
return false;
87138
}
88139

89140
if (!dax_dev) {
90-
pr_debug("%s: error: dax unsupported by block device\n",
91-
bdevname(bdev, buf));
141+
pr_debug("%pg: error: dax unsupported by block device\n", bdev);
92142
return false;
93143
}
94144

95145
err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff);
96146
if (err) {
97-
pr_info("%s: error: unaligned partition for dax\n",
98-
bdevname(bdev, buf));
147+
pr_info("%pg: error: unaligned partition for dax\n", bdev);
99148
return false;
100149
}
101150

102151
last_page = PFN_DOWN((start + sectors - 1) * 512) * PAGE_SIZE / 512;
103152
err = bdev_dax_pgoff(bdev, last_page, PAGE_SIZE, &pgoff_end);
104153
if (err) {
105-
pr_info("%s: error: unaligned partition for dax\n",
106-
bdevname(bdev, buf));
154+
pr_info("%pg: error: unaligned partition for dax\n", bdev);
107155
return false;
108156
}
109157

@@ -112,8 +160,8 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
112160
len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn);
113161

114162
if (len < 1 || len2 < 1) {
115-
pr_info("%s: error: dax access failed (%ld)\n",
116-
bdevname(bdev, buf), len < 1 ? len : len2);
163+
pr_info("%pg: error: dax access failed (%ld)\n",
164+
bdev, len < 1 ? len : len2);
117165
dax_read_unlock(id);
118166
return false;
119167
}
@@ -147,57 +195,32 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
147195
dax_read_unlock(id);
148196

149197
if (!dax_enabled) {
150-
pr_info("%s: error: dax support not enabled\n",
151-
bdevname(bdev, buf));
198+
pr_info("%pg: error: dax support not enabled\n", bdev);
152199
return false;
153200
}
154201
return true;
155202
}
156-
EXPORT_SYMBOL_GPL(__generic_fsdax_supported);
203+
EXPORT_SYMBOL_GPL(generic_fsdax_supported);
157204

158-
/**
159-
* __bdev_dax_supported() - Check if the device supports dax for filesystem
160-
* @bdev: block device to check
161-
* @blocksize: The block size of the device
162-
*
163-
* This is a library function for filesystems to check if the block device
164-
* can be mounted with dax option.
165-
*
166-
* Return: true if supported, false if unsupported
167-
*/
168-
bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
205+
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
206+
int blocksize, sector_t start, sector_t len)
169207
{
170-
struct dax_device *dax_dev;
171-
struct request_queue *q;
172-
char buf[BDEVNAME_SIZE];
173-
bool ret;
208+
bool ret = false;
174209
int id;
175210

176-
q = bdev_get_queue(bdev);
177-
if (!q || !blk_queue_dax(q)) {
178-
pr_debug("%s: error: request queue doesn't support dax\n",
179-
bdevname(bdev, buf));
180-
return false;
181-
}
182-
183-
dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
184-
if (!dax_dev) {
185-
pr_debug("%s: error: device does not support dax\n",
186-
bdevname(bdev, buf));
211+
if (!dax_dev)
187212
return false;
188-
}
189213

190214
id = dax_read_lock();
191-
ret = dax_supported(dax_dev, bdev, blocksize, 0,
192-
i_size_read(bdev->bd_inode) / 512);
215+
if (dax_alive(dax_dev) && dax_dev->ops->dax_supported)
216+
ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize,
217+
start, len);
193218
dax_read_unlock(id);
194-
195-
put_dax(dax_dev);
196-
197219
return ret;
198220
}
199-
EXPORT_SYMBOL_GPL(__bdev_dax_supported);
200-
#endif
221+
EXPORT_SYMBOL_GPL(dax_supported);
222+
#endif /* CONFIG_FS_DAX */
223+
#endif /* CONFIG_BLOCK */
201224

202225
enum dax_device_flags {
203226
/* !alive + rcu grace period == no new operations / mappings */
@@ -208,24 +231,6 @@ enum dax_device_flags {
208231
DAXDEV_SYNC,
209232
};
210233

211-
/**
212-
* struct dax_device - anchor object for dax services
213-
* @inode: core vfs
214-
* @cdev: optional character interface for "device dax"
215-
* @host: optional name for lookups where the device path is not available
216-
* @private: dax driver private data
217-
* @flags: state and boolean properties
218-
*/
219-
struct dax_device {
220-
struct hlist_node list;
221-
struct inode inode;
222-
struct cdev cdev;
223-
const char *host;
224-
void *private;
225-
unsigned long flags;
226-
const struct dax_operations *ops;
227-
};
228-
229234
static ssize_t write_cache_show(struct device *dev,
230235
struct device_attribute *attr, char *buf)
231236
{
@@ -323,19 +328,6 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
323328
}
324329
EXPORT_SYMBOL_GPL(dax_direct_access);
325330

326-
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
327-
int blocksize, sector_t start, sector_t len)
328-
{
329-
if (!dax_dev)
330-
return false;
331-
332-
if (!dax_alive(dax_dev))
333-
return false;
334-
335-
return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len);
336-
}
337-
EXPORT_SYMBOL_GPL(dax_supported);
338-
339331
size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
340332
size_t bytes, struct iov_iter *i)
341333
{
@@ -423,11 +415,6 @@ bool dax_alive(struct dax_device *dax_dev)
423415
}
424416
EXPORT_SYMBOL_GPL(dax_alive);
425417

426-
static int dax_host_hash(const char *host)
427-
{
428-
return hashlen_hash(hashlen_string("DAX", host)) % DAX_HASH_SIZE;
429-
}
430-
431418
/*
432419
* Note, rcu is not protecting the liveness of dax_dev, rcu is ensuring
433420
* that any fault handlers or operations that might have seen
@@ -624,38 +611,6 @@ void put_dax(struct dax_device *dax_dev)
624611
}
625612
EXPORT_SYMBOL_GPL(put_dax);
626613

627-
/**
628-
* dax_get_by_host() - temporary lookup mechanism for filesystem-dax
629-
* @host: alternate name for the device registered by a dax driver
630-
*/
631-
struct dax_device *dax_get_by_host(const char *host)
632-
{
633-
struct dax_device *dax_dev, *found = NULL;
634-
int hash, id;
635-
636-
if (!host)
637-
return NULL;
638-
639-
hash = dax_host_hash(host);
640-
641-
id = dax_read_lock();
642-
spin_lock(&dax_host_lock);
643-
hlist_for_each_entry(dax_dev, &dax_host_list[hash], list) {
644-
if (!dax_alive(dax_dev)
645-
|| strcmp(host, dax_dev->host) != 0)
646-
continue;
647-
648-
if (igrab(&dax_dev->inode))
649-
found = dax_dev;
650-
break;
651-
}
652-
spin_unlock(&dax_host_lock);
653-
dax_read_unlock(id);
654-
655-
return found;
656-
}
657-
EXPORT_SYMBOL_GPL(dax_get_by_host);
658-
659614
/**
660615
* inode_dax: convert a public inode into its dax_dev
661616
* @inode: An inode with i_cdev pointing to a dax_dev

drivers/md/dm-table.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -809,14 +809,9 @@ EXPORT_SYMBOL_GPL(dm_table_set_type);
809809
int device_not_dax_capable(struct dm_target *ti, struct dm_dev *dev,
810810
sector_t start, sector_t len, void *data)
811811
{
812-
int blocksize = *(int *) data, id;
813-
bool rc;
812+
int blocksize = *(int *) data;
814813

815-
id = dax_read_lock();
816-
rc = !dax_supported(dev->dax_dev, dev->bdev, blocksize, start, len);
817-
dax_read_unlock(id);
818-
819-
return rc;
814+
return !dax_supported(dev->dax_dev, dev->bdev, blocksize, start, len);
820815
}
821816

822817
/* Check devices support synchronous DAX */

drivers/md/dm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ static int open_table_device(struct table_device *td, dev_t dev,
654654
}
655655

656656
td->dm_dev.bdev = bdev;
657-
td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
657+
td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev);
658658
return 0;
659659
}
660660

drivers/nvdimm/pmem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,11 +450,11 @@ static int pmem_attach_disk(struct device *dev,
450450
pmem->pfn_flags |= PFN_MAP;
451451
bb_range = pmem->pgmap.range;
452452
} else {
453+
addr = devm_memremap(dev, pmem->phys_addr,
454+
pmem->size, ARCH_MEMREMAP_PMEM);
453455
if (devm_add_action_or_reset(dev, pmem_release_queue,
454456
&pmem->pgmap))
455457
return -ENOMEM;
456-
addr = devm_memremap(dev, pmem->phys_addr,
457-
pmem->size, ARCH_MEMREMAP_PMEM);
458458
bb_range.start = res->start;
459459
bb_range.end = res->end;
460460
}

fs/Kconfig

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ source "fs/f2fs/Kconfig"
4343
source "fs/zonefs/Kconfig"
4444

4545
config FS_DAX
46-
bool "Direct Access (DAX) support"
46+
bool "File system based Direct Access (DAX) support"
4747
depends on MMU
4848
depends on !(ARM || MIPS || SPARC)
4949
select DEV_PAGEMAP_OPS if (ZONE_DEVICE && !FS_DAX_LIMITED)
@@ -53,8 +53,23 @@ config FS_DAX
5353
Direct Access (DAX) can be used on memory-backed block devices.
5454
If the block device supports DAX and the filesystem supports DAX,
5555
then you can avoid using the pagecache to buffer I/Os. Turning
56-
on this option will compile in support for DAX; you will need to
57-
mount the filesystem using the -o dax option.
56+
on this option will compile in support for DAX.
57+
58+
For a DAX device to support file system access it needs to have
59+
struct pages. For the nfit based NVDIMMs this can be enabled
60+
using the ndctl utility:
61+
62+
# ndctl create-namespace --force --reconfig=namespace0.0 \
63+
--mode=fsdax --map=mem
64+
65+
See the 'create-namespace' man page for details on the overhead of
66+
--map=mem:
67+
https://docs.pmem.io/ndctl-user-guide/ndctl-man-pages/ndctl-create-namespace
68+
69+
For ndctl to work CONFIG_DEV_DAX needs to be enabled as well. For most
70+
file systems DAX support needs to be manually enabled globally or
71+
per-inode using a mount option as well. See the file documentation in
72+
Documentation/filesystems/dax.rst for details.
5873

5974
If you do not have a block device that is capable of using this,
6075
or if unsure, say N. Saying Y will increase the size of the kernel

fs/erofs/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
546546
return err;
547547

548548
if (test_opt(ctx, DAX_ALWAYS) &&
549-
!bdev_dax_supported(sb->s_bdev, EROFS_BLKSIZ)) {
549+
!dax_supported(sbi->dax_dev, sb->s_bdev, EROFS_BLKSIZ, 0, bdev_nr_sectors(sb->s_bdev))) {
550550
errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
551551
clear_opt(ctx, DAX_ALWAYS);
552552
}

fs/ext2/super.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
946946
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
947947

948948
if (test_opt(sb, DAX)) {
949-
if (!bdev_dax_supported(sb->s_bdev, blocksize)) {
949+
if (!dax_supported(dax_dev, sb->s_bdev, blocksize, 0,
950+
bdev_nr_sectors(sb->s_bdev))) {
950951
ext2_msg(sb, KERN_ERR,
951952
"DAX unsupported by block device. Turning off DAX.");
952953
clear_opt(sbi->s_mount_opt, DAX);

fs/ext4/super.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4287,7 +4287,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42874287
goto failed_mount;
42884288
}
42894289

4290-
if (bdev_dax_supported(sb->s_bdev, blocksize))
4290+
if (dax_supported(dax_dev, sb->s_bdev, blocksize, 0,
4291+
bdev_nr_sectors(sb->s_bdev)))
42914292
set_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags);
42924293

42934294
if (sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS) {

0 commit comments

Comments
 (0)