2024-01-24 14:28:25

by John Garry

[permalink] [raw]
Subject: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

For when an inode is enabled for atomic writes, set FMODE_CAN_ATOMIC_WRITE
flag.

Signed-off-by: John Garry <[email protected]>
---
fs/xfs/xfs_file.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index e33e5e13b95f..1375d0089806 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1232,6 +1232,8 @@ xfs_file_open(
return -EIO;
file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT;
+ if (xfs_inode_atomicwrites(XFS_I(inode)))
+ file->f_mode |= FMODE_CAN_ATOMIC_WRITE;
return generic_file_open(inode, file);
}

--
2.31.1



2024-02-02 18:06:32

by Darrick J. Wong

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On Wed, Jan 24, 2024 at 02:26:45PM +0000, John Garry wrote:
> For when an inode is enabled for atomic writes, set FMODE_CAN_ATOMIC_WRITE
> flag.
>
> Signed-off-by: John Garry <[email protected]>
> ---
> fs/xfs/xfs_file.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index e33e5e13b95f..1375d0089806 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -1232,6 +1232,8 @@ xfs_file_open(
> return -EIO;
> file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
> FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT;
> + if (xfs_inode_atomicwrites(XFS_I(inode)))

Shouldn't we check that the device supports AWU at all before turning on
the FMODE flag?

--D

> + file->f_mode |= FMODE_CAN_ATOMIC_WRITE;
> return generic_file_open(inode, file);
> }
>
> --
> 2.31.1
>
>

2024-02-05 10:27:27

by John Garry

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On 02/02/2024 18:06, Darrick J. Wong wrote:
> On Wed, Jan 24, 2024 at 02:26:45PM +0000, John Garry wrote:
>> For when an inode is enabled for atomic writes, set FMODE_CAN_ATOMIC_WRITE
>> flag.
>>
>> Signed-off-by: John Garry <[email protected]>
>> ---
>> fs/xfs/xfs_file.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
>> index e33e5e13b95f..1375d0089806 100644
>> --- a/fs/xfs/xfs_file.c
>> +++ b/fs/xfs/xfs_file.c
>> @@ -1232,6 +1232,8 @@ xfs_file_open(
>> return -EIO;
>> file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
>> FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT;
>> + if (xfs_inode_atomicwrites(XFS_I(inode)))

Note to self: This should also check if O_DIRECT is set

>
> Shouldn't we check that the device supports AWU at all before turning on
> the FMODE flag?

Can we easily get this sort of bdev info here?

Currently if we do try to issue an atomic write and AWU for the bdev is
zero, then XFS iomap code will reject it.

Thanks,
John

>
> --D
>
>> + file->f_mode |= FMODE_CAN_ATOMIC_WRITE;
>> return generic_file_open(inode, file);
>> }
>>
>> --
>> 2.31.1
>>
>>


2024-02-13 18:03:19

by Darrick J. Wong

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On Mon, Feb 05, 2024 at 10:26:43AM +0000, John Garry wrote:
> On 02/02/2024 18:06, Darrick J. Wong wrote:
> > On Wed, Jan 24, 2024 at 02:26:45PM +0000, John Garry wrote:
> > > For when an inode is enabled for atomic writes, set FMODE_CAN_ATOMIC_WRITE
> > > flag.
> > >
> > > Signed-off-by: John Garry <[email protected]>
> > > ---
> > > fs/xfs/xfs_file.c | 2 ++
> > > 1 file changed, 2 insertions(+)
> > >
> > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> > > index e33e5e13b95f..1375d0089806 100644
> > > --- a/fs/xfs/xfs_file.c
> > > +++ b/fs/xfs/xfs_file.c
> > > @@ -1232,6 +1232,8 @@ xfs_file_open(
> > > return -EIO;
> > > file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
> > > FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT;
> > > + if (xfs_inode_atomicwrites(XFS_I(inode)))
>
> Note to self: This should also check if O_DIRECT is set
>
> >
> > Shouldn't we check that the device supports AWU at all before turning on
> > the FMODE flag?
>
> Can we easily get this sort of bdev info here?
>
> Currently if we do try to issue an atomic write and AWU for the bdev is
> zero, then XFS iomap code will reject it.

Hmm. Well, if we move towards pushing all the hardware checks out of
xfs/iomap and into whatever goes on underneath submit_bio then I guess
we don't need to check device support here at all.

--D

> Thanks,
> John
>
> >
> > --D
> >
> > > + file->f_mode |= FMODE_CAN_ATOMIC_WRITE;
> > > return generic_file_open(inode, file);
> > > }
> > > --
> > > 2.31.1
> > >
> > >
>
>

2024-02-14 12:37:19

by John Garry

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On 13/02/2024 17:59, Darrick J. Wong wrote:
>>> Shouldn't we check that the device supports AWU at all before turning on
>>> the FMODE flag?
>> Can we easily get this sort of bdev info here?
>>
>> Currently if we do try to issue an atomic write and AWU for the bdev is
>> zero, then XFS iomap code will reject it.
> Hmm. Well, if we move towards pushing all the hardware checks out of
> xfs/iomap and into whatever goes on underneath submit_bio then I guess
> we don't need to check device support here at all.

Yeah, I have been thinking about this. But I was still planning on
putting a "bdev on atomic write" check here, as you mentioned.

But is this a proper method to access the bdev for an xfs inode:

STATIC bool
xfs_file_can_atomic_write(
struct xfs_inode *inode)
{
struct xfs_buftarg *target = xfs_inode_buftarg(inode);
struct block_device *bdev = target->bt_bdev;

if (!xfs_inode_atomicwrites(inode))
return false;

return bdev_can_atomic_write(bdev);
}

I do notice the dax check in xfs_bmbt_to_iomap() when assigning
iomap->bdev, which is creating some doubt?

Thanks,
John

2024-02-21 17:03:05

by Darrick J. Wong

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On Wed, Feb 14, 2024 at 12:36:40PM +0000, John Garry wrote:
> On 13/02/2024 17:59, Darrick J. Wong wrote:
> > > > Shouldn't we check that the device supports AWU at all before turning on
> > > > the FMODE flag?
> > > Can we easily get this sort of bdev info here?
> > >
> > > Currently if we do try to issue an atomic write and AWU for the bdev is
> > > zero, then XFS iomap code will reject it.
> > Hmm. Well, if we move towards pushing all the hardware checks out of
> > xfs/iomap and into whatever goes on underneath submit_bio then I guess
> > we don't need to check device support here at all.
>
> Yeah, I have been thinking about this. But I was still planning on putting a
> "bdev on atomic write" check here, as you mentioned.
>
> But is this a proper method to access the bdev for an xfs inode:
>
> STATIC bool
> xfs_file_can_atomic_write(
> struct xfs_inode *inode)
> {
> struct xfs_buftarg *target = xfs_inode_buftarg(inode);
> struct block_device *bdev = target->bt_bdev;
>
> if (!xfs_inode_atomicwrites(inode))
> return false;
>
> return bdev_can_atomic_write(bdev);
> }

There's still a TOCTOU race problem if the bdev gets reconfigured
between xfs_file_can_atomic_write and submit_bio.

However, if you're only using this to advertise the capability via statx
then I suppose that's fine -- userspace has to have some means of
discovering the ability at all. Userspace is also inherently racy.

> I do notice the dax check in xfs_bmbt_to_iomap() when assigning iomap->bdev,
> which is creating some doubt?

Do you mean this?

if (mapping_flags & IOMAP_DAX)
iomap->dax_dev = target->bt_daxdev;
else
iomap->bdev = target->bt_bdev;

The dax path wants dax_dev set so that it can do the glorified memcpy
operation, and it doesn't need (or want) a block device.

--D

> Thanks,
> John
>

2024-02-21 17:39:33

by John Garry

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On 21/02/2024 17:00, Darrick J. Wong wrote:
>>> Hmm. Well, if we move towards pushing all the hardware checks out of
>>> xfs/iomap and into whatever goes on underneath submit_bio then I guess
>>> we don't need to check device support here at all.
>> Yeah, I have been thinking about this. But I was still planning on putting a
>> "bdev on atomic write" check here, as you mentioned.
>>
>> But is this a proper method to access the bdev for an xfs inode:
>>
>> STATIC bool
>> xfs_file_can_atomic_write(
>> struct xfs_inode *inode)
>> {
>> struct xfs_buftarg *target = xfs_inode_buftarg(inode);
>> struct block_device *bdev = target->bt_bdev;
>>
>> if (!xfs_inode_atomicwrites(inode))
>> return false;
>>
>> return bdev_can_atomic_write(bdev);
>> }
> There's still a TOCTOU race problem if the bdev gets reconfigured
> between xfs_file_can_atomic_write and submit_bio.

If that is the case then a check in the bio submit path is required to
catch any such reconfigure problems - and we effectively have that in
this series.

I am looking at change some of these XFS bdev_can_atomic_write() checks,
but would still have a check in the bio submit path.

>
> However, if you're only using this to advertise the capability via statx
> then I suppose that's fine -- userspace has to have some means of
> discovering the ability at all. Userspace is also inherently racy.
>
>> I do notice the dax check in xfs_bmbt_to_iomap() when assigning iomap->bdev,
>> which is creating some doubt?
> Do you mean this?
>
> if (mapping_flags & IOMAP_DAX)
> iomap->dax_dev = target->bt_daxdev;
> else
> iomap->bdev = target->bt_bdev;
>
> The dax path wants dax_dev set so that it can do the glorified memcpy
> operation, and it doesn't need (or want) a block device.

Yes, so proper to use target->bt_bdev for checks for bdev atomic write
capability, right?

Thanks,
John


2024-02-24 04:18:42

by Darrick J. Wong

[permalink] [raw]
Subject: Re: [PATCH 6/6] fs: xfs: Set FMODE_CAN_ATOMIC_WRITE for FS_XFLAG_ATOMICWRITES set

On Wed, Feb 21, 2024 at 05:38:39PM +0000, John Garry wrote:
> On 21/02/2024 17:00, Darrick J. Wong wrote:
> > > > Hmm. Well, if we move towards pushing all the hardware checks out of
> > > > xfs/iomap and into whatever goes on underneath submit_bio then I guess
> > > > we don't need to check device support here at all.
> > > Yeah, I have been thinking about this. But I was still planning on putting a
> > > "bdev on atomic write" check here, as you mentioned.
> > >
> > > But is this a proper method to access the bdev for an xfs inode:
> > >
> > > STATIC bool
> > > xfs_file_can_atomic_write(
> > > struct xfs_inode *inode)
> > > {
> > > struct xfs_buftarg *target = xfs_inode_buftarg(inode);
> > > struct block_device *bdev = target->bt_bdev;
> > >
> > > if (!xfs_inode_atomicwrites(inode))
> > > return false;
> > >
> > > return bdev_can_atomic_write(bdev);
> > > }
> > There's still a TOCTOU race problem if the bdev gets reconfigured
> > between xfs_file_can_atomic_write and submit_bio.
>
> If that is the case then a check in the bio submit path is required to catch
> any such reconfigure problems - and we effectively have that in this series.
>
> I am looking at change some of these XFS bdev_can_atomic_write() checks, but
> would still have a check in the bio submit path.

<nod> "check in the bio submit path" sounds good to me. Adding in
redundant checks which are eventually gated on whatever submit_bio does
sounds like excessive overhead and layering violations.

> >
> > However, if you're only using this to advertise the capability via statx
> > then I suppose that's fine -- userspace has to have some means of
> > discovering the ability at all. Userspace is also inherently racy.
> >
> > > I do notice the dax check in xfs_bmbt_to_iomap() when assigning iomap->bdev,
> > > which is creating some doubt?
> > Do you mean this?
> >
> > if (mapping_flags & IOMAP_DAX)
> > iomap->dax_dev = target->bt_daxdev;
> > else
> > iomap->bdev = target->bt_bdev;
> >
> > The dax path wants dax_dev set so that it can do the glorified memcpy
> > operation, and it doesn't need (or want) a block device.
>
> Yes, so proper to use target->bt_bdev for checks for bdev atomic write
> capability, right?

Right. fsdax doesn't support atomic memcpy to pmem.

--D

>
> Thanks,
> John
>
>