From: "Darrick J. Wong" <djwong@kernel.org>
To: Chi Zhiling <chizhiling@163.com>
Cc: cem@kernel.org, linux-xfs@vger.kernel.org,
linux-kernel@vger.kernel.org, Chi Zhiling <chizhiling@kylinos.cn>
Subject: Re: [RFC PATCH 1/2] xfs: Add i_direct_mode to indicate the IO mode of inode
Date: Fri, 25 Apr 2025 08:12:08 -0700 [thread overview]
Message-ID: <20250425151208.GN25675@frogsfrogsfrogs> (raw)
In-Reply-To: <20250425103841.3164087-2-chizhiling@163.com>
On Fri, Apr 25, 2025 at 06:38:40PM +0800, Chi Zhiling wrote:
> From: Chi Zhiling <chizhiling@kylinos.cn>
>
> Direct IO already uses shared lock. If buffered write also uses
> shared lock, we need to ensure mutual exclusion between DIO and
> buffered IO. Therefore, Now introduce a flag `i_direct_mode` to
> indicate the IO mode currently used by the file. In practical
> scenarios, DIO and buffered IO are typically not used together,
> so this flag is usually not modified.
>
> Additionally, this flag is protected by the i_rwsem lock,
> which avoids the need to introduce new lock. When reading this
> flag, we need to hold a read lock, and when writing, a write lock
> is required.
>
> When a file that uses buffered IO starts using DIO, it needs to
> acquire a write lock to modify i_direct_mode, which will force DIO
> to wait for the previous IO to complete before starting. After
> acquiring the write lock to modify `i_direct_mode`, subsequent
> buffered IO will need to acquire the write lock again to modify
> i_direct_mode, which will force those IOs to wait for the current
> IO to complete.
>
> Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
> ---
> fs/xfs/xfs_file.c | 37 +++++++++++++++++++++++++++++++++----
> fs/xfs/xfs_inode.h | 6 ++++++
> 2 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 84f08c976ac4..a6f214f57238 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -206,7 +206,8 @@ xfs_ilock_iocb(
> static int
> xfs_ilock_iocb_for_write(
> struct kiocb *iocb,
> - unsigned int *lock_mode)
> + unsigned int *lock_mode,
> + bool is_dio)
Is an explicit flag required here, or can you determine directness from
IS_DAX() || (iocb->ki_flags & IOCB_DIRECT) ?
Hmm, I guess not, since a directio falling back to the pagecache for an
unaligned out of place write doesn't clear IOCB_DIRECT?
How does this new flag intersect with XFS_IREMAPPING? Are we actually
modelling three states here: bufferedio <-> directio <-> remapping?
> {
> ssize_t ret;
> struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp));
> @@ -226,6 +227,21 @@ xfs_ilock_iocb_for_write(
> return xfs_ilock_iocb(iocb, *lock_mode);
> }
>
> + /*
> + * If the i_direct_mode need update, take the iolock exclusively to write
> + * it.
> + */
> + if (ip->i_direct_mode != is_dio) {
> + if (*lock_mode == XFS_IOLOCK_SHARED) {
> + xfs_iunlock(ip, *lock_mode);
> + *lock_mode = XFS_IOLOCK_EXCL;
> + ret = xfs_ilock_iocb(iocb, *lock_mode);
> + if (ret)
> + return ret;
> + }
> + ip->i_direct_mode = is_dio;
> + }
> +
> return 0;
> }
>
> @@ -247,6 +263,19 @@ xfs_file_dio_read(
> ret = xfs_ilock_iocb(iocb, XFS_IOLOCK_SHARED);
> if (ret)
> return ret;
> +
> + if (!ip->i_direct_mode) {
> + xfs_iunlock(ip, XFS_IOLOCK_SHARED);
> + ret = xfs_ilock_iocb(iocb, XFS_IOLOCK_EXCL);
> + if (ret)
> + return ret;
> +
> + ip->i_direct_mode = 1;
> +
> + /* Update finished, now downgrade to shared lock */
> + xfs_ilock_demote(ip, XFS_IOLOCK_EXCL);
> + }
> +
> ret = iomap_dio_rw(iocb, to, &xfs_read_iomap_ops, NULL, 0, NULL, 0);
> xfs_iunlock(ip, XFS_IOLOCK_SHARED);
>
> @@ -680,7 +709,7 @@ xfs_file_dio_write_aligned(
> unsigned int iolock = XFS_IOLOCK_SHARED;
> ssize_t ret;
>
> - ret = xfs_ilock_iocb_for_write(iocb, &iolock);
> + ret = xfs_ilock_iocb_for_write(iocb, &iolock, true);
> if (ret)
> return ret;
> ret = xfs_file_write_checks(iocb, from, &iolock, ac);
> @@ -767,7 +796,7 @@ xfs_file_dio_write_unaligned(
> flags = IOMAP_DIO_FORCE_WAIT;
> }
>
> - ret = xfs_ilock_iocb_for_write(iocb, &iolock);
> + ret = xfs_ilock_iocb_for_write(iocb, &iolock, true);
> if (ret)
> return ret;
>
> @@ -898,7 +927,7 @@ xfs_file_buffered_write(
>
> write_retry:
> iolock = XFS_IOLOCK_EXCL;
> - ret = xfs_ilock_iocb(iocb, iolock);
> + ret = xfs_ilock_iocb_for_write(iocb, &iolock, false);
> if (ret)
> return ret;
>
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index eae0159983ca..04f6c4174fab 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -51,6 +51,12 @@ typedef struct xfs_inode {
> uint16_t i_checked;
> uint16_t i_sick;
>
> + /*
> + * Indicates the current IO mode of this inode, (DIO/buffered IO)
> + * protected by i_rwsem lock.
> + */
> + uint32_t i_direct_mode;
Yeesh, a whole u32 to encode a single bit. Can you use i_flags instead?
--D
> +
> spinlock_t i_flags_lock; /* inode i_flags lock */
> /* Miscellaneous state. */
> unsigned long i_flags; /* see defined flags below */
> --
> 2.43.0
>
>
next prev parent reply other threads:[~2025-04-25 15:12 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-25 10:38 [RFC PATCH 0/2] Implement concurrent buffered write with folio lock Chi Zhiling
2025-04-25 10:38 ` [RFC PATCH 1/2] xfs: Add i_direct_mode to indicate the IO mode of inode Chi Zhiling
2025-04-25 15:12 ` Darrick J. Wong [this message]
2025-04-26 1:28 ` Chi Zhiling
2025-04-25 10:38 ` [RFC PATCH 2/2] xfs: Enable concurrency when writing within single block Chi Zhiling
2025-04-25 15:15 ` Darrick J. Wong
2025-04-26 1:34 ` Chi Zhiling
2025-04-30 2:05 ` [RFC PATCH 0/2] Implement concurrent buffered write with folio lock Dave Chinner
2025-04-30 9:03 ` Chi Zhiling
2025-04-30 23:45 ` Dave Chinner
2025-05-01 23:57 ` Chi Zhiling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250425151208.GN25675@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=cem@kernel.org \
--cc=chizhiling@163.com \
--cc=chizhiling@kylinos.cn \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.