vfs_fruit: prepare fruit_pwrite_meta() for on-demand opening and writing
authorRalph Boehme <slow@samba.org>
Wed, 22 Aug 2018 13:21:08 +0000 (15:21 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 31 Oct 2018 20:27:22 +0000 (21:27 +0100)
This avoid creating files or blobs in our streams backend when a client
creates a stream but hasn't written anything yet. This is the only sane
way to implement the following semantics:

* client 1: create stream "file:foo"

* client 2: open stream "file:foo"

The second operation of client 2 must fail with NT_STATUS_NOT_FOUND.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13646

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_fruit.c

index 60b74b48b6a44c23c3e479e5b9bf3d0234112c3e..f567b5002ead2d3f4f8a2f62e9e35a6a5fedad51 100644 (file)
@@ -4495,10 +4495,44 @@ static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle,
                                        files_struct *fsp, const void *data,
                                        size_t n, off_t offset)
 {
+       struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
        AfpInfo *ai = NULL;
        size_t nwritten;
+       int ret;
        bool ok;
 
+       DBG_DEBUG("Path [%s] offset=%"PRIdMAX", size=%zd\n",
+                 fsp_str_dbg(fsp), (intmax_t)offset, n);
+
+       if (fio == NULL) {
+               return -1;
+       }
+
+       if (fio->fake_fd) {
+               int fd;
+
+               ret = SMB_VFS_NEXT_CLOSE(handle, fsp);
+               if (ret != 0) {
+                       DBG_ERR("Close [%s] failed: %s\n",
+                               fsp_str_dbg(fsp), strerror(errno));
+                       fsp->fh->fd = -1;
+                       return -1;
+               }
+
+               fd = SMB_VFS_NEXT_OPEN(handle,
+                                      fsp->fsp_name,
+                                      fsp,
+                                      fio->flags,
+                                      fio->mode);
+               if (fd == -1) {
+                       DBG_ERR("On-demand create [%s] in write failed: %s\n",
+                               fsp_str_dbg(fsp), strerror(errno));
+                       return -1;
+               }
+               fsp->fh->fd = fd;
+               fio->fake_fd = false;
+       }
+
        ai = afpinfo_unpack(talloc_tos(), data);
        if (ai == NULL) {
                return -1;