From: Ralph Boehme Date: Mon, 10 Mar 2025 14:01:42 +0000 (+0100) Subject: vfs_fruit: add option "fruit:posix_opens = yes|no" (default: yes) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e86f0c2de80e2409bfe3fc12df24e94470988e3c;p=thirdparty%2Fsamba.git vfs_fruit: add option "fruit:posix_opens = yes|no" (default: yes) Tags alls opens as POSIX by setting fsp_flags.posix_open to true. POSIX handles have different behaviour compared to Windows: Behaviour | POSIX | Windows | macOS |fruit:posix_opens = yes -----------------------------------+------------+---------------------------------------- Deleting files with open handles | yes | no | yes | yes Moving directories with open files | yes | no | yes | yes Byterange locks behaviour | POSIX-ish | Window-ish | POSIX-ish | POSIX-ish Sticky writetime | no | yes | no | no Case sensitive | no | yes | yes | yes Streams allowed | no | yes | yes | yes macOS follows POSIX for the first four, but needs case insensitive behaviour and needs streams. By carefully setting fsp_flags.posix_open to true *after* going through the path resolution logic, but before opens are added to locking.tdb, with "fruit:posix_opens = yes" we get closest to macOS semantics. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15926 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke --- diff --git a/docs-xml/manpages/vfs_fruit.8.xml b/docs-xml/manpages/vfs_fruit.8.xml index 037fe611c4e..a2a382e6087 100644 --- a/docs-xml/manpages/vfs_fruit.8.xml +++ b/docs-xml/manpages/vfs_fruit.8.xml @@ -447,6 +447,22 @@ + + + fruit:posix_opens = yes | no + + + When fruit:posix_opens is set to + yes, vfs_fruit will internally translate + all filesystem semantics to use POSIX behaviour instead of Windows + behaviour. As Macs are closer to POSIX than Windows with regard + to filesystem semantics, this improves access semantics for + a lot of corner cases. + The default is yes. + + + + diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit index 6307e2b3404..b774b0503e7 100644 --- a/selftest/knownfail.d/samba3.vfs.fruit +++ b/selftest/knownfail.d/samba3.vfs.fruit @@ -1,2 +1,4 @@ ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\) ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion without embedded xattr\(nt4_dc\) +^samba3.vfs.fruit.*readonly-exclusive-lock\(.*\) +^samba3.vfs.fruit.*case_insensitive_find\(.*\) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 0acd7c86cad..34bd97fa3de 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -465,6 +465,15 @@ typedef struct files_struct { bool lock_failure_seen : 1; bool encryption_required : 1; bool fstat_before_close : 1; + /* + * For POSIX clients struct files_struct.fsp_flags.posix_open + * and struct smb_filename.flags SMB_FILENAME_POSIX_PATH will + * always be set to the same value. + * + * For macOS clients vfs_fruit with fruit:posix_open=yes, we + * deliberately set both flags to fsp_flags.posix_open=true + * while SMB_FILENAME_POSIX_PATH will not be set. + */ bool posix_open : 1; bool posix_append : 1; bool ntcreatex_deny_dos : 1; @@ -892,6 +901,15 @@ struct smb_filename { struct fsp_smb_fname_link *fsp_link; }; +/* + * For POSIX clients struct files_struct.fsp_flags.posix_open + * and struct smb_filename.flags SMB_FILENAME_POSIX_PATH will + * always be set to the same value. + * + * For macOS clients vfs_fruit with fruit:posix_open=yes, we + * deliberately set both flags to fsp_flags.posix_open=true + * while SMB_FILENAME_POSIX_PATH will not be set. + */ #define SMB_FILENAME_POSIX_PATH 0x01 enum vfs_translate_direction { diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 4ef7a68a30f..f044e755349 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -125,6 +125,7 @@ struct fruit_config_data { bool use_aapl; /* config from smb.conf */ bool use_copyfile; bool readdir_attr_enabled; + bool posix_opens; bool unix_info_enabled; bool copyfile_enabled; bool veto_appledouble; @@ -340,6 +341,9 @@ static int init_fruit_config(vfs_handle_struct *handle) config->use_copyfile = lp_parm_bool(-1, FRUIT_PARAM_TYPE_NAME, "copyfile", false); + config->posix_opens = lp_parm_bool( + SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME, "posix_opens", true); + config->aapl_zero_file_id = lp_parm_bool(SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME, "zero_file_id", true); @@ -1730,16 +1734,27 @@ static int fruit_openat(vfs_handle_struct *handle, files_struct *fsp, const struct vfs_open_how *how) { + struct fruit_config_data *config = NULL; int fd; + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct fruit_config_data, return -1); + DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname)); if (!is_named_stream(smb_fname)) { - return SMB_VFS_NEXT_OPENAT(handle, - dirfsp, - smb_fname, - fsp, - how); + fd = SMB_VFS_NEXT_OPENAT(handle, + dirfsp, + smb_fname, + fsp, + how); + if (fd == -1) { + return -1; + } + if (config->posix_opens && global_fruit_config.nego_aapl) { + fsp->fsp_flags.posix_open = true; + } + return fd; } if ((how->resolve & ~VFS_OPEN_HOW_WITH_BACKUP_INTENT) != 0) { @@ -1774,7 +1789,13 @@ static int fruit_openat(vfs_handle_struct *handle, DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd); /* Prevent reopen optimisation */ + if (fd == -1) { + return -1; + } fsp->fsp_flags.have_proc_fds = false; + if (config->posix_opens && global_fruit_config.nego_aapl) { + fsp->fsp_flags.posix_open = true; + } return fd; }