From patchwork Wed Dec 5 12:28:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713977 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3AA6914E2 for ; Wed, 5 Dec 2018 12:28:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2A58D2C78C for ; Wed, 5 Dec 2018 12:28:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1E8362CB4D; Wed, 5 Dec 2018 12:28:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B854A2C78C for ; Wed, 5 Dec 2018 12:28:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727620AbeLEM2y (ORCPT ); Wed, 5 Dec 2018 07:28:54 -0500 Received: from mx2.suse.de ([195.135.220.15]:48444 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727525AbeLEM2y (ORCPT ); Wed, 5 Dec 2018 07:28:54 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id CA666ADA9 for ; Wed, 5 Dec 2018 12:28:52 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 01/10] btrfs: create a mount option for dax Date: Wed, 5 Dec 2018 06:28:26 -0600 Message-Id: <20181205122835.19290-2-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Also, set the inode->i_flags to S_DAX Signed-off-by: Goldwyn Rodrigues Reviewed-by: Nikolay Borisov --- fs/btrfs/ctree.h | 1 + fs/btrfs/ioctl.c | 5 ++++- fs/btrfs/super.c | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 68f322f600a0..5cc470fa6a40 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1353,6 +1353,7 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info) #define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26) #define BTRFS_MOUNT_NOLOGREPLAY (1 << 27) #define BTRFS_MOUNT_REF_VERIFY (1 << 28) +#define BTRFS_MOUNT_DAX (1 << 29) #define BTRFS_DEFAULT_COMMIT_INTERVAL (30) #define BTRFS_DEFAULT_MAX_INLINE (2048) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 802a628e9f7d..e9146c157816 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -149,8 +149,11 @@ void btrfs_sync_inode_flags_to_i_flags(struct inode *inode) if (binode->flags & BTRFS_INODE_DIRSYNC) new_fl |= S_DIRSYNC; + if ((btrfs_test_opt(btrfs_sb(inode->i_sb), DAX)) && S_ISREG(inode->i_mode)) + new_fl |= S_DAX; + set_mask_bits(&inode->i_flags, - S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC, + S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC | S_DAX, new_fl); } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 645fc81e2a94..035263b61cf5 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -326,6 +326,7 @@ enum { Opt_treelog, Opt_notreelog, Opt_usebackuproot, Opt_user_subvol_rm_allowed, + Opt_dax, /* Deprecated options */ Opt_alloc_start, @@ -393,6 +394,7 @@ static const match_table_t tokens = { {Opt_notreelog, "notreelog"}, {Opt_usebackuproot, "usebackuproot"}, {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, + {Opt_dax, "dax"}, /* Deprecated options */ {Opt_alloc_start, "alloc_start=%s"}, @@ -739,6 +741,17 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, case Opt_user_subvol_rm_allowed: btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); break; +#ifdef CONFIG_FS_DAX + case Opt_dax: + if (btrfs_super_num_devices(info->super_copy) > 1) { + btrfs_info(info, + "dax not supported for multi-device btrfs partition\n"); + ret = -EOPNOTSUPP; + goto out; + } + btrfs_set_opt(info->mount_opt, DAX); + break; +#endif case Opt_enospc_debug: btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); break; @@ -1329,6 +1342,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) seq_puts(seq, ",clear_cache"); if (btrfs_test_opt(info, USER_SUBVOL_RM_ALLOWED)) seq_puts(seq, ",user_subvol_rm_allowed"); + if (btrfs_test_opt(info, DAX)) + seq_puts(seq, ",dax"); if (btrfs_test_opt(info, ENOSPC_DEBUG)) seq_puts(seq, ",enospc_debug"); if (btrfs_test_opt(info, AUTO_DEFRAG)) From patchwork Wed Dec 5 12:28:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713979 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1EAA14E2 for ; Wed, 5 Dec 2018 12:28:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E22AE2C78C for ; Wed, 5 Dec 2018 12:28:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D62F02CB4D; Wed, 5 Dec 2018 12:28:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A0C72C78C for ; Wed, 5 Dec 2018 12:28:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727680AbeLEM25 (ORCPT ); Wed, 5 Dec 2018 07:28:57 -0500 Received: from mx2.suse.de ([195.135.220.15]:48450 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727525AbeLEM25 (ORCPT ); Wed, 5 Dec 2018 07:28:57 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id C1BF0ADA9 for ; Wed, 5 Dec 2018 12:28:54 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 02/10] btrfs: basic dax read Date: Wed, 5 Dec 2018 06:28:27 -0600 Message-Id: <20181205122835.19290-3-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/Makefile | 1 + fs/btrfs/ctree.h | 5 ++++ fs/btrfs/dax.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/file.c | 13 ++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 fs/btrfs/dax.c diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index ca693dd554e9..1fa77b875ae9 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -12,6 +12,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ uuid-tree.o props.o free-space-tree.o tree-checker.o +btrfs-$(CONFIG_FS_DAX) += dax.o btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o btrfs-$(CONFIG_BTRFS_FS_REF_VERIFY) += ref-verify.o diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 5cc470fa6a40..038d64ecebe5 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3685,6 +3685,11 @@ int btrfs_reada_wait(void *handle); void btrfs_reada_detach(void *handle); int btree_readahead_hook(struct extent_buffer *eb, int err); +#ifdef CONFIG_FS_DAX +/* dax.c */ +ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to); +#endif /* CONFIG_FS_DAX */ + static inline int is_fstree(u64 rootid) { if (rootid == BTRFS_FS_TREE_OBJECTID || diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c new file mode 100644 index 000000000000..d614bf73bf8e --- /dev/null +++ b/fs/btrfs/dax.c @@ -0,0 +1,68 @@ +#include +#include +#include "ctree.h" +#include "btrfs_inode.h" + +static ssize_t em_dax_rw(struct inode *inode, struct extent_map *em, u64 pos, + u64 len, struct iov_iter *iter) +{ + struct dax_device *dax_dev = fs_dax_get_by_bdev(em->bdev); + ssize_t map_len; + pgoff_t blk_pg; + void *kaddr; + sector_t blk_start; + unsigned offset = pos & (PAGE_SIZE - 1); + + len = min(len + offset, em->len - (pos - em->start)); + len = ALIGN(len, PAGE_SIZE); + blk_start = (get_start_sect(em->bdev) << 9) + (em->block_start + (pos - em->start)); + blk_pg = blk_start - offset; + map_len = dax_direct_access(dax_dev, PHYS_PFN(blk_pg), PHYS_PFN(len), &kaddr, NULL); + map_len = PFN_PHYS(map_len); + kaddr += offset; + map_len -= offset; + if (map_len > len) + map_len = len; + if (iov_iter_rw(iter) == WRITE) + return dax_copy_from_iter(dax_dev, blk_pg, kaddr, map_len, iter); + else + return dax_copy_to_iter(dax_dev, blk_pg, kaddr, map_len, iter); +} + +ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to) +{ + size_t ret = 0, done = 0, count = iov_iter_count(to); + struct extent_map *em; + u64 pos = iocb->ki_pos; + u64 end = pos + count; + struct inode *inode = file_inode(iocb->ki_filp); + + if (!count) + return 0; + + end = i_size_read(inode) < end ? i_size_read(inode) : end; + + while (pos < end) { + u64 len = end - pos; + + em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, pos, len, 0); + if (IS_ERR(em)) { + if (!ret) + ret = PTR_ERR(em); + goto out; + } + + BUG_ON(em->flags & EXTENT_FLAG_FS_MAPPING); + + ret = em_dax_rw(inode, em, pos, len, to); + if (ret < 0) + goto out; + pos += ret; + done += ret; + } + +out: + iocb->ki_pos += done; + return done ? done : ret; +} + diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 58e93bce3036..ef6ed93f44d1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3308,9 +3308,20 @@ static int btrfs_file_open(struct inode *inode, struct file *filp) return generic_file_open(inode, filp); } +static ssize_t btrfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + struct inode *inode = file_inode(iocb->ki_filp); + +#ifdef CONFIG_FS_DAX + if (IS_DAX(inode)) + return btrfs_file_dax_read(iocb, to); +#endif + return generic_file_read_iter(iocb, to); +} + const struct file_operations btrfs_file_operations = { .llseek = btrfs_file_llseek, - .read_iter = generic_file_read_iter, + .read_iter = btrfs_file_read_iter, .splice_read = generic_file_splice_read, .write_iter = btrfs_file_write_iter, .mmap = btrfs_file_mmap, From patchwork Wed Dec 5 12:28:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713981 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9963214E2 for ; Wed, 5 Dec 2018 12:29:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89BAE2C78C for ; Wed, 5 Dec 2018 12:29:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7E4612CB4D; Wed, 5 Dec 2018 12:29:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C90A2C78C for ; Wed, 5 Dec 2018 12:29:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727698AbeLEM27 (ORCPT ); Wed, 5 Dec 2018 07:28:59 -0500 Received: from mx2.suse.de ([195.135.220.15]:48460 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727679AbeLEM26 (ORCPT ); Wed, 5 Dec 2018 07:28:58 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D79E2AE61 for ; Wed, 5 Dec 2018 12:28:56 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 03/10] btrfs: dax: read zeros from holes Date: Wed, 5 Dec 2018 06:28:28 -0600 Message-Id: <20181205122835.19290-4-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/dax.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c index d614bf73bf8e..5a297674adec 100644 --- a/fs/btrfs/dax.c +++ b/fs/btrfs/dax.c @@ -54,7 +54,12 @@ ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to) BUG_ON(em->flags & EXTENT_FLAG_FS_MAPPING); - ret = em_dax_rw(inode, em, pos, len, to); + if (em->block_start == EXTENT_MAP_HOLE) { + u64 zero_len = min(em->len - (em->start - pos), len); + ret = iov_iter_zero(zero_len, to); + } else { + ret = em_dax_rw(inode, em, pos, len, to); + } if (ret < 0) goto out; pos += ret; From patchwork Wed Dec 5 12:28:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713983 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BFC6A17D5 for ; Wed, 5 Dec 2018 12:29:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEE0B2C78C for ; Wed, 5 Dec 2018 12:29:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A316C2CB59; Wed, 5 Dec 2018 12:29:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2F83D2C78C for ; Wed, 5 Dec 2018 12:29:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727759AbeLEM3B (ORCPT ); Wed, 5 Dec 2018 07:29:01 -0500 Received: from mx2.suse.de ([195.135.220.15]:48468 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727679AbeLEM3A (ORCPT ); Wed, 5 Dec 2018 07:29:00 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E962CADA9 for ; Wed, 5 Dec 2018 12:28:58 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 04/10] Rename __endio_write_update_ordered() to btrfs_update_ordered_extent() Date: Wed, 5 Dec 2018 06:28:29 -0600 Message-Id: <20181205122835.19290-5-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Since we will be using it in another part of the code, use a better name to declare it non-static Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ctree.h | 7 +++++-- fs/btrfs/inode.c | 14 +++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 038d64ecebe5..5144d28216b0 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3170,8 +3170,11 @@ struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location, struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, struct btrfs_root *root, int *was_new); struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, - struct page *page, size_t pg_offset, - u64 start, u64 end, int create); + struct page *page, size_t pg_offset, + u64 start, u64 end, int create); +void btrfs_update_ordered_extent(struct inode *inode, + const u64 offset, const u64 bytes, + const bool uptodate); int btrfs_update_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9ea4c6f0352f..96e9fe9e4150 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -97,10 +97,6 @@ static struct extent_map *create_io_em(struct inode *inode, u64 start, u64 len, u64 ram_bytes, int compress_type, int type); -static void __endio_write_update_ordered(struct inode *inode, - const u64 offset, const u64 bytes, - const bool uptodate); - /* * Cleanup all submitted ordered extents in specified range to handle errors * from the fill_dellaloc() callback. @@ -130,7 +126,7 @@ static inline void btrfs_cleanup_ordered_extents(struct inode *inode, ClearPagePrivate2(page); put_page(page); } - return __endio_write_update_ordered(inode, offset + PAGE_SIZE, + return btrfs_update_ordered_extent(inode, offset + PAGE_SIZE, bytes - PAGE_SIZE, false); } @@ -8059,7 +8055,7 @@ static void btrfs_endio_direct_read(struct bio *bio) bio_put(bio); } -static void __endio_write_update_ordered(struct inode *inode, +void btrfs_update_ordered_extent(struct inode *inode, const u64 offset, const u64 bytes, const bool uptodate) { @@ -8112,7 +8108,7 @@ static void btrfs_endio_direct_write(struct bio *bio) struct btrfs_dio_private *dip = bio->bi_private; struct bio *dio_bio = dip->dio_bio; - __endio_write_update_ordered(dip->inode, dip->logical_offset, + btrfs_update_ordered_extent(dip->inode, dip->logical_offset, dip->bytes, !bio->bi_status); kfree(dip); @@ -8432,7 +8428,7 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, bio = NULL; } else { if (write) - __endio_write_update_ordered(inode, + btrfs_update_ordered_extent(inode, file_offset, dio_bio->bi_iter.bi_size, false); @@ -8572,7 +8568,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) */ if (dio_data.unsubmitted_oe_range_start < dio_data.unsubmitted_oe_range_end) - __endio_write_update_ordered(inode, + btrfs_update_ordered_extent(inode, dio_data.unsubmitted_oe_range_start, dio_data.unsubmitted_oe_range_end - dio_data.unsubmitted_oe_range_start, From patchwork Wed Dec 5 12:28:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AE9017D5 for ; Wed, 5 Dec 2018 12:29:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A1AA2CAFA for ; Wed, 5 Dec 2018 12:29:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6E74B2CB59; Wed, 5 Dec 2018 12:29:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12A8D2CAFA for ; Wed, 5 Dec 2018 12:29:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727777AbeLEM3D (ORCPT ); Wed, 5 Dec 2018 07:29:03 -0500 Received: from mx2.suse.de ([195.135.220.15]:48484 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727679AbeLEM3D (ORCPT ); Wed, 5 Dec 2018 07:29:03 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 33DD2AEB9 for ; Wed, 5 Dec 2018 12:29:01 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 05/10] btrfs: Carve out btrfs_get_extent_map_write() out of btrfs_get_blocks_write() Date: Wed, 5 Dec 2018 06:28:30 -0600 Message-Id: <20181205122835.19290-6-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues This makes btrfs_get_extent_map_write() independent of Direct I/O code. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/inode.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 5144d28216b0..a0d296b0d826 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3169,6 +3169,8 @@ struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location, struct btrfs_path *path); struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, struct btrfs_root *root, int *was_new); +int btrfs_get_extent_map_write(struct extent_map **map, struct buffer_head *bh, + struct inode *inode, u64 start, u64 len); struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, struct page *page, size_t pg_offset, u64 start, u64 end, int create); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 96e9fe9e4150..4671cd9165c1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7485,11 +7485,10 @@ static int btrfs_get_blocks_direct_read(struct extent_map *em, return 0; } -static int btrfs_get_blocks_direct_write(struct extent_map **map, - struct buffer_head *bh_result, - struct inode *inode, - struct btrfs_dio_data *dio_data, - u64 start, u64 len) +int btrfs_get_extent_map_write(struct extent_map **map, + struct buffer_head *bh, + struct inode *inode, + u64 start, u64 len) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct extent_map *em = *map; @@ -7543,22 +7542,38 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, */ btrfs_free_reserved_data_space_noquota(inode, start, len); - goto skip_cow; + /* skip COW */ + goto out; } } /* this will cow the extent */ - len = bh_result->b_size; + if (bh) + len = bh->b_size; free_extent_map(em); *map = em = btrfs_new_extent_direct(inode, start, len); - if (IS_ERR(em)) { - ret = PTR_ERR(em); - goto out; - } + if (IS_ERR(em)) + return PTR_ERR(em); +out: + return ret; +} +static int btrfs_get_blocks_direct_write(struct extent_map **map, + struct buffer_head *bh_result, + struct inode *inode, + struct btrfs_dio_data *dio_data, + u64 start, u64 len) +{ + int ret = 0; + struct extent_map *em; + + ret = btrfs_get_extent_map_write(map, bh_result, inode, + start, len); + if (ret < 0) + return ret; + em = *map; len = min(len, em->len - (start - em->start)); -skip_cow: bh_result->b_blocknr = (em->block_start + (start - em->start)) >> inode->i_blkbits; bh_result->b_size = len; @@ -7579,7 +7594,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, dio_data->reserve -= len; dio_data->unsubmitted_oe_range_end = start + len; current->journal_info = dio_data; -out: return ret; } From patchwork Wed Dec 5 12:28:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713987 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 243D114E2 for ; Wed, 5 Dec 2018 12:29:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 124E22CC55 for ; Wed, 5 Dec 2018 12:29:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0553F2CB59; Wed, 5 Dec 2018 12:29:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A29A2CBDA for ; Wed, 5 Dec 2018 12:29:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727784AbeLEM3F (ORCPT ); Wed, 5 Dec 2018 07:29:05 -0500 Received: from mx2.suse.de ([195.135.220.15]:48506 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727778AbeLEM3F (ORCPT ); Wed, 5 Dec 2018 07:29:05 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 4CA7AAEB9 for ; Wed, 5 Dec 2018 12:29:03 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 06/10] btrfs: dax write support Date: Wed, 5 Dec 2018 06:28:31 -0600 Message-Id: <20181205122835.19290-7-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues This is a combination of direct and buffered I/O. Similarties with direct I/O is that it needs to allocate space before writing. Similarities with buffered is when the data is not page-aligned, it needs to copy parts of the previous extents. In order to accomplish that, keep a references of the first and last extent (if required) and then perform allocations. If the "pos" or "end" is not aligned, copy the data from first and last extent respectively. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ctree.h | 1 + fs/btrfs/dax.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/file.c | 4 +- 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a0d296b0d826..d91ff283a966 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3693,6 +3693,7 @@ int btree_readahead_hook(struct extent_buffer *eb, int err); #ifdef CONFIG_FS_DAX /* dax.c */ ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to); +ssize_t btrfs_file_dax_write(struct kiocb *iocb, struct iov_iter *from); #endif /* CONFIG_FS_DAX */ static inline int is_fstree(u64 rootid) diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c index 5a297674adec..4000259a426c 100644 --- a/fs/btrfs/dax.c +++ b/fs/btrfs/dax.c @@ -2,6 +2,7 @@ #include #include "ctree.h" #include "btrfs_inode.h" +#include "extent_io.h" static ssize_t em_dax_rw(struct inode *inode, struct extent_map *em, u64 pos, u64 len, struct iov_iter *iter) @@ -71,3 +72,123 @@ ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to) return done ? done : ret; } +static int copy_extent_page(struct extent_map *em, void *daddr, u64 pos) +{ + struct dax_device *dax_dev; + void *saddr; + sector_t start; + size_t len; + + if (em->block_start == EXTENT_MAP_HOLE) { + memset(daddr, 0, PAGE_SIZE); + } else { + dax_dev = fs_dax_get_by_bdev(em->bdev); + start = (get_start_sect(em->bdev) << 9) + (em->block_start + (pos - em->start)); + len = dax_direct_access(dax_dev, PHYS_PFN(start), 1, &saddr, NULL); + memcpy(daddr, saddr, PAGE_SIZE); + } + free_extent_map(em); + + return 0; +} + + +ssize_t btrfs_file_dax_write(struct kiocb *iocb, struct iov_iter *from) +{ + ssize_t ret, done = 0, count = iov_iter_count(from); + struct inode *inode = file_inode(iocb->ki_filp); + u64 pos = iocb->ki_pos; + u64 start = round_down(pos, PAGE_SIZE); + u64 end = round_up(pos + count, PAGE_SIZE); + struct extent_state *cached_state = NULL; + struct extent_changeset *data_reserved = NULL; + struct extent_map *first = NULL, *last = NULL; + + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, start, end - start); + if (ret < 0) + return ret; + + /* Grab a reference of the first extent to copy data */ + if (start < pos) { + first = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, end - start, 0); + if (IS_ERR(first)) { + ret = PTR_ERR(first); + goto out2; + } + } + + /* Grab a reference of the last extent to copy data */ + if (pos + count < end) { + last = btrfs_get_extent(BTRFS_I(inode), NULL, 0, end - PAGE_SIZE, PAGE_SIZE, 0); + if (IS_ERR(last)) { + ret = PTR_ERR(last); + goto out2; + } + } + + lock_extent_bits(&BTRFS_I(inode)->io_tree, start, end, &cached_state); + while (done < count) { + struct extent_map *em; + struct dax_device *dax_dev; + int offset = pos & (PAGE_SIZE - 1); + u64 estart = round_down(pos, PAGE_SIZE); + u64 elen = end - estart; + size_t len = count - done; + sector_t dstart; + void *daddr; + ssize_t maplen; + + /* Read the current extent */ + em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, estart, elen, 0); + if (IS_ERR(em)) { + ret = PTR_ERR(em); + goto out; + } + + /* Get a new extent */ + ret = btrfs_get_extent_map_write(&em, NULL, inode, estart, elen); + if (ret < 0) + goto out; + + dax_dev = fs_dax_get_by_bdev(em->bdev); + /* Calculate start address start of destination extent */ + dstart = (get_start_sect(em->bdev) << 9) + em->block_start; + maplen = dax_direct_access(dax_dev, PHYS_PFN(dstart), + PHYS_PFN(em->len), &daddr, NULL); + + /* Copy front of extent page */ + if (offset) + ret = copy_extent_page(first, daddr, estart); + + /* Copy end of extent page */ + if ((pos + len > estart + PAGE_SIZE) && (pos + len < em->start + em->len)) + ret = copy_extent_page(last, daddr + em->len - PAGE_SIZE, em->start + em->len - PAGE_SIZE); + + /* Copy the data from the iter */ + maplen = PFN_PHYS(maplen); + maplen -= offset; + ret = dax_copy_from_iter(dax_dev, dstart, daddr + offset, maplen, from); + if (ret < 0) + goto out; + pos += ret; + done += ret; + } +out: + unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, end, &cached_state); + if (done) { + btrfs_update_ordered_extent(inode, start, + end - start, true); + iocb->ki_pos += done; + if (iocb->ki_pos > i_size_read(inode)) + i_size_write(inode, iocb->ki_pos); + } + + btrfs_delalloc_release_extents(BTRFS_I(inode), count, false); +out2: + if (count - done > 0) + btrfs_delalloc_release_space(inode, data_reserved, pos, + count - done, true); + extent_changeset_free(data_reserved); + return done ? done : ret; + +} diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ef6ed93f44d1..29a3b12e6660 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1964,7 +1964,9 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, if (sync) atomic_inc(&BTRFS_I(inode)->sync_writers); - if (iocb->ki_flags & IOCB_DIRECT) { + if (IS_DAX(inode)) { + num_written = btrfs_file_dax_write(iocb, from); + } else if (iocb->ki_flags & IOCB_DIRECT) { num_written = __btrfs_direct_write(iocb, from); } else { num_written = btrfs_buffered_write(iocb, from); From patchwork Wed Dec 5 12:28:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713989 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B47B017D5 for ; Wed, 5 Dec 2018 12:29:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A34A82C78C for ; Wed, 5 Dec 2018 12:29:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 94C5C2CC85; Wed, 5 Dec 2018 12:29:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D0FB2C78C for ; Wed, 5 Dec 2018 12:29:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727799AbeLEM3J (ORCPT ); Wed, 5 Dec 2018 07:29:09 -0500 Received: from mx2.suse.de ([195.135.220.15]:48516 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727778AbeLEM3I (ORCPT ); Wed, 5 Dec 2018 07:29:08 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 777C3ADA9 for ; Wed, 5 Dec 2018 12:29:05 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 07/10] dax: export functions for use with btrfs Date: Wed, 5 Dec 2018 06:28:32 -0600 Message-Id: <20181205122835.19290-8-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues These functions are required for btrfs dax support. Signed-off-by: Goldwyn Rodrigues --- fs/dax.c | 35 ++++++++++++++++++++++++----------- include/linux/dax.h | 16 ++++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 9bcce89ea18e..4578640af631 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -244,7 +244,7 @@ static void put_unlocked_entry(struct xa_state *xas, void *entry) * dropped the xa_lock, so we know the xa_state is stale and must be reset * before use. */ -static void dax_unlock_entry(struct xa_state *xas, void *entry) +void dax_unlock_entry(struct xa_state *xas, void *entry) { void *old; @@ -256,6 +256,7 @@ static void dax_unlock_entry(struct xa_state *xas, void *entry) BUG_ON(!dax_is_locked(old)); dax_wake_entry(xas, entry, false); } +EXPORT_SYMBOL(dax_unlock_entry); /* * Return: The entry stored at this location before it was locked. @@ -448,7 +449,7 @@ void dax_unlock_mapping_entry(struct page *page) * a VM_FAULT code, encoded as an xarray internal entry. The ERR_PTR values * overlap with xarray value entries. */ -static void *grab_mapping_entry(struct xa_state *xas, +void *grab_mapping_entry(struct xa_state *xas, struct address_space *mapping, unsigned long size_flag) { unsigned long index = xas->xa_index; @@ -531,6 +532,7 @@ static void *grab_mapping_entry(struct xa_state *xas, xas_unlock_irq(xas); return xa_mk_internal(VM_FAULT_FALLBACK); } +EXPORT_SYMBOL(grab_mapping_entry); /** * dax_layout_busy_page - find first pinned page in @mapping @@ -654,7 +656,7 @@ int dax_invalidate_mapping_entry_sync(struct address_space *mapping, return __dax_invalidate_entry(mapping, index, false); } -static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, +int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, sector_t sector, size_t size, struct page *to, unsigned long vaddr) { @@ -679,6 +681,7 @@ static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, dax_read_unlock(id); return 0; } +EXPORT_SYMBOL(copy_user_dax); /* * By this point grab_mapping_entry() has ensured that we have a locked entry @@ -687,7 +690,7 @@ static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, * already in the tree, we will skip the insertion and just dirty the PMD as * appropriate. */ -static void *dax_insert_entry(struct xa_state *xas, +void *dax_insert_entry(struct xa_state *xas, struct address_space *mapping, struct vm_fault *vmf, void *entry, pfn_t pfn, unsigned long flags, bool dirty) { @@ -736,6 +739,7 @@ static void *dax_insert_entry(struct xa_state *xas, xas_unlock_irq(xas); return entry; } +EXPORT_SYMBOL(dax_insert_entry); static inline unsigned long pgoff_address(pgoff_t pgoff, struct vm_area_struct *vma) @@ -962,19 +966,18 @@ static sector_t dax_iomap_sector(struct iomap *iomap, loff_t pos) return (iomap->addr + (pos & PAGE_MASK) - iomap->offset) >> 9; } -static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size, - pfn_t *pfnp) +int dax_pfn(struct dax_device *dax_dev, struct block_device *bdev, + const sector_t sector, size_t size, pfn_t *pfnp) { - const sector_t sector = dax_iomap_sector(iomap, pos); pgoff_t pgoff; int id, rc; long length; - rc = bdev_dax_pgoff(iomap->bdev, sector, size, &pgoff); + rc = bdev_dax_pgoff(bdev, sector, size, &pgoff); if (rc) return rc; id = dax_read_lock(); - length = dax_direct_access(iomap->dax_dev, pgoff, PHYS_PFN(size), + length = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), NULL, pfnp); if (length < 0) { rc = length; @@ -993,6 +996,14 @@ static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size, dax_read_unlock(id); return rc; } +EXPORT_SYMBOL(dax_pfn); + +static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size, + pfn_t *pfnp) +{ + const sector_t sector = dax_iomap_sector(iomap, pos); + return dax_pfn(iomap->dax_dev, iomap->bdev, sector, size, pfnp); +} /* * The user has performed a load from a hole in the file. Allocating a new @@ -1001,7 +1012,7 @@ static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size, * If this page is ever written to we will re-fault and change the mapping to * point to real DAX storage instead. */ -static vm_fault_t dax_load_hole(struct xa_state *xas, +vm_fault_t dax_load_hole(struct xa_state *xas, struct address_space *mapping, void **entry, struct vm_fault *vmf) { @@ -1017,6 +1028,7 @@ static vm_fault_t dax_load_hole(struct xa_state *xas, trace_dax_load_hole(inode, vmf, ret); return ret; } +EXPORT_SYMBOL(dax_load_hole); static bool dax_range_is_aligned(struct block_device *bdev, unsigned int offset, unsigned int length) @@ -1195,7 +1207,7 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, } EXPORT_SYMBOL_GPL(dax_iomap_rw); -static vm_fault_t dax_fault_return(int error) +vm_fault_t dax_fault_return(int error) { if (error == 0) return VM_FAULT_NOPAGE; @@ -1203,6 +1215,7 @@ static vm_fault_t dax_fault_return(int error) return VM_FAULT_OOM; return VM_FAULT_SIGBUS; } +EXPORT_SYMBOL(dax_fault_return); /* * MAP_SYNC on a dax mapping guarantees dirty metadata is diff --git a/include/linux/dax.h b/include/linux/dax.h index 450b28db9533..72f0a1e85ab5 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -155,6 +155,22 @@ vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf, int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index); int dax_invalidate_mapping_entry_sync(struct address_space *mapping, pgoff_t index); +int dax_pfn(struct dax_device *dax_dev, struct block_device *bdev, + const sector_t sector, size_t size, pfn_t *pfn); +void *dax_insert_entry(struct xa_state *xas, + struct address_space *mapping, struct vm_fault *vmf, + void *entry, pfn_t pfn, unsigned long flags, bool dirty); +void *grab_mapping_entry(struct xa_state *xas, + struct address_space *mapping, + unsigned long size_flag); +void dax_unlock_entry(struct xa_state *xas, void *entry); +vm_fault_t dax_load_hole(struct xa_state *xas, + struct address_space *mapping, void **entry, + struct vm_fault *vmf); +vm_fault_t dax_fault_return(int error); +int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev, + sector_t sector, size_t size, struct page *to, + unsigned long vaddr); #ifdef CONFIG_FS_DAX int __dax_zero_page_range(struct block_device *bdev, From patchwork Wed Dec 5 12:28:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713991 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 55E2717D5 for ; Wed, 5 Dec 2018 12:29:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 465322CC55 for ; Wed, 5 Dec 2018 12:29:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3AA6C2CC85; Wed, 5 Dec 2018 12:29:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 167162CC55 for ; Wed, 5 Dec 2018 12:29:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727803AbeLEM3K (ORCPT ); Wed, 5 Dec 2018 07:29:10 -0500 Received: from mx2.suse.de ([195.135.220.15]:48528 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727787AbeLEM3J (ORCPT ); Wed, 5 Dec 2018 07:29:09 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id A4BDAAEB9 for ; Wed, 5 Dec 2018 12:29:07 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 08/10] btrfs: dax add read mmap path Date: Wed, 5 Dec 2018 06:28:33 -0600 Message-Id: <20181205122835.19290-9-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ctree.h | 1 + fs/btrfs/dax.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/file.c | 12 +++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d91ff283a966..33648121ca52 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3694,6 +3694,7 @@ int btree_readahead_hook(struct extent_buffer *eb, int err); /* dax.c */ ssize_t btrfs_file_dax_read(struct kiocb *iocb, struct iov_iter *to); ssize_t btrfs_file_dax_write(struct kiocb *iocb, struct iov_iter *from); +vm_fault_t btrfs_dax_fault(struct vm_fault *vmf); #endif /* CONFIG_FS_DAX */ static inline int is_fstree(u64 rootid) diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c index 4000259a426c..88017f8799d1 100644 --- a/fs/btrfs/dax.c +++ b/fs/btrfs/dax.c @@ -190,5 +190,48 @@ ssize_t btrfs_file_dax_write(struct kiocb *iocb, struct iov_iter *from) count - done, true); extent_changeset_free(data_reserved); return done ? done : ret; +} + +/* As copied from dax_iomap_pte_fault() */ +vm_fault_t btrfs_dax_fault(struct vm_fault *vmf) +{ + pfn_t pfn; + struct address_space *mapping = vmf->vma->vm_file->f_mapping; + XA_STATE(xas, &mapping->i_pages, vmf->pgoff); + struct inode *inode = mapping->host; + loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT; + void *entry = NULL; + vm_fault_t ret = 0; + + if (pos > i_size_read(inode)) { + ret = VM_FAULT_SIGBUS; + goto out; + } + entry = grab_mapping_entry(&xas, mapping, 0); + if (IS_ERR(entry)) { + ret = dax_fault_return(PTR_ERR(entry)); + goto out; + } + + if (!vmf->cow_page) { + sector_t sector; + struct extent_map *em; + em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, pos, PAGE_SIZE, 0); + if (em->block_start == EXTENT_MAP_HOLE) { + ret = dax_load_hole(&xas, mapping, entry, vmf); + goto out; + } + sector = ((get_start_sect(em->bdev) << 9) + + (em->block_start + (pos - em->start))) >> 9; + ret = dax_pfn(fs_dax_get_by_bdev(em->bdev), em->bdev, sector, PAGE_SIZE, &pfn); + if (ret) + goto out; + dax_insert_entry(&xas, mapping, vmf, entry, pfn, 0, false); + ret = vmf_insert_mixed(vmf->vma, vmf->address, pfn); + } +out: + if (entry) + dax_unlock_entry(&xas, entry); + return ret; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 29a3b12e6660..38b494686fb2 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2227,8 +2227,18 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) return ret > 0 ? -EIO : ret; } +static vm_fault_t btrfs_fault(struct vm_fault *vmf) +{ + struct inode *inode = vmf->vma->vm_file->f_mapping->host; +#ifdef CONFIG_FS_DAX + if (IS_DAX(inode)) + return btrfs_dax_fault(vmf); +#endif + return filemap_fault(vmf); +} + static const struct vm_operations_struct btrfs_file_vm_ops = { - .fault = filemap_fault, + .fault = btrfs_fault, .map_pages = filemap_map_pages, .page_mkwrite = btrfs_page_mkwrite, }; From patchwork Wed Dec 5 12:28:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713993 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9DE1814E2 for ; Wed, 5 Dec 2018 12:29:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D9E32CC55 for ; Wed, 5 Dec 2018 12:29:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 81C762CC8A; Wed, 5 Dec 2018 12:29:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2F0872CC55 for ; Wed, 5 Dec 2018 12:29:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727807AbeLEM3M (ORCPT ); Wed, 5 Dec 2018 07:29:12 -0500 Received: from mx2.suse.de ([195.135.220.15]:48534 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727787AbeLEM3L (ORCPT ); Wed, 5 Dec 2018 07:29:11 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D0057ADA9 for ; Wed, 5 Dec 2018 12:29:09 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 09/10] btrfs: dax support for cow_page/mmap_private and shared Date: Wed, 5 Dec 2018 06:28:34 -0600 Message-Id: <20181205122835.19290-10-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/dax.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c index 88017f8799d1..6d68d39cc5da 100644 --- a/fs/btrfs/dax.c +++ b/fs/btrfs/dax.c @@ -198,10 +198,13 @@ vm_fault_t btrfs_dax_fault(struct vm_fault *vmf) pfn_t pfn; struct address_space *mapping = vmf->vma->vm_file->f_mapping; XA_STATE(xas, &mapping->i_pages, vmf->pgoff); + unsigned long vaddr = vmf->address; struct inode *inode = mapping->host; loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT; void *entry = NULL; vm_fault_t ret = 0; + struct extent_map *em; + struct dax_device *dax_dev; if (pos > i_size_read(inode)) { ret = VM_FAULT_SIGBUS; @@ -214,21 +217,33 @@ vm_fault_t btrfs_dax_fault(struct vm_fault *vmf) goto out; } - if (!vmf->cow_page) { + em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, pos, PAGE_SIZE, 0); + if (em->block_start != EXTENT_MAP_HOLE) + dax_dev = fs_dax_get_by_bdev(em->bdev); + + if (vmf->cow_page) { + sector_t sector; + if (em->block_start == EXTENT_MAP_HOLE) { + clear_user_highpage(vmf->cow_page, vaddr); + goto out; + } + sector = (get_start_sect(em->bdev) << 9) + (em->block_start + (pos - em->start)); + sector >>= 9; + ret = copy_user_dax(em->bdev, dax_dev, sector, PAGE_SIZE, vmf->cow_page, vaddr); + goto out; + } else { sector_t sector; - struct extent_map *em; - em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, pos, PAGE_SIZE, 0); if (em->block_start == EXTENT_MAP_HOLE) { ret = dax_load_hole(&xas, mapping, entry, vmf); goto out; } sector = ((get_start_sect(em->bdev) << 9) + (em->block_start + (pos - em->start))) >> 9; - ret = dax_pfn(fs_dax_get_by_bdev(em->bdev), em->bdev, sector, PAGE_SIZE, &pfn); + ret = dax_pfn(dax_dev, em->bdev, sector, PAGE_SIZE, &pfn); if (ret) goto out; dax_insert_entry(&xas, mapping, vmf, entry, pfn, 0, false); - ret = vmf_insert_mixed(vmf->vma, vmf->address, pfn); + ret = vmf_insert_mixed(vmf->vma, vaddr, pfn); } out: if (entry) From patchwork Wed Dec 5 12:28:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 10713997 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7228B17D5 for ; Wed, 5 Dec 2018 12:29:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6229F2C78C for ; Wed, 5 Dec 2018 12:29:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 568B72CC62; Wed, 5 Dec 2018 12:29:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53B5D2C78C for ; Wed, 5 Dec 2018 12:29:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727819AbeLEM3O (ORCPT ); Wed, 5 Dec 2018 07:29:14 -0500 Received: from mx2.suse.de ([195.135.220.15]:48544 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727787AbeLEM3N (ORCPT ); Wed, 5 Dec 2018 07:29:13 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id DFD53AEB9 for ; Wed, 5 Dec 2018 12:29:11 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 10/10] btrfs: dax mmap write Date: Wed, 5 Dec 2018 06:28:35 -0600 Message-Id: <20181205122835.19290-11-rgoldwyn@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181205122835.19290-1-rgoldwyn@suse.de> References: <20181205122835.19290-1-rgoldwyn@suse.de> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goldwyn Rodrigues Create a page size extent and copy the contents of the original extent into the new one, and present to user space as the page to write. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/dax.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/fs/btrfs/dax.c b/fs/btrfs/dax.c index 6d68d39cc5da..4634917877f3 100644 --- a/fs/btrfs/dax.c +++ b/fs/btrfs/dax.c @@ -231,6 +231,45 @@ vm_fault_t btrfs_dax_fault(struct vm_fault *vmf) sector >>= 9; ret = copy_user_dax(em->bdev, dax_dev, sector, PAGE_SIZE, vmf->cow_page, vaddr); goto out; + } else if (vmf->flags & FAULT_FLAG_WRITE) { + pfn_t pfn; + struct extent_map *orig = em; + void *daddr; + sector_t dstart; + size_t maplen; + struct extent_changeset *data_reserved = NULL; + struct extent_state *cached_state = NULL; + + ret = btrfs_delalloc_reserve_space(inode, &data_reserved, pos, PAGE_SIZE); + if (ret < 0) + return ret; + refcount_inc(&orig->refs); + lock_extent_bits(&BTRFS_I(inode)->io_tree, pos, pos + PAGE_SIZE, &cached_state); + /* Create an extent of page size */ + ret = btrfs_get_extent_map_write(&em, NULL, inode, pos, + PAGE_SIZE); + if (ret < 0) { + free_extent_map(orig); + btrfs_delalloc_release_space(inode, data_reserved, pos, + PAGE_SIZE, true); + goto out; + } + + dax_dev = fs_dax_get_by_bdev(em->bdev); + /* Calculate start address of destination extent */ + dstart = (get_start_sect(em->bdev) << 9) + em->block_start; + maplen = dax_direct_access(dax_dev, PHYS_PFN(dstart), + 1, &daddr, &pfn); + + /* Copy the original contents into new destination */ + copy_extent_page(orig, daddr, pos); + btrfs_update_ordered_extent(inode, pos, PAGE_SIZE, true); + dax_insert_entry(&xas, mapping, vmf, entry, pfn, 0, false); + ret = vmf_insert_mixed(vmf->vma, vaddr, pfn); + free_extent_map(orig); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, pos, pos + PAGE_SIZE, &cached_state); + extent_changeset_free(data_reserved); + btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, false); } else { sector_t sector; if (em->block_start == EXTENT_MAP_HOLE) {