From nobody Sun Feb 8 09:27:26 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.2]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EF47D2405F8; Fri, 25 Apr 2025 10:57:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745578635; cv=none; b=KgdLw/cJWWiLtZdIqyzoNg8sGN1oj+LHbhtf/T9p29gQwHXkR3TVQBuZe8w9nmNMT9sWbJLMKfrIpaYNcFqtSLfyO9snW52Z+vrB0DE63N2A5gv8mqbr9dqygcqJEZyETKwu6aR4JDI7KvXYbnqYYP/BN2HLZ++The/Bqit60Jk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745578635; c=relaxed/simple; bh=YPTBCelIk0A8i2QhKhdm8JqpQG5uD+FpwDp+nUFc+Ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oPr6sOPNx59IQeIbyBQGtzHQAKKCukV4eUJZ/fACyURCT4Uj6zZ3fI4sVO1WZKeVWHPYMJdCH3h+3QFr/HlinaBf7z+yctf36zw/iSMb1WGEkSzPJ27NTnFkTtbm0YKKrA7hFxWGvXHFJ1gz0uWyObaLB5SAJGgYrdlJsLllslg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=CelgIhzI; arc=none smtp.client-ip=117.135.210.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="CelgIhzI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=dfg4q eT5ji3cZsBk6SVgnJou8Q/FEs5TStRdhKywXVM=; b=CelgIhzI77LkubL3n83X2 pUKvTCcXAYkGITJq9cqSWeCu1au7n0XrHwsi5pX1gYLV+ljbxPhsLnoA5E8BgcDY xsgjF5MtBsDLxcnienZpIbygtRt8YRx8ZIibURhb3b4lHBGXBo7UNpngSB1EBPHr 5dpJvSYqORj6ShsxTjLclA= Received: from chi-Redmi-Book.. (unknown []) by gzsmtp4 (Coremail) with SMTP id PygvCgAHVbB1agtoLX64Ag--.54305S3; Fri, 25 Apr 2025 18:56:56 +0800 (CST) From: Chi Zhiling To: cem@kernel.org Cc: linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chi Zhiling Subject: [RFC PATCH 1/2] xfs: Add i_direct_mode to indicate the IO mode of inode Date: Fri, 25 Apr 2025 18:38:40 +0800 Message-ID: <20250425103841.3164087-2-chizhiling@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250425103841.3164087-1-chizhiling@163.com> References: <20250425103841.3164087-1-chizhiling@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: PygvCgAHVbB1agtoLX64Ag--.54305S3 X-Coremail-Antispam: 1Uf129KBjvJXoWxur47CF47tw1kGw1rKFWkCrg_yoWrGFyDpr saka90krs7tr9F9Fs7JF4UuwnxKay8Wr4UZF4I93W7uw45GrnI9r4IvF12qa1jqrsxZr4v vFs0kry5C3W7JFUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jeLvtUUUUU= X-CM-SenderInfo: hfkl6xxlol0wi6rwjhhfrp/1tbiKQQ6nWgLY22ergAAsX Content-Type: text/plain; charset="utf-8" From: Chi Zhiling 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 --- 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) { ssize_t ret; struct xfs_inode *ip =3D XFS_I(file_inode(iocb->ki_filp)); @@ -226,6 +227,21 @@ xfs_ilock_iocb_for_write( return xfs_ilock_iocb(iocb, *lock_mode); } =20 + /* + * If the i_direct_mode need update, take the iolock exclusively to write + * it. + */ + if (ip->i_direct_mode !=3D is_dio) { + if (*lock_mode =3D=3D XFS_IOLOCK_SHARED) { + xfs_iunlock(ip, *lock_mode); + *lock_mode =3D XFS_IOLOCK_EXCL; + ret =3D xfs_ilock_iocb(iocb, *lock_mode); + if (ret) + return ret; + } + ip->i_direct_mode =3D is_dio; + } + return 0; } =20 @@ -247,6 +263,19 @@ xfs_file_dio_read( ret =3D xfs_ilock_iocb(iocb, XFS_IOLOCK_SHARED); if (ret) return ret; + + if (!ip->i_direct_mode) { + xfs_iunlock(ip, XFS_IOLOCK_SHARED); + ret =3D xfs_ilock_iocb(iocb, XFS_IOLOCK_EXCL); + if (ret) + return ret; + + ip->i_direct_mode =3D 1; + + /* Update finished, now downgrade to shared lock */ + xfs_ilock_demote(ip, XFS_IOLOCK_EXCL); + } + ret =3D iomap_dio_rw(iocb, to, &xfs_read_iomap_ops, NULL, 0, NULL, 0); xfs_iunlock(ip, XFS_IOLOCK_SHARED); =20 @@ -680,7 +709,7 @@ xfs_file_dio_write_aligned( unsigned int iolock =3D XFS_IOLOCK_SHARED; ssize_t ret; =20 - ret =3D xfs_ilock_iocb_for_write(iocb, &iolock); + ret =3D xfs_ilock_iocb_for_write(iocb, &iolock, true); if (ret) return ret; ret =3D xfs_file_write_checks(iocb, from, &iolock, ac); @@ -767,7 +796,7 @@ xfs_file_dio_write_unaligned( flags =3D IOMAP_DIO_FORCE_WAIT; } =20 - ret =3D xfs_ilock_iocb_for_write(iocb, &iolock); + ret =3D xfs_ilock_iocb_for_write(iocb, &iolock, true); if (ret) return ret; =20 @@ -898,7 +927,7 @@ xfs_file_buffered_write( =20 write_retry: iolock =3D XFS_IOLOCK_EXCL; - ret =3D xfs_ilock_iocb(iocb, iolock); + ret =3D xfs_ilock_iocb_for_write(iocb, &iolock, false); if (ret) return ret; =20 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; =20 + /* + * Indicates the current IO mode of this inode, (DIO/buffered IO) + * protected by i_rwsem lock. + */ + uint32_t i_direct_mode; + spinlock_t i_flags_lock; /* inode i_flags lock */ /* Miscellaneous state. */ unsigned long i_flags; /* see defined flags below */ --=20 2.43.0 From nobody Sun Feb 8 09:27:26 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DA4BE4438B; Fri, 25 Apr 2025 10:57:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745578638; cv=none; b=jX4qx/5WVoiKYJHnaOgArdcYN6Qq5c4eQo0e3S5s4VRa9ypgg0WSaeaAMwQhCMYbssalIMqHouA/JmnrRiK/9Sq/Dz6LJqh961b8PghrPqB06VmlUzsgosb7SA7IFIj49jOSs1mKnGZmHZ4WAZY3D12+CisUxXrTQZ4lGfVz/dg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745578638; c=relaxed/simple; bh=Aq2C9REd9eMerPjlM2bo4vOa8FLEpQfONHKutZ31pdo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lIQvXLRbHkBr2IGZNlaX+TZWyilNE65SrtE0Hpo1aTYla9ygox5WKmdf33T1CPgjqvbIu06pUlbwErWbco/jmTYK9Xsih3ogrzM2dT/19FsE/RF7fDiP8g5VJ6sQhwNZ40UxzP/Z7I5xta7FAGqUTEif6cc5ABXaG03nwGycfyA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=ekS6cHyE; arc=none smtp.client-ip=220.197.31.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="ekS6cHyE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=pTVkQ MCUkaTY+UzZ0K9jTS+tVIl0x6eYM6tigXiHKaU=; b=ekS6cHyEcxrOoyiB7YO6r KD31sbTcIzBa0LcSP45QFFFPh/Y7JoOwaZfy0ZwmfgmAFtHoMZYRZLS7TdXr0g+Q SaBvk1lTwonUJa0BYIXOY1KOu6Ct3iGPPCfXnxHdwZ6vN/PWSdJcxpnPce9gslmy aK3x3vzC3gs3QJBmTv+vq8= Received: from chi-Redmi-Book.. (unknown []) by gzsmtp4 (Coremail) with SMTP id PygvCgAHVbB1agtoLX64Ag--.54305S4; Fri, 25 Apr 2025 18:56:59 +0800 (CST) From: Chi Zhiling To: cem@kernel.org Cc: linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org, Chi Zhiling Subject: [RFC PATCH 2/2] xfs: Enable concurrency when writing within single block Date: Fri, 25 Apr 2025 18:38:41 +0800 Message-ID: <20250425103841.3164087-3-chizhiling@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250425103841.3164087-1-chizhiling@163.com> References: <20250425103841.3164087-1-chizhiling@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: PygvCgAHVbB1agtoLX64Ag--.54305S4 X-Coremail-Antispam: 1Uf129KBjvJXoW7CF47GF1DXrWxtF4Dtry8Grg_yoW8uryxpr ZakayY9rZ2qw1xArn3JF15u343Kas7XFW2qryxur1xZ3WUGwsI93WSvr1Y9a1UtrZ7ZrW0 gF4vkry8Cw1jyr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j7wIDUUUUU= X-CM-SenderInfo: hfkl6xxlol0wi6rwjhhfrp/xtbBgBU6nWgLZlla6wAAsf Content-Type: text/plain; charset="utf-8" From: Chi Zhiling For unextending writes, we will only update the pagecache and extent. In this case, if our write occurs within a single block, that is, within a single folio, we don't need an exclusive lock to ensure the atomicity of the write, because we already have the folio lock. Signed-off-by: Chi Zhiling --- fs/xfs/xfs_file.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index a6f214f57238..8eaa98464328 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -914,6 +914,27 @@ xfs_file_dax_write( return ret; } =20 +#define offset_in_block(inode, p) ((unsigned long)(p) & (i_blocksize(inode= ) - 1)) + +static inline bool xfs_allow_concurrent( + struct kiocb *iocb, + struct iov_iter *from) +{ + struct inode *inode =3D iocb->ki_filp->f_mapping->host; + + /* Extending write? */ + if (iocb->ki_flags & IOCB_APPEND || + iocb->ki_pos >=3D i_size_read(inode)) + return false; + + /* Exceeds a block range? */ + if (iov_iter_count(from) > i_blocksize(inode) || + offset_in_block(inode, iocb->ki_pos) + iov_iter_count(from) > i_block= size(inode)) + return false; + + return true; +} + STATIC ssize_t xfs_file_buffered_write( struct kiocb *iocb, @@ -925,8 +946,12 @@ xfs_file_buffered_write( bool cleared_space =3D false; unsigned int iolock; =20 + if (xfs_allow_concurrent(iocb, from)) + iolock =3D XFS_IOLOCK_SHARED; + else + iolock =3D XFS_IOLOCK_EXCL; + write_retry: - iolock =3D XFS_IOLOCK_EXCL; ret =3D xfs_ilock_iocb_for_write(iocb, &iolock, false); if (ret) return ret; @@ -935,6 +960,13 @@ xfs_file_buffered_write( if (ret) goto out; =20 + if (iolock =3D=3D XFS_IOLOCK_SHARED && + iocb->ki_pos + iov_iter_count(from) > i_size_read(inode)) { + xfs_iunlock(ip, iolock); + iolock =3D XFS_IOLOCK_EXCL; + goto write_retry; + } + trace_xfs_file_buffered_write(iocb, from); ret =3D iomap_file_buffered_write(iocb, from, &xfs_buffered_write_iomap_ops, NULL); --=20 2.43.0