> -----Original Message----- > From: Su Yue <l@xxxxxxxxxx> > Subject: Re: [PATCH v4 7/7] fs/xfs: Add dedupe support for fsdax > > > On Thu 08 Apr 2021 at 20:04, Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> wrote: > > > Add xfs_break_two_dax_layouts() to break layout for tow dax files. > > Then call compare range function only when files are both DAX or not. > > > > Signed-off-by: Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> > > > Not family with xfs code but reading code make my sleep better :) See bellow. > > > --- > > fs/xfs/xfs_file.c | 20 ++++++++++++++++++++ > > fs/xfs/xfs_inode.c | 8 +++++++- > > fs/xfs/xfs_inode.h | 1 + > > fs/xfs/xfs_reflink.c | 5 +++-- > > 4 files changed, 31 insertions(+), 3 deletions(-) > > > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index > > 5795d5d6f869..1fd457167c12 100644 > > --- a/fs/xfs/xfs_file.c > > +++ b/fs/xfs/xfs_file.c > > @@ -842,6 +842,26 @@ xfs_break_dax_layouts( > > 0, 0, xfs_wait_dax_page(inode)); > > } > > > > +int > > +xfs_break_two_dax_layouts( > > + struct inode *src, > > + struct inode *dest) > > +{ > > + int error; > > + bool retry = false; > > + > > +retry: > > > 'retry = false;' ? since xfs_break_dax_layouts() won't set retry to false if there is > no busy page in inode->i_mapping. > Dead loop will happen if retry is true once. Yes, I should move 'retry=false;' under the retry label. > > > + error = xfs_break_dax_layouts(src, &retry); > > + if (error || retry) > > + goto retry; > > + > > + error = xfs_break_dax_layouts(dest, &retry); > > + if (error || retry) > > + goto retry; > > + > > + return error; > > +} > > + > > int > > xfs_break_layouts( > > struct inode *inode, > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index > > f93370bd7b1e..c01786917eef 100644 > > --- a/fs/xfs/xfs_inode.c > > +++ b/fs/xfs/xfs_inode.c > > @@ -3713,8 +3713,10 @@ xfs_ilock2_io_mmap( > > struct xfs_inode *ip2) > > { > > int ret; > > + struct inode *inode1 = VFS_I(ip1); > > + struct inode *inode2 = VFS_I(ip2); > > > > - ret = xfs_iolock_two_inodes_and_break_layout(VFS_I(ip1), > > VFS_I(ip2)); > > + ret = xfs_iolock_two_inodes_and_break_layout(inode1, inode2); > > if (ret) > > return ret; > > if (ip1 == ip2) > > @@ -3722,6 +3724,10 @@ xfs_ilock2_io_mmap( > > else > > xfs_lock_two_inodes(ip1, XFS_MMAPLOCK_EXCL, > > ip2, XFS_MMAPLOCK_EXCL); > > + > > + if (IS_DAX(inode1) && IS_DAX(inode2)) > > + ret = xfs_break_two_dax_layouts(inode1, inode2); > > + > ret is ignored here. Thanks, it's my mistake. -- Thanks, Ruan Shiyang. > > -- > Su > > return 0; > > } > > > > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index > > 88ee4c3930ae..5ef21924dddc 100644 > > --- a/fs/xfs/xfs_inode.h > > +++ b/fs/xfs/xfs_inode.h > > @@ -435,6 +435,7 @@ enum xfs_prealloc_flags { > > > > int xfs_update_prealloc_flags(struct xfs_inode *ip, > > enum xfs_prealloc_flags flags); > > +int xfs_break_two_dax_layouts(struct inode *inode1, struct > > inode *inode2); > > int xfs_break_layouts(struct inode *inode, uint *iolock, > > enum layout_break_reason reason); > > > > diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index > > a4cd6e8a7aa0..4426bcc8a985 100644 > > --- a/fs/xfs/xfs_reflink.c > > +++ b/fs/xfs/xfs_reflink.c > > @@ -29,6 +29,7 @@ > > #include "xfs_iomap.h" > > #include "xfs_sb.h" > > #include "xfs_ag_resv.h" > > +#include <linux/dax.h> > > > > /* > > * Copy on Write of Shared Blocks > > @@ -1324,8 +1325,8 @@ xfs_reflink_remap_prep( > > if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest)) > > goto out_unlock; > > > > - /* Don't share DAX file data for now. */ > > - if (IS_DAX(inode_in) || IS_DAX(inode_out)) > > + /* Don't share DAX file data with non-DAX file. */ > > + if (IS_DAX(inode_in) != IS_DAX(inode_out)) > > goto out_unlock; > > > > if (!IS_DAX(inode_in))