fs/xfs: Make DAX mount option a tri-state
authorIra Weiny <ira.weiny@intel.com>
Thu, 30 Apr 2020 14:41:35 +0000 (07:41 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Sat, 30 May 2020 03:13:20 +0000 (20:13 -0700)
As agreed upon[1].  We make the dax mount option a tri-state.  '-o dax'
continues to operate the same.  We add 'always', 'never', and 'inode'
(default).

[1] https://lore.kernel.org/lkml/20200405061945.GA94792@iweiny-DESK2.sc.intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_mount.h
fs/xfs/xfs_super.c

index f6123fb0113c685b51770cf4eb3f000918c7c269..37bfb50db8090d5b807a57fd1305eafdf074ded8 100644 (file)
@@ -238,6 +238,7 @@ typedef struct xfs_mount {
                                                   allocator */
 #define XFS_MOUNT_NOATTR2      (1ULL << 25)    /* disable use of attr2 format */
 #define XFS_MOUNT_DAX_ALWAYS   (1ULL << 26)
+#define XFS_MOUNT_DAX_NEVER    (1ULL << 27)
 
 /*
  * Max and min values for mount-option defined I/O
index 51fdef91edda535fdb469842473cff1e69397180..6f91c13fb6ea83d06a7fcc4331282a0e910bf015 100644 (file)
@@ -47,6 +47,39 @@ static struct kset *xfs_kset;                /* top-level xfs sysfs dir */
 static struct xfs_kobj xfs_dbg_kobj;   /* global debug sysfs attrs */
 #endif
 
+enum xfs_dax_mode {
+       XFS_DAX_INODE = 0,
+       XFS_DAX_ALWAYS = 1,
+       XFS_DAX_NEVER = 2,
+};
+
+static void
+xfs_mount_set_dax_mode(
+       struct xfs_mount        *mp,
+       enum xfs_dax_mode       mode)
+{
+       switch (mode) {
+       case XFS_DAX_INODE:
+               mp->m_flags &= ~(XFS_MOUNT_DAX_ALWAYS | XFS_MOUNT_DAX_NEVER);
+               break;
+       case XFS_DAX_ALWAYS:
+               mp->m_flags |= XFS_MOUNT_DAX_ALWAYS;
+               mp->m_flags &= ~XFS_MOUNT_DAX_NEVER;
+               break;
+       case XFS_DAX_NEVER:
+               mp->m_flags |= XFS_MOUNT_DAX_NEVER;
+               mp->m_flags &= ~XFS_MOUNT_DAX_ALWAYS;
+               break;
+       }
+}
+
+static const struct constant_table dax_param_enums[] = {
+       {"inode",       XFS_DAX_INODE },
+       {"always",      XFS_DAX_ALWAYS },
+       {"never",       XFS_DAX_NEVER },
+       {}
+};
+
 /*
  * Table driven mount option parser.
  */
@@ -59,7 +92,7 @@ enum {
        Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota,
        Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota,
        Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
-       Opt_discard, Opt_nodiscard, Opt_dax,
+       Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum,
 };
 
 static const struct fs_parameter_spec xfs_fs_parameters[] = {
@@ -103,6 +136,7 @@ static const struct fs_parameter_spec xfs_fs_parameters[] = {
        fsparam_flag("discard",         Opt_discard),
        fsparam_flag("nodiscard",       Opt_nodiscard),
        fsparam_flag("dax",             Opt_dax),
+       fsparam_enum("dax",             Opt_dax_enum, dax_param_enums),
        {}
 };
 
@@ -129,7 +163,8 @@ xfs_fs_show_options(
                { XFS_MOUNT_GRPID,              ",grpid" },
                { XFS_MOUNT_DISCARD,            ",discard" },
                { XFS_MOUNT_LARGEIO,            ",largeio" },
-               { XFS_MOUNT_DAX_ALWAYS,         ",dax" },
+               { XFS_MOUNT_DAX_ALWAYS,         ",dax=always" },
+               { XFS_MOUNT_DAX_NEVER,          ",dax=never" },
                { 0, NULL }
        };
        struct xfs_mount        *mp = XFS_M(root->d_sb);
@@ -1261,7 +1296,10 @@ xfs_fc_parse_param(
                return 0;
 #ifdef CONFIG_FS_DAX
        case Opt_dax:
-               mp->m_flags |= XFS_MOUNT_DAX_ALWAYS;
+               xfs_mount_set_dax_mode(mp, XFS_DAX_ALWAYS);
+               return 0;
+       case Opt_dax_enum:
+               xfs_mount_set_dax_mode(mp, result.uint_32);
                return 0;
 #endif
        default:
@@ -1468,7 +1506,7 @@ xfs_fc_fill_super(
                if (!rtdev_is_dax && !datadev_is_dax) {
                        xfs_alert(mp,
                        "DAX unsupported by block device. Turning off DAX.");
-                       mp->m_flags &= ~XFS_MOUNT_DAX_ALWAYS;
+                       xfs_mount_set_dax_mode(mp, XFS_DAX_NEVER);
                }
                if (xfs_sb_version_hasreflink(&mp->m_sb)) {
                        xfs_alert(mp,