vfs_streams_xattr: Do not attempt to write empty attribute twice
authorChristof Schmitt <christof.schmitt@us.ibm.com>
Wed, 12 Jun 2013 21:55:15 +0000 (14:55 -0700)
committerJeremy Allison <jra@samba.org>
Mon, 17 Jun 2013 17:41:46 +0000 (10:41 -0700)
The create disposition FILE_OVERWRITE_IF is mapped to the flags
O_CREAT|O_TRUNC. In vfs_streams_xattr, this triggers two calls to
SMB_VFS_SETXATTR. The second can fail if O_EXCL is also set, resulting
in an unnecessary error.

Merge the identical code to handle O_CREAT and O_TRUNC to avoid setting
an empty attribute twice. Also add the flags parameter to the debug
message.

Signed-off-by: Christof Schmitt <christof.schmitt@us.ibm.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/modules/vfs_streams_xattr.c

index 82e2dd8d1efb2ab9e65cc4fe3f62e52aac3f85fe..11a3cc63e89b3077aa3782b83ef3ea9114ee6f1a 100644 (file)
@@ -364,8 +364,8 @@ static int streams_xattr_open(vfs_handle_struct *handle,
        int baseflags;
        int hostfd = -1;
 
-       DEBUG(10, ("streams_xattr_open called for %s\n",
-                  smb_fname_str_dbg(smb_fname)));
+       DEBUG(10, ("streams_xattr_open called for %s with flags 0x%x\n",
+                  smb_fname_str_dbg(smb_fname), flags));
 
        if (!is_ntfs_stream_smb_fname(smb_fname)) {
                return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
@@ -447,40 +447,20 @@ static int streams_xattr_open(vfs_handle_struct *handle,
                goto fail;
        }
 
-       if (!NT_STATUS_IS_OK(status)) {
+       if ((!NT_STATUS_IS_OK(status) && (flags & O_CREAT)) ||
+           (flags & O_TRUNC)) {
                /*
-                * The attribute does not exist
+                * The attribute does not exist or needs to be truncated
                 */
 
-                if (flags & O_CREAT) {
-                       /*
-                        * Darn, xattrs need at least 1 byte
-                        */
-                        char null = '\0';
+               /*
+                * Darn, xattrs need at least 1 byte
+                */
+               char null = '\0';
 
-                       DEBUG(10, ("creating attribute %s on file %s\n",
-                                  xattr_name, smb_fname->base_name));
+               DEBUG(10, ("creating or truncating attribute %s on file %s\n",
+                          xattr_name, smb_fname->base_name));
 
-                       if (fsp->base_fsp->fh->fd != -1) {
-                               if (SMB_VFS_FSETXATTR(
-                                       fsp->base_fsp, xattr_name,
-                                       &null, sizeof(null),
-                                       flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
-                                       goto fail;
-                               }
-                       } else {
-                               if (SMB_VFS_SETXATTR(
-                                       handle->conn, smb_fname->base_name,
-                                       xattr_name, &null, sizeof(null),
-                                       flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
-                                       goto fail;
-                               }
-                       }
-               }
-       }
-
-       if (flags & O_TRUNC) {
-               char null = '\0';
                if (fsp->base_fsp->fh->fd != -1) {
                        if (SMB_VFS_FSETXATTR(
                                        fsp->base_fsp, xattr_name,