* [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; 6+ 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;
}
^ permalink raw reply related [flat|nested] 6+ 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; 6+ 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
^ permalink raw reply related [flat|nested] 6+ 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; 6+ messages in thread
From: Jan Kara @ 2018-08-09 8:57 UTC (permalink / raw)
To: Dave Jiang
Cc: tytso, darrick.wong, jack, zwisler, linux-nvdimm, david,
linux-xfs, linux-fsdevel, lczerner, 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
^ permalink raw reply [flat|nested] 6+ 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; 6+ messages in thread
From: Dave Jiang @ 2018-08-09 16:21 UTC (permalink / raw)
To: Jan Kara
Cc: tytso, darrick.wong, zwisler, linux-nvdimm, david, linux-xfs,
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
>>
^ permalink raw reply [flat|nested] 6+ 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; 6+ 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;
> }
>
^ permalink raw reply [flat|nested] 6+ 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; 6+ messages in thread
From: Jan Kara @ 2018-09-11 15:26 UTC (permalink / raw)
To: sandeen
Cc: Dave Jiang, tytso, darrick.wong, jack, zwisler, linux-nvdimm,
david, linux-xfs, linux-fsdevel, lczerner, 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
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-09-11 20:26 UTC | newest]
Thread overview: 6+ 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
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).