From: Shiyang Ruan <ruansy.fnst@fujitsu.com> To: <linux-kernel@vger.kernel.org>, <linux-xfs@vger.kernel.org>, <linux-nvdimm@lists.01.org>, <linux-fsdevel@vger.kernel.org> Cc: <darrick.wong@oracle.com>, <dan.j.williams@intel.com>, <willy@infradead.org>, <viro@zeniv.linux.org.uk>, <david@fromorbit.com>, <hch@lst.de>, <rgoldwyn@suse.de> Subject: [PATCH v5 6/7] fs/xfs: Handle CoW for fsdax write() path Date: Tue, 11 May 2021 11:09:32 +0800 [thread overview] Message-ID: <20210511030933.3080921-7-ruansy.fnst@fujitsu.com> (raw) In-Reply-To: <20210511030933.3080921-1-ruansy.fnst@fujitsu.com> In fsdax mode, WRITE and ZERO on a shared extent need CoW performed. After CoW, new allocated extents needs to be remapped to the file. So, add an iomap_end for dax write ops to do the remapping work. Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com> --- fs/xfs/xfs_bmap_util.c | 3 +-- fs/xfs/xfs_file.c | 9 +++---- fs/xfs/xfs_iomap.c | 61 +++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_iomap.h | 4 +++ fs/xfs/xfs_iops.c | 7 +++-- fs/xfs/xfs_reflink.c | 3 +-- 6 files changed, 72 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index a5e9d7d34023..2a36dc93ff27 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -965,8 +965,7 @@ xfs_free_file_space( return 0; if (offset + len > XFS_ISIZE(ip)) len = XFS_ISIZE(ip) - offset; - error = iomap_zero_range(VFS_I(ip), offset, len, NULL, - &xfs_buffered_write_iomap_ops); + error = xfs_iomap_zero_range(ip, offset, len, NULL); if (error) return error; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 396ef36dcd0a..38d8eca05aee 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -684,11 +684,8 @@ xfs_file_dax_write( pos = iocb->ki_pos; trace_xfs_file_dax_write(iocb, from); - ret = dax_iomap_rw(iocb, from, &xfs_direct_write_iomap_ops); - if (ret > 0 && iocb->ki_pos > i_size_read(inode)) { - i_size_write(inode, iocb->ki_pos); - error = xfs_setfilesize(ip, pos, ret); - } + ret = dax_iomap_rw(iocb, from, &xfs_dax_write_iomap_ops); + out: if (iolock) xfs_iunlock(ip, iolock); @@ -1309,7 +1306,7 @@ __xfs_filemap_fault( ret = dax_iomap_fault(vmf, pe_size, &pfn, NULL, (write_fault && !vmf->cow_page) ? - &xfs_direct_write_iomap_ops : + &xfs_dax_write_iomap_ops : &xfs_read_iomap_ops); if (ret & VM_FAULT_NEEDDSYNC) ret = dax_finish_sync_fault(vmf, pe_size, pfn); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d154f42e2dc6..8b593a51480d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -761,7 +761,8 @@ xfs_direct_write_iomap_begin( /* may drop and re-acquire the ilock */ error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared, - &lockmode, flags & IOMAP_DIRECT); + &lockmode, + (flags & IOMAP_DIRECT) || IS_DAX(inode)); if (error) goto out_unlock; if (shared) @@ -854,6 +855,41 @@ const struct iomap_ops xfs_direct_write_iomap_ops = { .iomap_begin = xfs_direct_write_iomap_begin, }; +static int +xfs_dax_write_iomap_end( + struct inode *inode, + loff_t pos, + loff_t length, + ssize_t written, + unsigned int flags, + struct iomap *iomap) +{ + int error = 0; + struct xfs_inode *ip = XFS_I(inode); + bool cow = xfs_is_cow_inode(ip); + + if (!written) + return 0; + + if (pos + written > i_size_read(inode) && !(flags & IOMAP_FAULT)) { + i_size_write(inode, pos + written); + error = xfs_setfilesize(ip, pos, written); + if (error && cow) { + xfs_reflink_cancel_cow_range(ip, pos, written, true); + return error; + } + } + if (cow) + error = xfs_reflink_end_cow(ip, pos, written); + + return error; +} + +const struct iomap_ops xfs_dax_write_iomap_ops = { + .iomap_begin = xfs_direct_write_iomap_begin, + .iomap_end = xfs_dax_write_iomap_end, +}; + static int xfs_buffered_write_iomap_begin( struct inode *inode, @@ -1311,3 +1347,26 @@ xfs_xattr_iomap_begin( const struct iomap_ops xfs_xattr_iomap_ops = { .iomap_begin = xfs_xattr_iomap_begin, }; + +int +xfs_iomap_zero_range( + struct xfs_inode *ip, + loff_t offset, + loff_t len, + bool *did_zero) +{ + return iomap_zero_range(VFS_I(ip), offset, len, did_zero, + IS_DAX(VFS_I(ip)) ? &xfs_dax_write_iomap_ops + : &xfs_buffered_write_iomap_ops); +} + +int +xfs_iomap_truncate_page( + struct xfs_inode *ip, + loff_t pos, + bool *did_zero) +{ + return iomap_truncate_page(VFS_I(ip), pos, did_zero, + IS_DAX(VFS_I(ip)) ? &xfs_dax_write_iomap_ops + : &xfs_buffered_write_iomap_ops); +} diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 7d3703556d0e..e4e515cd63b5 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -14,6 +14,9 @@ struct xfs_bmbt_irec; int xfs_iomap_write_direct(struct xfs_inode *ip, xfs_fileoff_t offset_fsb, xfs_fileoff_t count_fsb, struct xfs_bmbt_irec *imap); int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); +int xfs_iomap_zero_range(struct xfs_inode *ip, loff_t offset, loff_t len, + bool *did_zero); +int xfs_iomap_truncate_page(struct xfs_inode *ip, loff_t pos, bool *did_zero); xfs_fileoff_t xfs_iomap_eof_align_last_fsb(struct xfs_inode *ip, xfs_fileoff_t end_fsb); @@ -42,6 +45,7 @@ xfs_aligned_fsb_count( extern const struct iomap_ops xfs_buffered_write_iomap_ops; extern const struct iomap_ops xfs_direct_write_iomap_ops; +extern const struct iomap_ops xfs_dax_write_iomap_ops; extern const struct iomap_ops xfs_read_iomap_ops; extern const struct iomap_ops xfs_seek_iomap_ops; extern const struct iomap_ops xfs_xattr_iomap_ops; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index dfe24b7f26e5..6d936c3e1a6e 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -911,8 +911,8 @@ xfs_setattr_size( */ if (newsize > oldsize) { trace_xfs_zero_eof(ip, oldsize, newsize - oldsize); - error = iomap_zero_range(inode, oldsize, newsize - oldsize, - &did_zeroing, &xfs_buffered_write_iomap_ops); + error = xfs_iomap_zero_range(ip, oldsize, newsize - oldsize, + &did_zeroing); } else { /* * iomap won't detect a dirty page over an unwritten block (or a @@ -924,8 +924,7 @@ xfs_setattr_size( newsize); if (error) return error; - error = iomap_truncate_page(inode, newsize, &did_zeroing, - &xfs_buffered_write_iomap_ops); + error = xfs_iomap_truncate_page(ip, newsize, &did_zeroing); } if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index d25434f93235..9a780948dbd0 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1266,8 +1266,7 @@ xfs_reflink_zero_posteof( return 0; trace_xfs_zero_eof(ip, isize, pos - isize); - return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL, - &xfs_buffered_write_iomap_ops); + return xfs_iomap_zero_range(ip, isize, pos - isize, NULL); } /* -- 2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Shiyang Ruan <ruansy.fnst@fujitsu.com> To: <linux-kernel@vger.kernel.org>, <linux-xfs@vger.kernel.org>, <linux-nvdimm@lists.01.org>, <linux-fsdevel@vger.kernel.org> Cc: darrick.wong@oracle.com, willy@infradead.org, viro@zeniv.linux.org.uk, david@fromorbit.com, hch@lst.de, rgoldwyn@suse.de Subject: [PATCH v5 6/7] fs/xfs: Handle CoW for fsdax write() path Date: Tue, 11 May 2021 11:09:32 +0800 [thread overview] Message-ID: <20210511030933.3080921-7-ruansy.fnst@fujitsu.com> (raw) In-Reply-To: <20210511030933.3080921-1-ruansy.fnst@fujitsu.com> In fsdax mode, WRITE and ZERO on a shared extent need CoW performed. After CoW, new allocated extents needs to be remapped to the file. So, add an iomap_end for dax write ops to do the remapping work. Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com> --- fs/xfs/xfs_bmap_util.c | 3 +-- fs/xfs/xfs_file.c | 9 +++---- fs/xfs/xfs_iomap.c | 61 +++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_iomap.h | 4 +++ fs/xfs/xfs_iops.c | 7 +++-- fs/xfs/xfs_reflink.c | 3 +-- 6 files changed, 72 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index a5e9d7d34023..2a36dc93ff27 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -965,8 +965,7 @@ xfs_free_file_space( return 0; if (offset + len > XFS_ISIZE(ip)) len = XFS_ISIZE(ip) - offset; - error = iomap_zero_range(VFS_I(ip), offset, len, NULL, - &xfs_buffered_write_iomap_ops); + error = xfs_iomap_zero_range(ip, offset, len, NULL); if (error) return error; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 396ef36dcd0a..38d8eca05aee 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -684,11 +684,8 @@ xfs_file_dax_write( pos = iocb->ki_pos; trace_xfs_file_dax_write(iocb, from); - ret = dax_iomap_rw(iocb, from, &xfs_direct_write_iomap_ops); - if (ret > 0 && iocb->ki_pos > i_size_read(inode)) { - i_size_write(inode, iocb->ki_pos); - error = xfs_setfilesize(ip, pos, ret); - } + ret = dax_iomap_rw(iocb, from, &xfs_dax_write_iomap_ops); + out: if (iolock) xfs_iunlock(ip, iolock); @@ -1309,7 +1306,7 @@ __xfs_filemap_fault( ret = dax_iomap_fault(vmf, pe_size, &pfn, NULL, (write_fault && !vmf->cow_page) ? - &xfs_direct_write_iomap_ops : + &xfs_dax_write_iomap_ops : &xfs_read_iomap_ops); if (ret & VM_FAULT_NEEDDSYNC) ret = dax_finish_sync_fault(vmf, pe_size, pfn); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d154f42e2dc6..8b593a51480d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -761,7 +761,8 @@ xfs_direct_write_iomap_begin( /* may drop and re-acquire the ilock */ error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared, - &lockmode, flags & IOMAP_DIRECT); + &lockmode, + (flags & IOMAP_DIRECT) || IS_DAX(inode)); if (error) goto out_unlock; if (shared) @@ -854,6 +855,41 @@ const struct iomap_ops xfs_direct_write_iomap_ops = { .iomap_begin = xfs_direct_write_iomap_begin, }; +static int +xfs_dax_write_iomap_end( + struct inode *inode, + loff_t pos, + loff_t length, + ssize_t written, + unsigned int flags, + struct iomap *iomap) +{ + int error = 0; + struct xfs_inode *ip = XFS_I(inode); + bool cow = xfs_is_cow_inode(ip); + + if (!written) + return 0; + + if (pos + written > i_size_read(inode) && !(flags & IOMAP_FAULT)) { + i_size_write(inode, pos + written); + error = xfs_setfilesize(ip, pos, written); + if (error && cow) { + xfs_reflink_cancel_cow_range(ip, pos, written, true); + return error; + } + } + if (cow) + error = xfs_reflink_end_cow(ip, pos, written); + + return error; +} + +const struct iomap_ops xfs_dax_write_iomap_ops = { + .iomap_begin = xfs_direct_write_iomap_begin, + .iomap_end = xfs_dax_write_iomap_end, +}; + static int xfs_buffered_write_iomap_begin( struct inode *inode, @@ -1311,3 +1347,26 @@ xfs_xattr_iomap_begin( const struct iomap_ops xfs_xattr_iomap_ops = { .iomap_begin = xfs_xattr_iomap_begin, }; + +int +xfs_iomap_zero_range( + struct xfs_inode *ip, + loff_t offset, + loff_t len, + bool *did_zero) +{ + return iomap_zero_range(VFS_I(ip), offset, len, did_zero, + IS_DAX(VFS_I(ip)) ? &xfs_dax_write_iomap_ops + : &xfs_buffered_write_iomap_ops); +} + +int +xfs_iomap_truncate_page( + struct xfs_inode *ip, + loff_t pos, + bool *did_zero) +{ + return iomap_truncate_page(VFS_I(ip), pos, did_zero, + IS_DAX(VFS_I(ip)) ? &xfs_dax_write_iomap_ops + : &xfs_buffered_write_iomap_ops); +} diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 7d3703556d0e..e4e515cd63b5 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -14,6 +14,9 @@ struct xfs_bmbt_irec; int xfs_iomap_write_direct(struct xfs_inode *ip, xfs_fileoff_t offset_fsb, xfs_fileoff_t count_fsb, struct xfs_bmbt_irec *imap); int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); +int xfs_iomap_zero_range(struct xfs_inode *ip, loff_t offset, loff_t len, + bool *did_zero); +int xfs_iomap_truncate_page(struct xfs_inode *ip, loff_t pos, bool *did_zero); xfs_fileoff_t xfs_iomap_eof_align_last_fsb(struct xfs_inode *ip, xfs_fileoff_t end_fsb); @@ -42,6 +45,7 @@ xfs_aligned_fsb_count( extern const struct iomap_ops xfs_buffered_write_iomap_ops; extern const struct iomap_ops xfs_direct_write_iomap_ops; +extern const struct iomap_ops xfs_dax_write_iomap_ops; extern const struct iomap_ops xfs_read_iomap_ops; extern const struct iomap_ops xfs_seek_iomap_ops; extern const struct iomap_ops xfs_xattr_iomap_ops; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index dfe24b7f26e5..6d936c3e1a6e 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -911,8 +911,8 @@ xfs_setattr_size( */ if (newsize > oldsize) { trace_xfs_zero_eof(ip, oldsize, newsize - oldsize); - error = iomap_zero_range(inode, oldsize, newsize - oldsize, - &did_zeroing, &xfs_buffered_write_iomap_ops); + error = xfs_iomap_zero_range(ip, oldsize, newsize - oldsize, + &did_zeroing); } else { /* * iomap won't detect a dirty page over an unwritten block (or a @@ -924,8 +924,7 @@ xfs_setattr_size( newsize); if (error) return error; - error = iomap_truncate_page(inode, newsize, &did_zeroing, - &xfs_buffered_write_iomap_ops); + error = xfs_iomap_truncate_page(ip, newsize, &did_zeroing); } if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index d25434f93235..9a780948dbd0 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1266,8 +1266,7 @@ xfs_reflink_zero_posteof( return 0; trace_xfs_zero_eof(ip, isize, pos - isize); - return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL, - &xfs_buffered_write_iomap_ops); + return xfs_iomap_zero_range(ip, isize, pos - isize, NULL); } /* -- 2.31.1 _______________________________________________ Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
next prev parent reply other threads:[~2021-05-11 3:10 UTC|newest] Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-11 3:09 [PATCH v5 0/7] fsdax,xfs: Add reflink&dedupe support for fsdax Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-11 3:09 ` [PATCH v5 1/7] fsdax: Introduce dax_iomap_cow_copy() Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-12 1:08 ` Darrick J. Wong 2021-05-12 1:08 ` Darrick J. Wong 2021-05-13 7:57 ` ruansy.fnst 2021-05-13 7:57 ` ruansy.fnst 2021-05-13 15:02 ` Darrick J. Wong 2021-05-13 15:02 ` Darrick J. Wong 2021-05-11 3:09 ` [PATCH v5 2/7] fsdax: Replace mmap entry in case of CoW Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-12 1:09 ` Darrick J. Wong 2021-05-12 1:09 ` Darrick J. Wong 2021-05-11 3:09 ` [PATCH v5 3/7] fsdax: Add dax_iomap_cow_copy() for dax_iomap_zero Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-12 1:17 ` Darrick J. Wong 2021-05-12 1:17 ` Darrick J. Wong 2021-05-12 1:37 ` ruansy.fnst 2021-05-12 1:37 ` ruansy.fnst 2021-05-25 22:17 ` Darrick J. Wong 2021-05-12 2:27 ` Mika Penttilä 2021-05-12 2:27 ` Mika Penttilä 2021-05-13 7:48 ` ruansy.fnst 2021-05-13 7:48 ` ruansy.fnst 2021-05-11 3:09 ` [PATCH v5 4/7] iomap: Introduce iomap_apply2() for operations on two files Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-11 3:09 ` [PATCH v5 5/7] fsdax: Dedup file range to use a compare function Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-12 1:23 ` Darrick J. Wong 2021-05-12 1:23 ` Darrick J. Wong 2021-05-14 8:35 ` ruansy.fnst 2021-05-14 8:35 ` ruansy.fnst 2021-05-14 16:03 ` Darrick J. Wong 2021-05-14 16:03 ` Darrick J. Wong 2021-05-11 3:09 ` Shiyang Ruan [this message] 2021-05-11 3:09 ` [PATCH v5 6/7] fs/xfs: Handle CoW for fsdax write() path Shiyang Ruan 2021-05-12 1:30 ` Darrick J. Wong 2021-05-12 1:30 ` Darrick J. Wong 2021-05-11 3:09 ` [PATCH v5 7/7] fs/xfs: Add dax dedupe support Shiyang Ruan 2021-05-11 3:09 ` Shiyang Ruan 2021-05-12 1:04 ` Darrick J. Wong 2021-05-12 1:04 ` Darrick J. Wong 2021-05-12 1:26 ` ruansy.fnst 2021-05-12 1:26 ` ruansy.fnst 2021-05-11 3:57 ` [PATCH v5 0/7] fsdax,xfs: Add reflink&dedupe support for fsdax Darrick J. Wong 2021-05-11 3:57 ` Darrick J. Wong 2021-05-11 5:53 ` ruansy.fnst 2021-05-11 5:53 ` ruansy.fnst
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210511030933.3080921-7-ruansy.fnst@fujitsu.com \ --to=ruansy.fnst@fujitsu.com \ --cc=dan.j.williams@intel.com \ --cc=darrick.wong@oracle.com \ --cc=david@fromorbit.com \ --cc=hch@lst.de \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-nvdimm@lists.01.org \ --cc=linux-xfs@vger.kernel.org \ --cc=rgoldwyn@suse.de \ --cc=viro@zeniv.linux.org.uk \ --cc=willy@infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.