]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fruit: set delete-on-close for empty finderinfo
authorRalph Boehme <slow@samba.org>
Wed, 6 Dec 2017 21:09:52 +0000 (22:09 +0100)
committerKarolin Seeger <kseeger@samba.org>
Thu, 25 Jan 2018 18:25:24 +0000 (19:25 +0100)
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Tue Jan  9 17:09:12 CET 2018 on sn-devel-144

(backported from commit e61e9e98e9ff461055daae2fe78f0202f7ed8663)

Autobuild-User(v4-6-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-6-test): Thu Jan 25 19:25:24 CET 2018 on sn-devel-144

selftest/knownfail.d/samba3.vfs.fruit [deleted file]
source3/modules/vfs_fruit.c

diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit
deleted file mode 100644 (file)
index 1ba64fe..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^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\)
index 18cbd23ba073d9d48c09e17c6eec8dab04806b9f..7ae51ee3f6fb12a7c8f307f2bc17b840e2d3e97a 100644 (file)
@@ -4065,26 +4065,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,
@@ -4095,26 +4104,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->base_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);
@@ -4139,6 +4135,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;
 }