Ok - this is a big patch - and it may break smbd a bit (although
authorJeremy Allison <jra@samba.org>
Thu, 19 Oct 2000 02:58:24 +0000 (02:58 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 19 Oct 2000 02:58:24 +0000 (02:58 +0000)
I hope not). If you encounter strange file-serving behavior after this
patch then back it out. I analysed our stat() usage and realised we
were doing approx. 3 stat calls per open, and 2 per getattr/setattr.
This patch should fix all that. It causes the stat struct returned
from unix_convert() (which now *must* be passed a valid SMB_STRUCT_STAT
pointer) to be passed through into the open code. This should prevent
the multiple stats that were being done so as not to violate layer
encapsulation in the API's.

Herb - if you could run a NetBench test with this code and do a
padc/par syscall test and also run with the current 2.2.0 code
and test the padc/par syscalls I'd appreciate it - you should
find the number of stat calls reduced - not sure by how much.

The patch depends on unix_convert() actually finding the file
and returning a stat struct, or returning a zero'd out stat
struct if the file didn't exist. I believe we can guarentee this
to be the case - I just wasn't confident enough to make this
an assertion before.

Ok ok - I did write this whilst at the Miami conference.....
sometimes you get a little free time at these things :-).

Jeremy.
(This used to be commit 66a5c05ec46b641224fbe01b30bd7e83571a2a1b)

source3/include/proto.h
source3/include/smb_macros.h
source3/smbd/filename.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/reply.c
source3/smbd/statcache.c
source3/smbd/trans2.c
source3/smbd/vfs.c

index f52bff2ce02209ea51d99339045508e6bd40d9e9..89ee6cbdc38a6acb15dd7945ed183c103e53c545 100644 (file)
@@ -3608,12 +3608,12 @@ int reply_nttrans(connection_struct *conn,
 
 #if OLD_NTDOMAIN
 int fd_close(struct connection_struct *conn, files_struct *fsp);
-files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mode,int ofun,
-                     mode_t mode,int oplock_request, int *Access,int *action);
-files_struct *open_file_stat(connection_struct *conn,
-                  char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action);
-files_struct *open_directory(connection_struct *conn,
-                  char *fname, int smb_ofun, mode_t unixmode, int *action);
+files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
+                               int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action);
+files_struct *open_file_stat(connection_struct *conn, char *fname,
+                                                       SMB_STRUCT_STAT *psbuf, int smb_ofun, int *action);
+files_struct *open_directory(connection_struct *conn, char *fname,
+                                                       SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action);
 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
 #endif
 
index a65b7048e91c1d5071f631d60d28c9c50215e653..2e74d7e69f55f7f9f6332d44b3d1299b4e05b197 100644 (file)
  * stat structure is valid.
  */
 
-#define VALID_STAT(st) (st.st_nlink != 0)  
-#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR(st.st_mode))
+#define VALID_STAT(st) ((st).st_nlink != 0)  
+#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
 
 #define SMBENCRYPT()       (lp_encrypted_passwords())
 
index 9ac82386f924e13f239bcd501e8ee928d61e4165..5fe4a4c9038a4ecc675711836281eca80ee554cc 100644 (file)
@@ -111,6 +111,11 @@ The bad_path arg is set to True if the filename walk failed. This is
 used to pick the correct error code to return between ENOENT and ENOTDIR
 as Windows applications depend on ERRbadpath being returned if a component
 of a pathname does not exist.
+
+On exit from unix_convert, if *pst was not null, then the file stat
+struct will be returned if the file exists and was found, if not this
+stat struct will be filled with zeros (and this can be detected by checking
+for nlinks = 0, which can never be true for any file).
 ****************************************************************************/
 
 BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, 
@@ -127,6 +132,13 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
   extern char magic_char;
 #endif
 
+  ZERO_STRUCTP(pst);
+
+  *dirpath = 0;
+  *bad_path = False;
+  if(saved_last_component)
+    *saved_last_component = 0;
+
   if (conn->printer) {
          /* we don't ever use the filenames on a printer share as a
             filename - so don't convert them */
@@ -135,15 +147,6 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
 
   DEBUG(5, ("unix_convert called on file \"%s\"\n", name));
 
-  *dirpath = 0;
-  *bad_path = False;
-  if(pst) {
-    ZERO_STRUCTP(pst);
-  }
-
-  if(saved_last_component)
-    *saved_last_component = 0;
-
   /* 
    * Convert to basic unix format - removing \ chars and cleaning it up.
    */
@@ -165,7 +168,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
    * printing share.
    */
 
-  if (!*name && (!conn -> printer)) {
+  if (!*name) {
     name[0] = '.';
     name[1] = '\0';
   }
@@ -202,8 +205,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
   pstrcpy(orig_path, name);
 
   if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
-    if(pst)
-      *pst = st;
+    *pst = st;
     return True;
   }
 
@@ -211,11 +213,10 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
    * stat the name - if it exists then we are all done!
    */
 
-  if (conn->vfs_ops.stat(conn,dos_to_unix(name,False),&st) == 0) {
+  if (vfs_stat(conn,name,&st) == 0) {
     stat_cache_add(orig_path, name);
     DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
-    if(pst)
-      *pst = st;
+    *pst = st;
     return(True);
   }
 
@@ -277,7 +278,8 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
        * Check if the name exists up to this point.
        */
 
-      if (conn->vfs_ops.stat(conn,dos_to_unix(name,False), &st) == 0) {
+      ZERO_STRUCT(st);
+      if (vfs_stat(conn,name, &st) == 0) {
         /*
          * It exists. it must either be a directory or this must be
          * the last part of the path for it to be OK.
@@ -308,8 +310,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
          * Try to find this part of the path in the directory.
          */
 
-        if (ms_has_wild(start) ||
-            !scan_directory(dirpath, start, conn, end?True:False)) {
+        if (ms_has_wild(start) || !scan_directory(dirpath, start, conn, end?True:False)) {
           if (end) {
             /*
              * An intermediate part of the name can't be found.
@@ -392,6 +393,14 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
   if(!component_was_mangled && !name_has_wildcard)
     stat_cache_add(orig_path, name);
 
+  /*
+   * If we ended up resolving the entire path then return a valid
+   * stat struct if we got one.
+   */
+
+  if (VALID_STAT(st) && (strlen(orig_path) == strlen(name)))
+    *pst = st;
+
   /* 
    * The name has been resolved.
    */
@@ -426,15 +435,13 @@ BOOL check_name(char *name,connection_struct *conn)
      University of Geneva */
 
 #ifdef S_ISLNK
-  if (!lp_symlinks(SNUM(conn)))
-    {
+  if (!lp_symlinks(SNUM(conn))) {
       SMB_STRUCT_STAT statbuf;
       if ( (conn->vfs_ops.lstat(conn,dos_to_unix(name,False),&statbuf) != -1) &&
-          (S_ISLNK(statbuf.st_mode)) )
-        {
+                (S_ISLNK(statbuf.st_mode)) ) {
           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
           ret=0; 
-        }
+      }
     }
 #endif
 
@@ -479,33 +486,29 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
     mangled = !check_mangled_cache( name );
 
   /* open the directory */
-  if (!(cur_dir = OpenDir(conn, path, True))) 
-    {
+  if (!(cur_dir = OpenDir(conn, path, True))) {
       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
       return(False);
-    }
+  }
 
   /* now scan for matching names */
-  while ((dname = ReadDirName(cur_dir))) 
-    {
-      if (*dname == '.' &&
-         (strequal(dname,".") || strequal(dname,"..")))
-       continue;
+  while ((dname = ReadDirName(cur_dir))) {
+      if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
+        continue;
 
       pstrcpy(name2,dname);
       if (!name_map_mangle(name2,False,True,SNUM(conn)))
         continue;
 
-      if ((mangled && mangled_equal(name,name2))
-         || fname_equal(name, name2))
-       {
-         /* we've found the file, change it's name and return */
-         if (docache) DirCacheAdd(path,name,dname,SNUM(conn));
-         pstrcpy(name, dname);
-         CloseDir(cur_dir);
-         return(True);
-       }
+      if ((mangled && mangled_equal(name,name2)) || fname_equal(name, name2)) {
+        /* we've found the file, change it's name and return */
+        if (docache)
+          DirCacheAdd(path,name,dname,SNUM(conn));
+        pstrcpy(name, dname);
+        CloseDir(cur_dir);
+        return(True);
     }
+  }
 
   CloseDir(cur_dir);
   return(False);
index 67f1a1bc9e18aed973ab1c49c93aefaca6326742..f8b6352ba175c069ab43adf53ea4b9ee32af01e6 100644 (file)
@@ -795,7 +795,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                
        set_posix_case_semantics(file_attributes);
                
-       unix_convert(fname,conn,0,&bad_path,NULL);
+       unix_convert(fname,conn,0,&bad_path,&sbuf);
                
        unixmode = unix_mode(conn,smb_attr | aARCH, fname);
     
@@ -806,7 +806,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
        if(create_options & FILE_DIRECTORY_FILE) {
                oplock_request = 0;
                
-               fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
+               fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
                        
                restore_case_semantics(file_attributes);
 
@@ -836,7 +836,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                 * before issuing an oplock break request to
                 * our client. JRA.  */
 
-               fsp = open_file_shared(conn,fname,smb_open_mode,
+               fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,
                                 smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
 
                if (!fsp) { 
@@ -873,7 +873,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                                }
        
                                oplock_request = 0;
-                               fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
+                               fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
                                
                                if(!fsp) {
                                        restore_case_semantics(file_attributes);
@@ -896,7 +896,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
 
                                oplock_request = 0;
 
-                               fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
+                               fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
 
                                if(!fsp) {
                                        restore_case_semantics(file_attributes);
@@ -919,22 +919,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
                } 
        }
                
-       if(fsp->is_directory) {
-               if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
-                       close_file(fsp,True);
-                       restore_case_semantics(file_attributes);
-                       END_PROFILE(SMBntcreateX);
-                       return(ERROR(ERRDOS,ERRnoaccess));
-               }
-       } else {
-               if (conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
-                       close_file(fsp,False);
-                       restore_case_semantics(file_attributes);
-                       END_PROFILE(SMBntcreateX);
-                       return(ERROR(ERRDOS,ERRnoaccess));
-               } 
-       }
-               
        restore_case_semantics(file_attributes);
                
        file_len = sbuf.st_size;
@@ -1231,7 +1215,7 @@ static int call_nt_transact_create(connection_struct *conn,
     
   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
     
   unixmode = unix_mode(conn,smb_attr | aARCH, fname);
    
@@ -1249,7 +1233,7 @@ static int call_nt_transact_create(connection_struct *conn,
      * CreateDirectory() call.
      */
 
-    fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
+    fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
 
     if(!fsp) {
       restore_case_semantics(file_attributes);
@@ -1260,20 +1244,13 @@ static int call_nt_transact_create(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRnoaccess));
     }
 
-    if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name, False),
-            &sbuf) != 0) {
-      close_file(fsp,True);
-      restore_case_semantics(file_attributes);
-      return(ERROR(ERRDOS,ERRnoaccess));
-    }
-
   } else {
 
     /*
      * Ordinary file case.
      */
 
-    fsp = open_file_shared(conn,fname,smb_open_mode,smb_ofun,unixmode,
+    fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,smb_ofun,unixmode,
                      oplock_request,&rmode,&smb_action);
 
     if (!fsp) { 
@@ -1291,7 +1268,7 @@ static int call_nt_transact_create(connection_struct *conn,
                        }
        
                        oplock_request = 0;
-                       fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
+                       fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
                                
                        if(!fsp) {
                                restore_case_semantics(file_attributes);
@@ -1314,7 +1291,7 @@ static int call_nt_transact_create(connection_struct *conn,
 
                        oplock_request = 0;
 
-                       fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
+                       fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
 
                        if(!fsp) {
                                restore_case_semantics(file_attributes);
@@ -1333,20 +1310,6 @@ static int call_nt_transact_create(connection_struct *conn,
                }
       } 
   
-      if(fsp->is_directory) {
-          if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
-              close_file(fsp,True);
-              restore_case_semantics(file_attributes);
-              return(ERROR(ERRDOS,ERRnoaccess));
-          }
-      } else {
-          if (!fsp->stat_open && conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
-              close_file(fsp,False);
-              restore_case_semantics(file_attributes);
-              return(ERROR(ERRDOS,ERRnoaccess));
-          } 
-      }
       file_len = sbuf.st_size;
       fmode = dos_mode(conn,fname,&sbuf);
       if(fmode == 0)
index edd94bd8653ee208c46c4fc0a78e3ace28ec08a3..12f6d12948412170cf94e4975612e6fd3b5bfd2d 100644 (file)
@@ -88,12 +88,11 @@ static void check_for_pipe(char *fname)
 ****************************************************************************/
 
 static BOOL open_file(files_struct *fsp,connection_struct *conn,
-                     char *fname1,int flags,mode_t mode)
+                     char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode)
 {
        extern struct current_user current_user;
        pstring fname;
        int accmode = (flags & O_ACCMODE);
-       SMB_STRUCT_STAT sbuf;
 
        fsp->fd = -1;
        fsp->oplock_type = NO_OPLOCK;
@@ -138,10 +137,12 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
                return False;
        }
 
-       if (conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf) == -1) {
-               DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
-               fd_close(conn, fsp);
-               return False;
+       if (!VALID_STAT(*psbuf)) {
+               if (vfs_fstat(fsp,fsp->fd,psbuf) == -1) {
+                       DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
+                       fd_close(conn, fsp);
+                       return False;
+               }
        }
 
        /*
@@ -150,18 +151,18 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
         * so catch a directory open and return an EISDIR. JRA.
         */
 
-       if(S_ISDIR(sbuf.st_mode)) {
+       if(S_ISDIR(psbuf->st_mode)) {
                fd_close(conn, fsp);
                errno = EISDIR;
                return False;
        }
 
-       fsp->mode = sbuf.st_mode;
-       fsp->inode = sbuf.st_ino;
-       fsp->dev = sbuf.st_dev;
+       fsp->mode = psbuf->st_mode;
+       fsp->inode = psbuf->st_ino;
+       fsp->dev = psbuf->st_dev;
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
-       fsp->size = 0;
+       fsp->size = psbuf->st_size;
        fsp->pos = -1;
        fsp->can_lock = True;
        fsp->can_read = ((flags & O_WRONLY)==0);
@@ -513,17 +514,17 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
 
 
 /****************************************************************************
- Open a file with a share mode.
+ Open a file with a share mode. On output from this open we are guarenteeing
+ that 
 ****************************************************************************/
-files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mode,int ofun,
-                     mode_t mode,int oplock_request, int *Access,int *action)
+files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
+                               int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action)
 {
        int flags=0;
        int flags2=0;
        int deny_mode = GET_DENY_MODE(share_mode);
        BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
-       SMB_STRUCT_STAT sbuf;
-       BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
+       BOOL file_existed = VALID_STAT(*psbuf);
        BOOL fcbopen = False;
        SMB_DEV_T dev = 0;
        SMB_INO_T inode = 0;
@@ -619,7 +620,7 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
 #endif /* O_SYNC */
   
        if (flags != O_RDONLY && file_existed && 
-                       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) {
+                       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
                if (!fcbopen) {
                        DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
                                fname, !CAN_WRITE(conn) ? "share" : "file" ));
@@ -638,8 +639,9 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
        }
 
        if (file_existed) {
-               dev = sbuf.st_dev;
-               inode = sbuf.st_ino;
+
+               dev = psbuf->st_dev;
+               inode = psbuf->st_ino;
 
                lock_share_entry(conn, dev, inode);
 
@@ -659,10 +661,10 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
        DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
                        flags,flags2,(int)mode));
 
-       fsp_open = open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode);
+       fsp_open = open_file(fsp,conn,fname,psbuf,flags|(flags2&~(O_TRUNC)),mode);
 
        if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
-               if((fsp_open = open_file(fsp,conn,fname,O_RDONLY,mode)) == True)
+               if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode)) == True)
                        flags = O_RDONLY;
        }
 
@@ -717,11 +719,16 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
         * If requested, truncate the file.
         */
 
-       if ((flags2&O_TRUNC) && (truncate_unless_locked(conn,fsp) == -1)) {
-               unlock_share_entry_fsp(fsp);
-               fd_close(conn,fsp);
-               file_free(fsp);
-               return NULL;
+       if (flags2&O_TRUNC) {
+               /*
+                * We are modifing the file after open - update the stat struct..
+                */
+               if ((truncate_unless_locked(conn,fsp) == -1) || (vfs_fstat(fsp,fsp->fd,psbuf)==-1)) {
+                       unlock_share_entry_fsp(fsp);
+                       fd_close(conn,fsp);
+                       file_free(fsp);
+                       return NULL;
+               }
        }
 
        switch (flags) {
@@ -783,28 +790,26 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
  with the 'stat_open' flag set 
 ****************************************************************************/
 
-files_struct *open_file_stat(connection_struct *conn,
-                  char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
+files_struct *open_file_stat(connection_struct *conn, char *fname,
+                                                       SMB_STRUCT_STAT *psbuf, int smb_ofun, int *action)
 {
        extern struct current_user current_user;
-       files_struct *fsp = file_new();
-
-       if(!fsp)
-               return NULL;
+       files_struct *fsp = NULL;
 
-       if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), pst) < 0) {
-               DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
-                        fname, strerror(errno) ));
-               file_free(fsp);
+       if (!VALID_STAT(*psbuf)) {
+               DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n", fname, strerror(errno) ));
                return NULL;
        }
 
-       if(S_ISDIR(pst->st_mode)) {
+       if(S_ISDIR(psbuf->st_mode)) {
                DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
-               file_free(fsp);
                return NULL;
        }
 
+       fsp = file_new();
+       if(!fsp)
+               return NULL;
+
        *action = FILE_WAS_OPENED;
        
        DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
@@ -814,10 +819,12 @@ files_struct *open_file_stat(connection_struct *conn,
         */
        
        fsp->fd = -1;
-       fsp->mode = 0;
+       fsp->mode = psbuf->st_mode;
+       fsp->inode = psbuf->st_ino;
+       fsp->dev = psbuf->st_dev;
        GetTimeOfDay(&fsp->open_time);
+       fsp->size = psbuf->st_size;
        fsp->vuid = current_user.vuid;
-       fsp->size = 0;
        fsp->pos = -1;
        fsp->can_lock = False;
        fsp->can_read = False;
@@ -851,20 +858,18 @@ files_struct *open_file_stat(connection_struct *conn,
  Open a directory from an NT SMB call.
 ****************************************************************************/
 
-files_struct *open_directory(connection_struct *conn,
-                  char *fname, int smb_ofun, mode_t unixmode, int *action)
+files_struct *open_directory(connection_struct *conn, char *fname,
+                                                       SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action)
 {
        extern struct current_user current_user;
-       SMB_STRUCT_STAT st;
        BOOL got_stat = False;
        files_struct *fsp = file_new();
 
        if(!fsp)
                return NULL;
 
-       if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), &st) == 0) {
+       if (VALID_STAT(*psbuf))
                got_stat = True;
-       }
 
        if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
                file_free(fsp);
@@ -876,7 +881,7 @@ files_struct *open_directory(connection_struct *conn,
 
                if (got_stat) {
 
-                       if(!S_ISDIR(st.st_mode)) {
+                       if(!S_ISDIR(psbuf->st_mode)) {
                                DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
                                file_free(fsp);
                                errno = EACCES;
@@ -903,6 +908,12 @@ files_struct *open_directory(connection_struct *conn,
                                file_free(fsp);
                                return NULL;
                        }
+
+                       if(vfs_stat(conn,fname, psbuf) != 0) {
+                               file_free(fsp);
+                               return NULL;
+                       }
+
                        *action = FILE_WAS_CREATED;
 
                }
@@ -919,7 +930,7 @@ files_struct *open_directory(connection_struct *conn,
                        return NULL;
                }
 
-               if(!S_ISDIR(st.st_mode)) {
+               if(!S_ISDIR(psbuf->st_mode)) {
                        DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
                        file_free(fsp);
                        return NULL;
@@ -928,18 +939,19 @@ files_struct *open_directory(connection_struct *conn,
                *action = FILE_WAS_OPENED;
        }
        
-       DEBUG(5,("open_directory: opening directory %s\n",
-                fname));
+       DEBUG(5,("open_directory: opening directory %s\n", fname));
 
        /*
         * Setup the files_struct for it.
         */
        
        fsp->fd = -1;
-       fsp->mode = 0;
+       fsp->mode = psbuf->st_mode;
+       fsp->inode = psbuf->st_ino;
+       fsp->dev = psbuf->st_dev;
        GetTimeOfDay(&fsp->open_time);
+       fsp->size = psbuf->st_size;
        fsp->vuid = current_user.vuid;
-       fsp->size = 0;
        fsp->pos = -1;
        fsp->can_lock = True;
        fsp->can_read = False;
@@ -983,7 +995,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
   SMB_DEV_T dev;
   SMB_INO_T inode;
 
-  if (conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf) == -1)
+  if (vfs_stat(conn,fname,&sbuf) == -1)
     return(True);
 
   dev = sbuf.st_dev;
index efd18799a2d7925f469e94acb6bb32e76a5572c1..4fd9f9c42d8269730301de34b2de1d6a47a19b1e 100644 (file)
@@ -1033,22 +1033,20 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   pstring name;
   BOOL ok = False;
   BOOL bad_path = False;
-  SMB_STRUCT_STAT st;
+  SMB_STRUCT_STAT sbuf;
   START_PROFILE(SMBchkpth);
  
   pstrcpy(name,smb_buf(inbuf) + 1);
 
   RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
 
-  unix_convert(name,conn,0,&bad_path,&st);
+  unix_convert(name,conn,0,&bad_path,&sbuf);
 
   mode = SVAL(inbuf,smb_vwv0);
 
   if (check_name(name,conn)) {
-    if(VALID_STAT(st))
-      ok = S_ISDIR(st.st_mode);
-    else
-      ok = vfs_directory_exist(conn,name,NULL);
+    if(VALID_STAT(sbuf))
+      ok = S_ISDIR(sbuf.st_mode);
   }
 
   if (!ok)
@@ -1182,17 +1180,17 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL ok=False;
   int mode;
   time_t mtime;
-  SMB_STRUCT_STAT st;
+  SMB_STRUCT_STAT sbuf;
   BOOL bad_path = False;
   START_PROFILE(SMBsetatr);
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
-  unix_convert(fname,conn,0,&bad_path,&st);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
 
   mode = SVAL(inbuf,smb_vwv0);
   mtime = make_unix_date3(inbuf+smb_vwv1);
   
-  if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, fname, NULL))
+  if (VALID_STAT_OF_DIR(sbuf))
     mode |= aDIR;
   if (check_name(fname,conn))
     ok =  (file_chmod(conn,fname,mode,NULL) == 0);
@@ -1292,11 +1290,12 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   
   if (status_len == 0)
   {
+    SMB_STRUCT_STAT sbuf;
     pstring dir2;
 
     pstrcpy(directory,smb_buf(inbuf)+1);
     pstrcpy(dir2,smb_buf(inbuf)+1);
-    unix_convert(directory,conn,0,&bad_path,NULL);
+    unix_convert(directory,conn,0,&bad_path,&sbuf);
     unix_format(dir2);
 
     if (!check_name(directory,conn))
@@ -1517,11 +1516,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
     
   unixmode = unix_mode(conn,aARCH,fname);
       
-  fsp = open_file_shared(conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+  fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
                    unixmode, oplock_request,&rmode,NULL);
 
   if (!fsp)
@@ -1535,12 +1534,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
-    close_file(fsp,False);
-    END_PROFILE(SMBopen);
-    return(ERROR(ERRDOS,ERRnoaccess));
-  }
-    
   size = sbuf.st_size;
   fmode = dos_mode(conn,fname,&sbuf);
   mtime = sbuf.st_mtime;
@@ -1618,11 +1611,11 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 
   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
     
   unixmode = unix_mode(conn,smb_attr | aARCH, fname);
       
-  fsp = open_file_shared(conn,fname,smb_mode,smb_ofun,unixmode,
+  fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
                       oplock_request, &rmode,&smb_action);
       
   if (!fsp)
@@ -1636,12 +1629,6 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
-    close_file(fsp,False);
-    END_PROFILE(SMBopenX);
-    return(ERROR(ERRDOS,ERRnoaccess));
-  }
-
   size = sbuf.st_size;
   fmode = dos_mode(conn,fname,&sbuf);
   mtime = sbuf.st_mtime;
@@ -1737,6 +1724,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
   files_struct *fsp;
   int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+  SMB_STRUCT_STAT sbuf;
   START_PROFILE(SMBcreate);
  
   com = SVAL(inbuf,smb_com);
@@ -1746,12 +1734,11 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
 
-  if (createmode & aVOLID)
-    {
+  if (createmode & aVOLID) {
       DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
-    }
+  }
   
   unixmode = unix_mode(conn,createmode,fname);
   
@@ -1767,7 +1754,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   }
 
   /* Open file in dos compatibility share mode. */
-  fsp = open_file_shared(conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
+  fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
                    ofun, unixmode, oplock_request, NULL, NULL);
   
   if (!fsp)
@@ -1813,23 +1800,27 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
   files_struct *fsp;
   int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+  SMB_STRUCT_STAT sbuf;
   START_PROFILE(SMBctemp);
+
   createmode = SVAL(inbuf,smb_vwv0);
   pstrcpy(fname,smb_buf(inbuf)+1);
   pstrcat(fname,"/TMXXXXXX");
 
   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
   
   unixmode = unix_mode(conn,createmode,fname);
   
   pstrcpy(fname2,(char *)smbd_mktemp(fname));
+  /* This file should not exist. */
+  ZERO_STRUCT(sbuf);
+  vfs_stat(conn,fname2,&sbuf);
 
   /* Open file in dos compatibility share mode. */
   /* We should fail if file exists. */
-  fsp = open_file_shared(conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
+  fsp = open_file_shared(conn,fname2,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
                    (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
 
   if (!fsp)
@@ -1904,6 +1895,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL exists=False;
   BOOL bad_path = False;
   BOOL rc = True;
+  SMB_STRUCT_STAT sbuf;
   START_PROFILE(SMBunlink);
 
   *directory = *mask = 0;
@@ -1916,7 +1908,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
   DEBUG(3,("reply_unlink : %s\n",name));
    
-  rc = unix_convert(name,conn,0,&bad_path,NULL);
+  rc = unix_convert(name,conn,0,&bad_path,&sbuf);
 
   p = strrchr(name,'/');
   if (!p) {
@@ -1948,7 +1940,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
     if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory))
       count++;
     if (!count)
-      exists = vfs_file_exist(conn,directory,NULL);    
+      exists = vfs_file_exist(conn,directory,&sbuf);    
   } else {
     void *dirptr = NULL;
     char *dname;
@@ -3281,9 +3273,10 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
 int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory)
 {
   BOOL bad_path = False;
+  SMB_STRUCT_STAT sbuf;
   int ret= -1;
   
-  unix_convert(directory,conn,0,&bad_path,NULL);
+  unix_convert(directory,conn,0,&bad_path,&sbuf);
   
   if (check_name(directory, conn))
     ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
@@ -3482,13 +3475,14 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   int outsize = 0;
   BOOL ok = False;
   BOOL bad_path = False;
+  SMB_STRUCT_STAT sbuf;
   START_PROFILE(SMBrmdir);
 
   pstrcpy(directory,smb_buf(inbuf) + 1);
 
   RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
 
-  unix_convert(directory,conn, NULL,&bad_path,NULL);
+  unix_convert(directory,conn, NULL,&bad_path,&sbuf);
   
   if (check_name(directory,conn))
   {
@@ -3614,12 +3608,13 @@ int rename_internals(connection_struct *conn,
        int error = ERRnoaccess;
        BOOL exists=False;
        BOOL rc = True;
-        pstring zdirectory;
+       SMB_STRUCT_STAT sbuf1, sbuf2;
+       pstring zdirectory;
 
        *directory = *mask = 0;
 
-       rc = unix_convert(name,conn,0,&bad_path1,NULL);
-       unix_convert(newname,conn,newname_last_component,&bad_path2,NULL);
+       rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+       unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
 
        /*
         * Split the old name into directory and last component
@@ -3855,7 +3850,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
                      int count,BOOL target_is_directory, int *err_ret)
 {
   int Access,action;
-  SMB_STRUCT_STAT st;
+  SMB_STRUCT_STAT src_sbuf, sbuf2;
   SMB_OFF_T ret=-1;
   files_struct *fsp1,*fsp2;
   pstring dest;
@@ -3873,10 +3868,10 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
     pstrcat(dest,p);
   }
 
-  if (!vfs_file_exist(conn,src,&st))
+  if (!vfs_file_exist(conn,src,&src_sbuf))
     return(False);
 
-  fsp1 = open_file_shared(conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+  fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
                   (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
 
   if (!fsp1) {
@@ -3884,10 +3879,11 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
 
   if (!target_is_directory && count)
-    ofun = 1;
+    ofun = FILE_EXISTS_OPEN;
 
-  fsp2 = open_file_shared(conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
-                  ofun,st.st_mode,0,&Access,&action);
+  vfs_stat(conn,dest,&sbuf2);
+  fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+                  ofun,src_sbuf.st_mode,0,&Access,&action);
 
   if (!fsp2) {
     close_file(fsp1,False);
@@ -3902,12 +3898,12 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        * Stop the copy from occurring.
        */
       ret = -1;
-      st.st_size = 0;
+      src_sbuf.st_size = 0;
     }
   }
   
-  if (st.st_size)
-    ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0);
+  if (src_sbuf.st_size)
+    ret = vfs_transfer_file(-1, fsp1, -1, fsp2, src_sbuf.st_size, NULL, 0, 0);
 
   close_file(fsp1,False);
   /*
@@ -3918,7 +3914,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
    */
   *err_ret = close_file(fsp2,False);
 
-  return(ret == (SMB_OFF_T)st.st_size);
+  return(ret == (SMB_OFF_T)src_sbuf.st_size);
 }
 
 
@@ -3945,6 +3941,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path1 = False;
   BOOL bad_path2 = False;
   BOOL rc = True;
+  SMB_STRUCT_STAT sbuf1, sbuf2;
   START_PROFILE(SMBcopy);
 
   *directory = *mask = 0;
@@ -3964,10 +3961,10 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
   RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
 
-  rc = unix_convert(name,conn,0,&bad_path1,NULL);
-  unix_convert(newname,conn,0,&bad_path2,NULL);
+  rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
+  unix_convert(newname,conn,0,&bad_path2,&sbuf2);
 
-  target_is_directory = vfs_directory_exist(conn,False,NULL);
+  target_is_directory = VALID_STAT_OF_DIR(sbuf2);
 
   if ((flags&1) && target_is_directory) {
     END_PROFILE(SMBcopy);
@@ -3979,7 +3976,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(ERROR(ERRDOS,ERRbadpath));
   }
 
-  if ((flags&(1<<5)) && vfs_directory_exist(conn,name,NULL)) {
+  if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
     /* wants a tree copy! XXXX */
     DEBUG(3,("Rejecting tree copy\n"));
     END_PROFILE(SMBcopy);
index 8d756a1d466b0c74de1750b050247e0db81c89f5..8200c277b322f974d383cbd7c3e902014e93c7c0 100644 (file)
@@ -193,7 +193,7 @@ BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
       scp = (stat_cache_entry *)(hash_elem->value);
       DO_PROFILE_INC(statcache_hits);
       trans_name = scp->names+scp->name_len+1;
-      if(conn->vfs_ops.stat(conn,dos_to_unix(trans_name,False), pst) != 0) {
+      if(vfs_stat(conn,trans_name, pst) != 0) {
         /* Discard this entry - it doesn't exist in the filesystem.  */
         hash_remove(&stat_cache, hash_elem);
         return False;
index 7e2c25109a78bc3f72948030c4fbb885c9eb124f..17a362fb5c0e95b4eab31c69d2601f42eef84890 100644 (file)
@@ -224,7 +224,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
 
   /* XXXX we need to handle passed times, sattr and flags */
 
-  unix_convert(fname,conn,0,&bad_path,NULL);
+  unix_convert(fname,conn,0,&bad_path,&sbuf);
     
   if (!check_name(fname,conn))
   {
@@ -238,7 +238,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
 
   unixmode = unix_mode(conn,open_attr | aARCH, fname);
       
-  fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
+  fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
                   oplock_request, &rmode,&smb_action);
       
   if (!fsp)
@@ -251,11 +251,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
-    close_file(fsp,False);
-    return(UNIXERROR(ERRDOS,ERRnoaccess));
-  }
-    
   size = sbuf.st_size;
   fmode = dos_mode(conn,fname,&sbuf);
   mtime = sbuf.st_mtime;
@@ -407,7 +402,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
       if(needslash)
         pstrcat(pathreal,"/");
       pstrcat(pathreal,dname);
-      if (conn->vfs_ops.stat(conn,dos_to_unix(pathreal,False),&sbuf) != 0) 
+      if (vfs_stat(conn,pathreal,&sbuf) != 0) 
       {
        /* Needed to show the msdfs symlinks as directories */
        if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn)) 
@@ -657,6 +652,7 @@ static int call_trans2findfirst(connection_struct *conn,
   BOOL out_of_space = False;
   int space_remaining;
   BOOL bad_path = False;
+  SMB_STRUCT_STAT sbuf;
 
   *directory = *mask = 0;
 
@@ -686,7 +682,7 @@ static int call_trans2findfirst(connection_struct *conn,
 
   DEBUG(5,("path=%s\n",directory));
 
-  unix_convert(directory,conn,0,&bad_path,NULL);
+  unix_convert(directory,conn,0,&bad_path,&sbuf);
   if(!check_name(directory,conn)) {
     if((errno == ENOENT) && bad_path)
     {
@@ -1112,7 +1108,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
 
   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
 
-  if(conn->vfs_ops.stat(conn,".",&st)!=0) {
+  if(vfs_stat(conn,".",&st)!=0) {
     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
     return (ERROR(ERRSRV,ERRinvdevice));
   }
@@ -1308,7 +1304,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       fname = fsp->fsp_name;
       unix_convert(fname,conn,0,&bad_path,&sbuf);
       if (!check_name(fname,conn) || 
-          (!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
+          (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1328,7 +1324,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       CHECK_ERROR(fsp);
 
       fname = fsp->fsp_name;
-      if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
+      if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
@@ -1350,7 +1346,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
 
     unix_convert(fname,conn,0,&bad_path,&sbuf);
     if (!check_name(fname,conn) || 
-        (!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
+        (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1567,7 +1563,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
   int mode=0;
   SMB_OFF_T size=0;
   struct utimbuf tvs;
-  SMB_STRUCT_STAT st;
+  SMB_STRUCT_STAT sbuf;
   pstring fname1;
   char *fname;
   int fd = -1;
@@ -1588,9 +1584,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
        * to do this call. JRA.
        */
       fname = fsp->fsp_name;
-      unix_convert(fname,conn,0,&bad_path,&st);
-      if (!check_name(fname,conn) || 
-          (!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st))) {
+      unix_convert(fname,conn,0,&bad_path,&sbuf);
+      if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1609,7 +1604,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       fname = fsp->fsp_name;
       fd = fsp->fd;
 
-      if (fsp->conn->vfs_ops.fstat(fsp,fd,&st) != 0) {
+      if (vfs_fstat(fsp,fd,&sbuf) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
@@ -1619,7 +1614,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
     info_level = SVAL(params,0);    
     fname = fname1;
     pstrcpy(fname,&params[6]);
-    unix_convert(fname,conn,0,&bad_path,&st);
+    unix_convert(fname,conn,0,&bad_path,&sbuf);
     if(!check_name(fname, conn))
     {
       if((errno == ENOENT) && bad_path)
@@ -1630,7 +1625,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRbadpath));
     }
  
-    if(!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st)!=0) {
+    if(!VALID_STAT(sbuf)) {
       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1651,10 +1646,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
 
   SSVAL(params,0,0);
 
-  size = st.st_size;
-  tvs.modtime = st.st_mtime;
-  tvs.actime = st.st_atime;
-  mode = dos_mode(conn,fname,&st);
+  size = sbuf.st_size;
+  tvs.modtime = sbuf.st_mtime;
+  tvs.actime = sbuf.st_atime;
+  mode = dos_mode(conn,fname,&sbuf);
 
   if (total_data > 0 && IVAL(pdata,0) == total_data) {
     /* uggh, EAs for OS2 */
@@ -1908,10 +1903,10 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
 
   /* get some defaults (no modifications) if any info is zero or -1. */
   if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
-    tvs.actime = st.st_atime;
+    tvs.actime = sbuf.st_atime;
 
   if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
-    tvs.modtime = st.st_mtime;
+    tvs.modtime = sbuf.st_mtime;
 
   DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
   DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
@@ -1925,13 +1920,13 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
      * changing the size of a file.
      */
     if (!size)
-      size = st.st_size;
+      size = sbuf.st_size;
   }
 
   /* Try and set the times, size and mode of this file -
      if they are different from the current values
    */
-  if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
+  if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
     if(fsp != NULL) {
       /*
        * This was a setfileinfo on an open file.
@@ -1957,7 +1952,7 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
   }
 
   /* check the mode isn't different, before changing it */
-  if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
+  if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
 
     DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
           fname, mode ));
@@ -1968,7 +1963,7 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
     }
   }
 
-  if(size != st.st_size) {
+  if(size != sbuf.st_size) {
 
     DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
           fname, (double)size ));
@@ -2004,6 +1999,7 @@ static int call_trans2mkdir(connection_struct *conn,
   char *params = *pparams;
   pstring directory;
   int ret = -1;
+  SMB_STRUCT_STAT sbuf;
   BOOL bad_path = False;
 
   if (!CAN_WRITE(conn))
@@ -2013,7 +2009,7 @@ static int call_trans2mkdir(connection_struct *conn,
 
   DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
 
-  unix_convert(directory,conn,0,&bad_path,NULL);
+  unix_convert(directory,conn,0,&bad_path,&sbuf);
   if (check_name(directory,conn))
     ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
   
index 467f3e47a2ba5bf25f52711008aae4d47369be24..2f984aee4f3d97873d4482a571489ff60609e277 100644 (file)
@@ -323,6 +323,8 @@ BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
 
        if (!sbuf)
                sbuf = &st;
+
+       ZERO_STRUCTP(sbuf);
  
        if (vfs_stat(conn,fname,sbuf) != 0) 
                return(False);