Re: [PATCH 1/3] cifs: use cifs_invalidate_cache() in cifs_do_truncate() for O_TRUNC
Frank Sorenson <[email protected]> Wed, 29 Jul 2026 08:52:45 -0500
| Newsgroups | org.kernel.vger.linux-cifs,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
Hi Huiwen,
Okay, that makes sense. Thanks for explaining further. Let me work on
that.
Frank
On 7/28/26 11:20 PM, Huiwen He wrote:
> Hi Frank,
>
> Patch 1 handles the quiescent-cookie case, but the cookie is not
> guaranteed to be quiescent here: another open may already keep it
> active. In that case, cifs_setsize() may still call
> fscache_resize_cookie() without i_rwsem before the invalidation.
>
> Maybe we could keep cifs_setsize() as the basic size/page-cache helper
> and add a wrapper for the paths holding i_rwsem, for example:
>
> /* Caller must hold inode->i_rwsem for write. */
> void cifs_resize_file_locked(struct inode *inode, loff_t offset)
> {
> struct fscache_cookie *cookie = cifs_inode_cookie(inode);
>
> lockdep_assert_held_write(&inode->i_rwsem);
>
> netfs_resize_file(netfs_inode(inode), offset, true);
> cifs_setsize(inode, offset);
>
> if (!cookie)
> return;
>
> fscache_use_cookie(cookie, true);
> fscache_resize_cookie(cookie, offset);
> cifs_fscache_unuse_inode_cookie(inode, true);
> }
>
> cifs_file_set_size(), smb2_duplicate_extents(), and both
> smb3_simple_falloc() branches could use this wrapper, since those
> paths already hold i_rwsem. O_TRUNC could continue to use cifs_setsize()
> followed by cifs_invalidate_cache(), without attempting a resize.
>
> Patches 2 and 3 look good to me.
>
> Thanks,
>
> Huiwen
>
>
> 在 2026/7/29 05:14, Frank Sorenson 写道:
>> cifs_setsize() now calls fscache_resize_cookie() since commit
>> fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()").
>> However, cifs_do_truncate() is called from cifs_open() before
>> fscache_use_cookie() activates the cookie, so the fscache cookie is
>> still quiescent at this point. fscache_begin_operation() requires
>> FSCACHE_COOKIE_IS_CACHING to be set and returns failure for a quiescent
>> cookie, making fscache_resize_cookie() a null operation in this path.
>>
>> The correct fix for this path is cifs_invalidate_cache(), which calls
>> fscache_invalidate(). Unlike fscache_resize_cookie(),
>> fscache_invalidate()
>> works on quiescent cookies: it unconditionally increments inval_counter
>> and sets FSCACHE_COOKIE_NO_DATA_TO_READ, ensuring that stale cached data
>> is not served once the cookie is later activated by
>> fscache_use_cookie().
>>
>> Truncation to zero leaves no valid cached data, making invalidation the
>> correct semantic. No inode lock is required for
>> cifs_invalidate_cache().
>>
>> Fixes: fa724e235cfd ("cifs: add fscache_resize_cookie() to
>> cifs_setsize()")
>> Cc: [email protected]
>> Cc: Huiwen He <[email protected]>
>> Cc: David Howells <[email protected]>
>> Cc: Paulo Alcantara <[email protected]>
>> Signed-off-by: Frank Sorenson <[email protected]>
>> ---
>> fs/smb/client/file.c | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
>> index ac89c1ba56b1..389083f9ce00 100644
>> --- a/fs/smb/client/file.c
>> +++ b/fs/smb/client/file.c
>> @@ -1016,6 +1016,7 @@ static int cifs_do_truncate(const unsigned int
>> xid, struct dentry *dentry)
>> if (!rc) {
>> netfs_resize_file(&cinode->netfs, 0, true);
>> cifs_setsize(inode, 0);
>> + cifs_invalidate_cache(inode, 0);
>> }
>> }
>> if (cfile)
>
--
Frank Sorenson
[email protected]
Principal Software Maintenance Engineer, filesystems
Red Hat