From: David Howells <dhowells@redhat.com>
To: Christian Brauner <christian@brauner.io>,
Steve French <sfrench@samba.org>
Cc: David Howells <dhowells@redhat.com>,
Paulo Alcantara <pc@manguebit.com>,
netfs@lists.linux.dev, linux-afs@lists.infradead.org,
linux-cifs@vger.kernel.org, linux-nfs@vger.kernel.org,
ceph-devel@vger.kernel.org, v9fs@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Paulo Alcantara <pc@manguebit.org>
Subject: [PATCH 10/13] netfs: Fix i_size updating
Date: Tue, 1 Jul 2025 17:38:45 +0100 [thread overview]
Message-ID: <20250701163852.2171681-11-dhowells@redhat.com> (raw)
In-Reply-To: <20250701163852.2171681-1-dhowells@redhat.com>
Fix the updating of i_size, particularly in regard to the completion of DIO
writes and especially async DIO writes by using a lock.
The bug is triggered occasionally by the generic/207 xfstest as it chucks a
bunch of AIO DIO writes at the filesystem and then checks that fstat()
returns a reasonable st_size as each completes.
The problem is that netfs is trying to do "if new_size > inode->i_size,
update inode->i_size" sort of thing but without a lock around it.
This can be seen with cifs, but shouldn't be seen with kafs because kafs
serialises modification ops on the client whereas cifs sends the requests
to the server as they're generated and lets the server order them.
Fixes: 153a9961b551 ("netfs: Implement unbuffered/DIO write support")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
fs/netfs/buffered_write.c | 2 ++
fs/netfs/direct_write.c | 8 ++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
index 72a3e6db2524..b87ef3fe4ea4 100644
--- a/fs/netfs/buffered_write.c
+++ b/fs/netfs/buffered_write.c
@@ -64,6 +64,7 @@ static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
return;
}
+ spin_lock(&inode->i_lock);
i_size_write(inode, pos);
#if IS_ENABLED(CONFIG_FSCACHE)
fscache_update_cookie(ctx->cache, NULL, &pos);
@@ -77,6 +78,7 @@ static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
DIV_ROUND_UP(pos, SECTOR_SIZE),
inode->i_blocks + add);
}
+ spin_unlock(&inode->i_lock);
}
/**
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index fa9a5bf3c6d5..3efa5894b2c0 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -14,13 +14,17 @@ static void netfs_cleanup_dio_write(struct netfs_io_request *wreq)
struct inode *inode = wreq->inode;
unsigned long long end = wreq->start + wreq->transferred;
- if (!wreq->error &&
- i_size_read(inode) < end) {
+ if (wreq->error || end <= i_size_read(inode))
+ return;
+
+ spin_lock(&inode->i_lock);
+ if (end > i_size_read(inode)) {
if (wreq->netfs_ops->update_i_size)
wreq->netfs_ops->update_i_size(inode, end);
else
i_size_write(inode, end);
}
+ spin_unlock(&inode->i_lock);
}
/*
next prev parent reply other threads:[~2025-07-01 16:39 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-01 16:38 [PATCH 00/13] netfs, cifs: Fixes to retry-related code David Howells
2025-07-01 16:38 ` [PATCH 01/13] netfs: Fix hang due to missing case in final DIO read result collection David Howells
2025-07-01 16:38 ` [PATCH 02/13] netfs: Fix double put of request David Howells
2025-07-01 16:38 ` [PATCH 03/13] netfs: Provide helpers to perform NETFS_RREQ_IN_PROGRESS flag wangling David Howells
2025-07-01 16:38 ` [PATCH 04/13] netfs: Fix looping in wait functions David Howells
2025-07-01 16:38 ` [PATCH 05/13] netfs: Fix ref leak on inserted extra subreq in write retry David Howells
2025-07-01 16:38 ` [PATCH 06/13] smb: client: set missing retry flag in smb2_writev_callback() David Howells
2025-07-01 16:38 ` [PATCH 07/13] smb: client: set missing retry flag in cifs_readv_callback() David Howells
2025-07-01 16:38 ` [PATCH 08/13] smb: client: set missing retry flag in cifs_writev_callback() David Howells
2025-07-01 16:38 ` [PATCH 09/13] smb: client: fix warning when reconnecting channel David Howells
2025-07-01 17:07 ` Steve French
2025-07-01 16:38 ` David Howells [this message]
2025-07-01 16:38 ` [PATCH 11/13] netfs: Merge i_size update functions David Howells
2025-07-01 16:38 ` [PATCH 12/13] netfs: Renumber the NETFS_RREQ_* flags to make traces easier to read David Howells
2025-07-01 16:38 ` [PATCH 13/13] netfs: Update tracepoints in a number of ways David Howells
2025-07-09 10:26 ` [PATCH 00/13] netfs, cifs: Fixes to retry-related code Max Kellermann
2025-07-09 13:01 ` David Howells
2025-07-09 19:04 ` Max Kellermann
2025-07-09 20:22 ` David Howells
2025-07-09 21:44 ` Max Kellermann
2025-07-10 10:47 ` David Howells
2025-07-10 11:17 ` David Howells
2025-07-10 13:41 ` Max Kellermann
2025-07-10 15:32 ` David Howells
2025-07-10 16:31 ` David Howells
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=20250701163852.2171681-11-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=ceph-devel@vger.kernel.org \
--cc=christian@brauner.io \
--cc=linux-afs@lists.infradead.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=netfs@lists.linux.dev \
--cc=pc@manguebit.com \
--cc=pc@manguebit.org \
--cc=sfrench@samba.org \
--cc=v9fs@lists.linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox