From: Volker Lendecke Date: Tue, 27 Jan 2026 17:46:30 +0000 (+0100) Subject: smbd: Call FSTATVFS instead of STATVFS X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d3e0866f8464f7fec6c1124f5812e300af41301;p=thirdparty%2Fsamba.git smbd: Call FSTATVFS instead of STATVFS To get the fs capabilities we do an openat_pathref_fsp_dot(), which also avoids a call to SMB_VFS_STAT there. Signed-off-by: Volker Lendecke Reviewed-by: Anoop C S --- diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c index b29fcbcca79..ed8d2595d96 100644 --- a/source3/smbd/smb2_trans2.c +++ b/source3/smbd/smb2_trans2.c @@ -2495,7 +2495,7 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn, return NT_STATUS_INVALID_LEVEL; } - rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs); + rc = SMB_VFS_FSTATVFS(conn, fsp, &svfs); #ifdef EOPNOTSUPP if (rc == EOPNOTSUPP) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 4778edfef59..473e0ccddd5 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1317,14 +1317,30 @@ uint32_t vfs_get_fs_capabilities(struct connection_struct *conn, uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; struct smb_filename *smb_fname_cpath = NULL; struct vfs_statvfs_struct statbuf = {}; - int ret; + NTSTATUS status; + int dirfd, ret; - smb_fname_cpath = cp_smb_basename(talloc_tos(), conn->connectpath); - if (smb_fname_cpath == NULL) { + dirfd = fsp_get_pathref_fd(conn->cwd_fsp); + + if (dirfd == -1) { + /* + * This happens in create_conn_struct_as_root() + */ + status = openat_pathref_fsp_rootdir(talloc_tos(), + conn, + &smb_fname_cpath); + } else { + status = openat_pathref_fsp_dot(talloc_tos(), + conn->cwd_fsp, + 0, + &smb_fname_cpath); + } + + if (!NT_STATUS_IS_OK(status)) { return caps; } - ret = SMB_VFS_STATVFS(conn, smb_fname_cpath, &statbuf); + ret = SMB_VFS_FSTATVFS(conn, smb_fname_cpath->fsp, &statbuf); if (ret == 0) { caps = statbuf.FsCapabilities; } @@ -1340,12 +1356,6 @@ uint32_t vfs_get_fs_capabilities(struct connection_struct *conn, /* Work out what timestamp resolution we can * use when setting a timestamp. */ - ret = SMB_VFS_STAT(conn, smb_fname_cpath); - if (ret == -1) { - TALLOC_FREE(smb_fname_cpath); - return caps; - } - if (smb_fname_cpath->st.st_ex_mtime.tv_nsec || smb_fname_cpath->st.st_ex_atime.tv_nsec || smb_fname_cpath->st.st_ex_ctime.tv_nsec) {