diff options
author | Toshi Kani <toshi.kani@hpe.com> | 2016-05-10 12:23:53 -0400 |
---|---|---|
committer | Vishal Verma <vishal.l.verma@intel.com> | 2016-05-17 02:44:11 -0400 |
commit | 2d96afc8f70ef86c66a0b5d80c24a27d6dd13df3 (patch) | |
tree | 094e60ebc2d1ecd365c8d2e38a1502d0e6c36999 | |
parent | 2af3a8159cd204fc8437ed2f75863f0fb930f0d0 (diff) |
block: Add bdev_dax_supported() for dax mount checks
DAX imposes additional requirements to a device. Add
bdev_dax_supported() which performs all the precondition checks
necessary for filesystem to mount the device with dax option.
Also add a new check to verify if a partition is aligned by 4KB.
When a partition is unaligned, any dax read/write access fails,
except for metadata update.
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jens Axboe <axboe@fb.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jan Kara <jack@suse.cz>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Boaz Harrosh <boaz@plexistor.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
-rw-r--r-- | fs/block_dev.c | 45 | ||||
-rw-r--r-- | include/linux/blkdev.h | 1 |
2 files changed, 46 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 91e0ec0233c0..518cde62c01c 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -509,6 +509,51 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax) | |||
509 | } | 509 | } |
510 | EXPORT_SYMBOL_GPL(bdev_direct_access); | 510 | EXPORT_SYMBOL_GPL(bdev_direct_access); |
511 | 511 | ||
512 | /** | ||
513 | * bdev_dax_supported() - Check if the device supports dax for filesystem | ||
514 | * @sb: The superblock of the device | ||
515 | * @blocksize: The block size of the device | ||
516 | * | ||
517 | * This is a library function for filesystems to check if the block device | ||
518 | * can be mounted with dax option. | ||
519 | * | ||
520 | * Return: negative errno if unsupported, 0 if supported. | ||
521 | */ | ||
522 | int bdev_dax_supported(struct super_block *sb, int blocksize) | ||
523 | { | ||
524 | struct blk_dax_ctl dax = { | ||
525 | .sector = 0, | ||
526 | .size = PAGE_SIZE, | ||
527 | }; | ||
528 | int err; | ||
529 | |||
530 | if (blocksize != PAGE_SIZE) { | ||
531 | vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax"); | ||
532 | return -EINVAL; | ||
533 | } | ||
534 | |||
535 | err = bdev_direct_access(sb->s_bdev, &dax); | ||
536 | if (err < 0) { | ||
537 | switch (err) { | ||
538 | case -EOPNOTSUPP: | ||
539 | vfs_msg(sb, KERN_ERR, | ||
540 | "error: device does not support dax"); | ||
541 | break; | ||
542 | case -EINVAL: | ||
543 | vfs_msg(sb, KERN_ERR, | ||
544 | "error: unaligned partition for dax"); | ||
545 | break; | ||
546 | default: | ||
547 | vfs_msg(sb, KERN_ERR, | ||
548 | "error: dax access failed (%d)", err); | ||
549 | } | ||
550 | return err; | ||
551 | } | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | EXPORT_SYMBOL_GPL(bdev_dax_supported); | ||
556 | |||
512 | /* | 557 | /* |
513 | * pseudo-fs | 558 | * pseudo-fs |
514 | */ | 559 | */ |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 78c48ab22f46..71231a55debd 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1688,6 +1688,7 @@ extern int bdev_read_page(struct block_device *, sector_t, struct page *); | |||
1688 | extern int bdev_write_page(struct block_device *, sector_t, struct page *, | 1688 | extern int bdev_write_page(struct block_device *, sector_t, struct page *, |
1689 | struct writeback_control *); | 1689 | struct writeback_control *); |
1690 | extern long bdev_direct_access(struct block_device *, struct blk_dax_ctl *); | 1690 | extern long bdev_direct_access(struct block_device *, struct blk_dax_ctl *); |
1691 | extern int bdev_dax_supported(struct super_block *, int); | ||
1691 | #else /* CONFIG_BLOCK */ | 1692 | #else /* CONFIG_BLOCK */ |
1692 | 1693 | ||
1693 | struct block_device; | 1694 | struct block_device; |