get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/810306/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 810306,
    "url": "http://patchwork.ozlabs.org/api/patches/810306/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20170905223541.20594-10-ross.zwisler@linux.intel.com/",
    "project": {
        "id": 8,
        "url": "http://patchwork.ozlabs.org/api/projects/8/?format=api",
        "name": "Linux ext4 filesystem development",
        "link_name": "linux-ext4",
        "list_id": "linux-ext4.vger.kernel.org",
        "list_email": "linux-ext4@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170905223541.20594-10-ross.zwisler@linux.intel.com>",
    "list_archive_url": null,
    "date": "2017-09-05T22:35:41",
    "name": "[9/9] ext4: add per-inode DAX flag",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": true,
    "hash": "41237f0aefb6d6e427f3ba5853bb4a9c6244d771",
    "submitter": {
        "id": 46514,
        "url": "http://patchwork.ozlabs.org/api/people/46514/?format=api",
        "name": "Ross Zwisler",
        "email": "ross.zwisler@linux.intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20170905223541.20594-10-ross.zwisler@linux.intel.com/mbox/",
    "series": [
        {
            "id": 1660,
            "url": "http://patchwork.ozlabs.org/api/series/1660/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/list/?series=1660",
            "date": "2017-09-05T22:35:36",
            "name": "add ext4 per-inode DAX flag",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/1660/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/810306/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/810306/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-ext4-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-ext4-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xn1nJ4XxTz9sP3\n\tfor <patchwork-incoming@ozlabs.org>;\n\tWed,  6 Sep 2017 08:37:40 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754449AbdIEWhZ (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tTue, 5 Sep 2017 18:37:25 -0400",
            "from mga01.intel.com ([192.55.52.88]:4505 \"EHLO mga01.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1754085AbdIEWgX (ORCPT <rfc822;linux-ext4@vger.kernel.org>);\n\tTue, 5 Sep 2017 18:36:23 -0400",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t05 Sep 2017 15:36:19 -0700",
            "from theros.lm.intel.com ([10.232.112.77])\n\tby fmsmga004.fm.intel.com with ESMTP; 05 Sep 2017 15:36:18 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.41,481,1498546800\"; d=\"scan'208\";a=\"308314899\"",
        "From": "Ross Zwisler <ross.zwisler@linux.intel.com>",
        "To": "Andrew Morton <akpm@linux-foundation.org>, linux-kernel@vger.kernel.org",
        "Cc": "Ross Zwisler <ross.zwisler@linux.intel.com>,\n\t\"Darrick J. Wong\" <darrick.wong@oracle.com>,\n\t\"Theodore Ts'o\" <tytso@mit.edu>,\n\tAndreas Dilger <adilger.kernel@dilger.ca>,\n\tChristoph Hellwig <hch@lst.de>, Dan Williams <dan.j.williams@intel.com>,\n\tDave Chinner <david@fromorbit.com>, Jan Kara <jack@suse.cz>,\n\tlinux-ext4@vger.kernel.org, linux-nvdimm@lists.01.org,\n\tlinux-xfs@vger.kernel.org",
        "Subject": "[PATCH 9/9] ext4: add per-inode DAX flag",
        "Date": "Tue,  5 Sep 2017 16:35:41 -0600",
        "Message-Id": "<20170905223541.20594-10-ross.zwisler@linux.intel.com>",
        "X-Mailer": "git-send-email 2.9.5",
        "In-Reply-To": "<20170905223541.20594-1-ross.zwisler@linux.intel.com>",
        "References": "<20170905223541.20594-1-ross.zwisler@linux.intel.com>",
        "Sender": "linux-ext4-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<linux-ext4.vger.kernel.org>",
        "X-Mailing-List": "linux-ext4@vger.kernel.org"
    },
    "content": "Follow the lead of XFS and add a per-inode flag that allows the choice of\nwhether or not to use DAX to be made for individual files.  As with XFS\nthis flag can also be set on a directory, in which case it will be\ninherited by new inodes (both subdirectories and files) created within that\ndirectory.\n\nThis inode flag can be viewed and manipulated using xfs_io, just as is done\nwith the XFS version of this flag:\n\n  # mount /dev/pmem0 /mnt/\n\n  # mount | grep /mnt\n  /dev/pmem0 on /mnt type ext4 (rw,relatime,seclabel,data=ordered)\n\n  # touch /mnt/a\n\n  # xfs_io -c lsattr /mnt/a\n  ---------------- /mnt/a\n\n  # xfs_io -c 'chattr +x' /mnt/a\n\n  # xfs_io -c lsattr /mnt/a\n  --------------x- /mnt/a\n\nWe will use DAX in ext4 if either the mount option is used or if the inode\nflag is set.\n\nThe 'chattr +x' functionality of xfs_io has been in place for foreign\nfilesystems (ext4) since xfsprogs v4.8.0.  Support for 'lsattr' on foreign\nfilesystems was added with:\n\ncommit e13a325cd7a9 (\"xfs_io: allow lsattr & lsproj on foreign filesystems\")\n\nwhich can currently be found in the \"for-next\" branch.\n\nThe rules for the per-inode DAX flag in ext4 are pretty much the same as\nthe rules for the '-o dax' mount option:\n\n1) When DAX and journaling are both requested on the same inode, journaling\nwill win and DAX will be turned off.  The S_DAX transitions due to\njournaling mode changes are done safely by locking out page faults and I/O,\ndoing a writeback and an invalidate.\n\n2) The DAX inode flag will fail with -EINVAL for filesystems that can\ncontain inline data.\n\n3) If you try and use DAX on an encrypted inode, the inode will accept the\nDAX inode flag but DAX will never be used.\n\nSigned-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>\n\n---\n\nThe behavior of the DAX inode flag when combined with journaling, inline\ndata and encryption was meant to stay as consistent as possible with the\n'-o dax' mount option.  If there is a better way to handle these conflics,\nplease let me know.\n---\n fs/ext4/ext4.h      | 10 ++++++----\n fs/ext4/ext4_jbd2.h |  5 +++--\n fs/ext4/inode.c     |  2 +-\n fs/ext4/ioctl.c     | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--\n 4 files changed, 63 insertions(+), 9 deletions(-)",
    "diff": "diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h\nindex c950278..9d8e067 100644\n--- a/fs/ext4/ext4.h\n+++ b/fs/ext4/ext4.h\n@@ -399,10 +399,11 @@ struct flex_groups {\n #define EXT4_EOFBLOCKS_FL\t\t0x00400000 /* Blocks allocated beyond EOF */\n #define EXT4_INLINE_DATA_FL\t\t0x10000000 /* Inode has inline data. */\n #define EXT4_PROJINHERIT_FL\t\t0x20000000 /* Create with parents projid */\n+#define EXT4_DAX_FL\t\t\t0x40000000 /* use DAX for IO */\n #define EXT4_RESERVED_FL\t\t0x80000000 /* reserved for ext4 lib */\n \n-#define EXT4_FL_USER_VISIBLE\t\t0x304BDFFF /* User visible flags */\n-#define EXT4_FL_USER_MODIFIABLE\t\t0x204BC0FF /* User modifiable flags */\n+#define EXT4_FL_USER_VISIBLE\t\t0x704BDFFF /* User visible flags */\n+#define EXT4_FL_USER_MODIFIABLE\t\t0x604BC0FF /* User modifiable flags */\n \n /* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */\n #define EXT4_FL_XFLAG_VISIBLE\t\t(EXT4_SYNC_FL | \\\n@@ -410,14 +411,15 @@ struct flex_groups {\n \t\t\t\t\t EXT4_APPEND_FL | \\\n \t\t\t\t\t EXT4_NODUMP_FL | \\\n \t\t\t\t\t EXT4_NOATIME_FL | \\\n-\t\t\t\t\t EXT4_PROJINHERIT_FL)\n+\t\t\t\t\t EXT4_PROJINHERIT_FL | \\\n+\t\t\t\t\t EXT4_DAX_FL)\n \n /* Flags that should be inherited by new inodes from their parent. */\n #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\\\n \t\t\t   EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\\\n \t\t\t   EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\\\n \t\t\t   EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\\\n-\t\t\t   EXT4_PROJINHERIT_FL)\n+\t\t\t   EXT4_PROJINHERIT_FL | EXT4_DAX_FL)\n \n /* Flags that are appropriate for regular files (all but dir-specific ones). */\n #define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))\ndiff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h\nindex 65e2aa9..14b7a84 100644\n--- a/fs/ext4/ext4_jbd2.h\n+++ b/fs/ext4/ext4_jbd2.h\n@@ -462,9 +462,10 @@ static inline int ext4_should_dioread_nolock(struct inode *inode)\n \treturn 1;\n }\n \n-static inline bool ext4_should_use_dax(struct inode *inode)\n+static inline bool ext4_should_use_dax(struct inode *inode,\n+\t\tbool dax_inode_flag)\n {\n-\tif (!test_opt(inode->i_sb, DAX))\n+\tif (!(test_opt(inode->i_sb, DAX) || dax_inode_flag))\n \t\treturn false;\n \tif (!S_ISREG(inode->i_mode))\n \t\treturn false;\ndiff --git a/fs/ext4/inode.c b/fs/ext4/inode.c\nindex facb5ae..022ca58 100644\n--- a/fs/ext4/inode.c\n+++ b/fs/ext4/inode.c\n@@ -4599,7 +4599,7 @@ void ext4_set_inode_flags(struct inode *inode)\n \t\tnew_fl |= S_NOATIME;\n \tif (flags & EXT4_DIRSYNC_FL)\n \t\tnew_fl |= S_DIRSYNC;\n-\tif (ext4_should_use_dax(inode))\n+\tif (ext4_should_use_dax(inode, !!(flags & EXT4_DAX_FL)))\n \t\tnew_fl |= S_DAX;\n \tinode_set_flags(inode, new_fl,\n \t\t\tS_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);\ndiff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c\nindex afb66d4..8626a94 100644\n--- a/fs/ext4/ioctl.c\n+++ b/fs/ext4/ioctl.c\n@@ -22,6 +22,7 @@\n #include <linux/fsmap.h>\n #include \"fsmap.h\"\n #include <trace/events/ext4.h>\n+#include <linux/dax.h>\n \n /**\n  * Swap memory between @a and @b for @len bytes.\n@@ -205,6 +206,41 @@ static int uuid_is_zero(__u8 u[16])\n }\n #endif\n \n+static int ext4_ioctl_dax_invalidate(struct inode *inode, bool dax_inode_flag)\n+{\n+\tbool old_dax = !!(inode->i_flags & S_DAX);\n+\tbool new_dax = ext4_should_use_dax(inode, dax_inode_flag);\n+\tstruct super_block *sb = inode->i_sb;\n+\n+\tlockdep_assert_held(&inode->i_rwsem);\n+\tlockdep_assert_held(&EXT4_I(inode)->i_mmap_sem);\n+\n+\tif (dax_inode_flag) {\n+\t\tif (ext4_has_feature_inline_data(sb)) {\n+\t\t\text4_msg(sb, KERN_ERR, \"Cannot use DAX on a filesystem\"\n+\t\t\t\t\t\" that may contain inline data\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))\n+\t\t\treturn -EINVAL;\n+\t\tif (bdev_dax_supported(sb, sb->s_blocksize) < 0)\n+\t\t\treturn -EINVAL;\n+\t}\n+\n+\tif (old_dax != new_dax) {\n+\t\tint err;\n+\n+\t\terr = filemap_write_and_wait(inode->i_mapping);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\terr = invalidate_inode_pages2(inode->i_mapping);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\treturn 0;\n+}\n+\n static int ext4_ioctl_setflags(struct inode *inode,\n \t\t\t       unsigned int flags)\n {\n@@ -258,10 +294,15 @@ static int ext4_ioctl_setflags(struct inode *inode,\n \t\t\tgoto flags_out;\n \t}\n \n+\tdown_write(&ei->i_mmap_sem);\n+\terr = ext4_ioctl_dax_invalidate(inode, !!(flags & EXT4_DAX_FL));\n+\tif (err)\n+\t\tgoto unlock_out;\n+\n \thandle = ext4_journal_start(inode, EXT4_HT_INODE, 1);\n \tif (IS_ERR(handle)) {\n \t\terr = PTR_ERR(handle);\n-\t\tgoto flags_out;\n+\t\tgoto unlock_out;\n \t}\n \tif (IS_SYNC(inode))\n \t\text4_handle_sync(handle);\n@@ -286,6 +327,7 @@ static int ext4_ioctl_setflags(struct inode *inode,\n \n \terr = ext4_mark_iloc_dirty(handle, inode, &iloc);\n flags_err:\n+\tup_write(&ei->i_mmap_sem);\n \text4_journal_stop(handle);\n \tif (err)\n \t\tgoto flags_out;\n@@ -303,6 +345,10 @@ static int ext4_ioctl_setflags(struct inode *inode,\n \n flags_out:\n \treturn err;\n+\n+unlock_out:\n+\tup_write(&ei->i_mmap_sem);\n+\treturn err;\n }\n \n #ifdef CONFIG_QUOTA\n@@ -425,12 +471,15 @@ static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)\n \t\txflags |= FS_XFLAG_NOATIME;\n \tif (iflags & EXT4_PROJINHERIT_FL)\n \t\txflags |= FS_XFLAG_PROJINHERIT;\n+\tif (iflags & EXT4_DAX_FL)\n+\t\txflags |= FS_XFLAG_DAX;\n \treturn xflags;\n }\n \n #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \\\n \t\t\t\t  FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \\\n-\t\t\t\t  FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT)\n+\t\t\t\t  FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \\\n+\t\t\t\t  FS_XFLAG_DAX)\n \n /* Transfer xflags flags to internal */\n static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)\n@@ -449,6 +498,8 @@ static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)\n \t\tiflags |= EXT4_NOATIME_FL;\n \tif (xflags & FS_XFLAG_PROJINHERIT)\n \t\tiflags |= EXT4_PROJINHERIT_FL;\n+\tif (xflags & FS_XFLAG_DAX)\n+\t\tiflags |= EXT4_DAX_FL;\n \n \treturn iflags;\n }\n",
    "prefixes": [
        "9/9"
    ]
}