summaryrefslogtreecommitdiff
path: root/fs/smb/client/inode.c
AgeCommit message (Collapse)AuthorFilesLines
2026-08-24Merge tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linuxLinus Torvalds1-33/+57
Pull smb client updates from Paulo Alcantara: - clear sensitive data after use (stack and heap cryptographic keys/hashes) - file size and cache synchronization fixes (fscache cookie serialization and truncation handling) - protocol validation and buffer safety fixes (prevent OOB access and loff_t underflow) - metadata and POSIX attribute fixes (proper hard-link counts and setuid/setgid stripping) - DFS cache and unmount fixes (prevent target-hint UAF and unmount hangs) - general client improvements (fix read request leaks, stats loops, handle servers that don't support O_TMPFILE) * tag 'cifs-fixes-7.3-rc1' of https://git.manguebit.org/linux: (33 commits) cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0 smb: client: reject a tree connect response whose byte count is too small cifs: call pagecache_isize_extended() in cifs_setsize() when extending smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV smb: client: remove redundant NULL check before kfree() smb: client: restore the data_offset bound in is_valid_oplock_break() cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size() smb: client: Avoid leaking sensitive data to the heap in connect.c smb: client: Clear sensitive stack data in smb1encrypt.c smb: client: Clear sensitive stack data in cifsencrypt.c smb: client: Clear sensitive stack and heap data in smb2ops.c smb: client: Clear sensitive stack data in smb2transport.c Revert "cifs: remove all cifs files before kill super" smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr() smb: client: fix ALIGN() overflow in symlink_data() error context loop smb: client: simplify __build_path_from_dentry_optional_prefix() smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2 smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2() smb/client: decode reparse metadata using its payload type smb/client: preserve open info type across compound queries ...
2026-08-24cifs: call pagecache_isize_extended() in cifs_setsize() when extendingFrank Sorenson1-0/+2
cifs_setsize() calls truncate_pagecache() but skips pagecache_isize_extended() on extension. truncate_setsize() shows the correct pattern: i_size_write(inode, newsize); if (newsize > oldsize) pagecache_isize_extended(inode, oldsize, newsize); truncate_pagecache(inode, newsize); pagecache_isize_extended() zeroes the tail of the page straddling old EOF. Without it, dirty bytes in that region can be written back to the server, exposing stale data in the newly extended range. Cc: stable@vger.kernel.org Cc: David Howells <dhowells@redhat.com> Signed-off-by: Frank Sorenson <sorenson@redhat.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()Frank Sorenson1-0/+1
When the else branch of cifs_file_set_size() finds a writable file handle via find_writable_file(), it borrows tcon and server from the handle's tlink, attempts the handle-based set_file_size() RPC, and then releases the handle with cifsFileInfo_put(). If set_file_size() fails, execution falls through to the path-based fallback, which reuses the borrowed tcon and server under the "if (tcon == NULL)" guard. Since tcon is not NULL at that point, the guard is skipped. If cifsFileInfo_put() dropped the last reference on a tlink that was already removed from the tlink tree (TCON_LINK_IN_TREE cleared, as happens during reconnection or session teardown), cifs_put_tlink() will have freed tcon; the subsequent set_path_size() call is then a use-after-free. Setting tcon = NULL after cifsFileInfo_put() causes the existing guard to take the cifs_sb_tlink() path, which acquires a fresh reference for the path-based operation or fails cleanly if the session is gone. Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") Cc: stable@vger.kernel.org Cc: Paulo Alcantara <pc@manguebit.com> Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-24smb/client: decode reparse metadata using its payload typeZe Tan1-4/+5
cifs_open_info_data stores FILE_ALL_INFORMATION and SMB3 POSIX query information in a union. reparse_info_to_fattr() selects a union member from the mount mode, while several directory checks always read fi.Attributes. The metadata can instead come from an SMB2 CREATE response on a POSIX mount, or from a POSIX query while processing a reparse point. In those cases the mount mode and hard-coded fi accesses select the wrong union member. See the procedures below: cifs_nt_open smb2_open_file SMB2_open data->fi = SMB2 CREATE response data->contains_posix_file_info = false cifs_get_inode_info reparse_info_to_fattr if (tcon->posix_extensions) // true smb311_posix_info_to_fattr data->posix_fi // wrong union member smb311_posix_get_fattr smb2_query_path_info smb2_compound_op data->posix_fi = SMB3 POSIX query response data->contains_posix_file_info = true reparse_info_to_fattr data->fi.Attributes // wrong union member Add a common DOS attribute accessor and use contains_posix_file_info both for attribute reads and for the final fattr conversion. Signed-off-by: Ze Tan <tanze@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19smb/client: fix nlink of an overwritten open fileChenXiaoSong1-5/+6
Reproducer: 1. server: systemctl start ksmbd 2. client: mount with `posix` option mount -t cifs -o posix //${server_ip}/export /mnt 3. client: touch /mnt/file1 /mnt/file2 4. client: C program: int fd = open("/mnt/file2", O_RDONLY); 5. client: C program: rename("/mnt/file1", "/mnt/file2"); 6. client: C program: struct stat stbuf; fstat(fd, &stbuf); stbuf.st_nlink is 1, should be 0 This patch fixes xfstests generic/035 when mounted with `posix` option. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19cifs: remove dead size-update blocks in cifs_setattr_unix/nounixFrank Sorenson1-14/+0
Commit 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") introduced cifs_file_set_size(), which calls netfs_resize_file() and cifs_setsize() on success. cifs_setsize() calls i_size_write(), updating i_size to the new value. The subsequent blocks in both cifs_setattr_unix() and cifs_setattr_nounix(): if ((attrs->ia_valid & ATTR_SIZE) && attrs->ia_size != i_size_read(inode)) { truncate_setsize(inode, attrs->ia_size); netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true); fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size); } are therefore unreachable on the success path: attrs->ia_size == i_size_read(inode) always holds after cifs_file_set_size() succeeds. On the failure path, execution jumps to out/cifs_setattr_exit before reaching these blocks. truncate_setsize() and netfs_resize_file() are redundant with what cifs_file_set_size() already did; fscache_resize_cookie() was moved there by commit fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()"). Remove both dead blocks. Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Reviewed-by: Huiwen He <hehuiwen@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under ↵Frank Sorenson1-5/+19
i_rwsem cifs_setsize() calls fscache_resize_cookie() without holding i_rwsem. When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHING is set), fscache_resize_cookie() performs a real resize that requires i_rwsem held exclusively. If another file descriptor has the same inode open, fscache_use_cookie() was already called from that cifs_open(), making the cookie active. In that case, calling cifs_setsize() from cifs_do_truncate() (invoked from cifs_open() without i_rwsem) races against concurrent fscache I/O. Strip fscache_resize_cookie() from cifs_setsize(), making it a pure size/page-cache helper. Add cifs_resize_file_locked() for callers that already hold i_rwsem: it calls netfs_resize_file() and cifs_setsize(), then temporarily activates the cookie with fscache_use_cookie() to perform the resize under the lock, then deactivates it with cifs_fscache_unuse_inode_cookie(). Using fscache_use_cookie() before the resize ensures correctness whether or not another fd already holds the cookie active. Switch cifs_file_set_size(), smb2_duplicate_extents(), and both size- extension branches of smb3_simple_falloc() to the new wrapper; those paths already hold i_rwsem via VFS setattr, lock_two_nondirectories(), or cifs_fallocate() respectively. cifs_do_truncate() continues to call cifs_setsize() followed by cifs_invalidate_cache(), since it runs without i_rwsem. Fixes: fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()") Cc: stable@vger.kernel.org Cc: David Howells <dhowells@redhat.com> Cc: Paulo Alcantara <pc@manguebit.com> Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-19smb: client: clear setuid/setgid bit on write with cifsacl/modefromsid/posix ↵Jiangshan Yi1-5/+24
extensions When a file has the setuid or setgid bit set and is written to, the VFS strips those bits and issues a setattr with ATTR_KILL_SUID/ATTR_KILL_SGID together with an ATTR_MODE carrying the already-cleared mode. Both cifs_setattr_unix() and cifs_setattr_nounix() unconditionally dropped ATTR_MODE in that case: /* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; This is fine for the default mount, where the mode is only emulated via the DOS read-only attribute and cannot represent the setuid/setgid bits anyway. However, with the "cifsacl" or "modefromsid" mount options the mode is stored on the server through an ACL (id_mode_to_cifs_acl()), with the SMB3.1.1 POSIX extensions the mode is sent to the server directly, and with the SMB1 Unix extensions (cifs_setattr_unix) the mode is sent via CIFSSMBUnixSetPathInfo(). In all those cases dropping ATTR_MODE means the cleared mode is never pushed to the server, so the setuid/setgid bit survives the write. This is a security issue: on local filesystems the setuid bit is stripped when a file is written, but over these cifs.ko mounts the bit persists on the server, potentially allowing an unexpected privilege escalation on subsequent execution. Fix this in two places: 1. cifs_setattr_nounix(): only take the "skip mode change" shortcut when the mode is emulated via the DOS read-only attribute (i.e. neither cifsacl/modefromsid nor the SMB3.1.1 POSIX extensions are in effect), so that the cleared mode is propagated to the server in the ACL / POSIX cases. 2. cifs_setattr_unix(): this function is only called when Unix extensions are in effect, so the mode is always stored on the server. Remove the shortcut entirely so that the cleared mode is always pushed. Fixes: d32c4f2626ac ("CIFS: ignore mode change if it's just for clearing setuid/setgid bits") Cc: stable@vger.kernel.org Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
2026-08-17Merge tag 'vfs-7.3-rc1.misc' of ↵Linus Torvalds1-0/+7
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull misc vfs updates from Christian Brauner: "Bigger cleanups: - The lockref dead-count handling is tidied up. The open-coded check for a count below zero as the dead marker relies on information the caller should not have. - make put_mnt_ns() leave mounts connected. Destroying a mount namespace disconnected its mounts from their mount points. So a file descriptor still open on the parent of a mount point could be used to peek under it. Locked mounts were already kept connected to prevent exactly that. But a mount is only locked when its tree is copied across a user namespace boundary. So a mount namespace set up by a privileged component had no locked mounts and its mounts were disconnected. Passing UMOUNT_CONNECTED keeps every mount connected and prevents that bug. - vfs_prepare_mode() passes S_IFDIR for directories. I meant to fix that ago but didn't get to it. So now someone finally did it. This kills the exception where the mode could be 0 when a directory was created whereas every other creation operation passed it explicitly already. - move long delayed work for ufs, jffs2, hfsplus, hfs and affs from the per-cpu system_long_wq to the new unbound system_dfl_long_wq. None of that work relies on per-cpu state and the work item is enqueued with queue_delayed_work() whose timer is global anyway. So it may as well benefit from scheduler task placement. Smaller fixes and cleanups: - unlock_buffer() and journal_end_buffer_io_sync() use clear_and_wake_up_bit() - the pipe page pools are unified into a single per-pipe pool and the extra wake_up(rd_wait) is limited to EPOLLET consumers - eventpoll now computes its timer slack lazily in ep_poll() - shrink_dcache_for_umount() keeps making progress on busy roots - excess xarray nodes are freed in clear_inode() - romfs detects hard link cycles - the user path of nested backing files is fixed - pidfd holds exec_update_lock around the namespace ioctl - non-memcg-aware nr_cached_objects is skipped during memcg slab shrink - iomap_write_iter() always returns status - mangle_path() is renamed to seq_mangle_path() - inode timestamp accessors are annotated - new regression test for pipe->poll_usage. - a few documentation, kernel-doc and selftest fixes" * tag 'vfs-7.3-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (67 commits) selftests/namespaces: Fix racy pipe handshake in timens and pidns_separate selftests/epoll: add a regression test for pipe->poll_usage pipe: only enable the extra wake_up(rd_wait) for EPOLLET consumers pidfd: hold exec_update_lock around namespace ioctl fs: fix user path of nested backing files fs: remove stale inode_insert5() kernel-doc parameter fs: fix switch/case indentation in sysfs() syscall fs: document semantics of kstat::{uid,gid} fields dcache: keep shrink_dcache_for_umount() making progress on busy roots seq_file: rename mangle_path to seq_mangle_path nstree: add/fix struct ns_id_req kernel-doc member fields dcache: use lockref routines for dead count checks lockref: tidy up dead count handling initramfs: fix typo in reserve_initrd_mem comment fs/pipe: unify the page pools into a single per-pipe pool fs: annotate inode timestamp accessors eventpoll: compute timer slack lazily in ep_poll() selftests/filesystems: add mntns cleanup test put_mnt_ns(): leave mounts connected affs: Move long delayed work on system_dfl_long_wq ...
2026-07-27cifs: add fscache_resize_cookie() to cifs_setsize()Frank Sorenson1-0/+1
Several code paths update the VFS inode size by calling netfs_resize_file() and cifs_setsize(), but omit the corresponding fscache_resize_cookie() call, leaving the fscache cookie out of sync with the actual file size: - cifs_file_set_size() in inode.c: server-side truncation via setattr - cifs_do_truncate() in file.c: truncates to zero on O_TRUNC open - smb2_duplicate_extents() in smb2ops.c: file clone extending EOF - smb3_simple_falloc() in smb2ops.c: two branches that extend EOF via write-range and SMB2_set_eof respectively Since every caller of cifs_setsize() must resize the fscache cookie, add the call to cifs_setsize() itself, consistent with how truncate_pagecache() is already consolidated there. Fixes: 70431bfd825d ("cifs: Support fscache indexing rewrite") Fixes: 93a43155127f ("cifs: Fix missing set of remote_i_size") Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC") Fixes: 7a06d3b816d7 ("smb/client: emulate small EOF-extending mode 0 fallocate ranges") Cc: stable@vger.kernel.org Cc: David Howells <dhowells@redhat.com> Cc: Paulo Alcantara <pc@manguebit.org> Cc: Huiwen He <hehuiwen@kylinos.cn> Signed-off-by: Frank Sorenson <sorenson@redhat.com> Reviewed-by: Paulo Alcantara <pc@manguebit.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-27cifs: fix time_last_write stamp placement in setattr/truncate pathsFrank Sorenson1-4/+22
cifs_file_set_size() calls cifs_setsize() on success, which calls i_size_write(), updating i_size to the new value. The subsequent check attrs->ia_size != i_size_read() in both cifs_setattr_unix() and cifs_setattr_nounix() therefore always evaluates false after a successful cifs_file_set_size(), making the smp_store_release() of time_last_write dead code. The truncate path was unprotected against stale readdir size updates. Move the stamp to before the cifs_file_set_size() RPC call, guarded by attrs->ia_size != i_size_read() to exclude no-op same-size ftruncate(2) calls from stamping time_last_write unnecessarily. On the error path the stamp remains rather than being restored: restoring a stale snapshot (prev_tlw) could silently erase a concurrent _cifsFileInfo_put() close stamp if that close arrived between the READ_ONCE and the smp_store_release. readdir is suppressed until the stamp expires, which extends beyond one acregmax if the caller retries failed truncations. stat() is unaffected: the cifs_revalidate_dentry_attr() path calls cifs_fattr_to_inode() with from_readdir=false, which bypasses the time_last_write check in is_size_safe_to_change() entirely and always writes the authoritative QUERY_INFO result to i_size. Remove the now-unreachable stamp from the dead block in both functions. Fixes: e8a8d54c2d50 ("cifs: prevent readdir from changing file size due to stale directory metadata") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-21cifs: prevent readdir from changing file size due to stale directory metadataFrank Sorenson1-0/+6
Windows Server's directory enumeration metadata lags behind the actual file size after a write+close or rename. A concurrent readdir() in the window between close() returning to userspace and stat() being called overwrites the correct cached i_size with the stale server value, causing stat() to return the wrong size. Once _cifsFileInfo_put() removes the last writable handle from openFileList, is_size_safe_to_change() permits readdir to overwrite i_size. smb2_close_getattr() then stamps cifs_i->time = jiffies, making the corrupt cached value appear fresh to the next stat(). The existing check (see Fixes:) only blocked stale size updates while an active RW lease was held, not after the last writable handle closes. Add cifsInodeInfo->time_last_write, written via smp_store_release() at writable close and on setattr/truncate. is_size_safe_to_change() checks is_inode_writable() first (acquiring open_file_lock), then rejects a readdir size update if time_last_write falls within acregmax jiffies. The spinlock release in _cifsFileInfo_put() forms a store-release barrier that pairs with the spin_lock() (load-acquire) in is_inode_writable(), ensuring the subsequent smp_load_acquire() on time_last_write observes any update from a concurrent close(). When a size update is rejected and the server value differs from the cached one, cifs_i->time is cleared to force a fresh QUERY_INFO on the next stat(). readdir is also blocked from changing i_size while writable handles are open or an RW lease is held, even on direct-IO mounts. For deferred close (closetimeo > 0), time_last_write is refreshed at the actual server close in smb2_deferred_work_close() and in the cifs_close_deferred_file*() drain paths invoked by lease/oplock breaks and tcon teardown, anchoring the protection window to the real close time rather than the earlier userspace close. time_last_write == 0 skips the time_before() check to avoid false positives near boot on 32-bit systems where jiffies starts close to INITIAL_JIFFIES. Does not reproduce against Samba or with actimeo=0. Fixes: e4b61f3b1c67 ("cifs: prevent updating file size from server if we have a read/write lease") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-09cifs: Show reason why autodisabling serverino supportPali Rohár1-3/+4
Extend cifs_autodisable_serverino() function to print also text message why the function was called. The text message is printed just once for mount then autodisabling serverino support. Once the serverino support is disabled for mount it will not be re-enabled. So those text messages do not cause flooding logs. This change allows to debug issues why cifs.ko decide to turn off server inode number support and hence disable support for detection of hardlinks. Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-09smb/client: fix incorrect nlink returned by fstat()ChenXiaoSong1-0/+2
Reproducer: 1. mount -t cifs //${server_ip}/export /mnt 2. touch /mnt/file1; ln /mnt/file1 /mnt/file2; ln /mnt/file1 /mnt/file3 3. C program: int fd = open("/mnt/file1", O_RDONLY); 4. C program: struct stat stbuf; fstat(fd, &stbuf); stbuf.st_nlink is always 1, should be 3 Setting `unknown_nlink` to true in `SMB2_open()` triggers the `CIFS_FATTR_UNKNOWN_NLINK` flag in `cifs_open_info_to_fattr()`, which safely preserves the existing i_nlink in `cifs_nlink_fattr_to_inode()`. See the detailed procedure below: path_openat open_last_lookups lookup_open atomic_open cifs_atomic_open // dir->i_op->atomic_open cifs_lookup cifs_get_inode_info cifs_get_fattr smb2_query_path_info // server->ops->query_path_info smb2_compound_op SMB2_open_init case SMB2_OP_QUERY_INFO SMB2_query_info_init(FILE_ALL_INFORMATION,) cifs_open_info_to_fattr fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks) update_inode_info cifs_iget cifs_fattr_to_inode cifs_nlink_fattr_to_inode set_nlink(inode, fattr->cf_nlink) do_open vfs_open do_dentry_open cifs_open cifs_nt_open smb2_open_file // server->ops->open SMB2_open buf->unknown_nlink = true cifs_get_inode_info cifs_get_fattr cifs_open_info_to_fattr if (data->unknown_nlink) // true fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK update_inode_info cifs_fattr_to_inode cifs_nlink_fattr_to_inode if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) // true return // do not modify nlink Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-05smb: client: refactor cifs_revalidate_mapping() to use clear_and_wake_up_bit()Mehdi Hassan1-3/+1
In the `skip_invalidate:` path under `cifs_revalidate_mapping()`, the sequence of calls: clear_bit_unlock(); smp_mb__after_atomic(); wake_up_bit(); can be replaced exactly by `clear_and_wake_up_bit()`. The `clear_and_wake_up_bit()` helper function was introduced in 'commit 8236b0ae31c83 ("bdi: wake up concurrent wb_shutdown() callers.")' to replace equivalent instances of this sequence of operations. This substitution has been applied in multiple subsystems. Compile-tested with CONFIG_CIFS=y on x86_64, no new warnings present. Suggested-by: Agatha Isabelle Moreira <code@agatha.dev> Link: https://kernelnewbies.org/Beginner%20Cleanup%20and%20Refactor%20Tasks%20by%20Agatha%20Isabelle%20Moreira#task_010 Cc: Agatha Isabelle Moreira <code@agatha.dev> Signed-off-by: Mehdi Hassan <mehdi.h.business@pm.me> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-01vfs: pass S_IFDIR mode to vfs_prepare_mode()Jori Koolstra1-0/+7
There is a comment in vfs_prepare_mode() that says: Note that it's currently valid for @type to be 0 if a directory is created. Filesystems raise that flag individually and we need to check whether each filesystem can deal with receiving S_IFDIR from the vfs before we enforce a non-zero type. It is safe to do this clean-up except that three filesystems (fuse, cifs, and coda) forward the mkdir @mode unchanged to something outside the kernel. Mask S_IFDIR back out in coda_mkdir(), fuse_mkdir() and cifs_mkdir() so that what is sent outside the kernel is unchanged. Their maintainers can drop the mask once they have confirmed it is safe. Assisted-by: LLM Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260630105400.68459-2-jkoolstra@xs4all.nl Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-24smb/client: do not account EOF extension as allocationHuiwen He1-3/+10
cifs_setsize() updates the local inode size after SetEOF succeeds. It also used the new EOF as a local i_blocks estimate, but extending EOF does not prove that the intervening range was allocated. For example, after writing 1 MiB and then extending EOF to 10 MiB, the client can report the file as fully allocated even though the server still reports a much smaller AllocationSize: $ dd if=/dev/zero of=test bs=1M count=1 $ truncate -s 10M test && stat -c 'size=%s blocks=%b' test $ stat --cached=never -c 'size=%s blocks=%b' test client stat: size=10485760 blocks=20480 server stat: size=10485760 blocks=2056 client stat after revalidation: size=10485760 blocks=2056 A later attribute revalidation may correct i_blocks, but callers such as xfstests generic/495 invoke swapon immediately after truncate. The swapfile hole check can therefore observe the inflated local i_blocks value and accept a sparse file. Do not grow i_blocks from cifs_setsize() on EOF extension. Only clamp it on shrink; allocation growth must come from write completion or from server-reported AllocationSize. With this change, EOF extension no longer makes a sparse file appear fully allocated before the next attribute revalidation, and xfstests generic/495 no longer accepts it through the inflated local i_blocks value. Signed-off-by: Huiwen He <hehuiwen@kylinos.cn> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-06-24smb/client: fix chown/chgrp with SMB3 POSIX ExtensionsRalph Boehme1-1/+2
Ownership (chown) and group (chgrp) modifications were being ignored when mounting with SMB3 POSIX Extensions unless CIFS_MOUNT_CIFS_ACL or CIFS_MOUNT_MODE_FROM_SID were also explicitly set. Fix this by checking for posix_extensions in cifs_setattr_nounix() when updating UID and GID, ensuring that id_mode_to_cifs_acl() is called to map and set the ownership/group information on the server. Cc: stable@vger.kernel.org Signed-off-by: Ralph Boehme <slow@samba.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-06-18Merge tag 'v7.2-rc-part1-smb3-client-fixes' of ↵Linus Torvalds1-1/+29
git://git.samba.org/sfrench/cifs-2.6 Pull smb client updates from Steve French: - Three cleanup patches - Fix error return value in smb2_aead_req_alloc - Three compression fixes - Update i_blocks after write (fixes various xfstests) - Fix races in cifsd thread creation - Fix potential out of bounds read parsing security descriptors - Witness protocol fix - Fix umount bug - Mount fix - Fix cached directory entries on unlink/rmdir/rename * tag 'v7.2-rc-part1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb: client: Use more common code in SMB2_tcon() smb: client: Use more common error handling code in smb3_reconfigure() smb/client: Fix error code in smb2_aead_req_alloc() smb/client: clean up a type issue in cifs_xattr_get() smb/client: allow FS_IOC_SETFLAGS to clear compression smb/client: use writable handle for FS_IOC_SETFLAGS compression smb/client: always return a value for FS_IOC_GETFLAGS smb/client: update i_blocks after contiguous writes smb: client: fix races in cifsd thread creation cifs: validate full SID length in security descriptors smb: client: resolve SWN tcon from live registrations cifs: remove all cifs files before kill super smb: client: fix conflicting option validation for new mount API cifs: invalidate cfid on unlink/rename/rmdir
2026-06-15Merge tag 'vfs-7.2-rc1.inode' of ↵Linus Torvalds1-1/+1
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs inode updates from Christian Brauner: "This extends the lockless ->i_count handling. iput() could already decrement any value greater than one locklessly but acquiring a reference always required taking inode->i_lock. Now acquiring a reference is lockless as long as the count was already at least 1, i.e., only the 0->1 and 1->0 transitions take the lock. This avoids the lock for the common cases of nfs calling into the inode hash and btrfs using igrab(). Cleanup-wise icount_read_once() is added to line up with inode_state_read_once() and the open-coded ->i_count loads across the tree are converted, and ihold() is relocated and tidied up. On top of that some stale lock ordering annotations are retired from the inode hash code: iunique() no longer takes the hash lock since the inode hash became RCU-searchable and s_inode_list_lock is no longer taken under the hash lock either" * tag 'vfs-7.2-rc1.inode' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: retire stale lock ordering annotations from inode hash fs: allow lockless ->i_count bumps as long as it does not transition 0->1 fs: relocate and tidy up ihold() fs: add icount_read_once() and stop open-coding ->i_count loads
2026-06-14cifs: invalidate cfid on unlink/rename/rmdirShyam Prasad N1-1/+29
Today we do not invalidate the cached_dirent or the entire parent cfid when a dentry in a dir has been removed/moved. This change invalidates the parent cfid so that we don't serve directory contents from the cache. Cc: <stable@vger.kernel.org> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-05-12netfs: Fix potential for tearing in ->remote_i_size and ->zero_pointDavid Howells1-6/+8
Fix potential tearing in using ->remote_i_size and ->zero_point by copying i_size_read() and i_size_write() and using the same seqcount as for i_size. We need to make sure that netfslib and the filesystems that use it always hold i_lock whilst updating any of the sizes to prevent i_size_seqcount from getting corrupted. Fixes: 4058f742105e ("netfs: Keep track of the actual remote file size") Fixes: 100ccd18bb41 ("netfs: Optimise away reads above the point at which there can be no data") Closes: https://sashiko.dev/#/patchset/20260414082004.3756080-1-dhowells%40redhat.com Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260512123404.719402-6-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11fs: add icount_read_once() and stop open-coding ->i_count loadsMateusz Guzik1-1/+1
Similarly to inode_state_read_once(), it makes the caller spell out they acknowledge instability of the returned value. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://patch.msgid.link/20260421182538.1215894-2-mjguzik@gmail.com Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-04-21Merge tag 'pull-dcache-busy-wait' of ↵Linus Torvalds1-1/+1
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull dcache busy loop updates from Al Viro: "Fix livelocks in shrink_dcache_tree() If shrink_dcache_tree() finds a dentry in the middle of being killed by another thread, it has to wait until the victim finishes dying, gets detached from the tree and ceases to pin its parent. The way we used to deal with that amounted to busy-wait; unfortunately, it's not just inefficient but can lead to reliably reproducible hard livelocks. Solved by having shrink_dentry_tree() attach a completion to such dentry, with dentry_unlist() calling complete() on all objects attached to it. With a bit of care it can be done without growing struct dentry or adding overhead in normal case" * tag 'pull-dcache-busy-wait' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: get rid of busy-waiting in shrink_dcache_tree() dcache.c: more idiomatic "positives are not allowed" sanity checks struct dentry: make ->d_u anonymous for_each_alias(): helper macro for iterating through dentries of given inode
2026-04-10smb: client: add support for O_TMPFILEPaulo Alcantara1-1/+2
Implement O_TMPFILE support for SMB2+ in the CIFS client. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: David Howells <dhowells@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: linux-fsdevel@vger.kernel.org Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2026-04-02for_each_alias(): helper macro for iterating through dentries of given inodeAl Viro1-1/+1
Most of the places using d_alias are loops iterating through all aliases for given inode; introduce a helper macro (for_each_alias(dentry, inode)) and convert open-coded instances of such loop to it. They are easier to read that way and it reduces the noise on the next steps. You _must_ hold inode->i_lock over that thing. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-03-19smb: client: fix generic/694 due to wrong ->i_blocksPaulo Alcantara1-15/+6
When updating ->i_size, make sure to always update ->i_blocks as well until we query new allocation size from the server. generic/694 was failing because smb3_simple_falloc() was missing the update of ->i_blocks after calling cifs_setsize(). So, fix this by updating ->i_blocks directly in cifs_setsize(), so all places that call it doesn't need to worry about updating ->i_blocks later. Reported-by: Shyam Prasad N <sprasad@microsoft.com> Closes: https://lore.kernel.org/r/CANT5p=rqgRwaADB=b_PhJkqXjtfq3SFv41SSTXSVEHnuh871pA@mail.gmail.com Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2026-03-11smb: client: fix open handle lookup in cifs_open()Paulo Alcantara1-3/+3
When looking up open handles to be re-used in cifs_open(), calling cifs_get_{writable,readable}_path() is wrong as it will look up for the first matching open handle, and if @file->f_flags doesn't match, it will ignore the remaining open handles in cifsInodeInfo::openFileList that might potentially match @file->f_flags. For writable and readable handles, fix this by calling __cifs_get_writable_file() and __find_readable_file(), respectively, with FIND_OPEN_FLAGS set. With the patch, the following program ends up with two opens instead of three sent over the wire. ``` #define _GNU_SOURCE #include <unistd.h> #include <string.h> #include <fcntl.h> int main(int argc, char *argv[]) { int fd; fd = open("/mnt/1/foo", O_CREAT | O_WRONLY | O_TRUNC, 0664); close(fd); fd = open("/mnt/1/foo", O_DIRECT | O_WRONLY); close(fd); fd = open("/mnt/1/foo", O_WRONLY); close(fd); fd = open("/mnt/1/foo", O_DIRECT | O_WRONLY); close(fd); return 0; } ``` ``` $ mount.cifs //srv/share /mnt/1 -o ... $ gcc test.c && ./a.out ``` Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Cc: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2026-02-26smb: client: use atomic_t for mnt_cifs_flagsPaulo Alcantara1-68/+74
Use atomic_t for cifs_sb_info::mnt_cifs_flags as it's currently accessed locklessly and may be changed concurrently in mount/remount and reconnect paths. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds1-5/+5
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook1-6/+5
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-08cifs: SMB1 split: Split SMB1 protocol defs into smb1pdu.hDavid Howells1-1/+0
Split SMB1 protocol defs into smb1pdu.h. This should perhaps go in the common/ directory. Signed-off-by: David Howells <dhowells@redhat.com> cc: Steve French <sfrench@samba.org> cc: Paulo Alcantara <pc@manguebit.org> cc: Enzo Matsumiya <ematsumiya@suse.de> cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-kernel@vger.kernel.org Acked-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-12-05cifs: Add a tracepoint to log EIO errorsDavid Howells1-7/+7
Add a tracepoint to log EIO errors and give it the capacity to convey up to two integers of information. This is then wrapped with three functions: int smb_EIO(enum smb_eio_trace trace) int smb_EIO1(enum smb_eio_trace trace, unsigned long info) int smb_EIO2(enum smb_eio_trace trace, unsigned long info, unsigned long info2) depending on how many bits of info are desired to be logged with any particular trace. The functions all return -EIO and can be used in place of -EIO. The trace argument is an enum value that gets translated to a string when the trace is printed. This makes is easier to log EIO instances when the client is under high load than turning on a printk wrapper such as cifs_dbg(). Granted, EIO could have its own separate EIO printing since EIO shouldn't happen. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-12-03Merge tag 'v6.19-rc-smb-fixes' of git://git.samba.org/ksmbdLinus Torvalds1-2/+2
Pull smb client and server updates from Steve French: - server fixes: - IPC use after free locking fix - fix locking bug in delete paths - fix use after free in disconnect - fix underflow in locking check - error mapping improvement - socket listening improvement - return code mapping fixes - crypto improvements (use default libraries) - cleanup patches: - netfs - client checkpatch cleanup - server cleanup - move server/client duplicate code to common code - fix some defines to better match protocol specification - smbdirect (RDMA) fixes - client debugging improvements for leases * tag 'v6.19-rc-smb-fixes' of git://git.samba.org/ksmbd: (44 commits) cifs: Use netfs_alloc/free_folioq_buffer() smb: client: show smb lease key in open_dirs output smb: client: show smb lease key in open_files output ksmbd: ipc: fix use-after-free in ipc_msg_send_request smb: client: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smbd_conn_upcall() smb: server: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smb_direct_cm_handler() smb: smbdirect: introduce SMBDIRECT_CHECK_STATUS_{WARN,DISCONNECT}() smb: smbdirect: introduce SMBDIRECT_DEBUG_ERR_PTR() helper ksmbd: vfs: fix race on m_flags in vfs_cache ksmbd: Replace strcpy + strcat to improve convert_to_nt_pathname smb: move FILE_SYSTEM_ATTRIBUTE_INFO to common/fscc.h ksmbd: implement error handling for STATUS_INFO_LENGTH_MISMATCH in smb server ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency ksmbd: server: avoid busy polling in accept loop smb: move create_durable_reconn to common/smb2pdu.h smb: fix some warnings reported by scripts/checkpatch.pl smb: do some cleanups smb: move FILE_SYSTEM_SIZE_INFO to common/fscc.h smb: move some duplicate struct definitions to common/fscc.h smb: move list of FileSystemAttributes to common/fscc.h ...
2025-12-01Merge tag 'vfs-6.19-rc1.fs_header' of ↵Linus Torvalds1-0/+1
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull fs header updates from Christian Brauner: "This contains initial work to start splitting up fs.h. Begin the long-overdue work of splitting up the monolithic fs.h header. The header has grown to over 3000 lines and includes types and functions for many different subsystems, making it difficult to navigate and causing excessive compilation dependencies. This series introduces new focused headers for superblock-related code: - Rename fs_types.h to fs_dirent.h to better reflect its actual content (directory entry types) - Add fs/super_types.h containing superblock type definitions - Add fs/super.h containing superblock function declarations This is the first step in a longer effort to modularize the VFS headers. Cleanups: - Inode Field Layout Optimization (Mateusz Guzik) Move inode fields used during fast path lookup closer together to improve cache locality during path resolution. - current_umask() Optimization (Mateusz Guzik) Inline current_umask() and move it to fs_struct.h. This improves performance by avoiding function call overhead for this frequently-used function, and places it in a more appropriate header since it operates on fs_struct" * tag 'vfs-6.19-rc1.fs_header' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: move inode fields used during fast path lookup closer together fs: inline current_umask() and move it to fs_struct.h fs: add fs/super.h header fs: add fs/super_types.h header fs: rename fs_types.h to fs_dirent.h
2025-12-01Merge tag 'vfs-6.19-rc1.inode' of ↵Linus Torvalds1-7/+7
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs inode updates from Christian Brauner: "Features: - Hide inode->i_state behind accessors. Open-coded accesses prevent asserting they are done correctly. One obvious aspect is locking, but significantly more can be checked. For example it can be detected when the code is clearing flags which are already missing, or is setting flags when it is illegal (e.g., I_FREEING when ->i_count > 0) - Provide accessors for ->i_state, converts all filesystems using coccinelle and manual conversions (btrfs, ceph, smb, f2fs, gfs2, overlayfs, nilfs2, xfs), and makes plain ->i_state access fail to compile - Rework I_NEW handling to operate without fences, simplifying the code after the accessor infrastructure is in place Cleanups: - Move wait_on_inode() from writeback.h to fs.h - Spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb for clarity - Cosmetic fixes to LRU handling - Push list presence check into inode_io_list_del() - Touch up predicts in __d_lookup_rcu() - ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage - Assert on ->i_count in iput_final() - Assert ->i_lock held in __iget() Fixes: - Add missing fences to I_NEW handling" * tag 'vfs-6.19-rc1.inode' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (22 commits) dcache: touch up predicts in __d_lookup_rcu() fs: push list presence check into inode_io_list_del() fs: cosmetic fixes to lru handling fs: rework I_NEW handling to operate without fences fs: make plain ->i_state access fail to compile xfs: use the new ->i_state accessors nilfs2: use the new ->i_state accessors overlayfs: use the new ->i_state accessors gfs2: use the new ->i_state accessors f2fs: use the new ->i_state accessors smb: use the new ->i_state accessors ceph: use the new ->i_state accessors btrfs: use the new ->i_state accessors Manual conversion to use ->i_state accessors of all places not covered by coccinelle Coccinelle-based conversion to use ->i_state accessors fs: provide accessors for ->i_state fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb fs: move wait_on_inode() from writeback.h to fs.h fs: add missing fences to I_NEW handling ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage ...
2025-11-30smb: move some duplicate struct definitions to common/fscc.hChenXiaoSong1-2/+2
Modify the following places: - smb2_file_ntwrk_info -> smb2_file_network_open_info - struct filesystem_device_info -> FILE_SYSTEM_DEVICE_INFO - struct file_directory_info -> FILE_DIRECTORY_INFO - struct file_full_directory_info -> FILE_FULL_DIRECTORY_INFO - struct file_both_directory_info -> FILE_BOTH_DIRECTORY_INFO - struct file_id_full_dir_info -> FILE_ID_FULL_DIR_INFO - struct filesystem_posix_info -> FILE_SYSTEM_POSIX_INFO The fields of these structures are exactly the same on both client and server, so move duplicate definitions to common header file. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-11-05fs: inline current_umask() and move it to fs_struct.hMateusz Guzik1-0/+1
There is no good reason to have this as a func call, other than avoiding the churn of adding fs_struct.h as needed. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://patch.msgid.link/20251104170448.630414-1-mjguzik@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-10-23smb: client: get rid of d_drop() in cifs_do_rename()Paulo Alcantara1-4/+1
There is no need to force a lookup by unhashing the moved dentry after successfully renaming the file on server. The file metadata will be re-fetched from server, if necessary, in the next call to ->d_revalidate() anyways. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: David Howells <dhowells@redhat.com> Cc: stable@vger.kernel.org Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-10-20smb: use the new ->i_state accessorsMateusz Guzik1-7/+7
Change generated with coccinelle and fixed up by hand as appropriate. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-10-15smb: client: Fix refcount leak for cifs_sb_tlinkShuhao Fu1-2/+4
Fix three refcount inconsistency issues related to `cifs_sb_tlink`. Comments for `cifs_sb_tlink` state that `cifs_put_tlink()` needs to be called after successful calls to `cifs_sb_tlink()`. Three calls fail to update refcount accordingly, leading to possible resource leaks. Fixes: 8ceb98437946 ("CIFS: Move rename to ops struct") Fixes: 2f1afe25997f ("cifs: Use smb 2 - 3 and cifsacl mount options getacl functions") Fixes: 366ed846df60 ("cifs: Use smb 2 - 3 and cifsacl mount options setacl function") Cc: stable@vger.kernel.org Signed-off-by: Shuhao Fu <sfual@cse.ust.hk> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-10-09smb: client: fix race with fallocate(2) and AIO+DIOPaulo Alcantara1-0/+1
AIO+DIO may extend the file size, hence we need to make sure ->i_size is stable across the entire fallocate(2) operation, otherwise it would become a truncate and then inode size reduced back down when it finishes. Fix this by calling netfs_wait_for_outstanding_io() right after acquiring ->i_rwsem exclusively in cifs_fallocate() and then guarantee a stable ->i_size across fallocate(2). Also call netfs_wait_for_outstanding_io() after truncating pagecache to avoid any potential races with writeback. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: David Howells <dhowells@redhat.com> Fixes: 210627b0aca9 ("smb: client: fix missing timestamp updates with O_TRUNC") Cc: Frank Sorenson <sorenson@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-10-09smb: client: fix missing timestamp updates after ftruncate(2)Paulo Alcantara1-10/+8
Mask off ATTR_MTIME|ATTR_CTIME bits on ATTR_SIZE (e.g. ftruncate(2)) to prevent the client from sending set info calls and then disabling automatic timestamp updates on server side as per MS-FSA 2.1.4.17. ---8<--- import os import time filename = '/mnt/foo' def print_stat(prefix): st = os.stat(filename) print(prefix, ': ', time.ctime(st.st_atime), time.ctime(st.st_ctime)) fd = os.open(filename, os.O_CREAT|os.O_TRUNC|os.O_WRONLY, 0o644) print_stat('old') os.ftruncate(fd, 10) time.sleep(2) os.write(fd, b'foo') os.close(fd) time.sleep(2) print_stat('new') ---8<--- Before patch: $ mount.cifs //srv/share /mnt -o ... $ python3 run.py old : Fri Oct 3 13:47:03 2025 Fri Oct 3 13:47:03 2025 new : Fri Oct 3 13:47:00 2025 Fri Oct 3 13:47:03 2025 After patch: $ mount.cifs //srv/share /mnt -o ... $ python3 run.py old : Fri Oct 3 13:48:39 2025 Fri Oct 3 13:48:39 2025 new : Fri Oct 3 13:48:41 2025 Fri Oct 3 13:48:41 2025 Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: Frank Sorenson <sorenson@redhat.com> Reviewed-by: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-10-09smb: client: fix missing timestamp updates with O_TRUNCPaulo Alcantara1-67/+85
Don't call ->set_file_info() on open handle to prevent the server from stopping [cm]time updates automatically as per MS-FSA 2.1.4.17. Fix this by checking for ATTR_OPEN bit earlier in cifs_setattr() to prevent ->set_file_info() from being called when opening a file with O_TRUNC. Do the truncation in ->open() instead. This also saves two roundtrips when opening a file with O_TRUNC and there are currently no open handles to be reused. Before patch: $ mount.cifs //srv/share /mnt -o ... $ cd /mnt $ exec 3>foo; stat -c 'old: %z %y' foo; sleep 2; echo test >&3; exec 3>&-; sleep 2; stat -c 'new: %z %y' foo old: 2025-10-03 13:26:23.151030500 -0300 2025-10-03 13:26:23.151030500 -0300 new: 2025-10-03 13:26:23.151030500 -0300 2025-10-03 13:26:23.151030500 -0300 After patch: $ mount.cifs //srv/share /mnt -o ... $ cd /mnt $ exec 3>foo; stat -c 'old: %z %y' foo; sleep 2; echo test >&3; exec 3>&-; sleep 2; stat -c 'new: %z %y' foo $ exec 3>foo; stat -c 'old: %z %y' foo; sleep 2; echo test >&3; exec 3>&-; sleep 2; stat -c 'new: %z %y' foo old: 2025-10-03 13:28:13.911933800 -0300 2025-10-03 13:28:13.911933800 -0300 new: 2025-10-03 13:28:26.647492700 -0300 2025-10-03 13:28:26.647492700 -0300 Reported-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-10-01smb: client: ensure open_cached_dir_by_dentry() only returns valid cfidSteve French1-1/+1
open_cached_dir_by_dentry() was exposing an invalid cached directory to callers. The validity check outside the function was exclusively based on cfid->time. Add validity check before returning success and introduce is_valid_cached_dir() helper for consistent checks across the code. Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com> Reviwed-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
2025-09-29Merge tag 'vfs-6.18-rc1.inode' of ↵Linus Torvalds1-1/+1
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs inode updates from Christian Brauner: "This contains a series I originally wrote and that Eric brought over the finish line. It moves out the i_crypt_info and i_verity_info pointers out of 'struct inode' and into the fs-specific part of the inode. So now the few filesytems that actually make use of this pay the price in their own private inode storage instead of forcing it upon every user of struct inode. The pointer for the crypt and verity info is simply found by storing an offset to its address in struct fsverity_operations and struct fscrypt_operations. This shrinks struct inode by 16 bytes. I hope to move a lot more out of it in the future so that struct inode becomes really just about very core stuff that we need, much like struct dentry and struct file, instead of the dumping ground it has become over the years. On top of this are a various changes associated with the ongoing inode lifetime handling rework that multiple people are pushing forward: - Stop accessing inode->i_count directly in f2fs and gfs2. They simply should use the __iget() and iput() helpers - Make the i_state flags an enum - Rework the iput() logic Currently, if we are the last iput, and we have the I_DIRTY_TIME bit set, we will grab a reference on the inode again and then mark it dirty and then redo the put. This is to make sure we delay the time update for as long as possible We can rework this logic to simply dec i_count if it is not 1, and if it is do the time update while still holding the i_count reference Then we can replace the atomic_dec_and_lock with locking the ->i_lock and doing atomic_dec_and_test, since we did the atomic_add_unless above - Add an icount_read() helper and convert everyone that accesses inode->i_count directly for this purpose to use the helper - Expand dump_inode() to dump more information about an inode helping in debugging - Add some might_sleep() annotations to iput() and associated helpers" * tag 'vfs-6.18-rc1.inode' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: add might_sleep() annotation to iput() and more fs: expand dump_inode() inode: fix whitespace issues fs: add an icount_read helper fs: rework iput logic fs: make the i_state flags an enum fs: stop accessing ->i_count directly in f2fs and gfs2 fsverity: check IS_VERITY() in fsverity_cleanup_inode() fs: remove inode::i_verity_info btrfs: move verity info pointer to fs-specific part of inode f2fs: move verity info pointer to fs-specific part of inode ext4: move verity info pointer to fs-specific part of inode fsverity: add support for info in fs-specific part of inode fs: remove inode::i_crypt_info ceph: move crypt info pointer to fs-specific part of inode ubifs: move crypt info pointer to fs-specific part of inode f2fs: move crypt info pointer to fs-specific part of inode ext4: move crypt info pointer to fs-specific part of inode fscrypt: add support for info in fs-specific part of inode fscrypt: replace raw loads of info pointer with helper function
2025-09-18smb: client: fix file open check in __cifs_unlink()Paulo Alcantara1-2/+15
Fix the file open check to decide whether or not silly-rename the file in SMB2+. Fixes: c5ea3065586d ("smb: client: fix data loss due to broken rename(2)") Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: Frank Sorenson <sorenson@redhat.com> Reviewed-by: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-09-17smb: client: fix filename matching of deferred filesPaulo Alcantara1-3/+3
Fix the following case where the client would end up closing both deferred files (foo.tmp & foo) after unlink(foo) due to strstr() call in cifs_close_deferred_file_under_dentry(): fd1 = openat(AT_FDCWD, "foo", O_WRONLY|O_CREAT|O_TRUNC, 0666); fd2 = openat(AT_FDCWD, "foo.tmp", O_WRONLY|O_CREAT|O_TRUNC, 0666); close(fd1); close(fd2); unlink("foo"); Fixes: e3fc065682eb ("cifs: Deferred close performance improvements") Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de> Cc: Frank Sorenson <sorenson@redhat.com> Cc: David Howells <dhowells@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-09-09smb: client: fix data loss due to broken rename(2)Paulo Alcantara1-17/+69
Rename of open files in SMB2+ has been broken for a very long time, resulting in data loss as the CIFS client would fail the rename(2) call with -ENOENT and then removing the target file. Fix this by implementing ->rename_pending_delete() for SMB2+, which will rename busy files to random filenames (e.g. silly rename) during unlink(2) or rename(2), and then marking them to delete-on-close. Besides, introduce a FIND_WR_NO_PENDING_DELETE flag to prevent open(2) from reusing open handles that had been marked as delete pending. Handle it in cifs_get_readable_path() as well. Reported-by: Jean-Baptiste Denis <jbdenis@pasteur.fr> Closes: https://marc.info/?i=16aeb380-30d4-4551-9134-4e7d1dc833c0@pasteur.fr Reviewed-by: David Howells <dhowells@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Cc: Frank Sorenson <sorenson@redhat.com> Cc: Olga Kornievskaia <okorniev@redhat.com> Cc: Benjamin Coddington <bcodding@redhat.com> Cc: Scott Mayhew <smayhew@redhat.com> Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
2025-09-01fs: add an icount_read helperJosef Bacik1-1/+1
Instead of doing direct access to ->i_count, add a helper to handle this. This will make it easier to convert i_count to a refcount later. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://lore.kernel.org/9bc62a84c6b9d6337781203f60837bd98fbc4a96.1756222464.git.josef@toxicpanda.com Signed-off-by: Christian Brauner <brauner@kernel.org>