Let's validate using generic_atomic_write_valid() in
ext4_file_write_iter() if the write request has IOCB_ATOMIC set.
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
fs/ext4/file.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index f14aed14b9cf..b06c5d34bbd2 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -692,6 +692,20 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (IS_DAX(inode))
return ext4_dax_write_iter(iocb, from);
#endif
+
+ if (iocb->ki_flags & IOCB_ATOMIC) {
+ size_t len = iov_iter_count(from);
+ int ret;
+
+ if (!IS_ALIGNED(len, EXT4_SB(inode->i_sb)->fs_awu_min) ||
+ len > EXT4_SB(inode->i_sb)->fs_awu_max)
+ return -EINVAL;
+
+ ret = generic_atomic_write_valid(iocb, from);
+ if (ret)
+ return ret;
+ }
+
if (iocb->ki_flags & IOCB_DIRECT)
return ext4_dio_write_iter(iocb, from);
else
--
2.46.0
On 25/10/2024 04:45, Ritesh Harjani (IBM) wrote:
> Let's validate using generic_atomic_write_valid() in
> ext4_file_write_iter() if the write request has IOCB_ATOMIC set.
>
> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> ---
> fs/ext4/file.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
> index f14aed14b9cf..b06c5d34bbd2 100644
> --- a/fs/ext4/file.c
> +++ b/fs/ext4/file.c
> @@ -692,6 +692,20 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
> if (IS_DAX(inode))
> return ext4_dax_write_iter(iocb, from);
> #endif
> +
> + if (iocb->ki_flags & IOCB_ATOMIC) {
> + size_t len = iov_iter_count(from);
> + int ret;
> +
> + if (!IS_ALIGNED(len, EXT4_SB(inode->i_sb)->fs_awu_min) ||
> + len > EXT4_SB(inode->i_sb)->fs_awu_max)
> + return -EINVAL;
this looks ok, but the IS_ALIGNED() check looks odd. I am not sure why
you don't just check that fs_awu_max >= len >= fs_awu_min
> +
> + ret = generic_atomic_write_valid(iocb, from);
> + if (ret)
> + return ret;
> + }
> +
> if (iocb->ki_flags & IOCB_DIRECT)
> return ext4_dio_write_iter(iocb, from);
> else
John Garry <john.g.garry@oracle.com> writes:
> On 25/10/2024 04:45, Ritesh Harjani (IBM) wrote:
>> Let's validate using generic_atomic_write_valid() in
>> ext4_file_write_iter() if the write request has IOCB_ATOMIC set.
>>
>> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
>> ---
>> fs/ext4/file.c | 14 ++++++++++++++
>> 1 file changed, 14 insertions(+)
>>
>> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
>> index f14aed14b9cf..b06c5d34bbd2 100644
>> --- a/fs/ext4/file.c
>> +++ b/fs/ext4/file.c
>> @@ -692,6 +692,20 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
>> if (IS_DAX(inode))
>> return ext4_dax_write_iter(iocb, from);
>> #endif
>> +
>> + if (iocb->ki_flags & IOCB_ATOMIC) {
>> + size_t len = iov_iter_count(from);
>> + int ret;
>> +
>> + if (!IS_ALIGNED(len, EXT4_SB(inode->i_sb)->fs_awu_min) ||
>> + len > EXT4_SB(inode->i_sb)->fs_awu_max)
>> + return -EINVAL;
>
> this looks ok, but the IS_ALIGNED() check looks odd. I am not sure why
> you don't just check that fs_awu_max >= len >= fs_awu_min
>
I guess this was just a stricter check. But we anyways have power_of_2
and other checks in generic_atomic_write_valid(). So it does not matter.
I can change this in v2.
Thanks!
>> +
>> + ret = generic_atomic_write_valid(iocb, from);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> if (iocb->ki_flags & IOCB_DIRECT)
>> return ext4_dio_write_iter(iocb, from);
>> else
-ritesh
On Fri, Oct 25, 2024 at 04:03:02PM +0530, Ritesh Harjani wrote:
> John Garry <john.g.garry@oracle.com> writes:
>
> > On 25/10/2024 04:45, Ritesh Harjani (IBM) wrote:
> >> Let's validate using generic_atomic_write_valid() in
> >> ext4_file_write_iter() if the write request has IOCB_ATOMIC set.
> >>
> >> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> >> ---
> >> fs/ext4/file.c | 14 ++++++++++++++
> >> 1 file changed, 14 insertions(+)
> >>
> >> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
> >> index f14aed14b9cf..b06c5d34bbd2 100644
> >> --- a/fs/ext4/file.c
> >> +++ b/fs/ext4/file.c
> >> @@ -692,6 +692,20 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
> >> if (IS_DAX(inode))
> >> return ext4_dax_write_iter(iocb, from);
> >> #endif
> >> +
> >> + if (iocb->ki_flags & IOCB_ATOMIC) {
> >> + size_t len = iov_iter_count(from);
> >> + int ret;
> >> +
> >> + if (!IS_ALIGNED(len, EXT4_SB(inode->i_sb)->fs_awu_min) ||
> >> + len > EXT4_SB(inode->i_sb)->fs_awu_max)
> >> + return -EINVAL;
> >
> > this looks ok, but the IS_ALIGNED() check looks odd. I am not sure why
> > you don't just check that fs_awu_max >= len >= fs_awu_min
> >
>
> I guess this was just a stricter check. But we anyways have power_of_2
> and other checks in generic_atomic_write_valid(). So it does not matter.
>
> I can change this in v2.
Also please fix the weird indenting in the if test:
if (len < EXT4_SB(inode->i_sb)->fs_awu_min) ||
len > EXT4_SB(inode->i_sb)->fs_awu_max)
return -EINVAL;
--D
> Thanks!
>
> >> +
> >> + ret = generic_atomic_write_valid(iocb, from);
> >> + if (ret)
> >> + return ret;
> >> + }
> >> +
> >> if (iocb->ki_flags & IOCB_DIRECT)
> >> return ext4_dio_write_iter(iocb, from);
> >> else
>
> -ritesh
>
"Darrick J. Wong" <djwong@kernel.org> writes:
> On Fri, Oct 25, 2024 at 04:03:02PM +0530, Ritesh Harjani wrote:
>> John Garry <john.g.garry@oracle.com> writes:
>>
>> > On 25/10/2024 04:45, Ritesh Harjani (IBM) wrote:
>> >> Let's validate using generic_atomic_write_valid() in
>> >> ext4_file_write_iter() if the write request has IOCB_ATOMIC set.
>> >>
>> >> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
>> >> ---
>> >> fs/ext4/file.c | 14 ++++++++++++++
>> >> 1 file changed, 14 insertions(+)
>> >>
>> >> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
>> >> index f14aed14b9cf..b06c5d34bbd2 100644
>> >> --- a/fs/ext4/file.c
>> >> +++ b/fs/ext4/file.c
>> >> @@ -692,6 +692,20 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
>> >> if (IS_DAX(inode))
>> >> return ext4_dax_write_iter(iocb, from);
>> >> #endif
>> >> +
>> >> + if (iocb->ki_flags & IOCB_ATOMIC) {
>> >> + size_t len = iov_iter_count(from);
>> >> + int ret;
>> >> +
>> >> + if (!IS_ALIGNED(len, EXT4_SB(inode->i_sb)->fs_awu_min) ||
>> >> + len > EXT4_SB(inode->i_sb)->fs_awu_max)
>> >> + return -EINVAL;
>> >
>> > this looks ok, but the IS_ALIGNED() check looks odd. I am not sure why
>> > you don't just check that fs_awu_max >= len >= fs_awu_min
>> >
>>
>> I guess this was just a stricter check. But we anyways have power_of_2
>> and other checks in generic_atomic_write_valid(). So it does not matter.
>>
>> I can change this in v2.
>
> Also please fix the weird indenting in the if test:
>
> if (len < EXT4_SB(inode->i_sb)->fs_awu_min) ||
> len > EXT4_SB(inode->i_sb)->fs_awu_max)
> return -EINVAL;
>
> --D
Got it!
-ritesh
>
>> Thanks!
>>
>> >> +
>> >> + ret = generic_atomic_write_valid(iocb, from);
>> >> + if (ret)
>> >> + return ret;
>> >> + }
>> >> +
>> >> if (iocb->ki_flags & IOCB_DIRECT)
>> >> return ext4_dio_write_iter(iocb, from);
>> >> else
>>
>> -ritesh
>>
© 2016 - 2026 Red Hat, Inc.