vfs_streams_xattr: fix open implementation
[kamenim/samba-autobuild/.git] / source3 / modules / vfs_streams_xattr.c
index 30459fec4bf23c7c5ec4abc54109c109d0c3bc53..9f4bc13b034772289d03e0e891f1e0cc88ed9574 100644 (file)
@@ -412,6 +412,7 @@ static int streams_xattr_open(vfs_handle_struct *handle,
        char *xattr_name = NULL;
        int pipe_fds[2];
        int fakefd = -1;
+       bool set_empty_xattr = false;
        int ret;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config,
@@ -445,39 +446,37 @@ static int streams_xattr_open(vfs_handle_struct *handle,
                goto fail;
        }
 
-       /*
-        * Return a valid fd, but ensure any attempt to use it returns an error
-        * (EPIPE).
-        */
-       ret = pipe(pipe_fds);
-       if (ret != 0) {
-               goto fail;
-       }
-
-       close(pipe_fds[1]);
-       pipe_fds[1] = -1;
-       fakefd = pipe_fds[0];
-
        status = get_ea_value(talloc_tos(), handle->conn, NULL,
                              smb_fname, xattr_name, &ea);
 
        DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
 
-       if (!NT_STATUS_IS_OK(status)
-           && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-               /*
-                * The base file is not there. This is an error even if we got
-                * O_CREAT, the higher levels should have created the base
-                * file for us.
-                */
-               DEBUG(10, ("streams_xattr_open: base file %s not around, "
-                          "returning ENOENT\n", smb_fname->base_name));
-               errno = ENOENT;
-               goto fail;
+       if (!NT_STATUS_IS_OK(status)) {
+               if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+                       /*
+                        * The base file is not there. This is an error even if
+                        * we got O_CREAT, the higher levels should have created
+                        * the base file for us.
+                        */
+                       DBG_DEBUG("streams_xattr_open: base file %s not around, "
+                                 "returning ENOENT\n", smb_fname->base_name);
+                       errno = ENOENT;
+                       goto fail;
+               }
+
+               if (!(flags & O_CREAT)) {
+                       errno = ENOATTR;
+                       goto fail;
+               }
+
+               set_empty_xattr = true;
        }
 
-       if ((!NT_STATUS_IS_OK(status) && (flags & O_CREAT)) ||
-           (flags & O_TRUNC)) {
+       if (flags & O_TRUNC) {
+               set_empty_xattr = true;
+       }
+
+       if (set_empty_xattr) {
                /*
                 * The attribute does not exist or needs to be truncated
                 */
@@ -500,6 +499,19 @@ static int streams_xattr_open(vfs_handle_struct *handle,
                }
        }
 
+       /*
+        * Return a valid fd, but ensure any attempt to use it returns an error
+        * (EPIPE).
+        */
+       ret = pipe(pipe_fds);
+       if (ret != 0) {
+               goto fail;
+       }
+
+       close(pipe_fds[1]);
+       pipe_fds[1] = -1;
+       fakefd = pipe_fds[0];
+
         sio = VFS_ADD_FSP_EXTENSION(handle, fsp, struct stream_io, NULL);
         if (sio == NULL) {
                 errno = ENOMEM;