r3200: - improved the accuracy of openx emulation. We now nearly pass the openx porti...
authorAndrew Tridgell <tridge@samba.org>
Mon, 25 Oct 2004 07:03:15 +0000 (07:03 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:04:40 +0000 (13:04 -0500)
- fixed directory size reporting to make it consistent. we now pass
  the ntcreatex portion of RAW-OPEN

source/ntvfs/ntvfs_generic.c
source/ntvfs/posix/pvfs_fileinfo.c
source/ntvfs/posix/pvfs_open.c

index ceb7900935d573c95fc7660871cff285409e2e13..452273cbdb2dfc23677923cc3fa185d32951b1f9 100644 (file)
@@ -90,14 +90,20 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) {
                case OPENX_MODE_ACCESS_READ:
                        io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ;
+                       io->openx.out.access = OPENX_MODE_ACCESS_READ;
                        break;
                case OPENX_MODE_ACCESS_WRITE:
                        io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE;
+                       io->openx.out.access = OPENX_MODE_ACCESS_WRITE;
                        break;
                case OPENX_MODE_ACCESS_RDWR:
                case OPENX_MODE_ACCESS_FCB:
+               case OPENX_MODE_ACCESS_EXEC:
                        io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE;
+                       io->openx.out.access = OPENX_MODE_ACCESS_RDWR;
                        break;
+               default:
+                       return NT_STATUS_INVALID_LOCK_SEQUENCE;
                }
 
                switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) {
@@ -129,12 +135,11 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                case OPENX_MODE_DENY_FCB:
                        io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
                        break;
+               default:
+                       return NT_STATUS_INVALID_LOCK_SEQUENCE;
                }
 
                switch (io->openx.in.open_func) {
-               case (OPENX_OPEN_FUNC_FAIL):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
-                       break;
                case (OPENX_OPEN_FUNC_OPEN):
                        io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN;
                        break;
@@ -150,8 +155,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE):
                        io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
                        break;                  
+               default:
+                       /* this one is very strange */
+                       if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) ==
+                           OPENX_MODE_ACCESS_EXEC) {
+                               io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
+                               break;
+                       }
+                       return NT_STATUS_INVALID_LOCK_SEQUENCE;
                }
-               io2->generic.in.alloc_size = io->openx.in.size;
+
+               io2->generic.in.alloc_size = 0;
                io2->generic.in.file_attr = io->openx.in.file_attrs;
                io2->generic.in.fname = io->openx.in.fname;
 
@@ -159,13 +173,35 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
+
+               io->openx.out.fnum        = io2->generic.out.fnum;
+               io->openx.out.attrib      = io2->generic.out.attrib;
+               io->openx.out.write_time  = nt_time_to_unix(io2->generic.out.write_time);
+               io->openx.out.size        = io2->generic.out.size;
+               io->openx.out.ftype       = 0;
+               io->openx.out.devstate    = 0;
+               io->openx.out.action      = io2->generic.out.create_action;
+               io->openx.out.unique_fid  = 0;
+               io->openx.out.access_mask = io2->generic.in.access_mask;
+               io->openx.out.unknown     = 0;
                
-               ZERO_STRUCT(io->openx.out);
-               io->openx.out.fnum = io2->generic.out.fnum;
-               io->openx.out.attrib = io2->generic.out.attrib;
-               io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
-               io->openx.out.size = io2->generic.out.size;
-               
+               /* we need to extend the file to the requested size if
+                  it was newly created */
+               if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED &&
+                   io->openx.in.size != 0) {
+                       union smb_setfileinfo *sf;
+                       sf = talloc_p(req, union smb_setfileinfo);
+                       if (sf != NULL) {
+                               sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+                               sf->generic.file.fnum = io2->generic.out.fnum;
+                               sf->end_of_file_info.in.size = io->openx.in.size;
+                               status = ntvfs->ops->setfileinfo(ntvfs, req, sf);
+                               if (NT_STATUS_IS_OK(status)) {
+                                       io->openx.out.size = io->openx.in.size;
+                               }
+                       }
+               }
+                               
                return NT_STATUS_OK;
 
 
index 4fa2c1601ba4169b377d3f9f76ebe1ce28dfc360..2e2acb2c8287be3236f080c7c54a6f4510cdd8e0 100644 (file)
@@ -57,12 +57,6 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st)
        if (S_ISDIR(st->st_mode))
                result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
 
-#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE)
-       if (st->st_size > st->st_blocks * (off_t)st->st_blksize) {
-               result |= FILE_ATTRIBUTE_SPARSE;
-       }
-#endif
-
        if (!(result & 
              (FILE_ATTRIBUTE_READONLY|
               FILE_ATTRIBUTE_ARCHIVE|
@@ -82,6 +76,11 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st)
 */
 NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name)
 {
+       /* make directories appear as size 0 */
+       if (S_ISDIR(name->st.st_mode)) {
+               name->st.st_size = 0;
+       }
+
        /* for now just use the simple samba mapping */
        unix_to_nt_time(&name->dos.create_time, name->st.st_ctime);
        unix_to_nt_time(&name->dos.access_time, name->st.st_atime);
index 4844521c45b5e9ccb18640b21bf32ee5746eea34..5e162ad147743a3cc484a2a2b6d302e7b2451f31 100644 (file)
@@ -180,8 +180,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        io->generic.out.write_time    = name->dos.write_time;
        io->generic.out.change_time   = name->dos.change_time;
        io->generic.out.attrib        = name->dos.attrib;
-       io->generic.out.alloc_size    = 0;
-       io->generic.out.size          = 0;
+       io->generic.out.alloc_size    = name->dos.alloc_size;
+       io->generic.out.size          = name->st.st_size;
        io->generic.out.file_type     = FILE_TYPE_DISK;
        io->generic.out.ipc_state     = 0;
        io->generic.out.is_directory  = 1;
@@ -457,9 +457,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
        switch (io->generic.in.open_disposition) {
        case NTCREATEX_DISP_SUPERSEDE:
-               if (!name->exists) {
-                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
                flags = O_TRUNC;
                break;