Re: [PATCH v2 3/3] xfs: Add alignment check for DAX mount

From: Dave Chinner
Date: Wed May 04 2016 - 19:19:17 EST


On Mon, May 02, 2016 at 12:42:58PM -0600, Toshi Kani wrote:
> When a partition is not aligned by 4KB, mount -o dax succeeds,
> but any read/write access to the filesystem fails, except for
> metadata update.
>
> Call bdev_direct_access to check the alignment when -o dax is
> specified.
>
> Signed-off-by: Toshi Kani <toshi.kani@xxxxxxx>
> Cc: Dave Chinner <david@xxxxxxxxxxxxx>
> Cc: Dan Williams <dan.j.williams@xxxxxxxxx>
> Cc: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
> Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
> Cc: Boaz Harrosh <boaz@xxxxxxxxxxxxx>
> ---
> fs/xfs/xfs_super.c | 23 +++++++++++++++++++----
> 1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 187e14b..b7ee323 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1557,15 +1557,30 @@ xfs_fs_fill_super(
> sb->s_flags |= MS_I_VERSION;
>
> if (mp->m_flags & XFS_MOUNT_DAX) {
> + struct blk_dax_ctl dax = {
> + .sector = 0,
> + .size = PAGE_SIZE,
> + };
> xfs_warn(mp,
> - "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> + "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> if (sb->s_blocksize != PAGE_SIZE) {
> xfs_alert(mp,
> "Filesystem block size invalid for DAX Turning DAX off.");
> mp->m_flags &= ~XFS_MOUNT_DAX;
> - } else if (!sb->s_bdev->bd_disk->fops->direct_access) {
> - xfs_alert(mp,
> - "Block device does not support DAX Turning DAX off.");
> + } else if ((error = bdev_direct_access(sb->s_bdev, &dax)) < 0) {
> + switch (error) {
> + case -EOPNOTSUPP:
> + xfs_alert(mp,
> + "Block device does not support DAX Turning DAX off.");
> + break;
> + case -EINVAL:
> + xfs_alert(mp,
> + "Partition alignment invalid for DAX Turning DAX off.");
> + break;
> + default:
> + xfs_alert(mp,
> + "DAX access failed (%d) DAX Turning DAX off.", error);
> + }

Please write a helper along the lines of:

error = blkdev_supports_dax(sb->s_bdev, sb->s_blocksize);

and encapsulate all this, including the specific error messages in the
helper (i.e. "Block device %s does not support DAX."). Then the rest
of the filesystem code looks something like this:

if (mp->m_flags & XFS_MOUNT_DAX) {
error = blkdev_supports_dax(sb->s_bdev, sb->s_blocksize);
if (error) {
xfs_alert(mp,
"DAX unsupported by block device. Turning off DAX.");
mp->m_flags &= ~XFS_MOUNT_DAX;
}
}

And each filesystem can choose to do what it wants with the error
without having to care exactly why DAX is not supported.

Cheers,

Dave.
--
Dave Chinner
david@xxxxxxxxxxxxx