From: Ralph Boehme Date: Wed, 6 Dec 2017 21:09:52 +0000 (+0100) Subject: vfs_fruit: set delete-on-close for empty finderinfo X-Git-Tag: talloc-2.1.11~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e61e9e98e9ff461055daae2fe78f0202f7ed8663;p=thirdparty%2Fsamba.git vfs_fruit: set delete-on-close for empty finderinfo We previously removed the stream from the underlying filesystem stream backing store when the client zeroes out FinderInfo in the AFP_AfpInfo stream, but this causes certain operations to fail (eg stat) when trying to access the stream over any file-handle open on that stream. So instead of deleting, set delete-on-close on the stream. The previous commit already implemented not to list list streams with delete-on-close set which is necessary to implemenent correct macOS semantics for this particular stream. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13181 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Tue Jan 9 17:09:12 CET 2018 on sn-devel-144 --- diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit index e8fd5e11fc2..8df25bccb79 100644 --- a/selftest/knownfail.d/samba3.vfs.fruit +++ b/selftest/knownfail.d/samba3.vfs.fruit @@ -1,3 +1 @@ ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\) -^samba3.vfs.fruit metadata_stream.delete AFP_AfpInfo by writing all 0\(nt4_dc\) -^samba3.vfs.fruit streams_depot.delete AFP_AfpInfo by writing all 0\(nt4_dc\) diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 4b53136aef9..9533da4a5f8 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -4166,26 +4166,35 @@ static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle, size_t n, off_t offset) { AfpInfo *ai = NULL; - int ret; + size_t nwritten; + bool ok; ai = afpinfo_unpack(talloc_tos(), data); if (ai == NULL) { return -1; } - if (ai_empty_finderinfo(ai)) { - ret = SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name); - if (ret != 0 && errno != ENOENT && errno != ENOATTR) { - DBG_ERR("Can't delete metadata for %s: %s\n", - fsp_str_dbg(fsp), strerror(errno)); - TALLOC_FREE(ai); - return -1; - } + nwritten = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); + if (nwritten != n) { + return -1; + } + if (!ai_empty_finderinfo(ai)) { return n; } - return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); + ok = set_delete_on_close( + fsp, + true, + handle->conn->session_info->security_token, + handle->conn->session_info->unix_token); + if (!ok) { + DBG_ERR("set_delete_on_close on [%s] failed\n", + fsp_str_dbg(fsp)); + return -1; + } + + return n; } static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle, @@ -4196,26 +4205,13 @@ static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle, AfpInfo *ai = NULL; char *p = NULL; int ret; + bool ok; ai = afpinfo_unpack(talloc_tos(), data); if (ai == NULL) { return -1; } - if (ai_empty_finderinfo(ai)) { - ret = SMB_VFS_REMOVEXATTR(handle->conn, - fsp->fsp_name, - AFPINFO_EA_NETATALK); - - if (ret != 0 && errno != ENOENT && errno != ENOATTR) { - DBG_ERR("Can't delete metadata for %s: %s\n", - fsp_str_dbg(fsp), strerror(errno)); - return -1; - } - - return n; - } - ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_META); if (ad == NULL) { ad = ad_init(talloc_tos(), handle, ADOUBLE_META); @@ -4240,6 +4236,22 @@ static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle, } TALLOC_FREE(ad); + + if (!ai_empty_finderinfo(ai)) { + return n; + } + + ok = set_delete_on_close( + fsp, + true, + handle->conn->session_info->security_token, + handle->conn->session_info->unix_token); + if (!ok) { + DBG_ERR("set_delete_on_close on [%s] failed\n", + fsp_str_dbg(fsp)); + return -1; + } + return n; }