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 <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
(backported from commit
e86f0c2de80e2409bfe3fc12df24e94470988e3c)
[slow@samba.org: conflict due to optino veto_localized only present in master]
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>fruit:posix_opens = yes | no</term>
+ <listitem>
+
+ <para>When <parameter>fruit:posix_opens</parameter> is set to
+ <parameter>yes</parameter>, 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.</para>
+ <para>The default is <emphasis>yes</emphasis>.</para>
+
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
^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\(.*\)
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;
} fsp_flags;
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 {
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;
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);
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 != 0) {
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;
}