smbd: Fix a typo in a few places
[samba.git] / source3 / modules / onefs_open.c
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
deleted file mode 100644 (file)
index c5030f4..0000000
+++ /dev/null
@@ -1,2165 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- *
- * This file began with some code from source3/smbd/open.c and has been
- * modified it work with ifs_createfile.
- *
- * ifs_createfile is a CIFS-specific syscall for opening/files and
- * directories.  It adds support for:
- *    - Full in-kernel access checks using a windows access_mask
- *    - Cluster-coherent share mode locks
- *    - Cluster-coherent oplocks
- *    - Streams
- *    - Setting security descriptors at create time
- *    - Setting dos_attributes at create time
- *
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Jeremy Allison 2001-2004
- * Copyright (C) Volker Lendecke 2005
- * Copyright (C) Tim Prouty, 2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-#include "onefs.h"
-#include "onefs_config.h"
-#include "oplock_onefs.h"
-#include "smbd/globals.h"
-
-extern const struct generic_mapping file_generic_mapping;
-
-struct onefs_fsp_data {
-       uint64_t oplock_callback_id;
-};
-
-static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
-                             struct smb_request *req,
-                             const char *fname,
-                             uint32_t access_mask,
-                             uint32_t share_access,
-                             uint32_t create_disposition,
-                             uint32_t create_options,
-                             uint32_t file_attributes,
-                             uint32_t oplock_request,
-                             uint64_t allocation_size,
-                             struct security_descriptor *sd,
-                             struct ea_list *ea_list,
-                             files_struct **result,
-                             int *pinfo,
-                             struct onefs_fsp_data *fsp_data,
-                             SMB_STRUCT_STAT *psbuf);
-
-/****************************************************************************
- Open a file.
-****************************************************************************/
-
-static NTSTATUS onefs_open_file(files_struct *fsp,
-                               connection_struct *conn,
-                               struct smb_request *req,
-                               const char *parent_dir,
-                               const char *name,
-                               const char *path,
-                               SMB_STRUCT_STAT *psbuf,
-                               int flags,
-                               mode_t unx_mode,
-                               uint32 access_mask,
-                               uint32 open_access_mask,
-                               int oplock_request,
-                               uint64 id,
-                               uint32 share_access,
-                               uint32 create_options,
-                               uint32_t new_dos_attributes,
-                               struct security_descriptor *sd,
-                               int *granted_oplock)
-{
-       NTSTATUS status = NT_STATUS_OK;
-       int accmode = (flags & O_ACCMODE);
-       int local_flags = flags;
-       bool file_existed = VALID_STAT(*psbuf);
-       const char *wild;
-       char *base = NULL;
-       char *stream = NULL;
-       int base_fd = -1;
-
-       fsp->fh->fd = -1;
-       errno = EPERM;
-
-       /* Check permissions */
-
-       /*
-        * This code was changed after seeing a client open request
-        * containing the open mode of (DENY_WRITE/read-only) with
-        * the 'create if not exist' bit set. The previous code
-        * would fail to open the file read only on a read-only share
-        * as it was checking the flags parameter  directly against O_RDONLY,
-        * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
-        * JRA.
-        */
-
-       if (!CAN_WRITE(conn)) {
-               /* It's a read-only share - fail if we wanted to write. */
-               if(accmode != O_RDONLY) {
-                       DEBUG(3,("Permission denied opening %s\n", path));
-                       return NT_STATUS_ACCESS_DENIED;
-               } else if(flags & O_CREAT) {
-                       /* We don't want to write - but we must make sure that
-                          O_CREAT doesn't create the file if we have write
-                          access into the directory.
-                       */
-                       flags &= ~O_CREAT;
-                       local_flags &= ~O_CREAT;
-               }
-       }
-
-       /*
-        * This little piece of insanity is inspired by the
-        * fact that an NT client can open a file for O_RDONLY,
-        * but set the create disposition to FILE_EXISTS_TRUNCATE.
-        * If the client *can* write to the file, then it expects to
-        * truncate the file, even though it is opening for readonly.
-        * Quicken uses this stupid trick in backup file creation...
-        * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
-        * for helping track this one down. It didn't bite us in 2.0.x
-        * as we always opened files read-write in that release. JRA.
-        */
-
-       if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
-               DEBUG(10,("onefs_open_file: truncate requested on read-only "
-                         "open for file %s\n", path));
-               local_flags = (flags & ~O_ACCMODE)|O_RDWR;
-       }
-
-#if defined(O_NONBLOCK) && defined(S_ISFIFO)
-       /*
-        * We would block on opening a FIFO with no one else on the
-        * other end. Do what we used to do and add O_NONBLOCK to the
-        * open flags. JRA.
-        */
-
-       if (file_existed && S_ISFIFO(psbuf->st_mode)) {
-               local_flags |= O_NONBLOCK;
-       }
-#endif
-
-       /* Don't create files with Microsoft wildcard characters. */
-       if (fsp->base_fsp) {
-               /*
-                * wildcard characters are allowed in stream names
-                * only test the basefilename
-                */
-               wild = fsp->base_fsp->fsp_name;
-       } else {
-               wild = path;
-       }
-       if ((local_flags & O_CREAT) && !file_existed &&
-           ms_has_wild(wild))  {
-               /*
-                * XXX: may need to remvoe this return...
-                *
-                * We dont think this check needs to exist. All it does is
-                * block creating files with Microsoft wildcards, which is
-                * fine if the creation originated from NFS or locally and
-                * then was copied via Samba.
-                */
-               DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
-                         path));
-               return NT_STATUS_OBJECT_NAME_INVALID;
-       }
-
-       /* Actually do the open */
-
-#ifdef O_NOFOLLOW
-       /*
-        * Never follow symlinks on a POSIX client. The
-        * client should be doing this.
-        */
-
-       if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
-               flags |= O_NOFOLLOW;
-       }
-#endif
-       /* Stream handling */
-       if (is_ntfs_stream_name(path)) {
-               status = onefs_split_ntfs_stream_name(talloc_tos(), path,
-                                                     &base, &stream);
-       }
-       /* It's a stream, so pass in the base_fd */
-       if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
-               SMB_ASSERT(fsp->base_fsp);
-
-               /*
-                * We have never seen an oplock taken on a stream, and our
-                * current implementation doesn't support it.  If a request is
-                * seen, log a loud error message and ignore the requested
-                * oplock.
-                */
-               if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
-                    NO_OPLOCK) {
-                       DEBUG(0,("Oplock(%d) being requested on a stream! "
-                               "Ignoring oplock request: base=%s, stream=%s",
-                               oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
-                               base, stream));
-                       /* Recover by requesting NO_OPLOCK instead. */
-                       oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
-               }
-
-               DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
-                         base, fsp->base_fsp->fh->fd, stream));
-
-               base_fd = fsp->base_fsp->fh->fd;
-       }
-
-       fsp->fh->fd = onefs_sys_create_file(conn,
-                                           base_fd,
-                                           stream != NULL ? stream :
-                                           (base != NULL ? base : path),
-                                           access_mask,
-                                           open_access_mask,
-                                           share_access,
-                                           create_options,
-                                           flags,
-                                           unx_mode,
-                                           oplock_request,
-                                           id,
-                                           sd,
-                                           new_dos_attributes,
-                                           granted_oplock);
-
-       if (fsp->fh->fd == -1) {
-               if (errno == EMFILE) {
-                       static time_t last_warned = 0L;
-
-                       if (time((time_t *) NULL) > last_warned) {
-                               DEBUG(0, ("Too many open files, unable "
-                                         "to open more!  smbd's max "
-                                         "open files = %d, also check "
-                                         "sysctl kern.maxfiles and "
-                                         "sysctl kern.maxfilesperproc\n",
-                                         lp_max_open_files()));
-                               last_warned = time((time_t *) NULL);
-                       }
-               }
-
-               status = map_nt_error_from_unix(errno);
-               DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
-                       "(flags=%d)\n",
-                       path, strerror(errno), local_flags, flags));
-               return status;
-       }
-
-       if ((local_flags & O_CREAT) && !file_existed) {
-
-               /* Inherit the ACL if required */
-               if (lp_inherit_perms(SNUM(conn))) {
-                       inherit_access_posix_acl(conn, parent_dir, path,
-                           unx_mode);
-               }
-
-               /* Change the owner if required. */
-               if (lp_inherit_owner(SNUM(conn))) {
-                       change_file_owner_to_parent(conn, parent_dir,
-                           fsp);
-               }
-
-               notify_fname(conn, NOTIFY_ACTION_ADDED,
-                   FILE_NOTIFY_CHANGE_FILE_NAME, path);
-       }
-
-       if (!file_existed) {
-               int ret;
-
-               if (fsp->fh->fd == -1) {
-                       ret = SMB_VFS_STAT(conn, path, psbuf);
-               } else {
-                       ret = SMB_VFS_FSTAT(fsp, psbuf);
-                       /* If we have an fd, this stat should succeed. */
-                       if (ret == -1) {
-                               DEBUG(0,("Error doing fstat on open file %s "
-                                        "(%s)\n", path,strerror(errno) ));
-                       }
-               }
-
-               /* For a non-io open, this stat failing means file not found. JRA */
-               if (ret == -1) {
-                       status = map_nt_error_from_unix(errno);
-                       fd_close(fsp);
-                       return status;
-               }
-       }
-
-       /*
-        * POSIX allows read-only opens of directories. We don't
-        * want to do this (we use a different code path for this)
-        * so catch a directory open and return an EISDIR. JRA.
-        */
-
-       if(S_ISDIR(psbuf->st_mode)) {
-               fd_close(fsp);
-               errno = EISDIR;
-               return NT_STATUS_FILE_IS_A_DIRECTORY;
-       }
-
-       fsp->mode = psbuf->st_mode;
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
-       fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
-       fsp->file_pid = req ? req->smbpid : 0;
-       fsp->can_lock = True;
-       fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
-       if (!CAN_WRITE(conn)) {
-               fsp->can_write = False;
-       } else {
-               fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
-                       True : False;
-       }
-       fsp->print_file = False;
-       fsp->modified = False;
-       fsp->sent_oplock_break = NO_BREAK_SENT;
-       fsp->is_directory = False;
-       if (conn->aio_write_behind_list &&
-           is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
-               fsp->aio_write_behind = True;
-       }
-
-       string_set(&fsp->fsp_name, path);
-       fsp->wcp = NULL; /* Write cache pointer. */
-
-       DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
-                conn->server_info->unix_name,
-                fsp->fsp_name,
-                BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
-                conn->num_files_open));
-
-       errno = 0;
-       return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Handle the 1 second delay in returning a SHARING_VIOLATION error.
-****************************************************************************/
-
-static void defer_open(struct share_mode_lock *lck,
-                      struct timeval request_time,
-                      struct timeval timeout,
-                      struct smb_request *req,
-                      struct deferred_open_record *state)
-{
-       int i;
-
-       /* Paranoia check */
-
-       for (i=0; i<lck->num_share_modes; i++) {
-               struct share_mode_entry *e = &lck->share_modes[i];
-
-               if (!is_deferred_open_entry(e)) {
-                       continue;
-               }
-
-               if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
-                       DEBUG(0, ("Trying to defer an already deferred "
-                                 "request: mid=%d, exiting\n", req->mid));
-                       exit_server("attempt to defer a deferred request");
-               }
-       }
-
-       /* End paranoia check */
-
-       DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
-                 "open entry for mid %u\n",
-                 (unsigned int)request_time.tv_sec,
-                 (unsigned int)request_time.tv_usec,
-                 (unsigned int)req->mid));
-
-       if (!push_deferred_smb_message(req, request_time, timeout,
-                                      (char *)state, sizeof(*state))) {
-               exit_server("push_deferred_smb_message failed");
-       }
-       add_deferred_open(lck, req->mid, request_time, state->id);
-
-       /*
-        * Push the MID of this packet on the signing queue.
-        * We only do this once, the first time we push the packet
-        * onto the deferred open queue, as this has a side effect
-        * of incrementing the response sequence number.
-        */
-
-       srv_defer_sign_response(req->mid);
-}
-
-static void schedule_defer_open(struct share_mode_lock *lck,
-                               struct timeval request_time,
-                               struct smb_request *req)
-{
-       struct deferred_open_record state;
-
-       /* This is a relative time, added to the absolute
-          request_time value to get the absolute timeout time.
-          Note that if this is the second or greater time we enter
-          this codepath for this particular request mid then
-          request_time is left as the absolute time of the *first*
-          time this request mid was processed. This is what allows
-          the request to eventually time out. */
-
-       struct timeval timeout;
-
-       /* Normally the smbd we asked should respond within
-        * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
-        * the client did, give twice the timeout as a safety
-        * measure here in case the other smbd is stuck
-        * somewhere else. */
-
-       /*
-        * On OneFS, the kernel will always send an oplock_revoked message
-        * before this timeout is hit.
-        */
-       timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
-
-       /* Nothing actually uses state.delayed_for_oplocks
-          but it's handy to differentiate in debug messages
-          between a 30 second delay due to oplock break, and
-          a 1 second delay for share mode conflicts. */
-
-       state.delayed_for_oplocks = True;
-       state.failed = false;
-       state.id = lck->id;
-
-       if (!request_timed_out(request_time, timeout)) {
-               defer_open(lck, request_time, timeout, req, &state);
-       }
-}
-
-/****************************************************************************
- Open a file with a share mode.  Passed in an already created files_struct.
-****************************************************************************/
-NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
-                                 struct smb_request *req,
-                                 const char *fname,
-                                 uint32 access_mask,
-                                 uint32 share_access,
-                                 uint32 create_disposition,
-                                 uint32 create_options,
-                                 uint32 new_dos_attributes,
-                                 int oplock_request,
-                                 struct security_descriptor *sd,
-                                 files_struct *fsp,
-                                 int *pinfo,
-                                 struct onefs_fsp_data *fsp_data,
-                                 SMB_STRUCT_STAT *psbuf)
-{
-       int flags=0;
-       int flags2=0;
-       bool file_existed = VALID_STAT(*psbuf);
-       bool def_acl = False;
-       bool posix_open = False;
-       bool new_file_created = False;
-       bool clear_ads = False;
-       struct file_id id;
-       mode_t new_unx_mode = (mode_t)0;
-       mode_t unx_mode = (mode_t)0;
-       int info;
-       uint32 existing_dos_attributes = 0;
-       struct pending_message_list *pml = NULL;
-       struct timeval request_time = timeval_zero();
-       struct share_mode_lock *lck = NULL;
-       uint32 open_access_mask = access_mask;
-       NTSTATUS status;
-       int ret_flock;
-       char *parent_dir;
-       const char *newname;
-       int granted_oplock;
-       uint64_t oplock_callback_id = 0;
-       uint32 createfile_attributes = 0;
-
-       ZERO_STRUCT(id);
-
-       if (conn->printer) {
-               /*
-                * Printers are handled completely differently.
-                * Most of the passed parameters are ignored.
-                */
-
-               if (pinfo) {
-                       *pinfo = FILE_WAS_CREATED;
-               }
-
-               DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
-                         fname));
-
-               return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
-       }
-
-       if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
-               posix_open = True;
-               unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
-               new_dos_attributes = 0;
-       } else {
-               /* We add aARCH to this as this mode is only used if the file is
-                * created new. */
-               unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
-                                    parent_dir);
-       }
-
-       DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
-                 "access_mask=0x%x share_access=0x%x "
-                 "create_disposition = 0x%x create_options=0x%x "
-                 "unix mode=0%o oplock_request=0x%x\n",
-                 fname, new_dos_attributes, access_mask, share_access,
-                 create_disposition, create_options, unx_mode,
-                 oplock_request));
-
-       /*
-        * Any non-stat-only open has the potential to contend oplocks, which
-        * means to avoid blocking in the kernel (which is unacceptable), the
-        * open must be deferred.  In order to defer opens, req must not be
-        * NULL.  The known cases of calling with a NULL req:
-        *
-        *   1. Open the base file of a stream: Always done stat-only
-        *
-        *   2. Open the stream: Oplocks are disallowed on streams, so an
-        *      oplock will never be contended.
-        *
-        *   3. open_file_fchmod(), which is called from 3 places:
-        *      A. try_chown: Posix acls only. Never called on onefs.
-        *      B. set_ea_dos_attributes: Can't be called from onefs, because
-        *         SMB_VFS_SETXATTR return ENOSYS.
-        *      C. file_set_dos_mode: This would only happen if the "dos
-        *         filemode" smb.conf parameter is set to yes.  We ship with
-        *         it off, but if a customer were to turn it on it would be
-        *         bad.
-        */
-       if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
-               smb_panic("NULL req on a non-stat-open!");
-       }
-
-       if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
-               DEBUG(0, ("No smb request but not an internal only open!\n"));
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       /*
-        * Only non-internal opens can be deferred at all
-        */
-
-       if ((req != NULL)
-           && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
-               struct deferred_open_record *state =
-                       (struct deferred_open_record *)pml->private_data.data;
-
-               /* Remember the absolute time of the original
-                  request with this mid. We'll use it later to
-                  see if this has timed out. */
-
-               request_time = pml->request_time;
-
-               /* Remove the deferred open entry under lock. */
-               lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
-                                         NULL);
-               if (lck == NULL) {
-                       DEBUG(0, ("could not get share mode lock\n"));
-               } else {
-                       del_deferred_open_entry(lck, req->mid);
-                       TALLOC_FREE(lck);
-               }
-
-               /* Ensure we don't reprocess this message. */
-               remove_deferred_open_smb_message(req->mid);
-
-               /*
-                * When receiving a semlock_async_failure message, the
-                * deferred open will be marked as "failed". Returning
-                * INTERNAL_ERROR.
-                */
-               if (state->failed) {
-                       DEBUG(0, ("onefs_open_file_ntcreate: "
-                                 "semlock_async_failure detected!\n"));
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-       }
-
-       status = check_name(conn, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (!posix_open) {
-               new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
-               if (file_existed) {
-                       existing_dos_attributes = dos_mode(conn, fname, psbuf);
-               }
-       }
-
-       /* Setup dos_attributes to be set by ifs_createfile */
-       if (lp_store_dos_attributes(SNUM(conn))) {
-               createfile_attributes = (new_dos_attributes | aARCH) &
-                   ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
-       }
-
-       /* Ignore oplock requests if oplocks are disabled. */
-       if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
-           IS_VETO_OPLOCK_PATH(conn, fname)) {
-               /* Mask off everything except the private Samba bits. */
-               oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
-       }
-
-       /* this is for OS/2 long file names - say we don't support them */
-       if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
-               /* OS/2 Workplace shell fix may be main code stream in a later
-                * release. */
-               DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
-                         "not supported.\n"));
-               if (use_nt_status()) {
-                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
-               return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
-       }
-
-       switch( create_disposition ) {
-               /*
-                * Currently we're using FILE_SUPERSEDE as the same as
-                * FILE_OVERWRITE_IF but they really are
-                * different. FILE_SUPERSEDE deletes an existing file
-                * (requiring delete access) then recreates it.
-                */
-               case FILE_SUPERSEDE:
-                       /**
-                        * @todo: Clear all file attributes?
-                        * http://www.osronline.com/article.cfm?article=302
-                        * create if not exist, trunc if exist
-                        *
-                        * If file exists replace/overwrite. If file doesn't
-                        * exist create.
-                        */
-                       flags2 |= (O_CREAT | O_TRUNC);
-                       clear_ads = true;
-                       break;
-
-               case FILE_OVERWRITE_IF:
-                       /* If file exists replace/overwrite. If file doesn't
-                        * exist create. */
-                       flags2 |= (O_CREAT | O_TRUNC);
-                       clear_ads = true;
-                       break;
-
-               case FILE_OPEN:
-                       /* If file exists open. If file doesn't exist error. */
-                       if (!file_existed) {
-                               DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
-                                        "requested for file %s and file "
-                                        "doesn't exist.\n", fname ));
-                               errno = ENOENT;
-                               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-                       }
-                       break;
-
-               case FILE_OVERWRITE:
-                       /* If file exists overwrite. If file doesn't exist
-                        * error. */
-                       if (!file_existed) {
-                               DEBUG(5, ("onefs_open_file_ntcreate: "
-                                         "FILE_OVERWRITE requested for file "
-                                         "%s and file doesn't exist.\n",
-                                         fname));
-                               errno = ENOENT;
-                               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-                       }
-                       flags2 |= O_TRUNC;
-                       clear_ads = true;
-                       break;
-
-               case FILE_CREATE:
-                       /* If file exists error. If file doesn't exist
-                        * create. */
-                       if (file_existed) {
-                               DEBUG(5, ("onefs_open_file_ntcreate: "
-                                         "FILE_CREATE requested for file %s "
-                                         "and file already exists.\n",
-                                         fname));
-                               if (S_ISDIR(psbuf->st_mode)) {
-                                       errno = EISDIR;
-                               } else {
-                                       errno = EEXIST;
-                               }
-                               return map_nt_error_from_unix(errno);
-                       }
-                       flags2 |= (O_CREAT|O_EXCL);
-                       break;
-
-               case FILE_OPEN_IF:
-                       /* If file exists open. If file doesn't exist
-                        * create. */
-                       flags2 |= O_CREAT;
-                       break;
-
-               default:
-                       return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       /* Match attributes on file exists and overwrite. */
-       if (!posix_open && file_existed &&
-           ((create_disposition == FILE_OVERWRITE) ||
-               (create_disposition == FILE_OVERWRITE_IF))) {
-               if (!open_match_attributes(conn, fname,
-                                          existing_dos_attributes,
-                                          new_dos_attributes, psbuf->st_mode,
-                                          unx_mode, &new_unx_mode)) {
-                       DEBUG(5, ("onefs_open_file_ntcreate: attributes "
-                                 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
-                                 fname, existing_dos_attributes,
-                                 new_dos_attributes,
-                                 (unsigned int)psbuf->st_mode,
-                                 (unsigned int)unx_mode ));
-                       errno = EACCES;
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-       }
-
-       /*
-        * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
-        * access_mask, but leave the MAA for the actual open in
-        * open_access_mask.
-        */
-       open_access_mask = access_mask;
-       if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
-               access_mask |= FILE_GENERIC_ALL;
-       }
-
-       /* Convert GENERIC bits to specific bits. */
-       se_map_generic(&access_mask, &file_generic_mapping);
-       se_map_generic(&open_access_mask, &file_generic_mapping);
-
-       if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
-               /* This will cause oplock breaks. */
-               open_access_mask |= FILE_WRITE_DATA;
-       }
-
-       if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
-               PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
-               access_mask &= ~SYSTEM_SECURITY_ACCESS;
-       }
-
-       DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
-                  "open_access_mask=%#x, access_mask=0x%x\n",
-                  fname, open_access_mask, access_mask));
-
-       /*
-        * Note that we ignore the append flag as append does not
-        * mean the same thing under DOS and Unix.
-        */
-
-       if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
-           (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
-
-               /*
-                * DENY_DOS opens are always underlying read-write on the
-                * file handle, no matter what the requested access mask
-                * says. Stock samba just sets the flags, but since
-                * ifs_createfile uses the access_mask, it must be updated as
-                * well.  This allows BASE-DENY* to pass.
-                */
-               if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
-
-                       DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
-                                 "Adding O_RDWR to flags "
-                                 "(0x%x) and some READ bits to "
-                                 "open_access_mask (0x%x)\n",
-                                 flags, open_access_mask));
-
-                       flags = O_RDWR;
-                       open_access_mask |= (FILE_READ_ATTRIBUTES |
-                           FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
-
-               } else if (access_mask & (FILE_READ_ATTRIBUTES |
-                              FILE_READ_DATA |
-                              FILE_READ_EA |
-                              FILE_EXECUTE)) {
-                       flags = O_RDWR;
-               } else {
-                       flags = O_WRONLY;
-               }
-       } else {
-               flags = O_RDONLY;
-       }
-
-       /* Currently we only look at FILE_WRITE_THROUGH for create options. */
-#if defined(O_SYNC)
-       if ((create_options & FILE_WRITE_THROUGH) &&
-           lp_strict_sync(SNUM(conn))) {
-               flags2 |= O_SYNC;
-       }
-#endif /* O_SYNC */
-
-       if (posix_open && (access_mask & FILE_APPEND_DATA)) {
-               flags2 |= O_APPEND;
-       }
-
-       if (!posix_open && !CAN_WRITE(conn)) {
-               /*
-                * We should really return a permission denied error if either
-                * O_CREAT or O_TRUNC are set, but for compatibility with
-                * older versions of Samba we just AND them out.
-                */
-               flags2 &= ~(O_CREAT|O_TRUNC);
-
-               /* Deny DELETE_ACCESS explicitly if the share is read only. */
-               if (access_mask & DELETE_ACCESS) {
-                       return map_nt_error_from_unix(EACCES);
-               }
-       }
-
-       /* Ensure we can't write on a read-only share or file. */
-       if (flags != O_RDONLY && file_existed &&
-           (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
-               DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
-                         "for file %s on read only %s\n",
-                         fname, !CAN_WRITE(conn) ? "share" : "file" ));
-               errno = EACCES;
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       DEBUG(10, ("fsp = %p\n", fsp));
-
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
-       fsp->share_access = share_access;
-       fsp->fh->private_options = create_options;
-       fsp->access_mask = open_access_mask; /* We change this to the
-                                             * requested access_mask after
-                                             * the open is done. */
-       fsp->posix_open = posix_open;
-
-       /* Ensure no SAMBA_PRIVATE bits can be set. */
-       fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
-
-       if (timeval_is_zero(&request_time)) {
-               request_time = fsp->open_time;
-       }
-
-       if (file_existed) {
-               struct timespec old_write_time = get_mtimespec(psbuf);
-               id = vfs_file_id_from_sbuf(conn, psbuf);
-
-               lck = get_share_mode_lock(talloc_tos(), id,
-                                         conn->connectpath,
-                                         fname, &old_write_time);
-
-               if (lck == NULL) {
-                       DEBUG(0, ("Could not get share mode lock\n"));
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
-
-               if (lck->delete_on_close) {
-                       /* DELETE_PENDING is not deferred for a second */
-                       TALLOC_FREE(lck);
-                       return NT_STATUS_DELETE_PENDING;
-               }
-       }
-
-       SMB_ASSERT(!file_existed || (lck != NULL));
-
-       /*
-        * Ensure we pay attention to default ACLs on directories.  May be
-        * neccessary depending on ACL policies.
-        */
-        if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
-           (def_acl = directory_has_default_acl(conn, parent_dir))) {
-               unx_mode = 0777;
-       }
-
-       DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
-                "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
-                (unsigned int)flags, (unsigned int)flags2,
-                (unsigned int)unx_mode, (unsigned int)access_mask,
-                (unsigned int)open_access_mask));
-
-       /*
-        * Since the open is guaranteed to be stat only if req == NULL, a
-        * callback record is only needed if req != NULL.
-        */
-       if (req) {
-               SMB_ASSERT(fsp_data);
-               oplock_callback_id = onefs_oplock_wait_record(req->mid);
-               if (oplock_callback_id == 0) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-       } else {
-               /*
-                * It is also already asserted it's either a stream or a
-                * stat-only open at this point.
-                */
-               SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
-       }
-
-       /* Do the open. */
-       status = onefs_open_file(fsp,
-                                conn,
-                                req,
-                                parent_dir,
-                                newname,
-                                fname,
-                                psbuf,
-                                flags|flags2,
-                                unx_mode,
-                                access_mask,
-                                open_access_mask,
-                                fsp->oplock_type,
-                                oplock_callback_id,
-                                share_access,
-                                create_options,
-                                createfile_attributes,
-                                sd,
-                                &granted_oplock);
-
-       if (!NT_STATUS_IS_OK(status)) {
-
-               /* OneFS Oplock Handling */
-               if (errno == EINPROGRESS) {
-
-                       if (lck == NULL) {
-
-                               struct deferred_open_record state;
-                               struct timespec old_write_time;
-
-                               old_write_time = get_mtimespec(psbuf);
-
-                               DEBUG(3, ("Someone created file %s with an "
-                                         "oplock after we looked: Retrying\n",
-                                         fname));
-                               /*
-                                * We hit the race that when we did the stat
-                                * on the file it did not exist, and someone
-                                * has created it in between the stat and the
-                                * open_file() call. Just retry immediately.
-                                */
-                               id = vfs_file_id_from_sbuf(conn, psbuf);
-                               if (!(lck = get_share_mode_lock(talloc_tos(),
-                                         id, conn->connectpath, fname,
-                                         &old_write_time))) {
-                                       /*
-                                        * Emergency exit
-                                        */
-                                       DEBUG(0, ("onefs_open_file_ntcreate: "
-                                                 "Could not get share mode "
-                                                 "lock for %s\n", fname));
-                                       status = NT_STATUS_SHARING_VIOLATION;
-                                       goto cleanup_destroy;
-                               }
-
-                               state.delayed_for_oplocks = False;
-                               state.id = id;
-
-                               if (req != NULL) {
-                                       defer_open(lck, request_time,
-                                           timeval_zero(), req, &state);
-                               }
-                               goto cleanup_destroy;
-                       }
-                       /* Waiting for an oplock */
-                       DEBUG(5,("Async createfile because a client has an "
-                                "oplock on %s\n", fname));
-
-                       SMB_ASSERT(req);
-                       schedule_defer_open(lck, request_time, req);
-                       goto cleanup;
-               }
-
-               /* Check for a sharing violation */
-               if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
-                       uint32 can_access_mask;
-                       bool can_access = True;
-
-                       /* Check if this can be done with the deny_dos and fcb
-                        * calls. */
-
-                       /* Try to find dup fsp if possible. */
-                       if (create_options &
-                           (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
-                            NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
-
-                               if (req == NULL) {
-                                       DEBUG(0, ("DOS open without an SMB "
-                                                 "request!\n"));
-                                       status = NT_STATUS_INTERNAL_ERROR;
-                                       goto cleanup_destroy;
-                               }
-
-                               /* Use the client requested access mask here,
-                                * not the one we open with. */
-                               status = fcb_or_dos_open(req,
-                                                       conn,
-                                                       fsp,
-                                                       fname,
-                                                       id,
-                                                       req->smbpid,
-                                                       req->vuid,
-                                                       access_mask,
-                                                       share_access,
-                                                       create_options);
-
-                               if (NT_STATUS_IS_OK(status)) {
-                                       TALLOC_FREE(lck);
-                                       if (pinfo) {
-                                               *pinfo = FILE_WAS_OPENED;
-                                       }
-                                       status =  NT_STATUS_OK;
-                                       goto cleanup;
-                               }
-                       }
-
-                       /*
-                        * This next line is a subtlety we need for
-                        * MS-Access. If a file open will fail due to share
-                        * permissions and also for security (access) reasons,
-                        * we need to return the access failed error, not the
-                        * share error. We can't open the file due to kernel
-                        * oplock deadlock (it's possible we failed above on
-                        * the open_mode_check()) so use a userspace check.
-                        */
-
-                       if (flags & O_RDWR) {
-                               can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
-                       } else if (flags & O_WRONLY) {
-                               can_access_mask = FILE_WRITE_DATA;
-                       } else {
-                               can_access_mask = FILE_READ_DATA;
-                       }
-
-                       if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
-                           !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
-                               can_access = False;
-                       }
-
-                       /*
-                        * If we're returning a share violation, ensure we
-                        * cope with the braindead 1 second delay.
-                        */
-                       if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
-                           lp_defer_sharing_violations()) {
-                               struct timeval timeout;
-                               struct deferred_open_record state;
-                               int timeout_usecs;
-
-                               /* this is a hack to speed up torture tests
-                                  in 'make test' */
-                               timeout_usecs = lp_parm_int(SNUM(conn),
-                                   "smbd","sharedelay",
-                                   SHARING_VIOLATION_USEC_WAIT);
-
-                               /* This is a relative time, added to the
-                                  absolute request_time value to get the
-                                  absolute timeout time.  Note that if this
-                                  is the second or greater time we enter this
-                                  codepath for this particular request mid
-                                  then request_time is left as the absolute
-                                  time of the *first* time this request mid
-                                  was processed. This is what allows the
-                                  request to eventually time out. */
-
-                               timeout = timeval_set(0, timeout_usecs);
-
-                               /* Nothing actually uses
-                                  state.delayed_for_oplocks but it's handy to
-                                  differentiate in debug messages between a
-                                  30 second delay due to oplock break, and a
-                                  1 second delay for share mode conflicts. */
-
-                               state.delayed_for_oplocks = False;
-                               state.id = id;
-                               state.failed = false;
-
-                               if ((req != NULL)
-                                   && !request_timed_out(request_time,
-                                                         timeout)) {
-                                       defer_open(lck, request_time, timeout,
-                                                  req, &state);
-                               }
-                       }
-
-                       if (can_access) {
-                               /*
-                                * We have detected a sharing violation here
-                                * so return the correct error code
-                                */
-                               status = NT_STATUS_SHARING_VIOLATION;
-                       } else {
-                               status = NT_STATUS_ACCESS_DENIED;
-                       }
-
-                       goto cleanup_destroy;
-               }
-
-               /*
-                * Normal error, for example EACCES
-                */
-        cleanup_destroy:
-               if (oplock_callback_id != 0) {
-                       destroy_onefs_callback_record(oplock_callback_id);
-               }
-        cleanup:
-               TALLOC_FREE(lck);
-               return status;
-       }
-
-       fsp->oplock_type = granted_oplock;
-
-       if (oplock_callback_id != 0) {
-               onefs_set_oplock_callback(oplock_callback_id, fsp);
-               fsp_data->oplock_callback_id = oplock_callback_id;
-       } else {
-               SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
-       }
-
-       if (!file_existed) {
-               struct timespec old_write_time = get_mtimespec(psbuf);
-               /*
-                * Deal with the race condition where two smbd's detect the
-                * file doesn't exist and do the create at the same time. One
-                * of them will win and set a share mode, the other (ie. this
-                * one) should check if the requested share mode for this
-                * create is allowed.
-                */
-
-               /*
-                * Now the file exists and fsp is successfully opened,
-                * fsp->dev and fsp->inode are valid and should replace the
-                * dev=0,inode=0 from a non existent file. Spotted by
-                * Nadav Danieli <nadavd@exanet.com>. JRA.
-                */
-
-               id = fsp->file_id;
-
-               lck = get_share_mode_lock(talloc_tos(), id,
-                                         conn->connectpath,
-                                         fname, &old_write_time);
-
-               if (lck == NULL) {
-                       DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
-                                 "share mode lock for %s\n", fname));
-                       fd_close(fsp);
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
-
-               if (lck->delete_on_close) {
-                       status = NT_STATUS_DELETE_PENDING;
-               }
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       struct deferred_open_record state;
-
-                       fd_close(fsp);
-
-                       state.delayed_for_oplocks = False;
-                       state.id = id;
-
-                       /* Do it all over again immediately. In the second
-                        * round we will find that the file existed and handle
-                        * the DELETE_PENDING and FCB cases correctly. No need
-                        * to duplicate the code here. Essentially this is a
-                        * "goto top of this function", but don't tell
-                        * anybody... */
-
-                       if (req != NULL) {
-                               defer_open(lck, request_time, timeval_zero(),
-                                          req, &state);
-                       }
-                       TALLOC_FREE(lck);
-                       return status;
-               }
-
-               /*
-                * We exit this block with the share entry *locked*.....
-                */
-
-       }
-
-       SMB_ASSERT(lck != NULL);
-
-       /* Delete streams if create_disposition requires it */
-       if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
-               status = delete_all_streams(conn, fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(lck);
-                       fd_close(fsp);
-                       return status;
-               }
-       }
-
-       /* note that we ignore failure for the following. It is
-           basically a hack for NFS, and NFS will never set one of
-           these only read them. Nobody but Samba can ever set a deny
-           mode and we have already checked our more authoritative
-           locking database for permission to set this deny mode. If
-           the kernel refuses the operations then the kernel is wrong.
-          note that GPFS supports it as well - jmcd */
-
-       if (fsp->fh->fd != -1) {
-               ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
-               if(ret_flock == -1 ){
-
-                       TALLOC_FREE(lck);
-                       fd_close(fsp);
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
-       }
-
-       /*
-        * At this point onwards, we can guarentee that the share entry
-        * is locked, whether we created the file or not, and that the
-        * deny mode is compatible with all current opens.
-        */
-
-       /* Record the options we were opened with. */
-       fsp->share_access = share_access;
-       fsp->fh->private_options = create_options;
-       /*
-        * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
-        */
-       fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
-
-       if (file_existed) {
-               /* stat opens on existing files don't get oplocks. */
-               if (is_stat_open(open_access_mask)) {
-                       fsp->oplock_type = NO_OPLOCK;
-               }
-
-               if (!(flags2 & O_TRUNC)) {
-                       info = FILE_WAS_OPENED;
-               } else {
-                       info = FILE_WAS_OVERWRITTEN;
-               }
-       } else {
-               info = FILE_WAS_CREATED;
-       }
-
-       if (pinfo) {
-               *pinfo = info;
-       }
-
-       /*
-        * Setup the oplock info in both the shared memory and
-        * file structs.
-        */
-
-       if ((fsp->oplock_type != NO_OPLOCK) &&
-           (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
-               if (!set_file_oplock(fsp, fsp->oplock_type)) {
-                       /* Could not get the kernel oplock */
-                       fsp->oplock_type = NO_OPLOCK;
-               }
-       }
-
-       if (fsp->oplock_type == LEVEL_II_OPLOCK &&
-           (!lp_level2_oplocks(SNUM(conn)) ||
-               !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
-
-               DEBUG(5, ("Downgrading level2 oplock on open "
-                         "because level2 oplocks = off\n"));
-
-               release_file_oplock(fsp);
-       }
-
-       if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
-           info == FILE_WAS_SUPERSEDED) {
-               new_file_created = True;
-       }
-
-       set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
-                      fsp->oplock_type);
-
-       /* Handle strange delete on close create semantics. */
-       if (create_options & FILE_DELETE_ON_CLOSE) {
-               status = can_set_delete_on_close(fsp, True, new_dos_attributes);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       /* Remember to delete the mode we just added. */
-                       del_share_mode(lck, fsp);
-                       TALLOC_FREE(lck);
-                       fd_close(fsp);
-                       return status;
-               }
-               /* Note that here we set the *inital* delete on close flag,
-                  not the regular one. The magic gets handled in close. */
-               fsp->initial_delete_on_close = True;
-       }
-
-       /*
-        * Take care of inherited ACLs on created files - if default ACL not
-        * selected.
-        * May be necessary depending on acl policies.
-        */
-       if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
-                 && (psbuf->st_flags & SF_HASNTFSACL))) {
-
-               int saved_errno = errno; /* We might get ENOSYS in the next
-                                         * call.. */
-
-               if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
-                   errno == ENOSYS) {
-                       errno = saved_errno; /* Ignore ENOSYS */
-               }
-
-       } else if (new_unx_mode) {
-
-               int ret = -1;
-
-               /* Attributes need changing. File already existed. */
-
-               {
-                       int saved_errno = errno; /* We might get ENOSYS in the
-                                                 * next call.. */
-                       ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
-
-                       if (ret == -1 && errno == ENOSYS) {
-                               errno = saved_errno; /* Ignore ENOSYS */
-                       } else {
-                               DEBUG(5, ("onefs_open_file_ntcreate: reset "
-                                         "attributes of file %s to 0%o\n",
-                                         fname, (unsigned int)new_unx_mode));
-                               ret = 0; /* Don't do the fchmod below. */
-                       }
-               }
-
-               if ((ret == -1) &&
-                   (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
-                       DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
-                                 "attributes of file %s to 0%o\n",
-                                 fname, (unsigned int)new_unx_mode));
-       }
-
-       /* If this is a successful open, we must remove any deferred open
-        * records. */
-       if (req != NULL) {
-               del_deferred_open_entry(lck, req->mid);
-       }
-       TALLOC_FREE(lck);
-
-       return NT_STATUS_OK;
-}
-
-
-/****************************************************************************
- Open a directory from an NT SMB call.
-****************************************************************************/
-static NTSTATUS onefs_open_directory(connection_struct *conn,
-                                    struct smb_request *req,
-                                    const char *fname,
-                                    uint32 access_mask,
-                                    uint32 share_access,
-                                    uint32 create_disposition,
-                                    uint32 create_options,
-                                    uint32 file_attributes,
-                                    struct security_descriptor *sd,
-                                    files_struct **result,
-                                    int *pinfo,
-                                    SMB_STRUCT_STAT *psbuf)
-{
-       files_struct *fsp = NULL;
-       struct share_mode_lock *lck = NULL;
-       NTSTATUS status;
-       struct timespec mtimespec;
-       int info = 0;
-       char *parent_dir;
-       const char *dirname;
-       bool posix_open = false;
-       uint32 create_flags = 0;
-       uint32 mode = lp_dir_mask(SNUM(conn));
-
-       DEBUG(5, ("onefs_open_directory: opening directory %s, "
-                 "access_mask = 0x%x, "
-                 "share_access = 0x%x create_options = 0x%x, "
-                 "create_disposition = 0x%x, file_attributes = 0x%x\n",
-                 fname, (unsigned int)access_mask, (unsigned int)share_access,
-                 (unsigned int)create_options, (unsigned int)create_disposition,
-                 (unsigned int)file_attributes));
-
-       if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
-           (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
-           is_ntfs_stream_name(fname)) {
-               DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
-               return NT_STATUS_NOT_A_DIRECTORY;
-       }
-
-       switch (create_disposition) {
-               case FILE_OPEN:
-                       /* If directory exists open. If directory doesn't
-                        * exist error. */
-                       create_flags = 0;
-                       info = FILE_WAS_OPENED;
-                       break;
-               case FILE_CREATE:
-                       /* If directory exists error. If directory doesn't
-                        * exist create. */
-                       create_flags = O_CREAT | O_EXCL;
-                       info = FILE_WAS_CREATED;
-                       break;
-               case FILE_OPEN_IF:
-                       /* If directory exists open. If directory doesn't
-                        * exist create. */
-
-                       /* Note: in order to return whether the directory was
-                        * opened or created, we first try to open and then try
-                        * to create. */
-                       create_flags = 0;
-                       info = FILE_WAS_OPENED;
-                       break;
-               case FILE_SUPERSEDE:
-               case FILE_OVERWRITE:
-               case FILE_OVERWRITE_IF:
-               default:
-                       DEBUG(5, ("onefs_open_directory: invalid "
-                                 "create_disposition 0x%x for directory %s\n",
-                                 (unsigned int)create_disposition, fname));
-                       return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       /*
-        * Check for write access to the share. Done in mkdir_internal() in
-        * mainline samba.
-        */
-       if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       /* Get parent dirname */
-       if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
-               posix_open = true;
-               mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
-               file_attributes = 0;
-       } else {
-               mode = unix_mode(conn, aDIR, fname, parent_dir);
-       }
-
-       /*
-        * The NONINDEXED and COMPRESSED bits seem to always be cleared on
-        * directories, no matter if you specify that they should be set.
-        */
-       file_attributes &=
-           ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
-
-       status = file_new(req, conn, &fsp);
-       if(!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /*
-        * Actual open with retry magic to handle FILE_OPEN_IF which is
-        * unique because the kernel won't tell us if the file was opened or
-        * created.
-        */
- retry_open:
-       fsp->fh->fd = onefs_sys_create_file(conn,
-                                           -1,
-                                           fname,
-                                           access_mask,
-                                           access_mask,
-                                           share_access,
-                                           create_options,
-                                           create_flags | O_DIRECTORY,
-                                           mode,
-                                           0,
-                                           0,
-                                           sd,
-                                           file_attributes,
-                                           NULL);
-
-       if (fsp->fh->fd == -1) {
-               DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
-                         strerror(errno)));
-               SMB_ASSERT(errno != EINPROGRESS);
-
-               if (create_disposition == FILE_OPEN_IF) {
-                       if (errno == ENOENT) {
-                               /* Try again, creating it this time. */
-                               create_flags = O_CREAT | O_EXCL;
-                               info = FILE_WAS_CREATED;
-                               goto retry_open;
-                       } else if (errno == EEXIST) {
-                               /* Uggh. Try again again. */
-                               create_flags = 0;
-                               info = FILE_WAS_OPENED;
-                               goto retry_open;
-                       }
-               }
-
-               /* Error cases below: */
-               file_free(req, fsp);
-
-               if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
-                       DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
-                                 "for directory %s and it doesn't "
-                                 "exist.\n", fname ));
-                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               } else if ((errno == EEXIST) &&
-                   (create_disposition == FILE_CREATE)) {
-                       DEBUG(5,("onefs_open_directory: FILE_CREATE "
-                                 "requested for directory %s and it "
-                                 "already exists.\n", fname ));
-                       return NT_STATUS_OBJECT_NAME_COLLISION;
-               } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
-                       /* Catch sharing violations. */
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
-
-               return map_nt_error_from_unix(errno);
-       }
-
-       if (info == FILE_WAS_CREATED) {
-
-               /* Pulled from mkdir_internal() */
-               if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
-                       DEBUG(2, ("Could not stat directory '%s' just "
-                                 "created: %s\n",fname, strerror(errno)));
-                       return map_nt_error_from_unix(errno);
-               }
-
-               if (!S_ISDIR(psbuf->st_mode)) {
-                       DEBUG(0, ("Directory just '%s' created is not a "
-                                 "directory\n", fname));
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-
-               if (!posix_open) {
-                       /*
-                        * Check if high bits should have been set, then (if
-                        * bits are missing): add them.  Consider bits
-                        * automagically set by UNIX, i.e. SGID bit from
-                        * parent dir.
-                        */
-                       if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
-                           (mode & ~psbuf->st_mode)) {
-                               SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
-                                                 (mode & ~psbuf->st_mode)));
-                       }
-               }
-
-               /* Change the owner if required. */
-               if (lp_inherit_owner(SNUM(conn))) {
-                       change_dir_owner_to_parent(conn, parent_dir, fname,
-                                                  psbuf);
-               }
-
-               notify_fname(conn, NOTIFY_ACTION_ADDED,
-                            FILE_NOTIFY_CHANGE_DIR_NAME, fname);
-       }
-
-       /* Stat the fd for Samba bookkeeping. */
-       if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
-               fd_close(fsp);
-               file_free(req, fsp);
-               return map_nt_error_from_unix(errno);
-       }
-
-       /* Setup the files_struct for it. */
-       fsp->mode = psbuf->st_mode;
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
-       fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
-       fsp->file_pid = req ? req->smbpid : 0;
-       fsp->can_lock = False;
-       fsp->can_read = False;
-       fsp->can_write = False;
-
-       fsp->share_access = share_access;
-       fsp->fh->private_options = create_options;
-       /*
-        * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
-        */
-       fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
-       fsp->print_file = False;
-       fsp->modified = False;
-       fsp->oplock_type = NO_OPLOCK;
-       fsp->sent_oplock_break = NO_BREAK_SENT;
-       fsp->is_directory = True;
-       fsp->posix_open = posix_open;
-
-       string_set(&fsp->fsp_name,fname);
-
-       mtimespec = get_mtimespec(psbuf);
-
-       /*
-        * Still set the samba share mode lock for correct delete-on-close
-        * semantics and to make smbstatus more useful.
-        */
-       lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
-                                 conn->connectpath,
-                                 fname, &mtimespec);
-
-       if (lck == NULL) {
-               DEBUG(0, ("onefs_open_directory: Could not get share mode "
-                         "lock for %s\n", fname));
-               fd_close(fsp);
-               file_free(req, fsp);
-               return NT_STATUS_SHARING_VIOLATION;
-       }
-
-       if (lck->delete_on_close) {
-               TALLOC_FREE(lck);
-               fd_close(fsp);
-               file_free(req, fsp);
-               return NT_STATUS_DELETE_PENDING;
-       }
-
-       set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
-
-       /*
-        * For directories the delete on close bit at open time seems
-        * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
-        */
-       if (create_options & FILE_DELETE_ON_CLOSE) {
-               status = can_set_delete_on_close(fsp, True, 0);
-               if (!NT_STATUS_IS_OK(status) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
-                       TALLOC_FREE(lck);
-                       fd_close(fsp);
-                       file_free(req, fsp);
-                       return status;
-               }
-
-               if (NT_STATUS_IS_OK(status)) {
-                       /* Note that here we set the *inital* delete on close flag,
-                          not the regular one. The magic gets handled in close. */
-                       fsp->initial_delete_on_close = True;
-               }
-       }
-
-       TALLOC_FREE(lck);
-
-       if (pinfo) {
-               *pinfo = info;
-       }
-
-       *result = fsp;
-       return NT_STATUS_OK;
-}
-
-/*
- * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
- */
-static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
-                                          struct smb_request *req,
-                                          const char *fname,
-                                          uint32_t access_mask,
-                                          uint32_t share_access,
-                                          uint32_t create_disposition,
-                                          uint32_t create_options,
-                                          uint32_t file_attributes,
-                                          uint32_t oplock_request,
-                                          uint64_t allocation_size,
-                                          struct security_descriptor *sd,
-                                          struct ea_list *ea_list,
-                                          files_struct **result,
-                                          int *pinfo,
-                                          struct onefs_fsp_data *fsp_data,
-                                          SMB_STRUCT_STAT *psbuf)
-{
-       SMB_STRUCT_STAT sbuf;
-       int info = FILE_WAS_OPENED;
-       files_struct *base_fsp = NULL;
-       files_struct *fsp = NULL;
-       NTSTATUS status;
-
-       DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
-                 "file_attributes = 0x%x, share_access = 0x%x, "
-                 "create_disposition = 0x%x create_options = 0x%x "
-                 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
-                 "fname = %s\n",
-                 (unsigned int)access_mask,
-                 (unsigned int)file_attributes,
-                 (unsigned int)share_access,
-                 (unsigned int)create_disposition,
-                 (unsigned int)create_options,
-                 (unsigned int)oplock_request,
-                 ea_list, sd, fname));
-
-       if (create_options & FILE_OPEN_BY_FILE_ID) {
-               status = NT_STATUS_NOT_SUPPORTED;
-               goto fail;
-       }
-
-       if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto fail;
-       }
-
-       if (req == NULL) {
-               SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
-                           NO_OPLOCK);
-               oplock_request |= INTERNAL_OPEN_ONLY;
-       }
-
-       if (psbuf != NULL) {
-               sbuf = *psbuf;
-       }
-       else {
-               if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
-                       SET_STAT_INVALID(sbuf);
-               }
-       }
-
-       if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-           && (access_mask & DELETE_ACCESS)
-           && !is_ntfs_stream_name(fname)) {
-               /*
-                * We can't open a file with DELETE access if any of the
-                * streams is open without FILE_SHARE_DELETE
-                */
-               status = open_streams_for_delete(conn, fname);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-       }
-
-       if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-           && is_ntfs_stream_name(fname)) {
-               char *base;
-               uint32 base_create_disposition;
-
-               if (create_options & FILE_DIRECTORY_FILE) {
-                       status = NT_STATUS_NOT_A_DIRECTORY;
-                       goto fail;
-               }
-
-               status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
-                                                     &base, NULL);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("onefs_create_file_unixpath: "
-                                 "split_ntfs_stream_name failed: %s\n",
-                                 nt_errstr(status)));
-                       goto fail;
-               }
-
-               SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
-
-               switch (create_disposition) {
-               case FILE_OPEN:
-                       base_create_disposition = FILE_OPEN;
-                       break;
-               default:
-                       base_create_disposition = FILE_OPEN_IF;
-                       break;
-               }
-
-               status = onefs_create_file_unixpath(
-                       conn,                           /* conn */
-                       NULL,                           /* req */
-                       base,                           /* fname */
-                       SYNCHRONIZE_ACCESS,             /* access_mask */
-                       (FILE_SHARE_READ |
-                           FILE_SHARE_WRITE |
-                           FILE_SHARE_DELETE),         /* share_access */
-                       base_create_disposition,        /* create_disposition*/
-                       0,                              /* create_options */
-                       file_attributes,                /* file_attributes */
-                       NO_OPLOCK,                      /* oplock_request */
-                       0,                              /* allocation_size */
-                       NULL,                           /* sd */
-                       NULL,                           /* ea_list */
-                       &base_fsp,                      /* result */
-                       NULL,                           /* pinfo */
-                       NULL,                           /* fsp_data */
-                       NULL);                          /* psbuf */
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("onefs_create_file_unixpath for base %s "
-                                 "failed: %s\n", base, nt_errstr(status)));
-                       goto fail;
-               }
-       }
-
-       /* Covert generic bits in the security descriptor. */
-       if (sd != NULL) {
-               security_acl_map_generic(sd->dacl, &file_generic_mapping);
-               security_acl_map_generic(sd->sacl, &file_generic_mapping);
-       }
-
-       /*
-        * If it's a request for a directory open, deal with it separately.
-        */
-
-       if (create_options & FILE_DIRECTORY_FILE) {
-
-               if (create_options & FILE_NON_DIRECTORY_FILE) {
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto fail;
-               }
-
-               /* Can't open a temp directory. IFS kit test. */
-               if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
-                    (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto fail;
-               }
-
-               /*
-                * We will get a create directory here if the Win32
-                * app specified a security descriptor in the
-                * CreateDirectory() call.
-                */
-
-               status = onefs_open_directory(
-                       conn,                           /* conn */
-                       req,                            /* req */
-                       fname,                          /* fname */
-                       access_mask,                    /* access_mask */
-                       share_access,                   /* share_access */
-                       create_disposition,             /* create_disposition*/
-                       create_options,                 /* create_options */
-                       file_attributes,                /* file_attributes */
-                       sd,                             /* sd */
-                       &fsp,                           /* result */
-                       &info,                          /* pinfo */
-                       &sbuf);                         /* psbuf */
-       } else {
-
-               /*
-                * Ordinary file case.
-                */
-
-               status = file_new(req, conn, &fsp);
-               if(!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-
-               /*
-                * We're opening the stream element of a base_fsp
-                * we already opened. Set up the base_fsp pointer.
-                */
-               if (base_fsp) {
-                       fsp->base_fsp = base_fsp;
-               }
-
-               status = onefs_open_file_ntcreate(
-                       conn,                           /* conn */
-                       req,                            /* req */
-                       fname,                          /* fname */
-                       access_mask,                    /* access_mask */
-                       share_access,                   /* share_access */
-                       create_disposition,             /* create_disposition*/
-                       create_options,                 /* create_options */
-                       file_attributes,                /* file_attributes */
-                       oplock_request,                 /* oplock_request */
-                       sd,                             /* sd */
-                       fsp,                            /* result */
-                       &info,                          /* pinfo */
-                       fsp_data,                       /* fsp_data */
-                       &sbuf);                         /* psbuf */
-
-               if(!NT_STATUS_IS_OK(status)) {
-                       file_free(req, fsp);
-                       fsp = NULL;
-               }
-
-               if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
-
-                       /* A stream open never opens a directory */
-
-                       if (base_fsp) {
-                               status = NT_STATUS_FILE_IS_A_DIRECTORY;
-                               goto fail;
-                       }
-
-                       /*
-                        * Fail the open if it was explicitly a non-directory
-                        * file.
-                        */
-
-                       if (create_options & FILE_NON_DIRECTORY_FILE) {
-                               status = NT_STATUS_FILE_IS_A_DIRECTORY;
-                               goto fail;
-                       }
-
-                       create_options |= FILE_DIRECTORY_FILE;
-
-                       status = onefs_open_directory(
-                               conn,                   /* conn */
-                               req,                    /* req */
-                               fname,                  /* fname */
-                               access_mask,            /* access_mask */
-                               share_access,           /* share_access */
-                               create_disposition,     /* create_disposition*/
-                               create_options,         /* create_options */
-                               file_attributes,        /* file_attributes */
-                               sd,                     /* sd */
-                               &fsp,                   /* result */
-                               &info,                  /* pinfo */
-                               &sbuf);                 /* psbuf */
-               }
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
-
-       fsp->base_fsp = base_fsp;
-
-       SMB_ASSERT(fsp);
-
-       if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
-               status = set_ea(conn, fsp, fname, ea_list);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-       }
-
-       if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
-               status = NT_STATUS_ACCESS_DENIED;
-               goto fail;
-       }
-
-       /* Save the requested allocation size. */
-       if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
-               if (allocation_size
-                   && (allocation_size > sbuf.st_size)) {
-                       fsp->initial_allocation_size = smb_roundup(
-                               fsp->conn, allocation_size);
-                       if (fsp->is_directory) {
-                               /* Can't set allocation size on a directory. */
-                               status = NT_STATUS_ACCESS_DENIED;
-                               goto fail;
-                       }
-                       if (vfs_allocate_file_space(
-                                   fsp, fsp->initial_allocation_size) == -1) {
-                               status = NT_STATUS_DISK_FULL;
-                               goto fail;
-                       }
-               } else {
-                       fsp->initial_allocation_size = smb_roundup(
-                               fsp->conn, (uint64_t)sbuf.st_size);
-               }
-       }
-
-       DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
-
-       *result = fsp;
-       if (pinfo != NULL) {
-               *pinfo = info;
-       }
-       if (psbuf != NULL) {
-               if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
-                       *psbuf = sbuf;
-               }
-               else {
-                       SMB_VFS_FSTAT(fsp, psbuf);
-               }
-       }
-       return NT_STATUS_OK;
-
- fail:
-       DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
-
-       if (fsp != NULL) {
-               if (base_fsp && fsp->base_fsp == base_fsp) {
-                       /*
-                        * The close_file below will close
-                        * fsp->base_fsp.
-                        */
-                       base_fsp = NULL;
-               }
-               close_file(req, fsp, ERROR_CLOSE);
-               fsp = NULL;
-       }
-       if (base_fsp != NULL) {
-               close_file(req, base_fsp, ERROR_CLOSE);
-               base_fsp = NULL;
-       }
-       return status;
-}
-
-static void destroy_onefs_fsp_data(void *p_data)
-{
-       struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
-
-       destroy_onefs_callback_record(fsp_data->oplock_callback_id);
-}
-
-/**
- * SMB_VFS_CREATE_FILE interface to onefs.
- */
-NTSTATUS onefs_create_file(vfs_handle_struct *handle,
-                          struct smb_request *req,
-                          uint16_t root_dir_fid,
-                          const char *fname,
-                          uint32_t create_file_flags,
-                          uint32_t access_mask,
-                          uint32_t share_access,
-                          uint32_t create_disposition,
-                          uint32_t create_options,
-                          uint32_t file_attributes,
-                          uint32_t oplock_request,
-                          uint64_t allocation_size,
-                          struct security_descriptor *sd,
-                          struct ea_list *ea_list,
-                          files_struct **result,
-                          int *pinfo,
-                          SMB_STRUCT_STAT *psbuf)
-{
-       connection_struct *conn = handle->conn;
-       struct case_semantics_state *case_state = NULL;
-       struct onefs_fsp_data fsp_data = {};
-       SMB_STRUCT_STAT sbuf;
-       int info = FILE_WAS_OPENED;
-       files_struct *fsp = NULL;
-       NTSTATUS status;
-
-       DEBUG(10,("onefs_create_file: access_mask = 0x%x "
-                 "file_attributes = 0x%x, share_access = 0x%x, "
-                 "create_disposition = 0x%x create_options = 0x%x "
-                 "oplock_request = 0x%x "
-                 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
-                 "create_file_flags = 0x%x, fname = %s\n",
-                 (unsigned int)access_mask,
-                 (unsigned int)file_attributes,
-                 (unsigned int)share_access,
-                 (unsigned int)create_disposition,
-                 (unsigned int)create_options,
-                 (unsigned int)oplock_request,
-                 (unsigned int)root_dir_fid,
-                 ea_list, sd, create_file_flags, fname));
-
-       /* Get the file name if root_dir_fid was specified. */
-       if (root_dir_fid != 0) {
-               char *new_fname;
-
-               status = get_relative_fid_filename(conn, req, root_dir_fid,
-                                                  fname, &new_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-
-               fname = new_fname;
-       }
-
-       /* Resolve the file name if this was a DFS pathname. */
-       if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
-               char *resolved_fname;
-
-               status = resolve_dfspath(talloc_tos(), conn, true, fname,
-                                        &resolved_fname);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       /*
-                        * For PATH_NOT_COVERED we had
-                        * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                        *                 ERRSRV, ERRbadpath);
-                        * Need to fix in callers
-                        */
-                       goto fail;
-               }
-               fname = resolved_fname;
-       }
-
-       /* Check if POSIX semantics are wanted. */
-       if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
-               case_state = set_posix_case_semantics(talloc_tos(), conn);
-       }
-
-       /* Convert dos path to unix path if it hasn't already been done. */
-       if (create_file_flags & CFF_DOS_PATH) {
-               char *converted_fname;
-
-               SET_STAT_INVALID(sbuf);
-
-               status = unix_convert(talloc_tos(), conn, fname, False,
-                                     &converted_fname, NULL, &sbuf);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-               fname = converted_fname;
-       } else {
-               if (psbuf != NULL) {
-                       sbuf = *psbuf;
-               } else {
-                       if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
-                               SET_STAT_INVALID(sbuf);
-                       }
-               }
-
-       }
-
-       TALLOC_FREE(case_state);
-
-       /* All file access must go through check_name() */
-       status = check_name(conn, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
-
-       status = onefs_create_file_unixpath(
-               conn,                                   /* conn */
-               req,                                    /* req */
-               fname,                                  /* fname */
-               access_mask,                            /* access_mask */
-               share_access,                           /* share_access */
-               create_disposition,                     /* create_disposition*/
-               create_options,                         /* create_options */
-               file_attributes,                        /* file_attributes */
-               oplock_request,                         /* oplock_request */
-               allocation_size,                        /* allocation_size */
-               sd,                                     /* sd */
-               ea_list,                                /* ea_list */
-               &fsp,                                   /* result */
-               &info,                                  /* pinfo */
-               &fsp_data,                              /* fsp_data */
-               &sbuf);                                 /* psbuf */
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
-
-       DEBUG(10, ("onefs_create_file: info=%d\n", info));
-
-       /*
-        * Setup private onefs_fsp_data.  Currently the private data struct is
-        * only used to store the oplock_callback_id so that when the file is
-        * closed, the onefs_callback_record can be properly cleaned up in the
-        * oplock_onefs sub-system.
-        */
-       if (fsp) {
-               struct onefs_fsp_data *fsp_data_tmp = NULL;
-               fsp_data_tmp = (struct onefs_fsp_data *)
-                   VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
-                       &destroy_onefs_fsp_data);
-
-               if (fsp_data_tmp == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto fail;
-               }
-
-               *fsp_data_tmp = fsp_data;
-       }
-
-       *result = fsp;
-       if (pinfo != NULL) {
-               *pinfo = info;
-       }
-       if (psbuf != NULL) {
-               *psbuf = sbuf;
-       }
-       return NT_STATUS_OK;
-
- fail:
-       DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
-
-       if (fsp != NULL) {
-               close_file(req, fsp, ERROR_CLOSE);
-               fsp = NULL;
-       }
-       return status;
-}