From: Ralph Boehme Date: Wed, 24 Aug 2022 09:40:41 +0000 (+0200) Subject: smbd: cache DOS attributes in struct smb_filename.cached_dos_attributes X-Git-Tag: talloc-2.4.0~1236 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=169d8fe4a956c98da9558ccef9b1c90ea6a841e4;p=thirdparty%2Fsamba.git smbd: cache DOS attributes in struct smb_filename.cached_dos_attributes BUG: https://bugzilla.samba.org/show_bug.cgi?id=14215 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index a043cbc883e..862bf49861b 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -329,6 +329,7 @@ enum csc_policy { #define FLAGS2_UNICODE_STRINGS 0x8000 /* FileAttributes (search attributes) field */ +#define FILE_ATTRIBUTES_INVALID 0x0000L #define FILE_ATTRIBUTE_READONLY 0x0001L #define FILE_ATTRIBUTE_HIDDEN 0x0002L #define FILE_ATTRIBUTE_SYSTEM 0x0004L diff --git a/source3/include/includes.h b/source3/include/includes.h index bb93aad02a0..27ce2074a72 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -201,6 +201,7 @@ struct stat_ex { struct timespec st_ex_mtime; struct timespec st_ex_ctime; struct timespec st_ex_btime; /* birthtime */ + uint32_t cached_dos_attributes; blksize_t st_ex_blksize; blkcnt_t st_ex_blocks; diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 33623969ef3..fc7afccfdb3 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -376,6 +376,7 @@ * Version 47 - Change SMB_VFS_OPENAT() to match the Linux openat2 prototype, add vfs_open_how * Version 47 - Add VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS for SMB_VFS_OPENAT() * Change to Version 48 - will ship with 4.18 + * Version 48 - Add cached_dos_attributes to struct stat_ex */ #define SMB_VFS_INTERFACE_VERSION 48 diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a16d6ec7c90..40fe7b5166a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -727,6 +727,10 @@ uint32_t fdos_mode(struct files_struct *fsp) return FILE_ATTRIBUTE_NORMAL; } + if (fsp->fsp_name->st.cached_dos_attributes != FILE_ATTRIBUTES_INVALID) { + return fsp->fsp_name->st.cached_dos_attributes; + } + /* Get the DOS attributes via the VFS if we can */ status = vfs_fget_dos_attributes(fsp, &result); if (!NT_STATUS_IS_OK(status)) { @@ -738,8 +742,8 @@ uint32_t fdos_mode(struct files_struct *fsp) } } - result = dos_mode_post(result, fsp, __func__); - return result; + fsp->fsp_name->st.cached_dos_attributes = dos_mode_post(result, fsp, __func__); + return fsp->fsp_name->st.cached_dos_attributes; } struct dos_mode_at_state { @@ -940,6 +944,7 @@ int file_set_dosmode(connection_struct *conn, } if (NT_STATUS_IS_OK(status)) { + smb_fname->st.cached_dos_attributes = dosmode; ret = 0; goto done; } @@ -1147,6 +1152,7 @@ NTSTATUS file_set_sparse(connection_struct *conn, FILE_NOTIFY_CHANGE_ATTRIBUTES, fsp->fsp_name->base_name); + fsp->fsp_name->st.cached_dos_attributes = new_dosmode; fsp->fsp_flags.is_sparse = sparse; return NT_STATUS_OK; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index b494a8b789a..095a01723b1 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -1843,6 +1843,7 @@ files_struct *file_fsp(struct smb_request *req, uint16_t fid) } req->chain_fsp = fsp; + fsp->fsp_name->st.cached_dos_attributes = FILE_ATTRIBUTES_INVALID; return fsp; } @@ -1889,6 +1890,8 @@ struct files_struct *file_fsp_get(struct smbd_smb2_request *smb2req, return NULL; } + fsp->fsp_name->st.cached_dos_attributes = FILE_ATTRIBUTES_INVALID; + return fsp; } @@ -1902,6 +1905,8 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req, if (smb2req->compat_chain_fsp->fsp_flags.closing) { return NULL; } + smb2req->compat_chain_fsp->fsp_name->st.cached_dos_attributes = + FILE_ATTRIBUTES_INVALID; return smb2req->compat_chain_fsp; } @@ -2027,6 +2032,7 @@ static NTSTATUS fsp_attach_smb_fname(struct files_struct *fsp, fsp->name_hash = name_hash; fsp->fsp_name = smb_fname_new; + fsp->fsp_name->st.cached_dos_attributes = FILE_ATTRIBUTES_INVALID; *_smb_fname = NULL; return NT_STATUS_OK; }