Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7bf7eac

Browse files
committed
dax: Arrange for dax_supported check to span multiple devices
Pankaj reports that starting with commitad428cd "dax: Check theend of the block-device capacity with dax_direct_access()" device-mapperno longer allows dax operation. This results from the stricter checks in__bdev_dax_supported() that validate that the start and end of ablock-device map to the same 'pagemap' instance.Teach the dax-core and device-mapper to validate the 'pagemap' on aper-target basis. This is accomplished by refactoring thebdev_dax_supported() internals into generic_fsdax_supported() whichtakes a sector range to validate. Consequently generic_fsdax_supported()is suitable to be used in a device-mapper ->iterate_devices() callback.A new ->dax_supported() operation is added to allow composite devices tosplit and route upper-level bdev_dax_supported() requests.Fixes:ad428cd ("dax: Check the end of the block-device...")Cc: <stable@vger.kernel.org>Cc: Ira Weiny <ira.weiny@intel.com>Cc: Dave Jiang <dave.jiang@intel.com>Cc: Keith Busch <keith.busch@intel.com>Cc: Matthew Wilcox <willy@infradead.org>Cc: Vishal Verma <vishal.l.verma@intel.com>Cc: Heiko Carstens <heiko.carstens@de.ibm.com>Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>Reviewed-by: Jan Kara <jack@suse.cz>Reported-by: Pankaj Gupta <pagupta@redhat.com>Reviewed-by: Pankaj Gupta <pagupta@redhat.com>Tested-by: Pankaj Gupta <pagupta@redhat.com>Tested-by: Vaibhav Jain <vaibhav@linux.ibm.com>Reviewed-by: Mike Snitzer <snitzer@redhat.com>Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parentc01dafa commit7bf7eac

File tree

7 files changed

+117
-37
lines changed

7 files changed

+117
-37
lines changed

‎drivers/dax/super.c‎

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,12 @@ struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
7373
EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
7474
#endif
7575

76-
/**
77-
* __bdev_dax_supported() - Check if the device supports dax for filesystem
78-
* @bdev: block device to check
79-
* @blocksize: The block size of the device
80-
*
81-
* This is a library function for filesystems to check if the block device
82-
* can be mounted with dax option.
83-
*
84-
* Return: true if supported, false if unsupported
85-
*/
86-
bool__bdev_dax_supported(structblock_device*bdev,intblocksize)
76+
bool__generic_fsdax_supported(structdax_device*dax_dev,
77+
structblock_device*bdev,intblocksize,sector_tstart,
78+
sector_tsectors)
8779
{
88-
structdax_device*dax_dev;
8980
booldax_enabled= false;
9081
pgoff_tpgoff,pgoff_end;
91-
structrequest_queue*q;
9282
charbuf[BDEVNAME_SIZE];
9383
void*kaddr,*end_kaddr;
9484
pfn_tpfn,end_pfn;
@@ -102,42 +92,26 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
10292
return false;
10393
}
10494

105-
q=bdev_get_queue(bdev);
106-
if (!q|| !blk_queue_dax(q)) {
107-
pr_debug("%s: error: request queue doesn't support dax\n",
108-
bdevname(bdev,buf));
109-
return false;
110-
}
111-
112-
err=bdev_dax_pgoff(bdev,0,PAGE_SIZE,&pgoff);
95+
err=bdev_dax_pgoff(bdev,start,PAGE_SIZE,&pgoff);
11396
if (err) {
11497
pr_debug("%s: error: unaligned partition for dax\n",
11598
bdevname(bdev,buf));
11699
return false;
117100
}
118101

119-
last_page=PFN_DOWN(i_size_read(bdev->bd_inode)-1)*8;
102+
last_page=PFN_DOWN((start+sectors-1)*512)*PAGE_SIZE /512;
120103
err=bdev_dax_pgoff(bdev,last_page,PAGE_SIZE,&pgoff_end);
121104
if (err) {
122105
pr_debug("%s: error: unaligned partition for dax\n",
123106
bdevname(bdev,buf));
124107
return false;
125108
}
126109

127-
dax_dev=dax_get_by_host(bdev->bd_disk->disk_name);
128-
if (!dax_dev) {
129-
pr_debug("%s: error: device does not support dax\n",
130-
bdevname(bdev,buf));
131-
return false;
132-
}
133-
134110
id=dax_read_lock();
135111
len=dax_direct_access(dax_dev,pgoff,1,&kaddr,&pfn);
136112
len2=dax_direct_access(dax_dev,pgoff_end,1,&end_kaddr,&end_pfn);
137113
dax_read_unlock(id);
138114

139-
put_dax(dax_dev);
140-
141115
if (len<1||len2<1) {
142116
pr_debug("%s: error: dax access failed (%ld)\n",
143117
bdevname(bdev,buf),len<1 ?len :len2);
@@ -178,6 +152,49 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
178152
}
179153
return true;
180154
}
155+
EXPORT_SYMBOL_GPL(__generic_fsdax_supported);
156+
157+
/**
158+
* __bdev_dax_supported() - Check if the device supports dax for filesystem
159+
* @bdev: block device to check
160+
* @blocksize: The block size of the device
161+
*
162+
* This is a library function for filesystems to check if the block device
163+
* can be mounted with dax option.
164+
*
165+
* Return: true if supported, false if unsupported
166+
*/
167+
bool__bdev_dax_supported(structblock_device*bdev,intblocksize)
168+
{
169+
structdax_device*dax_dev;
170+
structrequest_queue*q;
171+
charbuf[BDEVNAME_SIZE];
172+
boolret;
173+
intid;
174+
175+
q=bdev_get_queue(bdev);
176+
if (!q|| !blk_queue_dax(q)) {
177+
pr_debug("%s: error: request queue doesn't support dax\n",
178+
bdevname(bdev,buf));
179+
return false;
180+
}
181+
182+
dax_dev=dax_get_by_host(bdev->bd_disk->disk_name);
183+
if (!dax_dev) {
184+
pr_debug("%s: error: device does not support dax\n",
185+
bdevname(bdev,buf));
186+
return false;
187+
}
188+
189+
id=dax_read_lock();
190+
ret=dax_supported(dax_dev,bdev,blocksize,0,
191+
i_size_read(bdev->bd_inode) /512);
192+
dax_read_unlock(id);
193+
194+
put_dax(dax_dev);
195+
196+
returnret;
197+
}
181198
EXPORT_SYMBOL_GPL(__bdev_dax_supported);
182199
#endif
183200

@@ -303,6 +320,15 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
303320
}
304321
EXPORT_SYMBOL_GPL(dax_direct_access);
305322

323+
booldax_supported(structdax_device*dax_dev,structblock_device*bdev,
324+
intblocksize,sector_tstart,sector_tlen)
325+
{
326+
if (!dax_alive(dax_dev))
327+
return false;
328+
329+
returndax_dev->ops->dax_supported(dax_dev,bdev,blocksize,start,len);
330+
}
331+
306332
size_tdax_copy_from_iter(structdax_device*dax_dev,pgoff_tpgoff,void*addr,
307333
size_tbytes,structiov_iter*i)
308334
{

‎drivers/md/dm-table.c‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -880,13 +880,17 @@ void dm_table_set_type(struct dm_table *t, enum dm_queue_mode type)
880880
}
881881
EXPORT_SYMBOL_GPL(dm_table_set_type);
882882

883+
/* validate the dax capability of the target device span */
883884
staticintdevice_supports_dax(structdm_target*ti,structdm_dev*dev,
884-
sector_tstart,sector_tlen,void*data)
885+
sector_tstart,sector_tlen,void*data)
885886
{
886-
returnbdev_dax_supported(dev->bdev,PAGE_SIZE);
887+
intblocksize=*(int*)data;
888+
889+
returngeneric_fsdax_supported(dev->dax_dev,dev->bdev,blocksize,
890+
start,len);
887891
}
888892

889-
staticbooldm_table_supports_dax(structdm_table*t)
893+
booldm_table_supports_dax(structdm_table*t,intblocksize)
890894
{
891895
structdm_target*ti;
892896
unsignedi;
@@ -899,7 +903,8 @@ static bool dm_table_supports_dax(struct dm_table *t)
899903
return false;
900904

901905
if (!ti->type->iterate_devices||
902-
!ti->type->iterate_devices(ti,device_supports_dax,NULL))
906+
!ti->type->iterate_devices(ti,device_supports_dax,
907+
&blocksize))
903908
return false;
904909
}
905910

@@ -979,7 +984,7 @@ static int dm_table_determine_type(struct dm_table *t)
979984
verify_bio_based:
980985
/* We must use this table as bio-based */
981986
t->type=DM_TYPE_BIO_BASED;
982-
if (dm_table_supports_dax(t)||
987+
if (dm_table_supports_dax(t,PAGE_SIZE)||
983988
(list_empty(devices)&&live_md_type==DM_TYPE_DAX_BIO_BASED)) {
984989
t->type=DM_TYPE_DAX_BIO_BASED;
985990
}else {
@@ -1905,7 +1910,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
19051910
}
19061911
blk_queue_write_cache(q,wc,fua);
19071912

1908-
if (dm_table_supports_dax(t))
1913+
if (dm_table_supports_dax(t,PAGE_SIZE))
19091914
blk_queue_flag_set(QUEUE_FLAG_DAX,q);
19101915
else
19111916
blk_queue_flag_clear(QUEUE_FLAG_DAX,q);

‎drivers/md/dm.c‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,25 @@ static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
11071107
returnret;
11081108
}
11091109

1110+
staticbooldm_dax_supported(structdax_device*dax_dev,structblock_device*bdev,
1111+
intblocksize,sector_tstart,sector_tlen)
1112+
{
1113+
structmapped_device*md=dax_get_private(dax_dev);
1114+
structdm_table*map;
1115+
intsrcu_idx;
1116+
boolret;
1117+
1118+
map=dm_get_live_table(md,&srcu_idx);
1119+
if (!map)
1120+
return false;
1121+
1122+
ret=dm_table_supports_dax(map,blocksize);
1123+
1124+
dm_put_live_table(md,srcu_idx);
1125+
1126+
returnret;
1127+
}
1128+
11101129
staticsize_tdm_dax_copy_from_iter(structdax_device*dax_dev,pgoff_tpgoff,
11111130
void*addr,size_tbytes,structiov_iter*i)
11121131
{
@@ -3192,6 +3211,7 @@ static const struct block_device_operations dm_blk_dops = {
31923211

31933212
staticconststructdax_operationsdm_dax_ops= {
31943213
.direct_access=dm_dax_direct_access,
3214+
.dax_supported=dm_dax_supported,
31953215
.copy_from_iter=dm_dax_copy_from_iter,
31963216
.copy_to_iter=dm_dax_copy_to_iter,
31973217
};

‎drivers/md/dm.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ bool dm_table_bio_based(struct dm_table *t);
7272
booldm_table_request_based(structdm_table*t);
7373
voiddm_table_free_md_mempools(structdm_table*t);
7474
structdm_md_mempools*dm_table_get_md_mempools(structdm_table*t);
75+
booldm_table_supports_dax(structdm_table*t,intblocksize);
7576

7677
voiddm_lock_md_type(structmapped_device*md);
7778
voiddm_unlock_md_type(structmapped_device*md);

‎drivers/nvdimm/pmem.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ static size_t pmem_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
295295

296296
staticconststructdax_operationspmem_dax_ops= {
297297
.direct_access=pmem_dax_direct_access,
298+
.dax_supported=generic_fsdax_supported,
298299
.copy_from_iter=pmem_copy_from_iter,
299300
.copy_to_iter=pmem_copy_to_iter,
300301
};

‎drivers/s390/block/dcssblk.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static size_t dcssblk_dax_copy_to_iter(struct dax_device *dax_dev,
5959

6060
staticconststructdax_operationsdcssblk_dax_ops= {
6161
.direct_access=dcssblk_dax_direct_access,
62+
.dax_supported=generic_fsdax_supported,
6263
.copy_from_iter=dcssblk_dax_copy_from_iter,
6364
.copy_to_iter=dcssblk_dax_copy_to_iter,
6465
};

‎include/linux/dax.h‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ struct dax_operations {
1919
*/
2020
long (*direct_access)(structdax_device*,pgoff_t,long,
2121
void**,pfn_t*);
22+
/*
23+
* Validate whether this device is usable as an fsdax backing
24+
* device.
25+
*/
26+
bool (*dax_supported)(structdax_device*,structblock_device*,int,
27+
sector_t,sector_t);
2228
/* copy_from_iter: required operation for fs-dax direct-i/o */
2329
size_t (*copy_from_iter)(structdax_device*,pgoff_t,void*,size_t,
2430
structiov_iter*);
@@ -75,6 +81,17 @@ static inline bool bdev_dax_supported(struct block_device *bdev, int blocksize)
7581
return__bdev_dax_supported(bdev,blocksize);
7682
}
7783

84+
bool__generic_fsdax_supported(structdax_device*dax_dev,
85+
structblock_device*bdev,intblocksize,sector_tstart,
86+
sector_tsectors);
87+
staticinlineboolgeneric_fsdax_supported(structdax_device*dax_dev,
88+
structblock_device*bdev,intblocksize,sector_tstart,
89+
sector_tsectors)
90+
{
91+
return__generic_fsdax_supported(dax_dev,bdev,blocksize,start,
92+
sectors);
93+
}
94+
7895
staticinlinestructdax_device*fs_dax_get_by_host(constchar*host)
7996
{
8097
returndax_get_by_host(host);
@@ -99,6 +116,13 @@ static inline bool bdev_dax_supported(struct block_device *bdev,
99116
return false;
100117
}
101118

119+
staticinlineboolgeneric_fsdax_supported(structdax_device*dax_dev,
120+
structblock_device*bdev,intblocksize,sector_tstart,
121+
sector_tsectors)
122+
{
123+
return false;
124+
}
125+
102126
staticinlinestructdax_device*fs_dax_get_by_host(constchar*host)
103127
{
104128
returnNULL;
@@ -142,6 +166,8 @@ bool dax_alive(struct dax_device *dax_dev);
142166
void*dax_get_private(structdax_device*dax_dev);
143167
longdax_direct_access(structdax_device*dax_dev,pgoff_tpgoff,longnr_pages,
144168
void**kaddr,pfn_t*pfn);
169+
booldax_supported(structdax_device*dax_dev,structblock_device*bdev,
170+
intblocksize,sector_tstart,sector_tlen);
145171
size_tdax_copy_from_iter(structdax_device*dax_dev,pgoff_tpgoff,void*addr,
146172
size_tbytes,structiov_iter*i);
147173
size_tdax_copy_to_iter(structdax_device*dax_dev,pgoff_tpgoff,void*addr,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp