pvfs: fix handling of create_option flags
[tprouty/samba.git] / source4 / ntvfs / posix / pvfs_open.c
index 43203086f8711de7859cad828aa2388c6f81e7eb..c127885a68f3cae149cb6321d19cdf0076c4206c 100644 (file)
@@ -631,12 +631,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        status = pvfs_access_check_create(pvfs, req, name, &access_mask);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       if (io->generic.in.query_maximal_access) {
-               status = pvfs_access_maximal_allowed(pvfs, req, name, 
-                                                    &io->generic.out.maximal_access);
-               NT_STATUS_NOT_OK_RETURN(status);
-       }
-
        /* check that the parent isn't opened with delete on close set */
        status = pvfs_resolve_parent(pvfs, req, name, &parent);
        if (NT_STATUS_IS_OK(status)) {
@@ -707,6 +701,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
                goto cleanup_delete;
        }
 
+       if (io->generic.in.query_maximal_access) {
+               status = pvfs_access_maximal_allowed(pvfs, req, name, 
+                                                    &io->generic.out.maximal_access);
+               NT_STATUS_NOT_OK_RETURN(status);
+       }
+
        /* form the lock context used for byte range locking and
           opendb locking */
        status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
@@ -1173,7 +1173,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                   struct ntvfs_request *req, union smb_open *io)
 {
        struct pvfs_state *pvfs = ntvfs->private_data;
-       int flags;
+       int flags = 0;
        struct pvfs_filename *name;
        struct pvfs_file *f;
        struct ntvfs_handle *h;
@@ -1181,6 +1181,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        int fd;
        struct odb_lock *lck;
        uint32_t create_options;
+       uint32_t create_options_must_ignore_mask;
        uint32_t share_access;
        uint32_t access_mask;
        uint32_t create_action = NTCREATEX_ACTION_EXISTED;
@@ -1206,11 +1207,46 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       /* some create options are not supported */
+       /*
+        * These options are ignored,
+        * but we reuse some of them as private values for the generic mapping
+        */
+       create_options_must_ignore_mask = NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+       create_options_must_ignore_mask &= ~NTCREATEX_OPTIONS_PRIVATE_MASK;
+       create_options &= ~create_options_must_ignore_mask;
+
        if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
                return NT_STATUS_NOT_SUPPORTED;
        }
 
+       if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* TODO: When we implement HSM, add a hook here not to pull
+        * the actual file off tape, when this option is passed from
+        * the client */
+       if (create_options & NTCREATEX_OPTIONS_NO_RECALL) {
+               /* no-op */
+       }
+
+       /* TODO: If (unlikely) Linux does a good compressed
+        * filesystem, we might need an ioctl call for this */
+       if (create_options & NTCREATEX_OPTIONS_NO_COMPRESSION) {
+               /* no-op */
+       }
+
+       if (create_options & NTCREATEX_OPTIONS_NO_INTERMEDIATE_BUFFERING) {
+               create_options |= NTCREATEX_OPTIONS_WRITE_THROUGH;
+       }
+
+       /* Open the file with sync, if they asked for it, but
+          'strict sync = no' turns this client request into a no-op */
+       if (create_options & (NTCREATEX_OPTIONS_WRITE_THROUGH) && !(pvfs->flags | PVFS_FLAG_STRICT_SYNC)) {
+               flags |= O_SYNC;
+       }
+
+
        /* other create options are not allowed */
        if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
            !(access_mask & SEC_STD_DELETE)) {
@@ -1271,8 +1307,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
           open doesn't match */
        io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
 
-       flags = 0;
-
        switch (io->generic.in.open_disposition) {
        case NTCREATEX_DISP_SUPERSEDE:
        case NTCREATEX_DISP_OVERWRITE_IF: