nvdimm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts()
@ 2018-08-08 17:25 Dave Jiang
  2018-08-08 17:26 ` [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
  2018-09-10 16:23 ` [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Eric Sandeen
  0 siblings, 2 replies; 15+ messages in thread
From: Dave Jiang @ 2018-08-08 17:25 UTC (permalink / raw)
  To: tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch

From: Ross Zwisler <zwisler@kernel.org>

If the refcount of a page is lowered between the time that it is returned
by dax_busy_page() and when the refcount is again checked in
ext4_break_layouts() => ___wait_var_event(), the waiting function
ext4_wait_dax_page() will never be called.  This means that
ext4_break_layouts() will still have 'retry' set to false, so we'll stop
looping and never check the refcount of other pages in this inode.

Instead, always continue looping as long as dax_layout_busy_page() gives us
a page which it found with an elevated refcount.

Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---

v2:
- remove verbiage in comment header (Jan)

 fs/ext4/inode.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 8f6ad7667974..d2663a1e3ec2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4191,9 +4191,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
 	return 0;
 }
 
-static void ext4_wait_dax_page(struct ext4_inode_info *ei, bool *did_unlock)
+static void ext4_wait_dax_page(struct ext4_inode_info *ei)
 {
-	*did_unlock = true;
 	up_write(&ei->i_mmap_sem);
 	schedule();
 	down_write(&ei->i_mmap_sem);
@@ -4203,14 +4202,12 @@ int ext4_break_layouts(struct inode *inode)
 {
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	struct page *page;
-	bool retry;
 	int error;
 
 	if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
 		return -EINVAL;
 
 	do {
-		retry = false;
 		page = dax_layout_busy_page(inode->i_mapping);
 		if (!page)
 			return 0;
@@ -4218,8 +4215,8 @@ int ext4_break_layouts(struct inode *inode)
 		error = ___wait_var_event(&page->_refcount,
 				atomic_read(&page->_refcount) == 1,
 				TASK_INTERRUPTIBLE, 0, 0,
-				ext4_wait_dax_page(ei, &retry));
-	} while (error == 0 && retry);
+				ext4_wait_dax_page(ei));
+	} while (error == 0);
 
 	return error;
 }

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-08 17:25 [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Dave Jiang
@ 2018-08-08 17:26 ` Dave Jiang
  2018-08-09  8:57   ` Jan Kara
  2018-09-10 16:23 ` [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Eric Sandeen
  1 sibling, 1 reply; 15+ messages in thread
From: Dave Jiang @ 2018-08-08 17:26 UTC (permalink / raw)
  To: tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch

This patch is the duplicate of ross's fix for ext4 for xfs.

If the refcount of a page is lowered between the time that it is returned
by dax_busy_page() and when the refcount is again checked in
xfs_break_layouts() => ___wait_var_event(), the waiting function
xfs_wait_dax_page() will never be called.  This means that
xfs_break_layouts() will still have 'retry' set to false, so we'll stop
looping and never check the refcount of other pages in this inode.

Instead, always continue looping as long as dax_layout_busy_page() gives us
a page which it found with an elevated refcount.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---

v2:
- Rename parameter from did_unlock to retry (Jan) 

 fs/xfs/xfs_file.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index a3e7767a5715..cd6f0d8c4922 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -721,12 +721,10 @@ xfs_file_write_iter(
 
 static void
 xfs_wait_dax_page(
-	struct inode		*inode,
-	bool			*did_unlock)
+	struct inode		*inode)
 {
 	struct xfs_inode        *ip = XFS_I(inode);
 
-	*did_unlock = true;
 	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
 	schedule();
 	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
@@ -736,7 +734,7 @@ static int
 xfs_break_dax_layouts(
 	struct inode		*inode,
 	uint			iolock,
-	bool			*did_unlock)
+	bool			*retry)
 {
 	struct page		*page;
 
@@ -746,9 +744,10 @@ xfs_break_dax_layouts(
 	if (!page)
 		return 0;
 
+	*retry = true;
 	return ___wait_var_event(&page->_refcount,
 			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
-			0, 0, xfs_wait_dax_page(inode, did_unlock));
+			0, 0, xfs_wait_dax_page(inode));
 }
 
 int

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-08 17:26 ` [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
@ 2018-08-09  8:57   ` Jan Kara
  2018-08-09 16:21     ` Dave Jiang
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kara @ 2018-08-09  8:57 UTC (permalink / raw)
  To: Dave Jiang
  Cc: lczerner, jack, linux-nvdimm, darrick.wong, david, linux-xfs,
	zwisler, linux-fsdevel, tytso, linux-ext4, hch

On Wed 08-08-18 10:26:36, Dave Jiang wrote:
> This patch is the duplicate of ross's fix for ext4 for xfs.
> 
> If the refcount of a page is lowered between the time that it is returned
> by dax_busy_page() and when the refcount is again checked in
> xfs_break_layouts() => ___wait_var_event(), the waiting function
> xfs_wait_dax_page() will never be called.  This means that
> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
> looping and never check the refcount of other pages in this inode.
> 
> Instead, always continue looping as long as dax_layout_busy_page() gives us
> a page which it found with an elevated refcount.
> 
> Signed-off-by: Dave Jiang <dave.jiang@intel.com>

I think I gave you my reviewed-by tag already for the previous version. But
here it is again:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
> 
> v2:
> - Rename parameter from did_unlock to retry (Jan) 
> 
>  fs/xfs/xfs_file.c |    9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index a3e7767a5715..cd6f0d8c4922 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>  
>  static void
>  xfs_wait_dax_page(
> -	struct inode		*inode,
> -	bool			*did_unlock)
> +	struct inode		*inode)
>  {
>  	struct xfs_inode        *ip = XFS_I(inode);
>  
> -	*did_unlock = true;
>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>  	schedule();
>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
> @@ -736,7 +734,7 @@ static int
>  xfs_break_dax_layouts(
>  	struct inode		*inode,
>  	uint			iolock,
> -	bool			*did_unlock)
> +	bool			*retry)
>  {
>  	struct page		*page;
>  
> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>  	if (!page)
>  		return 0;
>  
> +	*retry = true;
>  	return ___wait_var_event(&page->_refcount,
>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
> +			0, 0, xfs_wait_dax_page(inode));
>  }
>  
>  int
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-09  8:57   ` Jan Kara
@ 2018-08-09 16:21     ` Dave Jiang
  0 siblings, 0 replies; 15+ messages in thread
From: Dave Jiang @ 2018-08-09 16:21 UTC (permalink / raw)
  To: Jan Kara
  Cc: tytso, linux-nvdimm, darrick.wong, david, linux-xfs, zwisler,
	linux-fsdevel, lczerner, linux-ext4, hch



On 08/09/2018 01:57 AM, Jan Kara wrote:
> On Wed 08-08-18 10:26:36, Dave Jiang wrote:
>> This patch is the duplicate of ross's fix for ext4 for xfs.
>>
>> If the refcount of a page is lowered between the time that it is returned
>> by dax_busy_page() and when the refcount is again checked in
>> xfs_break_layouts() => ___wait_var_event(), the waiting function
>> xfs_wait_dax_page() will never be called.  This means that
>> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
>> looping and never check the refcount of other pages in this inode.
>>
>> Instead, always continue looping as long as dax_layout_busy_page() gives us
>> a page which it found with an elevated refcount.
>>
>> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> 
> I think I gave you my reviewed-by tag already for the previous version. But
> here it is again:
> 
> Reviewed-by: Jan Kara <jack@suse.cz>

Yes you did. I forgot to append it when I sent it out the first time. I
resent it. :)

> 
> 								Honza
> 
>> ---
>>
>> v2:
>> - Rename parameter from did_unlock to retry (Jan) 
>>
>>  fs/xfs/xfs_file.c |    9 ++++-----
>>  1 file changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
>> index a3e7767a5715..cd6f0d8c4922 100644
>> --- a/fs/xfs/xfs_file.c
>> +++ b/fs/xfs/xfs_file.c
>> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>>  
>>  static void
>>  xfs_wait_dax_page(
>> -	struct inode		*inode,
>> -	bool			*did_unlock)
>> +	struct inode		*inode)
>>  {
>>  	struct xfs_inode        *ip = XFS_I(inode);
>>  
>> -	*did_unlock = true;
>>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>>  	schedule();
>>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
>> @@ -736,7 +734,7 @@ static int
>>  xfs_break_dax_layouts(
>>  	struct inode		*inode,
>>  	uint			iolock,
>> -	bool			*did_unlock)
>> +	bool			*retry)
>>  {
>>  	struct page		*page;
>>  
>> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>>  	if (!page)
>>  		return 0;
>>  
>> +	*retry = true;
>>  	return ___wait_var_event(&page->_refcount,
>>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
>> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
>> +			0, 0, xfs_wait_dax_page(inode));
>>  }
>>  
>>  int
>>
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts()
  2018-08-08 17:25 [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Dave Jiang
  2018-08-08 17:26 ` [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
@ 2018-09-10 16:23 ` Eric Sandeen
  2018-09-11 15:26   ` Jan Kara
  1 sibling, 1 reply; 15+ messages in thread
From: Eric Sandeen @ 2018-09-10 16:23 UTC (permalink / raw)
  To: Dave Jiang, tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch

On 8/8/18 12:25 PM, Dave Jiang wrote:
> From: Ross Zwisler <zwisler@kernel.org>
> 
> If the refcount of a page is lowered between the time that it is returned
> by dax_busy_page() and when the refcount is again checked in
> ext4_break_layouts() => ___wait_var_event(), the waiting function
> ext4_wait_dax_page() will never be called.  This means that
> ext4_break_layouts() will still have 'retry' set to false, so we'll stop
> looping and never check the refcount of other pages in this inode.
> 
> Instead, always continue looping as long as dax_layout_busy_page() gives us
> a page which it found with an elevated refcount.
> 
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reviewed-by: Jan Kara <jack@suse.cz>

Ted - wondering if this one is still on your radar?

Thanks,
-Eric

> ---
> 
> v2:
> - remove verbiage in comment header (Jan)
> 
>  fs/ext4/inode.c |    9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 8f6ad7667974..d2663a1e3ec2 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -4191,9 +4191,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
>  	return 0;
>  }
>  
> -static void ext4_wait_dax_page(struct ext4_inode_info *ei, bool *did_unlock)
> +static void ext4_wait_dax_page(struct ext4_inode_info *ei)
>  {
> -	*did_unlock = true;
>  	up_write(&ei->i_mmap_sem);
>  	schedule();
>  	down_write(&ei->i_mmap_sem);
> @@ -4203,14 +4202,12 @@ int ext4_break_layouts(struct inode *inode)
>  {
>  	struct ext4_inode_info *ei = EXT4_I(inode);
>  	struct page *page;
> -	bool retry;
>  	int error;
>  
>  	if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
>  		return -EINVAL;
>  
>  	do {
> -		retry = false;
>  		page = dax_layout_busy_page(inode->i_mapping);
>  		if (!page)
>  			return 0;
> @@ -4218,8 +4215,8 @@ int ext4_break_layouts(struct inode *inode)
>  		error = ___wait_var_event(&page->_refcount,
>  				atomic_read(&page->_refcount) == 1,
>  				TASK_INTERRUPTIBLE, 0, 0,
> -				ext4_wait_dax_page(ei, &retry));
> -	} while (error == 0 && retry);
> +				ext4_wait_dax_page(ei));
> +	} while (error == 0);
>  
>  	return error;
>  }
> 
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts()
  2018-09-10 16:23 ` [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Eric Sandeen
@ 2018-09-11 15:26   ` Jan Kara
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Kara @ 2018-09-11 15:26 UTC (permalink / raw)
  To: sandeen
  Cc: lczerner, tytso, linux-nvdimm, darrick.wong, david, linux-xfs,
	zwisler, linux-fsdevel, jack, linux-ext4, hch

On Mon 10-09-18 11:23:56, Eric Sandeen wrote:
> On 8/8/18 12:25 PM, Dave Jiang wrote:
> > From: Ross Zwisler <zwisler@kernel.org>
> > 
> > If the refcount of a page is lowered between the time that it is returned
> > by dax_busy_page() and when the refcount is again checked in
> > ext4_break_layouts() => ___wait_var_event(), the waiting function
> > ext4_wait_dax_page() will never be called.  This means that
> > ext4_break_layouts() will still have 'retry' set to false, so we'll stop
> > looping and never check the refcount of other pages in this inode.
> > 
> > Instead, always continue looping as long as dax_layout_busy_page() gives us
> > a page which it found with an elevated refcount.
> > 
> > Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> > Reviewed-by: Jan Kara <jack@suse.cz>
> 
> Ted - wondering if this one is still on your radar?

Resent the patch to Ted to catch more attention.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 19:24     ` Ross Zwisler
@ 2018-08-10 19:26       ` Eric Sandeen
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Sandeen @ 2018-08-10 19:26 UTC (permalink / raw)
  To: Ross Zwisler, dave.jiang
  Cc: Jan Kara, linux-nvdimm, darrick.wong, Dave Chinner, linux-xfs,
	lczerner, linux-fsdevel, Theodore Ts'o, linux-ext4,
	Christoph Hellwig

On 8/10/18 2:24 PM, Ross Zwisler wrote:
> On Fri, Aug 10, 2018 at 9:23 AM Dave Jiang <dave.jiang@intel.com> wrote:
>> On 08/10/2018 11:31 AM, Eric Sandeen wrote:
>>> On 8/8/18 12:31 PM, Dave Jiang wrote:
>>>> This patch is the duplicate of ross's fix for ext4 for xfs.
>>>>
>>>> If the refcount of a page is lowered between the time that it is returned
>>>> by dax_busy_page() and when the refcount is again checked in
>>>> xfs_break_layouts() => ___wait_var_event(), the waiting function
>>>> xfs_wait_dax_page() will never be called.  This means that
>>>> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
>>>> looping and never check the refcount of other pages in this inode.
>>>>
>>>> Instead, always continue looping as long as dax_layout_busy_page() gives us
>>>> a page which it found with an elevated refcount.
>>>
>>> Hi Dave, does this have a testcase?  Have you seen the issue using Ross's
>>> xfstest generic/503 or is there some other test?  Apologies if I missed
>>> prior discussion on a testcase or race frequency...
>>
>> I do not have a testcase. I know Ross replicated it on ext4. And Jan
>> asked to create the same fix with XFS when he reviewed Ross's fix for ext4.
> 
> In my testing I couldn't get this race to hit with XFS.  I couldn't
> even get a failure with generic/503 when testing XFS before Dan's
> initial patches went in which added xfs_break_layouts() et al.  I
> think that Dan had to manually insert timing delays to get the warning
> to hit for XFS when testing his patches.
> 
> The race we're fixing happens consistently with ext4 and through code
> inspection we can see that the race exists in XFS.

Ok, thanks for the info Dave & Ross!

-Eric
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 19:23   ` Dave Jiang
@ 2018-08-10 19:24     ` Ross Zwisler
  2018-08-10 19:26       ` Eric Sandeen
  0 siblings, 1 reply; 15+ messages in thread
From: Ross Zwisler @ 2018-08-10 19:24 UTC (permalink / raw)
  To: dave.jiang
  Cc: Eric Sandeen, Jan Kara, linux-nvdimm, darrick.wong, Dave Chinner,
	linux-xfs, lczerner, linux-fsdevel, Theodore Ts'o,
	linux-ext4, Christoph Hellwig

On Fri, Aug 10, 2018 at 9:23 AM Dave Jiang <dave.jiang@intel.com> wrote:
> On 08/10/2018 11:31 AM, Eric Sandeen wrote:
> > On 8/8/18 12:31 PM, Dave Jiang wrote:
> >> This patch is the duplicate of ross's fix for ext4 for xfs.
> >>
> >> If the refcount of a page is lowered between the time that it is returned
> >> by dax_busy_page() and when the refcount is again checked in
> >> xfs_break_layouts() => ___wait_var_event(), the waiting function
> >> xfs_wait_dax_page() will never be called.  This means that
> >> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
> >> looping and never check the refcount of other pages in this inode.
> >>
> >> Instead, always continue looping as long as dax_layout_busy_page() gives us
> >> a page which it found with an elevated refcount.
> >
> > Hi Dave, does this have a testcase?  Have you seen the issue using Ross's
> > xfstest generic/503 or is there some other test?  Apologies if I missed
> > prior discussion on a testcase or race frequency...
>
> I do not have a testcase. I know Ross replicated it on ext4. And Jan
> asked to create the same fix with XFS when he reviewed Ross's fix for ext4.

In my testing I couldn't get this race to hit with XFS.  I couldn't
even get a failure with generic/503 when testing XFS before Dan's
initial patches went in which added xfs_break_layouts() et al.  I
think that Dan had to manually insert timing delays to get the warning
to hit for XFS when testing his patches.

The race we're fixing happens consistently with ext4 and through code
inspection we can see that the race exists in XFS.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 18:31 ` Eric Sandeen
@ 2018-08-10 19:23   ` Dave Jiang
  2018-08-10 19:24     ` Ross Zwisler
  0 siblings, 1 reply; 15+ messages in thread
From: Dave Jiang @ 2018-08-10 19:23 UTC (permalink / raw)
  To: sandeen, tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch



On 08/10/2018 11:31 AM, Eric Sandeen wrote:
> On 8/8/18 12:31 PM, Dave Jiang wrote:
>> This patch is the duplicate of ross's fix for ext4 for xfs.
>>
>> If the refcount of a page is lowered between the time that it is returned
>> by dax_busy_page() and when the refcount is again checked in
>> xfs_break_layouts() => ___wait_var_event(), the waiting function
>> xfs_wait_dax_page() will never be called.  This means that
>> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
>> looping and never check the refcount of other pages in this inode.
>>
>> Instead, always continue looping as long as dax_layout_busy_page() gives us
>> a page which it found with an elevated refcount.
> 
> Hi Dave, does this have a testcase?  Have you seen the issue using Ross's
> xfstest generic/503 or is there some other test?  Apologies if I missed
> prior discussion on a testcase or race frequency...

I do not have a testcase. I know Ross replicated it on ext4. And Jan
asked to create the same fix with XFS when he reviewed Ross's fix for ext4.

> 
> Thanks,
> -Eric
> 
>> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
>> Reviewed-by: Jan Kara <jack@suse.cz>
>> ---
>>
>> Sorry resend, forgot to add Jan's reviewed-by.
>>
>> v2:
>> - Rename parameter from did_unlock to retry (Jan)
>>
>>  fs/xfs/xfs_file.c |    9 ++++-----
>>  1 file changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
>> index a3e7767a5715..cd6f0d8c4922 100644
>> --- a/fs/xfs/xfs_file.c
>> +++ b/fs/xfs/xfs_file.c
>> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>>  
>>  static void
>>  xfs_wait_dax_page(
>> -	struct inode		*inode,
>> -	bool			*did_unlock)
>> +	struct inode		*inode)
>>  {
>>  	struct xfs_inode        *ip = XFS_I(inode);
>>  
>> -	*did_unlock = true;
>>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>>  	schedule();
>>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
>> @@ -736,7 +734,7 @@ static int
>>  xfs_break_dax_layouts(
>>  	struct inode		*inode,
>>  	uint			iolock,
>> -	bool			*did_unlock)
>> +	bool			*retry)
>>  {
>>  	struct page		*page;
>>  
>> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>>  	if (!page)
>>  		return 0;
>>  
>> +	*retry = true;
>>  	return ___wait_var_event(&page->_refcount,
>>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
>> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
>> +			0, 0, xfs_wait_dax_page(inode));
>>  }
>>  
>>  int
>>
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-08 17:31 [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
  2018-08-10 15:48 ` Darrick J. Wong
@ 2018-08-10 18:31 ` Eric Sandeen
  2018-08-10 19:23   ` Dave Jiang
  1 sibling, 1 reply; 15+ messages in thread
From: Eric Sandeen @ 2018-08-10 18:31 UTC (permalink / raw)
  To: Dave Jiang, tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch

On 8/8/18 12:31 PM, Dave Jiang wrote:
> This patch is the duplicate of ross's fix for ext4 for xfs.
> 
> If the refcount of a page is lowered between the time that it is returned
> by dax_busy_page() and when the refcount is again checked in
> xfs_break_layouts() => ___wait_var_event(), the waiting function
> xfs_wait_dax_page() will never be called.  This means that
> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
> looping and never check the refcount of other pages in this inode.
> 
> Instead, always continue looping as long as dax_layout_busy_page() gives us
> a page which it found with an elevated refcount.

Hi Dave, does this have a testcase?  Have you seen the issue using Ross's
xfstest generic/503 or is there some other test?  Apologies if I missed
prior discussion on a testcase or race frequency...

Thanks,
-Eric

> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> Reviewed-by: Jan Kara <jack@suse.cz>
> ---
> 
> Sorry resend, forgot to add Jan's reviewed-by.
> 
> v2:
> - Rename parameter from did_unlock to retry (Jan)
> 
>  fs/xfs/xfs_file.c |    9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index a3e7767a5715..cd6f0d8c4922 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>  
>  static void
>  xfs_wait_dax_page(
> -	struct inode		*inode,
> -	bool			*did_unlock)
> +	struct inode		*inode)
>  {
>  	struct xfs_inode        *ip = XFS_I(inode);
>  
> -	*did_unlock = true;
>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>  	schedule();
>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
> @@ -736,7 +734,7 @@ static int
>  xfs_break_dax_layouts(
>  	struct inode		*inode,
>  	uint			iolock,
> -	bool			*did_unlock)
> +	bool			*retry)
>  {
>  	struct page		*page;
>  
> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>  	if (!page)
>  		return 0;
>  
> +	*retry = true;
>  	return ___wait_var_event(&page->_refcount,
>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
> +			0, 0, xfs_wait_dax_page(inode));
>  }
>  
>  int
> 
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 16:02     ` Darrick J. Wong
@ 2018-08-10 16:05       ` Dave Jiang
  0 siblings, 0 replies; 15+ messages in thread
From: Dave Jiang @ 2018-08-10 16:05 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: lczerner, jack, linux-nvdimm, david, linux-xfs, zwisler,
	linux-fsdevel, tytso, linux-ext4, hch



On 08/10/2018 09:02 AM, Darrick J. Wong wrote:
> On Fri, Aug 10, 2018 at 08:54:00AM -0700, Dave Jiang wrote:
>>
>>
>> On 08/10/2018 08:48 AM, Darrick J. Wong wrote:
>>> On Wed, Aug 08, 2018 at 10:31:40AM -0700, Dave Jiang wrote:
>>>> This patch is the duplicate of ross's fix for ext4 for xfs.
>>>>
>>>> If the refcount of a page is lowered between the time that it is returned
>>>> by dax_busy_page() and when the refcount is again checked in
>>>> xfs_break_layouts() => ___wait_var_event(), the waiting function
>>>> xfs_wait_dax_page() will never be called.  This means that
>>>> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
>>>> looping and never check the refcount of other pages in this inode.
>>>>
>>>> Instead, always continue looping as long as dax_layout_busy_page() gives us
>>>> a page which it found with an elevated refcount.
>>>>
>>>> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
>>>> Reviewed-by: Jan Kara <jack@suse.cz>
>>>> ---
>>>>
>>>> Sorry resend, forgot to add Jan's reviewed-by.
>>>>
>>>> v2:
>>>> - Rename parameter from did_unlock to retry (Jan)
>>>>
>>>>  fs/xfs/xfs_file.c |    9 ++++-----
>>>>  1 file changed, 4 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
>>>> index a3e7767a5715..cd6f0d8c4922 100644
>>>> --- a/fs/xfs/xfs_file.c
>>>> +++ b/fs/xfs/xfs_file.c
>>>> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>>>>  
>>>>  static void
>>>>  xfs_wait_dax_page(
>>>> -	struct inode		*inode,
>>>> -	bool			*did_unlock)
>>>> +	struct inode		*inode)
>>>>  {
>>>>  	struct xfs_inode        *ip = XFS_I(inode);
>>>>  
>>>> -	*did_unlock = true;
>>>>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>>>>  	schedule();
>>>>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
>>>> @@ -736,7 +734,7 @@ static int
>>>>  xfs_break_dax_layouts(
>>>>  	struct inode		*inode,
>>>>  	uint			iolock,
>>>> -	bool			*did_unlock)
>>>> +	bool			*retry)
>>>
>>> Uhhh, this hunk doesn't apply.  xfs_break_dax_layouts doesn't have an
>>> iolock parameter anymore; was this not generated off of xfs for-next?
>>
>> Sorry. It was generated against 4.18-rc8. I'll respin patch against xfs
>> for-next.
> 
> I think it's just a matter of taking the old patch and changing
> "did_unlock" to "retry", right?  If so, I'll just change that and be
> done with this one. :)

For the conflict part yes. Thanks! :)

> 
> --D
> 
>>>
>>> --D
>>>
>>>>  {
>>>>  	struct page		*page;
>>>>  
>>>> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>>>>  	if (!page)
>>>>  		return 0;
>>>>  
>>>> +	*retry = true;
>>>>  	return ___wait_var_event(&page->_refcount,
>>>>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
>>>> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
>>>> +			0, 0, xfs_wait_dax_page(inode));
>>>>  }
>>>>  
>>>>  int
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 15:54   ` Dave Jiang
@ 2018-08-10 16:02     ` Darrick J. Wong
  2018-08-10 16:05       ` Dave Jiang
  0 siblings, 1 reply; 15+ messages in thread
From: Darrick J. Wong @ 2018-08-10 16:02 UTC (permalink / raw)
  To: Dave Jiang
  Cc: lczerner, jack, linux-nvdimm, david, linux-xfs, zwisler,
	linux-fsdevel, tytso, linux-ext4, hch

On Fri, Aug 10, 2018 at 08:54:00AM -0700, Dave Jiang wrote:
> 
> 
> On 08/10/2018 08:48 AM, Darrick J. Wong wrote:
> > On Wed, Aug 08, 2018 at 10:31:40AM -0700, Dave Jiang wrote:
> >> This patch is the duplicate of ross's fix for ext4 for xfs.
> >>
> >> If the refcount of a page is lowered between the time that it is returned
> >> by dax_busy_page() and when the refcount is again checked in
> >> xfs_break_layouts() => ___wait_var_event(), the waiting function
> >> xfs_wait_dax_page() will never be called.  This means that
> >> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
> >> looping and never check the refcount of other pages in this inode.
> >>
> >> Instead, always continue looping as long as dax_layout_busy_page() gives us
> >> a page which it found with an elevated refcount.
> >>
> >> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> >> Reviewed-by: Jan Kara <jack@suse.cz>
> >> ---
> >>
> >> Sorry resend, forgot to add Jan's reviewed-by.
> >>
> >> v2:
> >> - Rename parameter from did_unlock to retry (Jan)
> >>
> >>  fs/xfs/xfs_file.c |    9 ++++-----
> >>  1 file changed, 4 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> >> index a3e7767a5715..cd6f0d8c4922 100644
> >> --- a/fs/xfs/xfs_file.c
> >> +++ b/fs/xfs/xfs_file.c
> >> @@ -721,12 +721,10 @@ xfs_file_write_iter(
> >>  
> >>  static void
> >>  xfs_wait_dax_page(
> >> -	struct inode		*inode,
> >> -	bool			*did_unlock)
> >> +	struct inode		*inode)
> >>  {
> >>  	struct xfs_inode        *ip = XFS_I(inode);
> >>  
> >> -	*did_unlock = true;
> >>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
> >>  	schedule();
> >>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
> >> @@ -736,7 +734,7 @@ static int
> >>  xfs_break_dax_layouts(
> >>  	struct inode		*inode,
> >>  	uint			iolock,
> >> -	bool			*did_unlock)
> >> +	bool			*retry)
> > 
> > Uhhh, this hunk doesn't apply.  xfs_break_dax_layouts doesn't have an
> > iolock parameter anymore; was this not generated off of xfs for-next?
> 
> Sorry. It was generated against 4.18-rc8. I'll respin patch against xfs
> for-next.

I think it's just a matter of taking the old patch and changing
"did_unlock" to "retry", right?  If so, I'll just change that and be
done with this one. :)

--D

> > 
> > --D
> > 
> >>  {
> >>  	struct page		*page;
> >>  
> >> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
> >>  	if (!page)
> >>  		return 0;
> >>  
> >> +	*retry = true;
> >>  	return ___wait_var_event(&page->_refcount,
> >>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
> >> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
> >> +			0, 0, xfs_wait_dax_page(inode));
> >>  }
> >>  
> >>  int
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-10 15:48 ` Darrick J. Wong
@ 2018-08-10 15:54   ` Dave Jiang
  2018-08-10 16:02     ` Darrick J. Wong
  0 siblings, 1 reply; 15+ messages in thread
From: Dave Jiang @ 2018-08-10 15:54 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: lczerner, jack, linux-nvdimm, david, linux-xfs, zwisler,
	linux-fsdevel, tytso, linux-ext4, hch



On 08/10/2018 08:48 AM, Darrick J. Wong wrote:
> On Wed, Aug 08, 2018 at 10:31:40AM -0700, Dave Jiang wrote:
>> This patch is the duplicate of ross's fix for ext4 for xfs.
>>
>> If the refcount of a page is lowered between the time that it is returned
>> by dax_busy_page() and when the refcount is again checked in
>> xfs_break_layouts() => ___wait_var_event(), the waiting function
>> xfs_wait_dax_page() will never be called.  This means that
>> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
>> looping and never check the refcount of other pages in this inode.
>>
>> Instead, always continue looping as long as dax_layout_busy_page() gives us
>> a page which it found with an elevated refcount.
>>
>> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
>> Reviewed-by: Jan Kara <jack@suse.cz>
>> ---
>>
>> Sorry resend, forgot to add Jan's reviewed-by.
>>
>> v2:
>> - Rename parameter from did_unlock to retry (Jan)
>>
>>  fs/xfs/xfs_file.c |    9 ++++-----
>>  1 file changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
>> index a3e7767a5715..cd6f0d8c4922 100644
>> --- a/fs/xfs/xfs_file.c
>> +++ b/fs/xfs/xfs_file.c
>> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>>  
>>  static void
>>  xfs_wait_dax_page(
>> -	struct inode		*inode,
>> -	bool			*did_unlock)
>> +	struct inode		*inode)
>>  {
>>  	struct xfs_inode        *ip = XFS_I(inode);
>>  
>> -	*did_unlock = true;
>>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>>  	schedule();
>>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
>> @@ -736,7 +734,7 @@ static int
>>  xfs_break_dax_layouts(
>>  	struct inode		*inode,
>>  	uint			iolock,
>> -	bool			*did_unlock)
>> +	bool			*retry)
> 
> Uhhh, this hunk doesn't apply.  xfs_break_dax_layouts doesn't have an
> iolock parameter anymore; was this not generated off of xfs for-next?

Sorry. It was generated against 4.18-rc8. I'll respin patch against xfs
for-next.

> 
> --D
> 
>>  {
>>  	struct page		*page;
>>  
>> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>>  	if (!page)
>>  		return 0;
>>  
>> +	*retry = true;
>>  	return ___wait_var_event(&page->_refcount,
>>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
>> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
>> +			0, 0, xfs_wait_dax_page(inode));
>>  }
>>  
>>  int
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
  2018-08-08 17:31 [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
@ 2018-08-10 15:48 ` Darrick J. Wong
  2018-08-10 15:54   ` Dave Jiang
  2018-08-10 18:31 ` Eric Sandeen
  1 sibling, 1 reply; 15+ messages in thread
From: Darrick J. Wong @ 2018-08-10 15:48 UTC (permalink / raw)
  To: Dave Jiang
  Cc: lczerner, jack, linux-nvdimm, david, linux-xfs, zwisler,
	linux-fsdevel, tytso, linux-ext4, hch

On Wed, Aug 08, 2018 at 10:31:40AM -0700, Dave Jiang wrote:
> This patch is the duplicate of ross's fix for ext4 for xfs.
> 
> If the refcount of a page is lowered between the time that it is returned
> by dax_busy_page() and when the refcount is again checked in
> xfs_break_layouts() => ___wait_var_event(), the waiting function
> xfs_wait_dax_page() will never be called.  This means that
> xfs_break_layouts() will still have 'retry' set to false, so we'll stop
> looping and never check the refcount of other pages in this inode.
> 
> Instead, always continue looping as long as dax_layout_busy_page() gives us
> a page which it found with an elevated refcount.
> 
> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> Reviewed-by: Jan Kara <jack@suse.cz>
> ---
> 
> Sorry resend, forgot to add Jan's reviewed-by.
> 
> v2:
> - Rename parameter from did_unlock to retry (Jan)
> 
>  fs/xfs/xfs_file.c |    9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index a3e7767a5715..cd6f0d8c4922 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -721,12 +721,10 @@ xfs_file_write_iter(
>  
>  static void
>  xfs_wait_dax_page(
> -	struct inode		*inode,
> -	bool			*did_unlock)
> +	struct inode		*inode)
>  {
>  	struct xfs_inode        *ip = XFS_I(inode);
>  
> -	*did_unlock = true;
>  	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
>  	schedule();
>  	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
> @@ -736,7 +734,7 @@ static int
>  xfs_break_dax_layouts(
>  	struct inode		*inode,
>  	uint			iolock,
> -	bool			*did_unlock)
> +	bool			*retry)

Uhhh, this hunk doesn't apply.  xfs_break_dax_layouts doesn't have an
iolock parameter anymore; was this not generated off of xfs for-next?

--D

>  {
>  	struct page		*page;
>  
> @@ -746,9 +744,10 @@ xfs_break_dax_layouts(
>  	if (!page)
>  		return 0;
>  
> +	*retry = true;
>  	return ___wait_var_event(&page->_refcount,
>  			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
> -			0, 0, xfs_wait_dax_page(inode, did_unlock));
> +			0, 0, xfs_wait_dax_page(inode));
>  }
>  
>  int
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts()
@ 2018-08-08 17:31 Dave Jiang
  2018-08-10 15:48 ` Darrick J. Wong
  2018-08-10 18:31 ` Eric Sandeen
  0 siblings, 2 replies; 15+ messages in thread
From: Dave Jiang @ 2018-08-08 17:31 UTC (permalink / raw)
  To: tytso, darrick.wong, jack, zwisler
  Cc: linux-nvdimm, david, linux-xfs, linux-fsdevel, lczerner, linux-ext4, hch

This patch is the duplicate of ross's fix for ext4 for xfs.

If the refcount of a page is lowered between the time that it is returned
by dax_busy_page() and when the refcount is again checked in
xfs_break_layouts() => ___wait_var_event(), the waiting function
xfs_wait_dax_page() will never be called.  This means that
xfs_break_layouts() will still have 'retry' set to false, so we'll stop
looping and never check the refcount of other pages in this inode.

Instead, always continue looping as long as dax_layout_busy_page() gives us
a page which it found with an elevated refcount.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jan Kara <jack@suse.cz>
---

Sorry resend, forgot to add Jan's reviewed-by.

v2:
- Rename parameter from did_unlock to retry (Jan)

 fs/xfs/xfs_file.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index a3e7767a5715..cd6f0d8c4922 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -721,12 +721,10 @@ xfs_file_write_iter(
 
 static void
 xfs_wait_dax_page(
-	struct inode		*inode,
-	bool			*did_unlock)
+	struct inode		*inode)
 {
 	struct xfs_inode        *ip = XFS_I(inode);
 
-	*did_unlock = true;
 	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
 	schedule();
 	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
@@ -736,7 +734,7 @@ static int
 xfs_break_dax_layouts(
 	struct inode		*inode,
 	uint			iolock,
-	bool			*did_unlock)
+	bool			*retry)
 {
 	struct page		*page;
 
@@ -746,9 +744,10 @@ xfs_break_dax_layouts(
 	if (!page)
 		return 0;
 
+	*retry = true;
 	return ___wait_var_event(&page->_refcount,
 			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE,
-			0, 0, xfs_wait_dax_page(inode, did_unlock));
+			0, 0, xfs_wait_dax_page(inode));
 }
 
 int

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-09-11 15:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-08 17:25 [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Dave Jiang
2018-08-08 17:26 ` [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
2018-08-09  8:57   ` Jan Kara
2018-08-09 16:21     ` Dave Jiang
2018-09-10 16:23 ` [PATCH v2 1/2] ext4: Close race between direct IO and ext4_break_layouts() Eric Sandeen
2018-09-11 15:26   ` Jan Kara
2018-08-08 17:31 [PATCH v2 2/2] [PATCH] xfs: Close race between direct IO and xfs_break_layouts() Dave Jiang
2018-08-10 15:48 ` Darrick J. Wong
2018-08-10 15:54   ` Dave Jiang
2018-08-10 16:02     ` Darrick J. Wong
2018-08-10 16:05       ` Dave Jiang
2018-08-10 18:31 ` Eric Sandeen
2018-08-10 19:23   ` Dave Jiang
2018-08-10 19:24     ` Ross Zwisler
2018-08-10 19:26       ` Eric Sandeen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).