Restructuring of vfs layer to include a "this" pointer - can be an fsp or
authorJeremy Allison <jra@samba.org>
Fri, 6 Oct 2000 03:21:49 +0000 (03:21 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 6 Oct 2000 03:21:49 +0000 (03:21 +0000)
a conn struct depending on the call.
We need this to have a clean NT ACL call interface.
This will break any existing VFS libraries (that's why this is pre-release
code).
Andrew gets credit for this one :-) :-).

In addition - added Herb's WITH_PROFILE changes - Herb - please examine
the changes I've made to the smbd/reply.c code you added. The original
code was very ugly and I have replaced it with a
START_PROFILE(x)/END_PROFILE(x) pair using the preprocessor.
Please check this compiles ok with the --with-profile switch.
Jeremy.

22 files changed:
source/include/includes.h
source/include/profile.h
source/include/proto.h
source/include/smb.h
source/include/vfs.h
source/locking/posix.c
source/printing/printfsp.c
source/smbd/close.c
source/smbd/conn.c
source/smbd/dir.c
source/smbd/dosmode.c
source/smbd/fileio.c
source/smbd/filename.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/reply.c
source/smbd/service.c
source/smbd/statcache.c
source/smbd/trans2.c
source/smbd/unix_acls.c
source/smbd/vfs-wrap.c
source/smbd/vfs.c

index da16ae1..ad27716 100644 (file)
@@ -637,6 +637,9 @@ extern int errno;
 
 #ifdef WITH_PROFILE
 #include "profile.h"
+#else
+#define START_PROFILE(x)
+#define END_PROFILE(x)
 #endif
 
 #ifndef MAXCODEPAGELINES
index 0924dc2..9b6ec46 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef _PROFILE_H_
+#define _PROFILE_H_
 /* 
    Unix SMB/Netbios implementation.
    Version 1.9.
 
 #define PROF_SHMEM_KEY ((key_t)0x07021999)
 #define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 1
+#define PROF_SHM_VERSION 2
+
+/* time values in the following structure are in milliseconds */
 
 struct profile_struct {
        int prof_shm_magic;
        int prof_shm_version;
+/* general counters */
        unsigned smb_count; /* how many SMB packets we have processed */
        unsigned uid_changes; /* how many times we change our effective uid */
+/* system call counters */
+       unsigned syscall_opendir_count;
+       unsigned syscall_opendir_time;
+       unsigned syscall_readdir_count;
+       unsigned syscall_readdir_time;
+       unsigned syscall_mkdir_count;
+       unsigned syscall_mkdir_time;
+       unsigned syscall_rmdir_count;
+       unsigned syscall_rmdir_time;
+       unsigned syscall_closedir_count;
+       unsigned syscall_closedir_time;
+       unsigned syscall_open_count;
+       unsigned syscall_open_time;
+       unsigned syscall_close_count;
+       unsigned syscall_close_time;
+       unsigned syscall_read_count;
+       unsigned syscall_read_time;
+       unsigned syscall_read_bytes;    /* bytes read with read syscall */
+       unsigned syscall_write_count;
+       unsigned syscall_write_time;
+       unsigned syscall_write_bytes;   /* bytes written with write syscall */
+       unsigned syscall_lseek_count;
+       unsigned syscall_lseek_time;
+       unsigned syscall_rename_count;
+       unsigned syscall_rename_time;
+       unsigned syscall_fsync_count;
+       unsigned syscall_fsync_time;
+       unsigned syscall_stat_count;
+       unsigned syscall_stat_time;
+       unsigned syscall_fstat_count;
+       unsigned syscall_fstat_time;
+       unsigned syscall_lstat_count;
+       unsigned syscall_lstat_time;
+       unsigned syscall_unlink_count;
+       unsigned syscall_unlink_time;
+       unsigned syscall_chmod_count;
+       unsigned syscall_chmod_time;
+       unsigned syscall_chown_count;
+       unsigned syscall_chown_time;
+       unsigned syscall_chdir_count;
+       unsigned syscall_chdir_time;
+       unsigned syscall_getwd_count;
+       unsigned syscall_getwd_time;
+       unsigned syscall_utime_count;
+       unsigned syscall_utime_time;
+       unsigned syscall_ftruncate_count;
+       unsigned syscall_ftruncate_time;
+       unsigned syscall_fcntl_lock_count;
+       unsigned syscall_fcntl_lock_time;
+/* stat cache counters */
+       unsigned statcache_lookups;
+       unsigned statcache_misses;
+       unsigned statcache_hits;
+/* write cache counters */
+       unsigned writecache_read_hits;
+       unsigned writecache_abutted_writes;
+       unsigned writecache_total_writes;
+       unsigned writecache_non_oplock_writes;
+       unsigned writecache_direct_writes;
+       unsigned writecache_init_writes;
+       unsigned writecache_flushed_writes[NUM_FLUSH_REASONS];
+       unsigned writecache_num_perfect_writes;
+       unsigned writecache_num_write_caches;
+       unsigned writecache_allocated_write_caches;
+/* counters for individual SMB types */
+       unsigned SMBmkdir_count;        /* create directory */
+       unsigned SMBmkdir_time;
+       unsigned SMBrmdir_count;        /* delete directory */
+       unsigned SMBrmdir_time;
+       unsigned SMBopen_count;         /* open file */
+       unsigned SMBopen_time;
+       unsigned SMBcreate_count;       /* create file */
+       unsigned SMBcreate_time;
+       unsigned SMBclose_count;        /* close file */
+       unsigned SMBclose_time;
+       unsigned SMBflush_count;        /* flush file */
+       unsigned SMBflush_time;
+       unsigned SMBunlink_count;       /* delete file */
+       unsigned SMBunlink_time;
+       unsigned SMBmv_count;           /* rename file */
+       unsigned SMBmv_time;
+       unsigned SMBgetatr_count;       /* get file attributes */
+       unsigned SMBgetatr_time;
+       unsigned SMBsetatr_count;       /* set file attributes */
+       unsigned SMBsetatr_time;
+       unsigned SMBread_count;         /* read from file */
+       unsigned SMBread_time;
+       unsigned SMBwrite_count;        /* write to file */
+       unsigned SMBwrite_time;
+       unsigned SMBlock_count;         /* lock byte range */
+       unsigned SMBlock_time;
+       unsigned SMBunlock_count;       /* unlock byte range */
+       unsigned SMBunlock_time;
+       unsigned SMBctemp_count;        /* create temporary file */
+       unsigned SMBctemp_time;
+       /* SMBmknew stats are currently combined with SMBcreate */
+       unsigned SMBmknew_count;        /* make new file */
+       unsigned SMBmknew_time;
+       unsigned SMBchkpth_count;       /* check directory path */
+       unsigned SMBchkpth_time;
+       unsigned SMBexit_count;         /* process exit */
+       unsigned SMBexit_time;
+       unsigned SMBlseek_count;        /* seek */
+       unsigned SMBlseek_time;
+       unsigned SMBlockread_count;     /* Lock a range and read */
+       unsigned SMBlockread_time;
+       unsigned SMBwriteunlock_count;  /* Unlock a range then write */
+       unsigned SMBwriteunlock_time;
+       unsigned SMBreadbraw_count;     /* read a block of data with no smb header */
+       unsigned SMBreadbraw_time;
+       unsigned SMBreadBmpx_count;     /* read block multiplexed */
+       unsigned SMBreadBmpx_time;
+       unsigned SMBreadBs_count;       /* read block (secondary response) */
+       unsigned SMBreadBs_time;
+       unsigned SMBwritebraw_count;    /* write a block of data with no smb header */
+       unsigned SMBwritebraw_time;
+       unsigned SMBwriteBmpx_count;    /* write block multiplexed */
+       unsigned SMBwriteBmpx_time;
+       unsigned SMBwriteBs_count;      /* write block (secondary request) */
+       unsigned SMBwriteBs_time;
+       unsigned SMBwritec_count;       /* secondary write request */
+       unsigned SMBwritec_time;
+       unsigned SMBsetattrE_count;     /* set file attributes expanded */
+       unsigned SMBsetattrE_time;
+       unsigned SMBgetattrE_count;     /* get file attributes expanded */
+       unsigned SMBgetattrE_time;
+       unsigned SMBlockingX_count;     /* lock/unlock byte ranges and X */
+       unsigned SMBlockingX_time;
+       unsigned SMBtrans_count;        /* transaction - name, bytes in/out */
+       unsigned SMBtrans_time;
+       unsigned SMBtranss_count;       /* transaction (secondary request/response) */
+       unsigned SMBtranss_time;
+       unsigned SMBioctl_count;        /* IOCTL */
+       unsigned SMBioctl_time;
+       unsigned SMBioctls_count;       /* IOCTL  (secondary request/response) */
+       unsigned SMBioctls_time;
+       unsigned SMBcopy_count;         /* copy */
+       unsigned SMBcopy_time;
+       unsigned SMBmove_count;         /* move */
+       unsigned SMBmove_time;
+       unsigned SMBecho_count;         /* echo */
+       unsigned SMBecho_time;
+       unsigned SMBwriteclose_count;   /* write a file then close it */
+       unsigned SMBwriteclose_time;
+       unsigned SMBopenX_count;        /* open and X */
+       unsigned SMBopenX_time;
+       unsigned SMBreadX_count;        /* read and X */
+       unsigned SMBreadX_time;
+       unsigned SMBwriteX_count;       /* write and X */
+       unsigned SMBwriteX_time;
+       unsigned SMBtrans2_count;       /* TRANS2 protocol set */
+       unsigned SMBtrans2_time;
+       unsigned SMBtranss2_count;      /* TRANS2 protocol set, secondary command */
+       unsigned SMBtranss2_time;
+       unsigned SMBfindclose_count;    /* Terminate a TRANSACT2_FINDFIRST */
+       unsigned SMBfindclose_time;
+       unsigned SMBfindnclose_count;   /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
+       unsigned SMBfindnclose_time;
+       unsigned SMBtcon_count;         /* tree connect */
+       unsigned SMBtcon_time;
+       unsigned SMBtdis_count;         /* tree disconnect */
+       unsigned SMBtdis_time;
+       unsigned SMBnegprot_count;      /* negotiate protocol */
+       unsigned SMBnegprot_time;
+       unsigned SMBsesssetupX_count;   /* Session Set Up & X (including User Logon) */
+       unsigned SMBsesssetupX_time;
+       unsigned SMBulogoffX_count;     /* user logoff */
+       unsigned SMBulogoffX_time;
+       unsigned SMBtconX_count;        /* tree connect and X*/
+       unsigned SMBtconX_time;
+       unsigned SMBdskattr_count;      /* get disk attributes */
+       unsigned SMBdskattr_time;
+       unsigned SMBsearch_count;       /* search directory */
+       unsigned SMBsearch_time;
+       /* SBMffirst stats combined with SMBsearch */
+       unsigned SMBffirst_count;       /* find first */
+       unsigned SMBffirst_time;
+       /* SBMfunique stats combined with SMBsearch */
+       unsigned SMBfunique_count;      /* find unique */
+       unsigned SMBfunique_time;
+       unsigned SMBfclose_count;       /* find close */
+       unsigned SMBfclose_time;
+       unsigned SMBnttrans_count;      /* NT transact */
+       unsigned SMBnttrans_time;
+       unsigned SMBnttranss_count;     /* NT transact secondary */
+       unsigned SMBnttranss_time;
+       unsigned SMBntcreateX_count;    /* NT create and X */
+       unsigned SMBntcreateX_time;
+       unsigned SMBntcancel_count;     /* NT cancel */
+       unsigned SMBntcancel_time;
+       unsigned SMBsplopen_count;      /* open print spool file */
+       unsigned SMBsplopen_time;
+       unsigned SMBsplwr_count;        /* write to print spool file */
+       unsigned SMBsplwr_time;
+       unsigned SMBsplclose_count;     /* close print spool file */
+       unsigned SMBsplclose_time;
+       unsigned SMBsplretq_count;      /* return print queue */
+       unsigned SMBsplretq_time;
+       unsigned SMBsends_count;        /* send single block message */
+       unsigned SMBsends_time;
+       unsigned SMBsendb_count;        /* send broadcast message */
+       unsigned SMBsendb_time;
+       unsigned SMBfwdname_count;      /* forward user name */
+       unsigned SMBfwdname_time;
+       unsigned SMBcancelf_count;      /* cancel forward */
+       unsigned SMBcancelf_time;
+       unsigned SMBgetmac_count;       /* get machine name */
+       unsigned SMBgetmac_time;
+       unsigned SMBsendstrt_count;     /* send start of multi-block message */
+       unsigned SMBsendstrt_time;
+       unsigned SMBsendend_count;      /* send end of multi-block message */
+       unsigned SMBsendend_time;
+       unsigned SMBsendtxt_count;      /* send text of multi-block message */
+       unsigned SMBsendtxt_time;
+       unsigned SMBinvalid_count;      /* invalid command */
+       unsigned SMBinvalid_time;
+/* Pathworks setdir command */
+       unsigned pathworks_setdir_count;
+       unsigned pathworks_setdir_time;
+/* These are the TRANS2 sub commands */
+       unsigned Trans2_open_count;
+       unsigned Trans2_open_time;
+       unsigned Trans2_findfirst_count;
+       unsigned Trans2_findfirst_time;
+       unsigned Trans2_findnext_count;
+       unsigned Trans2_findnext_time;
+       unsigned Trans2_qfsinfo_count;
+       unsigned Trans2_qfsinfo_time;
+       unsigned Trans2_setfsinfo_count;
+       unsigned Trans2_setfsinfo_time;
+       unsigned Trans2_qpathinfo_count;
+       unsigned Trans2_qpathinfo_time;
+       unsigned Trans2_setpathinfo_count;
+       unsigned Trans2_setpathinfo_time;
+       unsigned Trans2_qfileinfo_count;
+       unsigned Trans2_qfileinfo_time;
+       unsigned Trans2_setfileinfo_count;
+       unsigned Trans2_setfileinfo_time;
+       unsigned Trans2_fsctl_count;
+       unsigned Trans2_fsctl_time;
+       unsigned Trans2_ioctl_count;
+       unsigned Trans2_ioctl_time;
+       unsigned Trans2_findnotifyfirst_count;
+       unsigned Trans2_findnotifyfirst_time;
+       unsigned Trans2_findnotifynext_count;
+       unsigned Trans2_findnotifynext_time;
+       unsigned Trans2_mkdir_count;
+       unsigned Trans2_mkdir_time;
+       unsigned Trans2_session_setup_count;
+       unsigned Trans2_session_setup_time;
+       unsigned Trans2_get_dfs_referral_count;
+       unsigned Trans2_get_dfs_referral_time;
+       unsigned Trans2_report_dfs_inconsistancy_count;
+       unsigned Trans2_report_dfs_inconsistancy_time;
+/* These are the NT transact sub commands. */
+       unsigned NT_transact_create_count;
+       unsigned NT_transact_create_time;
+       unsigned NT_transact_ioctl_count;
+       unsigned NT_transact_ioctl_time;
+       unsigned NT_transact_set_security_desc_count;
+       unsigned NT_transact_set_security_desc_time;
+       unsigned NT_transact_notify_change_count;
+       unsigned NT_transact_notify_change_time;
+       unsigned NT_transact_rename_count;
+       unsigned NT_transact_rename_time;
+       unsigned NT_transact_query_security_desc_count;
+       unsigned NT_transact_query_security_desc_time;
 };
 
 
 extern struct profile_struct *profile_p;
+
+#define INC_PROFILE_COUNT(x) if (profile_p) profile_p->x++
+#define DEC_PROFILE_COUNT(x) if (profile_p) profile_p->x--
+#define ADD_PROFILE_COUNT(x,y) if (profile_p) profile_p->x += (y)
+
+#define START_PROFILE(x) \
+       struct timeval starttime; \
+       struct timeval endtime; \
+       GetTimeOfDay(&starttime); \
+       INC_PROFILE_COUNT(x##_count)
+
+#define END_PROFILE(y) \
+       GetTimeOfDay(&endtime); \
+       ADD_PROFILE_COUNT((y##_time),TvalDiff(&starttime,&endtime))
+
+#endif
index 8d061f2..bb990a9 100644 (file)
@@ -3833,44 +3833,43 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd);
 
 /*The following definitions come from  smbd/vfs-wrap.c  */
 
-int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service,
-                         char *user);
+int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user);
 void vfswrap_dummy_disconnect(void);
-SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
+SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                               SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
-DIR *vfswrap_opendir(char *fname);
-struct dirent *vfswrap_readdir(DIR *dirp);
-int vfswrap_mkdir(char *path, mode_t mode);
-int vfswrap_rmdir(char *path);
-int vfswrap_closedir(DIR *dirp);
-int vfswrap_open(char *fname, int flags, mode_t mode);
-int vfswrap_close(int fd);
-ssize_t vfswrap_read(int fd, char *data, size_t n);
-ssize_t vfswrap_write(int fd, char *data, size_t n);
-SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence);
-int vfswrap_rename(char *old, char *new);
-int vfswrap_fsync(int fd);
-int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf);
-int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf);
-int vfswrap_lstat(char *path, 
-                 SMB_STRUCT_STAT *sbuf);
-int vfswrap_unlink(char *path);
-int vfswrap_chmod(char *path, mode_t mode);
-int vfswrap_chown(char *path, uid_t uid, gid_t gid);
-int vfswrap_chdir(char *path);
-char *vfswrap_getwd(char *path);
-int vfswrap_utime(char *path, struct utimbuf *times);
-int vfswrap_ftruncate(int fd, SMB_OFF_T offset);
-BOOL vfswrap_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+DIR *vfswrap_opendir(connection_struct *conn, char *fname);
+struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp);
+int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode);
+int vfswrap_rmdir(connection_struct *conn, char *path);
+int vfswrap_closedir(connection_struct *conn, DIR *dirp);
+int vfswrap_open(connection_struct *conn, char *fname, int flags, mode_t mode);
+int vfswrap_close(files_struct *fsp, int fd);
+ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n);
+ssize_t vfswrap_write(files_struct *fsp, int fd, char *data, size_t n);
+SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
+int vfswrap_rename(connection_struct *conn, char *old, char *new);
+int vfswrap_fsync(files_struct *fsp, int fd);
+int vfswrap_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
+int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+int vfswrap_lstat(connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf);
+int vfswrap_unlink(connection_struct *conn, char *path);
+int vfswrap_chmod(connection_struct *conn, char *path, mode_t mode);
+int vfswrap_chown(connection_struct *conn, char *path, uid_t uid, gid_t gid);
+int vfswrap_chdir(connection_struct *conn, char *path);
+char *vfswrap_getwd(connection_struct *conn, char *path);
+int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times);
+int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T offset);
+BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
 
 /*The following definitions come from  smbd/vfs.c  */
 
 int vfs_init_default(connection_struct *conn);
 BOOL vfs_init_custom(connection_struct *conn);
 int vfs_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *st);
-int vfs_fstat(connection_struct *conn, int fd, SMB_STRUCT_STAT *st);
+int vfs_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *st);
 BOOL vfs_directory_exist(connection_struct *conn, char *dname, SMB_STRUCT_STAT *st);
 int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode);
+int vfs_rmdir(connection_struct *conn, char *fname);
 int vfs_unlink(connection_struct *conn, char *fname);
 int vfs_chmod(connection_struct *conn, char *fname,mode_t mode);
 int vfs_chown(connection_struct *conn, char *fname, uid_t uid, gid_t gid);
index 02ef940..24211b0 100644 (file)
@@ -580,7 +580,8 @@ typedef struct connection_struct
        char *origpath;
 
        struct vfs_ops vfs_ops;                   /* Filesystem operations */
-       struct vfs_connection_struct *vfs_conn;   /* VFS specific connection stuff */
+       /* Handle on dlopen() call */
+       void *dl_handle;
 
        char *user; /* name of user who *opened* this connection */
        uid_t uid; /* uid of user who *opened* this connection */
index bb2239b..fb089c8 100644 (file)
 #ifndef _VFS_H
 #define _VFS_H
 
-/* Types used in the definition of VFS operations.  These are included
-   here so the vfs.h file can be included by VFS modules without
-   having to pull in unnecessary amounts of other stuff.  Note to VFS
-   writers: you must include config.h before including this file.
-   The following type definitions reference the HAVE_* symbols which
-   are defined in config.h */
-
-#ifndef SMB_OFF_T
-#  ifdef HAVE_OFF64_T
-#    define SMB_OFF_T off64_t
-#  else
-#    define SMB_OFF_T off_t
-#  endif
-#endif
-
-#ifndef SMB_STRUCT_STAT
-#  if defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
-#    define SMB_STRUCT_STAT struct stat64
-#  else
-#    define SMB_STRUCT_STAT struct stat
-#  endif
-#endif
-
-#ifndef _BOOL
-typedef int BOOL;
-#endif
-
-#ifndef _PSTRING
-#define PSTRING_LEN 1024
-#define FSTRING_LEN 128
-
-typedef char pstring[PSTRING_LEN];
-typedef char fstring[FSTRING_LEN];
-#define _PSTRING
-#endif
-
-#if defined(HAVE_LONGLONG)
-#define SMB_BIG_UINT unsigned long long
-#else
-#define SMB_BIG_UINT unsigned long
-#endif
-
-#ifndef MAXSUBAUTHS
-#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
-#endif
-
-#ifndef uint8
-#define uint8 unsigned char
-#endif 
-
-#if !defined(uint32) && !defined(HAVE_UINT32_FROM_RPC_RPC_H)
-#if (SIZEOF_INT == 4)
-#define uint32 unsigned int
-#elif (SIZEOF_LONG == 4)
-#define uint32 unsigned long
-#elif (SIZEOF_SHORT == 4)
-#define uint32 unsigned short
-#endif
-#endif
-
-#ifndef _DOM_SID
-/* DOM_SID - security id */
-typedef struct sid_info
-{
-  uint8  sid_rev_num;             /* SID revision number */
-  uint8  num_auths;               /* number of sub-authorities */
-  uint8  id_auth[6];              /* Identifier Authority */
-  /*
-   * Note that the values in these uint32's are in *native* byteorder,
-   * not neccessarily little-endian...... JRA.
-   */
-  uint32 sub_auths[MAXSUBAUTHS];  /* pointer to sub-authorities. */
-
-} DOM_SID;
-#define _DOM_SID
-#endif
-
-#ifndef _SEC_ACCESS
-/* SEC_ACCESS */
-typedef struct security_info_info
-{
-    uint32 mask;
-
-} SEC_ACCESS;
-#define _SEC_ACCESS
-#endif
-
-#ifndef _SEC_ACE
-/* SEC_ACE */
-typedef struct security_ace_info
-{
-    uint8 type;  /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
-    uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
-    uint16 size;
-
-    SEC_ACCESS info;
-    DOM_SID sid;
-
-} SEC_ACE;
-#define _SEC_ACE
-#endif
-
-#ifndef ACL_REVISION
-#define ACL_REVISION 0x3
-#endif
-
-#ifndef _SEC_ACL
-/* SEC_ACL */
-typedef struct security_acl_info
-{
-    uint16 revision; /* 0x0003 */
-    uint16 size; /* size in bytes of the entire ACL structure */
-    uint32 num_aces; /* number of Access Control Entries */
-
-    SEC_ACE *ace;
-
-} SEC_ACL;
-#define _SEC_ACL
-#endif
-
-#ifndef SEC_DESC_REVISION
-#define SEC_DESC_REVISION 0x1
-#endif
-
-#ifndef _SEC_DESC
-/* SEC_DESC */
-typedef struct security_descriptor_info
-{
-    uint16 revision; /* 0x0001 */
-    uint16 type;     /* SEC_DESC_xxxx flags */
-
-    uint32 off_owner_sid; /* offset to owner sid */
-    uint32 off_grp_sid  ; /* offset to group sid */
-    uint32 off_sacl     ; /* offset to system list of permissions */
-    uint32 off_dacl     ; /* offset to list of permissions */
-
-    SEC_ACL *dacl; /* user ACL */
-    SEC_ACL *sacl; /* system ACL */
-    DOM_SID *owner_sid;
-    DOM_SID *grp_sid;
-
-} SEC_DESC;
-#define _SEC_DESC
-#endif
-
-/*
- * The complete list of SIDS belonging to this user.
- * Created when a vuid is registered.
- */
-
-#ifndef _NT_USER_TOKEN
-typedef struct _nt_user_token {
-    size_t num_sids;
-    DOM_SID *user_sids;
-} NT_USER_TOKEN;
-#define _NT_USER_TOKEN
-#endif
-
 /* Avoid conflict with an AIX include file */
 
 #ifdef vfs_ops
 #undef vfs_ops
 #endif
 
-/* Information from the connection_struct passed to the vfs layer */
-
-struct vfs_connection_struct {
-
-    /* Connection information */
-
-    BOOL printer;
-    BOOL ipc;
-    BOOL read_only;
-    BOOL admin_user;
-
-    /* Handle on dlopen() call */
-
-    void *dl_handle;
-
-    /* Paths */
-
-    pstring dirpath;
-    pstring connectpath;
-    pstring origpath;
-    pstring service;
-    
-    /* Information on user who *opened* this connection */
-
-    pstring user;
-    uid_t uid;
-    gid_t gid;
-    int ngroups;
-    gid_t *groups;
-       NT_USER_TOKEN *nt_user_token;
-};
+/*
+ * As we're now (thanks Andrew ! :-) using file_structs and connection
+ * structs in the vfs - then anyone writing a vfs must include includes.h...
+ */
 
 /* VFS operations structure */
 
+struct connection_struct;
+struct files_struct;
+struct security_descriptor_info;
+
 struct vfs_ops {
 
     /* Disk operations */
     
-    int (*connect)(struct vfs_connection_struct *conn, char *service, char *user);
-    void (*disconnect)(void);
-    SMB_BIG_UINT (*disk_free)(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
+    int (*connect)(struct connection_struct *conn, char *service, char *user);
+    void (*disconnect)(struct connection_struct *conn);
+    SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                              SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
     
     /* Directory operations */
 
-    DIR *(*opendir)(char *fname);
-    struct dirent *(*readdir)(DIR *dirp);
-    int (*mkdir)(char *path, mode_t mode);
-    int (*rmdir)(char *path);
-    int (*closedir)(DIR *dir);
+    DIR *(*opendir)(struct connection_struct *conn, char *fname);
+    struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp);
+    int (*mkdir)(struct connection_struct *conn, char *path, mode_t mode);
+    int (*rmdir)(struct connection_struct *conn, char *path);
+    int (*closedir)(struct connection_struct *conn, DIR *dir);
     
     /* File operations */
     
-    int (*open)(char *fname, int flags, mode_t mode);
-    int (*close)(int fd);
-    ssize_t (*read)(int fd, char *data, size_t n);
-    ssize_t (*write)(int fd, char *data, size_t n);
-    SMB_OFF_T (*lseek)(int filedes, SMB_OFF_T offset, int whence);
-    int (*rename)(char *old, char *new);
-    int (*fsync)(int fd);
-    int (*stat)(char *fname, SMB_STRUCT_STAT *sbuf);
-    int (*fstat)(int fd, SMB_STRUCT_STAT *sbuf);
-    int (*lstat)(char *path, SMB_STRUCT_STAT *sbuf);
-    int (*unlink)(char *path);
-    int (*chmod)(char *path, mode_t mode);
-       int (*chown)(char *path, uid_t uid, gid_t gid);
-       int (*chdir)(char *path);
-       char *(*getwd)(char *buf);
-    int (*utime)(char *path, struct utimbuf *times);
-       int (*ftruncate)(int fd, SMB_OFF_T offset);
-       BOOL (*lock)(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
-
-       size_t (*fget_nt_acl)(int fd, SEC_DESC **ppdesc);
-       size_t (*get_nt_acl)(char *name, SEC_DESC **ppdesc);
-       BOOL (*fset_nt_acl)(int fd, uint32 security_info_sent, SEC_DESC *psd);
-       BOOL (*set_nt_acl)(char *name, uint32 security_info_sent, SEC_DESC *psd);
+    int (*open)(struct connection_struct *conn, char *fname, int flags, mode_t mode);
+    int (*close)(struct files_struct *fsp, int fd);
+    ssize_t (*read)(struct files_struct *fsp, int fd, char *data, size_t n);
+    ssize_t (*write)(struct files_struct *fsp, int fd, char *data, size_t n);
+    SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
+    int (*rename)(struct connection_struct *conn, char *old, char *new);
+    int (*fsync)(struct files_struct *fsp, int fd);
+    int (*stat)(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
+    int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+    int (*lstat)(struct connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf);
+    int (*unlink)(struct connection_struct *conn, char *path);
+    int (*chmod)(struct connection_struct *conn, char *path, mode_t mode);
+       int (*chown)(struct connection_struct *conn, char *path, uid_t uid, gid_t gid);
+       int (*chdir)(struct connection_struct *conn, char *path);
+       char *(*getwd)(struct connection_struct *conn, char *buf);
+    int (*utime)(struct connection_struct *conn, char *path, struct utimbuf *times);
+       int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset);
+       BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+
+       size_t (*fget_nt_acl)(struct files_struct *fsp, int fd, struct security_descriptor_info **ppdesc);
+       size_t (*get_nt_acl)(struct connection_struct *conn, char *name, struct security_descriptor_info **ppdesc);
+       BOOL (*fset_nt_acl)(struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor_info *psd);
+       BOOL (*set_nt_acl)(struct connection_struct *conn, char *name, uint32 security_info_sent, struct security_descriptor_info *psd);
 };
 
 struct vfs_options {
index 69df55b..7bac1ff 100644 (file)
@@ -204,7 +204,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
                /*
                 * No POSIX to worry about, just close.
                 */
-               ret = conn->vfs_ops.close(fsp->fd);
+               ret = conn->vfs_ops.close(fsp,fsp->fd);
                fsp->fd = -1;
                return ret;
        }
@@ -259,7 +259,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
                DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
 
                for(i = 0; i < count; i++) {
-                       if (conn->vfs_ops.close(fd_array[i]) == -1) {
+                       if (conn->vfs_ops.close(fsp,fd_array[i]) == -1) {
                                saved_errno = errno;
                        }
                }
@@ -279,7 +279,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
         * Finally close the fd associated with this fsp.
         */
 
-       ret = conn->vfs_ops.close(fsp->fd);
+       ret = conn->vfs_ops.close(fsp,fsp->fd);
 
        if (saved_errno != 0) {
         errno = saved_errno;
@@ -688,7 +688,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
 
        DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
 
-       ret = conn->vfs_ops.lock(fsp->fd,op,offset,count,type);
+       ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
 
        if (!ret && (errno == EFBIG)) {
                if( DEBUGLVL( 0 )) {
@@ -699,7 +699,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
                /* 32 bit NFS file system, retry with smaller offset */
                errno = 0;
                count &= 0x7fffffff;
-               ret = conn->vfs_ops.lock(fsp->fd,op,offset,count,type);
+               ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
        }
 
        /* A lock query - just return. */
@@ -727,7 +727,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
 
                                count = (orig_count & 0x7FFFFFFF);
                                offset = (SMB_OFF_T)map_lock_offset(off_high, off_low);
-                               ret = conn->vfs_ops.lock(fsp->fd,op,offset,count,type);
+                               ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
                                if (!ret) {
                                        if (errno == EINVAL) {
                                                DEBUG(3,("posix_fcntl_lock: locking not supported? returning True\n"));
index a1303eb..9b5a487 100644 (file)
@@ -50,10 +50,6 @@ files_struct *print_fsp_open(connection_struct *conn,char *jobname)
        /* setup a full fsp */
        fsp->print_jobid = jobid;
        fsp->fd = print_job_fd(jobid);
-       conn->vfs_ops.fstat(fsp->fd, &sbuf);
-       fsp->mode = sbuf.st_mode;
-       fsp->inode = sbuf.st_ino;
-       fsp->dev = sbuf.st_dev;
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
        fsp->size = 0;
@@ -73,6 +69,10 @@ files_struct *print_fsp_open(connection_struct *conn,char *jobname)
        string_set(&fsp->fsp_name,print_job_fname(jobid));
        fsp->wbmpx_ptr = NULL;      
        fsp->wcp = NULL; 
+       conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
+       fsp->mode = sbuf.st_mode;
+       fsp->inode = sbuf.st_ino;
+       fsp->dev = sbuf.st_dev;
 
        conn->num_files_open++;
 
index f71b6b0..62194f7 100644 (file)
@@ -146,7 +146,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
     if (normal_close && delete_on_close) {
         DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
            fsp->fsp_name));
-               if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) {
+               if(fsp->conn->vfs_ops.unlink(conn,dos_to_unix(fsp->fsp_name, False)) != 0) {
           /*
            * This call can potentially fail as another smbd may have
            * had the file open with delete on close set and deleted
index c1f42be..cd4ca9d 100644 (file)
@@ -170,19 +170,11 @@ void conn_free(connection_struct *conn)
        /* Free vfs_connection_struct */
            
 #ifdef HAVE_LIBDL
-       if (conn->vfs_conn != NULL) {
+       if (conn->dl_handle != NULL) {
                /* Close dlopen() handle */
-               if (conn->vfs_conn->dl_handle) {
-                       dlclose(conn->vfs_conn->dl_handle);
-               }
-#endif /* HAVE_LIBDL */
-
-               if (conn->vfs_conn->groups != NULL) {
-                       free(conn->vfs_conn->groups);
-               }
-               delete_nt_token(&conn->vfs_conn->nt_user_token);
-               free(conn->vfs_conn);
+               dlclose(conn->dl_handle);
        }
+#endif /* HAVE_LIBDL */
 
        DLIST_REMOVE(Connections, conn);
 
index aaab206..bf15be2 100644 (file)
@@ -627,7 +627,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
       pstrcpy(pathreal,path);
       pstrcat(path,fname);
       pstrcat(pathreal,dname);
-      if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
+      if (conn->vfs_ops.stat(conn,dos_to_unix(pathreal, False), &sbuf) != 0)
       {
         DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
         continue;
@@ -673,13 +673,13 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
 {
   Dir *dirp;
   char *n;
-  DIR *p = conn->vfs_ops.opendir(dos_to_unix(name,False));
+  DIR *p = conn->vfs_ops.opendir(conn,dos_to_unix(name,False));
   int used=0;
 
   if (!p) return(NULL);
   dirp = (Dir *)malloc(sizeof(Dir));
   if (!dirp) {
-    conn->vfs_ops.closedir(p);
+    conn->vfs_ops.closedir(conn,p);
     return(NULL);
   }
   dirp->pos = dirp->numentries = dirp->mallocsize = 0;
@@ -714,7 +714,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
     dirp->numentries++;
   }
 
-  conn->vfs_ops.closedir(p);
+  conn->vfs_ops.closedir(conn,p);
   return((void *)dirp);
 }
 
index 269d286..377cfbb 100644 (file)
@@ -243,7 +243,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
 
   errno = 0;
 
-  if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0)
+  if(conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times) == 0)
     return 0;
 
   if((errno != EPERM) && (errno != EACCES))
@@ -271,7 +271,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
                         current_user.ngroups,current_user.groups)))) {
                  /* We are allowed to become root and change the filetime. */
                  become_root();
-                 ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times);
+                 ret = conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times);
                  unbecome_root();
          }
   }
index 0c43a25..b8a0585 100644 (file)
@@ -38,7 +38,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
   if (fsp->print_file && lp_postscript(fsp->conn->service))
     offset = 3;
 
-  seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd,pos+offset,SEEK_SET);
+  seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET);
 
   /*
    * We want to maintain the fiction that we can seek
@@ -117,7 +117,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
   }
   
   if (n > 0) {
-    readret = fsp->conn->vfs_ops.read(fsp->fd,data,n);
+    readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
     if (readret == -1)
       return -1;
     if (readret > 0) ret += readret;
@@ -164,7 +164,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
     SMB_STRUCT_STAT st;
     fsp->modified = True;
 
-    if (fsp->conn->vfs_ops.fstat(fsp->fd,&st) == 0) {
+    if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) {
       int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
       if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {        
         file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
@@ -683,7 +683,7 @@ void sync_file(connection_struct *conn, files_struct *fsp)
 {
     if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) {
       flush_write_cache(fsp, SYNC_FLUSH);
-      conn->vfs_ops.fsync(fsp->fd);
+      conn->vfs_ops.fsync(fsp,fsp->fd);
     }
 }
 #undef OLD_NTDOMAIN
index 67fa85d..9ac8238 100644 (file)
@@ -211,7 +211,7 @@ 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(dos_to_unix(name,False),&st) == 0) {
+  if (conn->vfs_ops.stat(conn,dos_to_unix(name,False),&st) == 0) {
     stat_cache_add(orig_path, name);
     DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
     if(pst)
@@ -277,7 +277,7 @@ 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(dos_to_unix(name,False), &st) == 0) {
+      if (conn->vfs_ops.stat(conn,dos_to_unix(name,False), &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.
@@ -429,7 +429,7 @@ BOOL check_name(char *name,connection_struct *conn)
   if (!lp_symlinks(SNUM(conn)))
     {
       SMB_STRUCT_STAT statbuf;
-      if ( (conn->vfs_ops.lstat(dos_to_unix(name,False),&statbuf) != -1) &&
+      if ( (conn->vfs_ops.lstat(conn,dos_to_unix(name,False),&statbuf) != -1) &&
           (S_ISLNK(statbuf.st_mode)) )
         {
           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
index 95010cd..86b85ea 100644 (file)
@@ -892,13 +892,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
        }
                
        if(fsp->is_directory) {
-               if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
+               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 (conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+               if (conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
                        close_file(fsp,False);
                        restore_case_semantics(file_attributes);
                        return(ERROR(ERRDOS,ERRnoaccess));
@@ -1223,7 +1223,7 @@ static int call_nt_transact_create(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRnoaccess));
     }
 
-    if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
+    if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name, False),
             &sbuf) != 0) {
       close_file(fsp,True);
       restore_case_semantics(file_attributes);
@@ -1293,13 +1293,13 @@ static int call_nt_transact_create(connection_struct *conn,
       } 
   
       if(fsp->is_directory) {
-          if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
+          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->fd,&sbuf) != 0) {
+          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));
index 4964e15..edd94bd 100644 (file)
@@ -41,13 +41,13 @@ static int fd_open(struct connection_struct *conn, char *fname,
        flags |= O_NONBLOCK;
 #endif
 
-       fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode);
+       fd = conn->vfs_ops.open(conn,dos_to_unix(fname,False),flags,mode);
 
        /* Fix for files ending in '.' */
        if((fd == -1) && (errno == ENOENT) &&
           (strchr(fname,'.')==NULL)) {
                pstrcat(fname,".");
-               fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode);
+               fd = conn->vfs_ops.open(conn,dos_to_unix(fname,False),flags,mode);
        }
 
        DEBUG(10,("fd_open: name %s, mode = %d, fd = %d. %s\n", fname, (int)mode, fd,
@@ -138,7 +138,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
                return False;
        }
 
-       if (conn->vfs_ops.fstat(fsp->fd, &sbuf) == -1) {
+       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;
@@ -213,7 +213,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct *
                unix_ERR_code = ERRlock;
                return -1;
        } else {
-               return conn->vfs_ops.ftruncate(fsp->fd,0); 
+               return conn->vfs_ops.ftruncate(fsp,fsp->fd,0); 
        }
 }
 
@@ -792,7 +792,7 @@ files_struct *open_file_stat(connection_struct *conn,
        if(!fsp)
                return NULL;
 
-       if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) {
+       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);
@@ -862,7 +862,7 @@ files_struct *open_directory(connection_struct *conn,
        if(!fsp)
                return NULL;
 
-       if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) {
+       if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), &st) == 0) {
                got_stat = True;
        }
 
@@ -983,7 +983,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(dos_to_unix(fname,False),&sbuf) == -1)
+  if (conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf) == -1)
     return(True);
 
   dev = sbuf.st_dev;
index b98ae44..e64875a 100644 (file)
@@ -214,6 +214,7 @@ int reply_tcon(connection_struct *conn,
        uint16 vuid = SVAL(inbuf,smb_uid);
        int pwlen=0;
        int ecode = -1;
+       START_PROFILE(SMBtcon);
 
        *service = *user = *password = *dev = 0;
 
@@ -242,6 +243,7 @@ int reply_tcon(connection_struct *conn,
        conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
   
        if (!conn) {
+               END_PROFILE(SMBtcon);
                return(connection_error(inbuf,outbuf,ecode));
        }
   
@@ -253,6 +255,7 @@ int reply_tcon(connection_struct *conn,
        DEBUG(3,("tcon service=%s user=%s cnum=%d\n", 
                 service, user, conn->cnum));
   
+       END_PROFILE(SMBtcon);
        return(outsize);
 }
 
@@ -271,6 +274,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        int passlen = SVAL(inbuf,smb_vwv3);
        char *path;
        char *p;
+       START_PROFILE(SMBtconX);
        
        *service = *user = *password = *devicename = 0;
 
@@ -294,8 +298,10 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        }
        
        p = strchr(path+2,'\\');
-       if (!p)
+       if (!p) {
+               END_PROFILE(SMBtconX);
                return(ERROR(ERRDOS,ERRnosuchshare));
+       }
        fstrcpy(service,p+1);
        p = strchr(service,'%');
        if (p) {
@@ -327,8 +333,10 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        
        conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
        
-       if (!conn)
+       if (!conn) {
+               END_PROFILE(SMBtconX);
                return(connection_error(inbuf,outbuf,ecode));
+       }
 
        if (Protocol < PROTOCOL_NT1) {
                set_message(outbuf,2,strlen(devicename)+1,True);
@@ -359,6 +367,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        SSVAL(inbuf,smb_tid,conn->cnum);
        SSVAL(outbuf,smb_tid,conn->cnum);
 
+       END_PROFILE(SMBtconX);
        return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -390,6 +399,7 @@ int reply_ioctl(connection_struct *conn,
        int replysize, outsize;
        char *p;
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+       START_PROFILE(SMBioctl);
 
        DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
 
@@ -399,6 +409,7 @@ int reply_ioctl(connection_struct *conn,
                replysize = 32;
                break;
            default:
+               END_PROFILE(SMBioctl);
                return(ERROR(ERRSRV,ERRnosupport));
        }
 
@@ -417,6 +428,7 @@ int reply_ioctl(connection_struct *conn,
                break;
        }
 
+       END_PROFILE(SMBioctl);
        return outsize;
 }
 
@@ -653,6 +665,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   static BOOL done_sesssetup = False;
   BOOL doencrypt = SMBENCRYPT();
   char *domain = "";
+  START_PROFILE(SMBsesssetupX);
 
   *smb_apasswd = 0;
   *smb_ntpasswd = 0;
@@ -801,6 +814,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   /* say yes to everything ending in $. */
 
   if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
+    END_PROFILE(SMBsesssetupX);
     return session_trust_account(conn, inbuf, outbuf, user, 
                                  smb_apasswd, smb_apasslen,
                                  smb_ntpasswd, smb_ntpasslen);
@@ -816,6 +830,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
      */
     if (!*user && !*smb_apasswd && !*domain) {
       DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
+      END_PROFILE(SMBsesssetupX);
       return(ERROR(ERRDOS,ERRnoaccess));
     }
   }
@@ -913,6 +928,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
         if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
         {
           DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
+                 END_PROFILE(SMBsesssetupX);
           return bad_password_error(inbuf,outbuf);
         }
 
@@ -921,6 +937,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
           if (smb_getpwnam(user,True))
           {
             DEBUG(1,("Rejecting user '%s': bad password\n", user));
+               END_PROFILE(SMBsesssetupX);
             return bad_password_error(inbuf,outbuf);
           }
         }
@@ -976,6 +993,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
     const struct passwd *pw = smb_getpwnam(user,False);
     if (!pw) {
       DEBUG(1,("Username %s is invalid on this system\n",user));
+      END_PROFILE(SMBsesssetupX);
       return bad_password_error(inbuf,outbuf);
     }
     gid = pw->pw_gid;
@@ -1000,6 +1018,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   done_sesssetup = True;
 
+  END_PROFILE(SMBsesssetupX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -1015,6 +1034,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL ok = False;
   BOOL bad_path = False;
   SMB_STRUCT_STAT st;
+  START_PROFILE(SMBchkpth_count);
  
   pstrcpy(name,smb_buf(inbuf) + 1);
 
@@ -1061,6 +1081,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
   DEBUG(3,("chkpth %s mode=%d\n", name, mode));
 
+  END_PROFILE(SMBchkpth);
   return(outsize);
 }
 
@@ -1078,6 +1099,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   SMB_OFF_T size=0;
   time_t mtime=0;
   BOOL bad_path = False;
+  START_PROFILE(SMBgetatr);
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
 
@@ -1122,6 +1144,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
       unix_ERR_code = ERRbadpath;
     }
 
+    END_PROFILE(SMBgetatr);
     return(UNIXERROR(ERRDOS,ERRbadfile));
   }
  
@@ -1144,6 +1167,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   
   DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
   
+  END_PROFILE(SMBgetatr);
   return(outsize);
 }
 
@@ -1160,6 +1184,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   time_t mtime;
   SMB_STRUCT_STAT st;
   BOOL bad_path = False;
+  START_PROFILE(SMBsetatr);
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
   unix_convert(fname,conn,0,&bad_path,&st);
@@ -1182,6 +1207,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
       unix_ERR_code = ERRbadpath;
     }
 
+    END_PROFILE(SMBsetatr);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
  
@@ -1189,6 +1215,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   
   DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
   
+  END_PROFILE(SMBsetatr);
   return(outsize);
 }
 
@@ -1200,8 +1227,9 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
 {
   int outsize = 0;
   SMB_BIG_UINT dfree,dsize,bsize;
+  START_PROFILE(SMBdskattr);
   
-  conn->vfs_ops.disk_free(".",True,&bsize,&dfree,&dsize);
+  conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
   
   outsize = set_message(outbuf,5,0,True);
   
@@ -1212,6 +1240,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
 
   DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
 
+  END_PROFILE(SMBdskattr);
   return(outsize);
 }
 
@@ -1244,6 +1273,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL expect_close = False;
   BOOL can_open = True;
   BOOL bad_path = False;
+  START_PROFILE(SMBsearch);
 
   *mask = *directory = *fname = 0;
 
@@ -1324,8 +1354,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
             unix_ERR_class = ERRDOS;
             unix_ERR_code = ERRbadpath;
           }
+                END_PROFILE(SMBsearch);
           return (UNIXERROR(ERRDOS,ERRnofids));
         }
+               END_PROFILE(SMBsearch);
         return(ERROR(ERRDOS,ERRnofids));
       }
       dptr_set_wcard(dptr_num, strdup(mask));
@@ -1416,6 +1448,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
         smb_fn_name(CVAL(inbuf,smb_com)), 
         mask, directory, dirtype, numentries, maxentries ) );
 
+  END_PROFILE(SMBsearch);
   return(outsize);
 }
 
@@ -1430,14 +1463,17 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   char *path;
   char status[21];
   int dptr_num= -2;
+  START_PROFILE(SMBfclose);
 
   outsize = set_message(outbuf,1,0,True);
   path = smb_buf(inbuf) + 1;
   status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
 
   
-  if (status_len == 0)
+  if (status_len == 0) {
+    END_PROFILE(SMBfclose);
     return(ERROR(ERRSRV,ERRsrverror));
+  }
 
   memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
 
@@ -1450,6 +1486,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
   DEBUG(3,("search close\n"));
 
+  END_PROFILE(SMBfclose);
   return(outsize);
 }
 
@@ -1472,6 +1509,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
   files_struct *fsp;
   int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+  START_PROFILE(SMBopen);
  
   share_mode = SVAL(inbuf,smb_vwv0);
 
@@ -1493,11 +1531,13 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
+    END_PROFILE(SMBopen);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+  if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
     close_file(fsp,False);
+    END_PROFILE(SMBopen);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
     
@@ -1508,6 +1548,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if (fmode & aDIR) {
     DEBUG(3,("attempt to open a directory %s\n",fname));
     close_file(fsp,False);
+    END_PROFILE(SMBopen);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
   
@@ -1527,6 +1568,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     
   if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
     CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+  END_PROFILE(SMBopen);
   return(outsize);
 }
 
@@ -1557,13 +1599,17 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   int smb_action = 0;
   BOOL bad_path = False;
   files_struct *fsp;
+  START_PROFILE(SMBopenX);
 
   /* If it's an IPC, pass off the pipe handler. */
   if (IS_IPC(conn)) {
-    if (lp_nt_pipe_support())
+    if (lp_nt_pipe_support()) {
+           END_PROFILE(SMBopenX);
            return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
-    else
+    } else {
+               END_PROFILE(SMBopenX);
         return (ERROR(ERRSRV,ERRaccess));
+    }
   }
 
   /* XXXX we need to handle passed times, sattr and flags */
@@ -1586,11 +1632,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
+    END_PROFILE(SMBopenX);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+  if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
     close_file(fsp,False);
+    END_PROFILE(SMBopenX);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1599,6 +1647,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   mtime = sbuf.st_mtime;
   if (fmode & aDIR) {
     close_file(fsp,False);
+    END_PROFILE(SMBopenX);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1639,6 +1688,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   SSVAL(outbuf,smb_vwv8,rmode);
   SSVAL(outbuf,smb_vwv11,smb_action);
 
+  END_PROFILE(SMBopenX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -1650,6 +1700,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
 {
   uint16 vuid = SVAL(inbuf,smb_uid);
   user_struct *vuser = get_valid_user_struct(vuid);
+  START_PROFILE(SMBulogoffX);
 
   if(vuser == 0) {
     DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
@@ -1667,6 +1718,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
 
   DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
 
+  END_PROFILE(SMBulogoffX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -1685,6 +1737,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);
+  START_PROFILE(SMBcreate);
  
   com = SVAL(inbuf,smb_com);
 
@@ -1724,6 +1777,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
+    END_PROFILE(SMBcreate);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
  
@@ -1741,6 +1795,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
         fname, fsp->fd, createmode, (int)unixmode ) );
 
+  END_PROFILE(SMBcreate);
   return(outsize);
 }
 
@@ -1758,6 +1813,7 @@ 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);
+  START_PROFILE(SMBctemp);
  
   createmode = SVAL(inbuf,smb_vwv0);
   pstrcpy(fname,smb_buf(inbuf)+1);
@@ -1783,6 +1839,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
+    END_PROFILE(SMBctemp);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
@@ -1802,6 +1859,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
         fname2, fsp->fd, createmode, (int)unixmode ) );
 
+  END_PROFILE(SMBctemp);
   return(outsize);
 }
 
@@ -1816,7 +1874,7 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (conn->vfs_ops.lstat(dos_to_unix(fname,False),&sbuf) != 0) return(False);
+  if (conn->vfs_ops.lstat(conn,dos_to_unix(fname,False),&sbuf) != 0) return(False);
   fmode = dos_mode(conn,fname,&sbuf);
   if (fmode & aDIR) return(False);
   if (!lp_delete_readonly(SNUM(conn))) {
@@ -1846,6 +1904,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL exists=False;
   BOOL bad_path = False;
   BOOL rc = True;
+  START_PROFILE(SMBunlink);
 
   *directory = *mask = 0;
 
@@ -1919,7 +1978,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
            error = ERRnoaccess;
            slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
            if (!can_delete(fname,conn,dirtype)) continue;
-           if (!conn->vfs_ops.unlink(dos_to_unix(fname,False))) count++;
+           if (!vfs_unlink(conn,fname)) count++;
            DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
          }
        CloseDir(dirptr);
@@ -1927,21 +1986,24 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   }
   
   if (count == 0) {
-    if (exists)
+    if (exists) {
+      END_PROFILE(SMBunlink);
       return(ERROR(ERRDOS,error));
-    else
+    else
     {
       if((errno == ENOENT) && bad_path)
       {
         unix_ERR_class = ERRDOS;
         unix_ERR_code = ERRbadpath;
       }
+      END_PROFILE(SMBunlink);
       return(UNIXERROR(ERRDOS,error));
     }
   }
   
   outsize = set_message(outbuf,0,0,True);
   
+  END_PROFILE(SMBunlink);
   return(outsize);
 }
 
@@ -1958,6 +2020,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   char *header = outbuf;
   ssize_t ret=0;
   files_struct *fsp;
+  START_PROFILE(SMBreadbraw);
 
   /*
    * Special check if an oplock break has been issued
@@ -1970,6 +2033,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     _smb_setlen(header,0);
     transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
     DEBUG(5,("readbraw - oplock break finished\n"));
+    END_PROFILE(SMBreadbraw);
     return -1;
   }
 
@@ -1982,6 +2046,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
          DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
          _smb_setlen(header,0);
          transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
+         END_PROFILE(SMBreadbraw);
          return(-1);
   }
 
@@ -2009,6 +2074,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
       _smb_setlen(header,0);
       transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
+      END_PROFILE(SMBreadbraw);
       return(-1);
     }
 
@@ -2019,6 +2085,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
             (double)startpos ));
          _smb_setlen(header,0);
          transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
+         END_PROFILE(SMBreadbraw);
          return(-1);
     }      
   }
@@ -2037,7 +2104,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     if (size < sizeneeded)
     {
       SMB_STRUCT_STAT st;
-      if (fsp->conn->vfs_ops.fstat(fsp->fd,&st) == 0)
+      if (vfs_fstat(fsp,fsp->fd,&st) == 0)
         size = st.st_size;
       if (!fsp->can_write) 
         fsp->size = size;
@@ -2060,7 +2127,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     _smb_setlen(header,nread);
 
     if ((nread-predict) > 0) {
-      if(conn->vfs_ops.seek(fsp,startpos + predict) == -1) {
+      if(conn->vfs_ops.seek(fsp,fsp->fd,startpos + predict) == -1) {
         DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
         ret = 0;
         seek_fail = True;
@@ -2068,7 +2135,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     }
 
     if(!seek_fail)
-      ret = (ssize_t)vfs_transfer_file(-1, fsp->fd, Client, NULL,
+      ret = (ssize_t)vfs_transfer_file(-1, fsp, fsp->fd, Client, NULL,
                                    (SMB_OFF_T)(nread-predict),header,4+predict, 
                                    startpos+predict);
   }
@@ -2086,6 +2153,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 #endif /* UNSAFE_READRAW */
 
   DEBUG(5,("readbraw finished\n"));
+  END_PROFILE(SMBreadbraw);
   return -1;
 }
 
@@ -2103,6 +2171,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
   int eclass;
   uint32 ecode;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBlockread);
 
   CHECK_FSP(fsp,conn);
   CHECK_READ(fsp);
@@ -2130,15 +2199,19 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
        * onto the blocking lock queue.
        */
       if(push_blocking_lock_request(inbuf, length, -1, 0))
+               END_PROFILE(SMBlockread);
         return -1;
     }
+    END_PROFILE(SMBlockread);
     return (ERROR(eclass,ecode));
   }
 
   nread = read_file(fsp,data,startpos,numtoread);
 
-  if (nread < 0)
+  if (nread < 0) {
+    END_PROFILE(SMBlockread);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
 
   outsize += nread;
   SSVAL(outbuf,smb_vwv0,nread);
@@ -2148,6 +2221,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
   DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
             fsp->fnum, (int)numtoread, (int)nread ) );
 
+  END_PROFILE(SMBlockread);
   return(outsize);
 }
 
@@ -2164,6 +2238,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   SMB_OFF_T startpos;
   int outsize = 0;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBread);
 
   CHECK_FSP(fsp,conn);
   CHECK_READ(fsp);
@@ -2176,14 +2251,18 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+    END_PROFILE(SMBread);
     return(ERROR(ERRDOS,ERRlock));     
+  }
 
   if (numtoread > 0)
     nread = read_file(fsp,data,startpos,numtoread);
   
-  if (nread < 0)
+  if (nread < 0) {
+    END_PROFILE(SMBread);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
   
   outsize += nread;
   SSVAL(outbuf,smb_vwv0,nread);
@@ -2194,6 +2273,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
             fsp->fnum, (int)numtoread, (int)nread ) );
 
+  END_PROFILE(SMBread);
   return(outsize);
 }
 
@@ -2209,10 +2289,13 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
   ssize_t nread = -1;
   char *data;
+  START_PROFILE(SMBreadX);
 
   /* If it's an IPC, pass off the pipe handler. */
-  if (IS_IPC(conn))
+  if (IS_IPC(conn)) {
+    END_PROFILE(SMBreadX);
     return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
+  }
 
   CHECK_FSP(fsp,conn);
   CHECK_READ(fsp);
@@ -2237,6 +2320,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     if(IVAL(inbuf,smb_vwv10) != 0) {
       DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
+      END_PROFILE(SMBreadX);
       return(ERROR(ERRDOS,ERRbadaccess));
     }
 
@@ -2244,12 +2328,16 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 
   }
 
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+    END_PROFILE(SMBreadX);
     return(ERROR(ERRDOS,ERRlock));
+  }
   nread = read_file(fsp,data,startpos,smb_maxcnt);
   
-  if (nread < 0)
+  if (nread < 0) {
+    END_PROFILE(SMBreadX);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
   
   SSVAL(outbuf,smb_vwv5,nread);
   SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
@@ -2258,6 +2346,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
              fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) );
 
+  END_PROFILE(SMBreadX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -2276,6 +2365,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
   BOOL write_through;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
   int outsize = 0;
+  START_PROFILE(SMBwritebraw);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2299,8 +2389,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
   CVAL(inbuf,smb_com) = SMBwritec;
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+    END_PROFILE(SMBwritebraw);
     return(ERROR(ERRDOS,ERRlock));
+  }
 
   if (numtowrite>0)
     nwritten = write_file(fsp,data,startpos,numtowrite);
@@ -2308,8 +2400,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
   DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
           fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
 
-  if (nwritten < numtowrite) 
+  if (nwritten < numtowrite)  {
+    END_PROFILE(SMBwritebraw);
     return(UNIXERROR(ERRHRD,ERRdiskfull));
+  }
 
   total_written = nwritten;
 
@@ -2358,8 +2452,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
   /* we won't return a status if write through is not selected - this 
      follows what WfWg does */
-  if (!write_through && total_written==tcount)
+  END_PROFILE(SMBwritebraw);
+  if (!write_through && total_written==tcount) {
     return(-1);
+  }
 
   return(outsize);
 }
@@ -2378,6 +2474,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
   uint32 ecode;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
   int outsize = 0;
+  START_PROFILE(SMBwriteunlock);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2387,8 +2484,10 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+    END_PROFILE(SMBwriteunlock);
     return(ERROR(ERRDOS,ERRlock));
+  }
 
   /* The special X/Open SMB protocol handling of
      zero length writes is *NOT* done for
@@ -2401,11 +2500,15 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
   if (lp_syncalways(SNUM(conn)))
       sync_file(conn,fsp);
 
-  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
+  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+    END_PROFILE(SMBwriteunlock);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
 
-  if(!do_unlock(fsp, conn, (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode))
+  if(!do_unlock(fsp, conn, (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode)) {
+    END_PROFILE(SMBwriteunlock);
     return(ERROR(eclass,ecode));
+  }
 
   outsize = set_message(outbuf,1,0,True);
   
@@ -2414,6 +2517,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
   DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
              fsp->fnum, (int)numtowrite, (int)nwritten ) );
 
+  END_PROFILE(SMBwriteunlock);
   return(outsize);
 }
 
@@ -2428,10 +2532,13 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
   char *data;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
   int outsize = 0;
+  START_PROFILE(SMBwrite);
 
   /* If it's an IPC, pass off the pipe handler. */
-  if (IS_IPC(conn))
+  if (IS_IPC(conn)) {
+    END_PROFILE(SMBwrite);
     return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
+  }
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2441,8 +2548,10 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+    END_PROFILE(SMBwrite);
     return(ERROR(ERRDOS,ERRlock));
+  }
 
   /* X/Open SMB protocol says that if smb_vwv1 is
      zero then the file size should be extended or
@@ -2456,8 +2565,10 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
   if (lp_syncalways(SNUM(conn)))
     sync_file(conn,fsp);
 
-  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
+  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+    END_PROFILE(SMBwrite);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
 
   outsize = set_message(outbuf,1,0,True);
   
@@ -2471,6 +2582,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
   DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
           fsp->fnum, (int)numtowrite, (int)nwritten));
 
+  END_PROFILE(SMBwrite);
   return(outsize);
 }
 
@@ -2487,17 +2599,22 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   ssize_t nwritten = -1;
   unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
   char *data;
+  START_PROFILE(SMBwriteX);
 
   /* If it's an IPC, pass off the pipe handler. */
-  if (IS_IPC(conn))
+  if (IS_IPC(conn)) {
+    END_PROFILE(SMBwriteX);
     return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
+  }
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
   CHECK_ERROR(fsp);
 
-  if(smb_doff > smb_len(inbuf))
+  if(smb_doff > smb_len(inbuf)) {
+    END_PROFILE(SMBwriteX);
     return(ERROR(ERRDOS,ERRbadmem));
+  }
 
   data = smb_base(inbuf) + smb_doff;
 
@@ -2517,14 +2634,17 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
     if(IVAL(inbuf,smb_vwv12) != 0) {
       DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
+      END_PROFILE(SMBwriteX);
       return(ERROR(ERRDOS,ERRbadaccess));
     }
 
 #endif /* LARGE_SMB_OFF_T */
   }
 
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+    END_PROFILE(SMBwriteX);
     return(ERROR(ERRDOS,ERRlock));
+  }
 
   /* X/Open SMB protocol says that, unlike SMBwrite
      if the length is zero then NO truncation is
@@ -2535,8 +2655,10 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   else
     nwritten = write_file(fsp,data,startpos,numtowrite);
   
-  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
+  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+    END_PROFILE(SMBwriteX);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
 
   set_message(outbuf,6,0,True);
   
@@ -2553,6 +2675,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   if (lp_syncalways(SNUM(conn)) || write_through)
     sync_file(conn,fsp);
 
+  END_PROFILE(SMBwriteX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -2568,6 +2691,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   int mode,umode;
   int outsize = 0;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBlseek);
 
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
@@ -2585,7 +2709,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
       umode = SEEK_SET; break;
   }
 
-  if((res = conn->vfs_ops.lseek(fsp->fd,startpos,umode)) == -1) {
+  if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) {
     /*
      * Check for the special case where a seek before the start
      * of the file sets the offset to zero. Added in the CIFS spec,
@@ -2597,8 +2721,10 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 
       if(umode == SEEK_CUR) {
 
-        if((current_pos = conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
+        if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
+                       END_PROFILE(SMBlseek);
           return(UNIXERROR(ERRDOS,ERRnoaccess));
+       }
 
         current_pos += startpos;
 
@@ -2606,18 +2732,22 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 
         SMB_STRUCT_STAT sbuf;
 
-        if(conn->vfs_ops.fstat(fsp->fd, &sbuf) == -1)
+        if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
+                 END_PROFILE(SMBlseek);
           return(UNIXERROR(ERRDOS,ERRnoaccess));
+       }
 
         current_pos += sbuf.st_size;
       }
  
       if(current_pos < 0)
-        res = conn->vfs_ops.lseek(fsp->fd,0,SEEK_SET);
+        res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
     }
 
-    if(res == -1)
+    if(res == -1) {
+      END_PROFILE(SMBlseek);
       return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
   }
 
   fsp->pos = res;
@@ -2628,6 +2758,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
           fsp->fnum, (double)startpos, (double)res, mode));
 
+  END_PROFILE(SMBlseek);
   return(outsize);
 }
 
@@ -2639,6 +2770,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 {
   int outsize = set_message(outbuf,0,0,True);
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBflush);
 
   if (fsp) {
          CHECK_FSP(fsp,conn);
@@ -2652,6 +2784,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   }
 
   DEBUG(3,("flush\n"));
+  END_PROFILE(SMBflush);
   return(outsize);
 }
 
@@ -2662,9 +2795,13 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 int reply_exit(connection_struct *conn, 
               char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int outsize = set_message(outbuf,0,0,True);
+       int outsize;
+       START_PROFILE(SMBexit);
+       outsize = set_message(outbuf,0,0,True);
+
        DEBUG(3,("exit\n"));
 
+       END_PROFILE(SMBexit);
        return(outsize);
 }
 
@@ -2679,12 +2816,15 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
        time_t mtime;
        int32 eclass = 0, err = 0;
        files_struct *fsp = NULL;
+       START_PROFILE(SMBclose);
 
        outsize = set_message(outbuf,0,0,True);
 
        /* If it's an IPC, pass off to the pipe handler. */
-       if (IS_IPC(conn))
+       if (IS_IPC(conn)) {
+               END_PROFILE(SMBclose);
                return reply_pipe_close(conn, inbuf,outbuf);
+       }
 
        fsp = file_fsp(inbuf,smb_vwv0);
 
@@ -2692,8 +2832,10 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!fsp || (fsp->conn != conn))
+       if(!fsp || (fsp->conn != conn)) {
+               END_PROFILE(SMBclose);
                return(ERROR(ERRDOS,ERRbadfid));
+       }
 
        if(HAS_CACHED_ERROR(fsp)) {
                eclass = fsp->wbmpx_ptr->wr_errclass;
@@ -2740,14 +2882,18 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
  
                if((close_err = close_file(fsp,True)) != 0) {
                        errno = close_err;
+                       END_PROFILE(SMBclose);
                        return (UNIXERROR(ERRHRD,ERRgeneral));
                }
        }  
 
        /* We have a cached error */
-       if(eclass || err)
+       if(eclass || err) {
+               END_PROFILE(SMBclose);
                return(ERROR(eclass,err));
+       }
 
+       END_PROFILE(SMBclose);
        return(outsize);
 }
 
@@ -2767,6 +2913,7 @@ int reply_writeclose(connection_struct *conn,
        char *data;
        time_t mtime;
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+       START_PROFILE(SMBwriteclose);
 
        CHECK_FSP(fsp,conn);
        CHECK_WRITE(fsp);
@@ -2777,9 +2924,11 @@ int reply_writeclose(connection_struct *conn,
        mtime = make_unix_date3(inbuf+smb_vwv4);
        data = smb_buf(inbuf) + 1;
   
-       if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK))
+       if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+               END_PROFILE(SMBwriteclose);
                return(ERROR(ERRDOS,ERRlock));
-          
+       }
+  
        nwritten = write_file(fsp,data,startpos,numtowrite);
 
        set_filetime(conn, fsp->fsp_name,mtime);
@@ -2790,17 +2939,21 @@ int reply_writeclose(connection_struct *conn,
                 fsp->fnum, (int)numtowrite, (int)nwritten,
                 conn->num_files_open));
   
-       if (nwritten <= 0)
+       if (nwritten <= 0) {
+               END_PROFILE(SMBwriteclose);
                return(UNIXERROR(ERRDOS,ERRnoaccess));
+       }
  
        if(close_err != 0) {
                errno = close_err;
+               END_PROFILE(SMBwriteclose);
                return(UNIXERROR(ERRHRD,ERRgeneral));
        }
  
        outsize = set_message(outbuf,1,0,True);
   
        SSVAL(outbuf,smb_vwv0,nwritten);
+       END_PROFILE(SMBwriteclose);
        return(outsize);
 }
 
@@ -2816,6 +2969,7 @@ int reply_lock(connection_struct *conn,
        int eclass;
        uint32 ecode;
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+       START_PROFILE(SMBlock);
 
        CHECK_FSP(fsp,conn);
        CHECK_ERROR(fsp);
@@ -2827,18 +2981,22 @@ int reply_lock(connection_struct *conn,
                 fsp->fd, fsp->fnum, (double)offset, (double)count));
 
        if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) {
-      if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
-        /*
-         * A blocking lock was requested. Package up
-         * this smb into a queued request and push it
-         * onto the blocking lock queue.
-         */
-        if(push_blocking_lock_request(inbuf, length, -1, 0))
-          return -1;
-      }
-      return (ERROR(eclass,ecode));
-    }
+          if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
+           /*
+             * A blocking lock was requested. Package up
+             * this smb into a queued request and push it
+             * onto the blocking lock queue.
+             */
+            if(push_blocking_lock_request(inbuf, length, -1, 0)) {
+             END_PROFILE(SMBlock);
+              return -1;
+           }
+          }
+         END_PROFILE(SMBlock);
+         return (ERROR(eclass,ecode));
+       }
 
+       END_PROFILE(SMBlock);
        return(outsize);
 }
 
@@ -2853,6 +3011,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in
   int eclass;
   uint32 ecode;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBunlock);
 
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
@@ -2860,12 +3019,15 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in
   count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
   offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
 
-  if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode))
+  if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode)) {
+    END_PROFILE(SMBunlock);
     return (ERROR(eclass,ecode));
+  }
 
   DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
         fsp->fd, fsp->fnum, (double)offset, (double)count ) );
   
+  END_PROFILE(SMBunlock);
   return(outsize);
 }
 
@@ -2878,11 +3040,13 @@ int reply_tdis(connection_struct *conn,
 {
        int outsize = set_message(outbuf,0,0,True);
        uint16 vuid;
+       START_PROFILE(SMBtdis);
 
        vuid = SVAL(inbuf,smb_uid);
 
        if (!conn) {
                DEBUG(4,("Invalid connection in tdis\n"));
+               END_PROFILE(SMBtdis);
                return(ERROR(ERRSRV,ERRinvnid));
        }
 
@@ -2890,6 +3054,7 @@ int reply_tdis(connection_struct *conn,
 
        close_cnum(conn,vuid);
   
+       END_PROFILE(SMBtdis);
        return outsize;
 }
 
@@ -2905,6 +3070,7 @@ int reply_echo(connection_struct *conn,
        int seq_num;
        unsigned int data_len = smb_buflen(inbuf);
        int outsize = set_message(outbuf,1,data_len,True);
+       START_PROFILE(SMBecho);
 
        data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
 
@@ -2929,6 +3095,7 @@ int reply_echo(connection_struct *conn,
 
        smb_echo_count++;
 
+       END_PROFILE(SMBecho);
        return -1;
 }
 
@@ -2941,14 +3108,18 @@ int reply_printopen(connection_struct *conn,
 {
        int outsize = 0;
        files_struct *fsp;
+       START_PROFILE(SMBsplopen);
        
-       if (!CAN_PRINT(conn))
+       if (!CAN_PRINT(conn)) {
+               END_PROFILE(SMBsplopen);
                return(ERROR(ERRDOS,ERRnoaccess));
+       }
 
        /* Open for exclusive use, write only. */
        fsp = print_fsp_open(conn,"dos.prn");
 
        if (!fsp) {
+               END_PROFILE(SMBsplopen);
                return(UNIXERROR(ERRDOS,ERRnoaccess));
        }
 
@@ -2958,6 +3129,7 @@ int reply_printopen(connection_struct *conn,
        DEBUG(3,("openprint fd=%d fnum=%d\n",
                 fsp->fd, fsp->fnum));
 
+       END_PROFILE(SMBsplopen);
        return(outsize);
 }
 
@@ -2971,12 +3143,15 @@ int reply_printclose(connection_struct *conn,
        int outsize = set_message(outbuf,0,0,True);
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
        int close_err = 0;
+       START_PROFILE(SMBsplclose);
 
        CHECK_FSP(fsp,conn);
        CHECK_ERROR(fsp);
 
-       if (!CAN_PRINT(conn))
+       if (!CAN_PRINT(conn)) {
+               END_PROFILE(SMBsplclose);
                return(ERROR(ERRDOS,ERRnoaccess));
+       }
   
        DEBUG(3,("printclose fd=%d fnum=%d\n",
                 fsp->fd,fsp->fnum));
@@ -2985,9 +3160,11 @@ int reply_printclose(connection_struct *conn,
 
        if(close_err != 0) {
                errno = close_err;
+               END_PROFILE(SMBsplclose);
                return(UNIXERROR(ERRHRD,ERRgeneral));
        }
 
+       END_PROFILE(SMBsplclose);
        return(outsize);
 }
 
@@ -3001,13 +3178,16 @@ int reply_printqueue(connection_struct *conn,
        int outsize = set_message(outbuf,2,3,True);
        int max_count = SVAL(inbuf,smb_vwv0);
        int start_index = SVAL(inbuf,smb_vwv1);
+       START_PROFILE(SMBsplretq);
 
        /* we used to allow the client to get the cnum wrong, but that
           is really quite gross and only worked when there was only
           one printer - I think we should now only accept it if they
           get it right (tridge) */
-       if (!CAN_PRINT(conn))
+       if (!CAN_PRINT(conn)) {
+               END_PROFILE(SMBsplretq);
                return(ERROR(ERRDOS,ERRnoaccess));
+       }
 
        SSVAL(outbuf,smb_vwv0,0);
        SSVAL(outbuf,smb_vwv1,0);
@@ -3054,6 +3234,7 @@ int reply_printqueue(connection_struct *conn,
                DEBUG(3,("%d entries returned in queue\n",count));
        }
   
+       END_PROFILE(SMBsplretq);
        return(outsize);
 }
 
@@ -3067,9 +3248,12 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
   int outsize = set_message(outbuf,0,0,True);
   char *data;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBsplwr);
   
-  if (!CAN_PRINT(conn))
+  if (!CAN_PRINT(conn)) {
+    END_PROFILE(SMBsplwr);
     return(ERROR(ERRDOS,ERRnoaccess));
+  }
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -3078,11 +3262,14 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
   numtowrite = SVAL(smb_buf(inbuf),1);
   data = smb_buf(inbuf) + 3;
   
-  if (write_file(fsp,data,-1,numtowrite) != numtowrite)
+  if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
+    END_PROFILE(SMBsplwr);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
-  
+  }
+
   DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
   
+  END_PROFILE(SMBsplwr);
   return(outsize);
 }
 
@@ -3121,6 +3308,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 {
   pstring directory;
   int outsize;
+  START_PROFILE(SMBmkdir);
  
   pstrcpy(directory,smb_buf(inbuf) + 1);
 
@@ -3130,6 +3318,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
 
+  END_PROFILE(SMBmkdir);
   return(outsize);
 }
 
@@ -3166,7 +3355,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
     pstrcat(fullname, "/");
     pstrcat(fullname, dname);
 
-    if(conn->vfs_ops.lstat(dos_to_unix(fullname,False), &st) != 0)
+    if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname,False), &st) != 0)
     {
       ret = True;
       break;
@@ -3179,13 +3368,13 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
         ret = True;
         break;
       }
-      if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0)
+      if(vfs_rmdir(conn,fullname) != 0)
       {
         ret = True;
         break;
       }
     }
-    else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
+    else if(vfs_unlink(conn,fullname) != 0)
     {
       ret = True;
       break;
@@ -3203,7 +3392,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
 {
   BOOL ok;
 
-  ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
+  ok = (vfs_rmdir(conn,directory) == 0);
   if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn)))
   {
     /* 
@@ -3250,7 +3439,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
           pstrcat(fullname, "/");
           pstrcat(fullname, dname);
                      
-          if(conn->vfs_ops.lstat(dos_to_unix(fullname, False), &st) != 0)
+          if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname, False), &st) != 0)
             break;
           if(st.st_mode & S_IFDIR)
           {
@@ -3259,15 +3448,15 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
               if(recursive_rmdir(conn, fullname) != 0)
                 break;
             }
-            if(conn->vfs_ops.rmdir(dos_to_unix(fullname, False)) != 0)
+            if(vfs_rmdir(conn,fullname) != 0)
               break;
           }
-          else if(conn->vfs_ops.unlink(dos_to_unix(fullname, False)) != 0)
+          else if(vfs_unlink(conn,fullname) != 0)
             break;
         }
         CloseDir(dirptr);
         /* Retry the rmdir */
-        ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
+        ok = (vfs_rmdir(conn,directory) == 0);
       }
       else
         CloseDir(dirptr);
@@ -3293,6 +3482,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   int outsize = 0;
   BOOL ok = False;
   BOOL bad_path = False;
+  START_PROFILE(SMBrmdir);
 
   pstrcpy(directory,smb_buf(inbuf) + 1);
 
@@ -3313,6 +3503,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadpath;
     }
+    END_PROFILE(SMBrmdir);
     return(UNIXERROR(ERRDOS,ERRbadpath));
   }
  
@@ -3320,6 +3511,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   
   DEBUG( 3, ( "rmdir %s\n", directory ) );
   
+  END_PROFILE(SMBrmdir);
   return(outsize);
 }
 
@@ -3397,7 +3589,7 @@ static BOOL can_rename(char *fname,connection_struct *conn)
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (conn->vfs_ops.lstat(dos_to_unix(fname,False),&sbuf) != 0) return(False);
+  if (conn->vfs_ops.lstat(conn,dos_to_unix(fname,False),&sbuf) != 0) return(False);
   if (!check_file_sharing(conn,fname,True)) return(False);
 
   return(True);
@@ -3529,14 +3721,14 @@ int rename_internals(connection_struct *conn,
                         */
                        if(resolve_wildcards(directory,newname) &&
                           can_rename(directory,conn) &&
-                          !conn->vfs_ops.rename(zdirectory,
+                          !conn->vfs_ops.rename(conn,zdirectory,
                                                 dos_to_unix(newname,False)))
                                count++;
                } else {
                        if (resolve_wildcards(directory,newname) && 
                            can_rename(directory,conn) && 
                            !vfs_file_exist(conn,newname,NULL) &&
-                           !conn->vfs_ops.rename(zdirectory,
+                           !conn->vfs_ops.rename(conn,zdirectory,
                                                  dos_to_unix(newname,False)))
                                count++;
                }
@@ -3595,7 +3787,7 @@ int rename_internals(connection_struct *conn,
                                        continue;
                                }
                                
-                               if (!conn->vfs_ops.rename(dos_to_unix(fname,False),
+                               if (!conn->vfs_ops.rename(conn,dos_to_unix(fname,False),
                                                           dos_to_unix(destname,False)))
                                        count++;
                                DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
@@ -3628,6 +3820,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
   int outsize = 0;
   pstring name;
   pstring newname;
+  START_PROFILE(SMBmv);
 
   pstrcpy(name,smb_buf(inbuf) + 1);
   pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
@@ -3650,6 +3843,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
     outsize = set_message(outbuf,0,0,True);
   }
   
+  END_PROFILE(SMBmv);
   return(outsize);
 }
 
@@ -3701,7 +3895,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
 
   if ((ofun&3) == 1) {
-    if(conn->vfs_ops.lseek(fsp2->fd,0,SEEK_END) == -1) {
+    if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
       DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
                strerror(errno) ));
       /*
@@ -3751,6 +3945,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;
+  START_PROFILE(SMBcopy);
 
   *directory = *mask = 0;
 
@@ -3762,6 +3957,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if (tid2 != conn->cnum) {
     /* can't currently handle inter share copies XXXX */
     DEBUG(3,("Rejecting inter-share copy\n"));
+    END_PROFILE(SMBcopy);
     return(ERROR(ERRSRV,ERRinvdevice));
   }
 
@@ -3774,16 +3970,19 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   target_is_directory = vfs_directory_exist(conn,False,NULL);
 
   if ((flags&1) && target_is_directory) {
+    END_PROFILE(SMBcopy);
     return(ERROR(ERRDOS,ERRbadfile));
   }
 
   if ((flags&2) && !target_is_directory) {
+    END_PROFILE(SMBcopy);
     return(ERROR(ERRDOS,ERRbadpath));
   }
 
   if ((flags&(1<<5)) && vfs_directory_exist(conn,name,NULL)) {
     /* wants a tree copy! XXXX */
     DEBUG(3,("Rejecting tree copy\n"));
+    END_PROFILE(SMBcopy);
     return(ERROR(ERRSRV,ERRerror));    
   }
 
@@ -3819,6 +4018,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                  count,target_is_directory,&err)) count++;
     if(!count && err) {
                errno = err;
+               END_PROFILE(SMBcopy);
                return(UNIXERROR(ERRHRD,ERRgeneral));
        }
     if (!count) exists = vfs_file_exist(conn,directory,NULL);
@@ -3859,18 +4059,21 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     if(err) {
       /* Error on close... */
       errno = err;
+      END_PROFILE(SMBcopy);
       return(UNIXERROR(ERRHRD,ERRgeneral));
     }
 
-    if (exists)
+    if (exists) {
+      END_PROFILE(SMBcopy);
       return(ERROR(ERRDOS,error));
-    else
+    else
     {
       if((errno == ENOENT) && (bad_path1 || bad_path2))
       {
         unix_ERR_class = ERRDOS;
         unix_ERR_code = ERRbadpath;
       }
+      END_PROFILE(SMBcopy);
       return(UNIXERROR(ERRDOS,error));
     }
   }
@@ -3878,6 +4081,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   outsize = set_message(outbuf,1,0,True);
   SSVAL(outbuf,smb_vwv0,count);
 
+  END_PROFILE(SMBcopy);
   return(outsize);
 }
 
@@ -3890,10 +4094,13 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   int outsize = 0;
   BOOL ok = False;
   pstring newdir;
+  START_PROFILE(pathworks_setdir);
   
   snum = SNUM(conn);
-  if (!CAN_SETDIR(snum))
+  if (!CAN_SETDIR(snum)) {
+    END_PROFILE(pathworks_setdir);
     return(ERROR(ERRDOS,ERRnoaccess));
+  }
   
   pstrcpy(newdir,smb_buf(inbuf) + 1);
   strlower(newdir);
@@ -3907,14 +4114,17 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
          }
   }
   
-  if (!ok)
+  if (!ok) {
+         END_PROFILE(pathworks_setdir);
          return(ERROR(ERRDOS,ERRbadpath));
+  }
   
   outsize = set_message(outbuf,0,0,True);
   CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
   
   DEBUG(3,("setdir %s\n", newdir));
 
+  END_PROFILE(pathworks_setdir);
   return(outsize);
 }
 
@@ -4026,6 +4236,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   int eclass=0, dummy1;
   BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
   BOOL err;
+  START_PROFILE(SMBlockingX);
 
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
@@ -4050,10 +4261,13 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
 
       /* if this is a pure oplock break request then don't send a reply */
-      if (num_locks == 0 && num_ulocks == 0)
+      if (num_locks == 0 && num_ulocks == 0) {
+       END_PROFILE(SMBlockingX);
         return -1;
-      else
+      } else {
+       END_PROFILE(SMBlockingX);
         return ERROR(ERRDOS,ERRlock);
+      }
     }
 
     if (remove_oplock(fsp) == False) {
@@ -4069,6 +4283,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
       if(CVAL(inbuf,smb_vwv0) != 0xff)
         DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
                  (unsigned int)CVAL(inbuf,smb_vwv0) ));
+      END_PROFILE(SMBlockingX);
       return -1;
     }
   }
@@ -4082,14 +4297,18 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
     /*
      * There is no error code marked "stupid client bug".... :-).
      */
-    if(err)
+    if(err) {
+      END_PROFILE(SMBlockingX);
       return ERROR(ERRDOS,ERRnoaccess);
+    }
 
     DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
           (double)offset, (double)count, fsp->fsp_name ));
 
-    if(!do_unlock(fsp,conn,count,offset, &eclass, &ecode))
+    if(!do_unlock(fsp,conn,count,offset, &eclass, &ecode)) {
+      END_PROFILE(SMBlockingX);
       return ERROR(eclass,ecode);
+    }
   }
 
   /* Setup the timeout in seconds. */
@@ -4108,8 +4327,10 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
     /*
      * There is no error code marked "stupid client bug".... :-).
      */
-    if(err)
+    if(err) {
+      END_PROFILE(SMBlockingX);
       return ERROR(ERRDOS,ERRnoaccess);
+    }
  
     DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
           (double)offset, (double)count, fsp->fsp_name ));
@@ -4122,8 +4343,10 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
          * this smb into a queued request and push it
          * onto the blocking lock queue.
          */
-        if(push_blocking_lock_request(inbuf, length, lock_timeout, i))
+        if(push_blocking_lock_request(inbuf, length, lock_timeout, i)) {
+         END_PROFILE(SMBlockingX);
           return -1;
+       }
       }
       break;
     }
@@ -4144,11 +4367,14 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
       /*
        * There is no error code marked "stupid client bug".... :-).
        */
-      if(err)
+      if(err) {
+       END_PROFILE(SMBlockingX);
         return ERROR(ERRDOS,ERRnoaccess);
+      }
  
       do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
     }
+    END_PROFILE(SMBlockingX);
     return ERROR(eclass,ecode);
   }
 
@@ -4157,6 +4383,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
   DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
        fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
 
+  END_PROFILE(SMBlockingX);
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -4176,10 +4403,13 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
   size_t tcount;
   int pad;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBreadBmpx);
 
   /* this function doesn't seem to work - disable by default */
-  if (!lp_readbmpx())
+  if (!lp_readbmpx()) {
+    END_PROFILE(SMBreadBmpx);
     return(ERROR(ERRSRV,ERRuseSTD));
+  }
 
   outsize = set_message(outbuf,8,0,True);
 
@@ -4199,9 +4429,11 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
   tcount = maxcount;
   total_read = 0;
 
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+    END_PROFILE(SMBreadBmpx);
     return(ERROR(ERRDOS,ERRlock));
-       
+  }
+
   do
     {
       size_t N = MIN(max_per_packet,tcount-total_read);
@@ -4226,6 +4458,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
     }
   while (total_read < (ssize_t)tcount);
 
+  END_PROFILE(SMBreadBmpx);
   return(-1);
 }
 
@@ -4244,6 +4477,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
   int smb_doff;
   char *data;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBwriteBmpx);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -4261,16 +4495,20 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
      not an SMBwritebmpx - set this up now so we don't forget */
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK))
+  if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
+    END_PROFILE(SMBwriteBmpx);
     return(ERROR(ERRDOS,ERRlock));
+  }
 
   nwritten = write_file(fsp,data,startpos,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
       sync_file(conn,fsp);
   
-  if(nwritten < (ssize_t)numtowrite)
+  if(nwritten < (ssize_t)numtowrite) {
+    END_PROFILE(SMBwriteBmpx);
     return(UNIXERROR(ERRHRD,ERRdiskfull));
+  }
 
   /* If the maximum to be written to this file
      is greater than what we just wrote then set
@@ -4286,6 +4524,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
     if(!wbms)
     {
       DEBUG(0,("Out of memory in reply_readmpx\n"));
+      END_PROFILE(SMBwriteBmpx);
       return(ERROR(ERRSRV,ERRnoresource));
     }
     wbms->wr_mode = write_through;
@@ -4318,6 +4557,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
     SSVAL(outbuf,smb_vwv0,nwritten);
   }
 
+  END_PROFILE(SMBwriteBmpx);
   return(outsize);
 }
 
@@ -4338,6 +4578,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   write_bmpx_struct *wbms;
   BOOL send_response = False; 
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBwriteBs);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -4355,15 +4596,20 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   /* This fd should have an auxiliary struct attached,
      check that it does */
   wbms = fsp->wbmpx_ptr;
-  if(!wbms) return(-1);
+  if(!wbms) {
+    END_PROFILE(SMBwriteBs);
+    return(-1);
+  }
 
   /* If write through is set we can return errors, else we must
      cache them */
   write_through = wbms->wr_mode;
 
   /* Check for an earlier error */
-  if(wbms->wr_discard)
+  if(wbms->wr_discard) {
+    END_PROFILE(SMBwriteBs);
     return -1; /* Just discard the packet */
+  }
 
   nwritten = write_file(fsp,data,startpos,numtowrite);
 
@@ -4377,8 +4623,10 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
       /* We are returning an error - we can delete the aux struct */
       if (wbms) free((char *)wbms);
       fsp->wbmpx_ptr = NULL;
+      END_PROFILE(SMBwriteBs);
       return(ERROR(ERRHRD,ERRdiskfull));
     }
+    END_PROFILE(SMBwriteBs);
     return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
   }
 
@@ -4398,9 +4646,12 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
     fsp->wbmpx_ptr = NULL;
   }
 
-  if(send_response)
+  if(send_response) {
+    END_PROFILE(SMBwriteBs);
     return(outsize);
+  }
 
+  END_PROFILE(SMBwriteBs);
   return(-1);
 }
 
@@ -4414,6 +4665,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   struct utimbuf unix_times;
   int outsize = 0;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBsetattrE);
 
   outsize = set_message(outbuf,0,0,True);
 
@@ -4439,6 +4691,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
       dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
       dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
       }
+    END_PROFILE(SMBsetattrE);
     return(outsize);
   }
   else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) 
@@ -4448,12 +4701,15 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   }
 
   /* Set the date on this file */
-  if(file_utime(conn, fsp->fsp_name, &unix_times))
+  if(file_utime(conn, fsp->fsp_name, &unix_times)) {
+    END_PROFILE(SMBsetattrE);
     return(ERROR(ERRDOS,ERRnoaccess));
+  }
   
   DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
             fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
 
+  END_PROFILE(SMBsetattrE);
   return(outsize);
 }
 
@@ -4468,6 +4724,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   int outsize = 0;
   int mode;
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  START_PROFILE(SMBgetattrE);
 
   outsize = set_message(outbuf,11,0,True);
 
@@ -4475,8 +4732,10 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   CHECK_ERROR(fsp);
 
   /* Do an fstat on this file */
-  if(fsp->conn->vfs_ops.fstat(fsp->fd, &sbuf))
+  if(vfs_fstat(fsp,fsp->fd, &sbuf)) {
+    END_PROFILE(SMBgetattrE);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
   
   mode = dos_mode(conn,fsp->fsp_name,&sbuf);
   
@@ -4500,6 +4759,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   
   DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
   
+  END_PROFILE(SMBgetattrE);
   return(outsize);
 }
 #undef OLD_NTDOMAIN
index e82bbef..e1e0fde 100644 (file)
@@ -481,46 +481,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int
 
        conn->nt_user_token = create_nt_token(conn->uid, conn->gid, conn->ngroups, conn->groups);
 
-       /*
-        * Now initialize the vfs layer.
-        */
-
-       conn->vfs_conn = (struct vfs_connection_struct *)
-               malloc(sizeof(struct vfs_connection_struct));
-
-       if (conn->vfs_conn == NULL) {
-               DEBUG(0, ("No memory to create vfs_connection_struct"));
-               return NULL;
-       }
-        
-       ZERO_STRUCTP(conn->vfs_conn);
-
-       /* Copy across relevant data from connection struct */
-        
-       conn->vfs_conn->printer = conn->printer;
-       conn->vfs_conn->ipc = conn->ipc;
-       conn->vfs_conn->read_only = conn->read_only;
-       conn->vfs_conn->admin_user = conn->admin_user;
-
-       pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
-       pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
-       pstrcpy(conn->vfs_conn->origpath, conn->origpath);
-        
-       pstrcpy(conn->vfs_conn->service, service);
-       pstrcpy(conn->vfs_conn->user, conn->user);
-        
-       conn->vfs_conn->uid = conn->uid;
-       conn->vfs_conn->gid = conn->gid;
-       conn->vfs_conn->ngroups = conn->ngroups;
-       if (conn->vfs_conn->ngroups != 0) {
-               conn->vfs_conn->groups = (gid_t *)memdup(conn->groups, 
-                                                        conn->ngroups * sizeof(gid_t));
-       } else {
-               conn->vfs_conn->groups = NULL;
-       }
-
-       conn->vfs_conn->nt_user_token = dup_nt_token(conn->nt_user_token);
-
        /* Initialise VFS function pointers */
 
        if (*lp_vfsobj(SNUM(conn))) {
@@ -646,7 +606,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        /* Invoke VFS make connection hook */
 
        if (conn->vfs_ops.connect) {
-               if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0)
+               if (conn->vfs_ops.connect(conn, service, user) < 0)
                        return NULL;
        }
             
@@ -671,7 +631,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
 
            /* Call VFS disconnect hook */
            
-           conn->vfs_ops.disconnect();
+           conn->vfs_ops.disconnect(conn);
            
        }
 
index 7b2916b..b66c5e2 100644 (file)
@@ -214,7 +214,7 @@ BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
       scp = (stat_cache_entry *)(hash_elem->value);
       global_stat_cache_hits++;
       trans_name = scp->names+scp->name_len+1;
-      if(conn->vfs_ops.stat(dos_to_unix(trans_name,False), pst) != 0) {
+      if(conn->vfs_ops.stat(conn,dos_to_unix(trans_name,False), pst) != 0) {
         /* Discard this entry - it doesn't exist in the filesystem.  */
         hash_remove(&stat_cache, hash_elem);
         return False;
index 2366fce..7df1c09 100644 (file)
@@ -251,7 +251,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+  if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
@@ -407,7 +407,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
       if(needslash)
         pstrcat(pathreal,"/");
       pstrcat(pathreal,dname);
-      if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0) 
+      if (conn->vfs_ops.stat(conn,dos_to_unix(pathreal,False),&sbuf) != 0) 
       {
        /* Needed to show the msdfs symlinks as directories */
        if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn)) 
@@ -1112,7 +1112,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
 
   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
 
-  if(conn->vfs_ops.stat(".",&st)!=0) {
+  if(conn->vfs_ops.stat(conn,".",&st)!=0) {
     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
     return (ERROR(ERRSRV,ERRinvdevice));
   }
@@ -1126,7 +1126,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
     {
       SMB_BIG_UINT dfree,dsize,bsize;
       data_len = 18;
-      conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); 
+      conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);    
       SIVAL(pdata,l1_idFileSystem,st.st_dev);
       SIVAL(pdata,l1_cSectorUnit,bsize/512);
       SIVAL(pdata,l1_cUnit,dsize);
@@ -1208,7 +1208,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
     {
       SMB_BIG_UINT dfree,dsize,bsize;
       data_len = 24;
-      conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); 
+      conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);    
       SBIG_UINT(pdata,0,dsize);
       SBIG_UINT(pdata,8,dfree);
       SIVAL(pdata,16,bsize/512);
@@ -1308,7 +1308,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(dos_to_unix(fname,False),&sbuf))) {
+          (!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1328,11 +1328,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       CHECK_ERROR(fsp);
 
       fname = fsp->fsp_name;
-      if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+      if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
-      if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
+      if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
         return(UNIXERROR(ERRDOS,ERRnoaccess));
 
       delete_pending = fsp->delete_on_close;
@@ -1350,7 +1350,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(dos_to_unix(fname,False),&sbuf))) {
+        (!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1590,7 +1590,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       fname = fsp->fsp_name;
       unix_convert(fname,conn,0,&bad_path,&st);
       if (!check_name(fname,conn) || 
-          (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
+          (!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1609,7 +1609,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       fname = fsp->fsp_name;
       fd = fsp->fd;
 
-      if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
+      if (fsp->conn->vfs_ops.fstat(fsp,fd,&st) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
@@ -1630,7 +1630,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRbadpath));
     }
  
-    if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
+    if(!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st)!=0) {
       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1974,11 +1974,11 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
           fname, (double)size ));
 
     if (fd == -1) {
-      fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
+      fd = conn->vfs_ops.open(conn,dos_to_unix(fname,False),O_RDWR,0);
       if (fd == -1)
         return(UNIXERROR(ERRDOS,ERRbadpath));
       set_filelen(fd, size); /* tpot vfs */
-      conn->vfs_ops.close(fd);
+      conn->vfs_ops.close(fsp,fd);
     } else {
         set_filelen(fd, size); /* tpot vfs */
     }
index a564ec9..d32f1cf 100644 (file)
@@ -357,16 +357,16 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
      */
 
     if ((fsp->is_directory || fsp->fd == -1) && fsp->conn->vfs_ops.get_nt_acl)
-      return fsp->conn->vfs_ops.get_nt_acl(dos_to_unix(fsp->fsp_name, False), ppdesc);
+      return fsp->conn->vfs_ops.get_nt_acl(fsp->conn,dos_to_unix(fsp->fsp_name, False), ppdesc);
     else if (fsp->conn->vfs_ops.fget_nt_acl)
-      return fsp->conn->vfs_ops.fget_nt_acl(fsp->fd, ppdesc);
+      return fsp->conn->vfs_ops.fget_nt_acl(fsp,fsp->fd, ppdesc);
 
     if(fsp->is_directory || fsp->fd == -1) {
       if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
         return 0;
       }
     } else {
-      if(fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
+      if(fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
         return 0;
       }
     }
@@ -467,9 +467,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
    */
 
   if ((fsp->is_directory || fsp->fd == -1) && fsp->conn->vfs_ops.set_nt_acl)
-    return fsp->conn->vfs_ops.set_nt_acl(dos_to_unix(fsp->fsp_name, False), security_info_sent, psd);
+    return fsp->conn->vfs_ops.set_nt_acl(conn,dos_to_unix(fsp->fsp_name, False), security_info_sent, psd);
   else if (fsp->conn->vfs_ops.fset_nt_acl)
-    return fsp->conn->vfs_ops.fset_nt_acl(fsp->fd, security_info_sent, psd);
+    return fsp->conn->vfs_ops.fset_nt_acl(fsp,fsp->fd, security_info_sent, psd);
 
   /*
    * Get the current state of the file.
@@ -479,7 +479,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
     if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0)
       return False;
   } else {
-    if(conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0)
+    if(conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0)
       return False;
   }
 
@@ -524,7 +524,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
       if(fsp->fd == -1)
         ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf);
       else
-        ret = conn->vfs_ops.fstat(fsp->fd,&sbuf);
+        ret = conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf);
   
       if(ret != 0)
         return False;
@@ -570,7 +570,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
       DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
             fsp->fsp_name, (unsigned int)perms ));
 
-      if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
+      if(conn->vfs_ops.chmod(conn,dos_to_unix(fsp->fsp_name, False), perms) == -1) {
         DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
               fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
         return False;
index d19be7f..7495a76 100644 (file)
@@ -29,8 +29,7 @@
    is sure to try and execute them.  These stubs are used to prevent
    this possibility. */
 
-int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service,
-                         char *user)
+int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user)
 {
     return 0;    /* Return >= 0 for success */
 }
@@ -41,7 +40,7 @@ void vfswrap_dummy_disconnect(void)
 
 /* Disk operations */
 
-SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
+SMB_BIG_UINT vfswrap_disk_free(connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                               SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
     SMB_BIG_UINT result;
@@ -60,7 +59,7 @@ SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize
     
 /* Directory operations */
 
-DIR *vfswrap_opendir(char *fname)
+DIR *vfswrap_opendir(connection_struct *conn, char *fname)
 {
     DIR *result;
 
@@ -74,7 +73,7 @@ DIR *vfswrap_opendir(char *fname)
     return result;
 }
 
-struct dirent *vfswrap_readdir(DIR *dirp)
+struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
 {
     struct dirent *result;
 
@@ -88,7 +87,7 @@ struct dirent *vfswrap_readdir(DIR *dirp)
     return result;
 }
 
-int vfswrap_mkdir(char *path, mode_t mode)
+int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode)
 {
     int result;
 
@@ -102,7 +101,7 @@ int vfswrap_mkdir(char *path, mode_t mode)
     return result;
 }
 
-int vfswrap_rmdir(char *path)
+int vfswrap_rmdir(connection_struct *conn, char *path)
 {
     int result;
 
@@ -116,7 +115,7 @@ int vfswrap_rmdir(char *path)
     return result;
 }
 
-int vfswrap_closedir(DIR *dirp)
+int vfswrap_closedir(connection_struct *conn, DIR *dirp)
 {
     int result;
 
@@ -132,7 +131,7 @@ int vfswrap_closedir(DIR *dirp)
 
 /* File operations */
     
-int vfswrap_open(char *fname, int flags, mode_t mode)
+int vfswrap_open(connection_struct *conn, char *fname, int flags, mode_t mode)
 {
     int result;
 
@@ -146,7 +145,7 @@ int vfswrap_open(char *fname, int flags, mode_t mode)
     return result;
 }
 
-int vfswrap_close(int fd)
+int vfswrap_close(files_struct *fsp, int fd)
 {
     int result;
 
@@ -154,7 +153,7 @@ int vfswrap_close(int fd)
     return result;
 }
 
-ssize_t vfswrap_read(int fd, char *data, size_t n)
+ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n)
 {
     ssize_t result;
 
@@ -168,7 +167,7 @@ ssize_t vfswrap_read(int fd, char *data, size_t n)
     return result;
 }
 
-ssize_t vfswrap_write(int fd, char *data, size_t n)
+ssize_t vfswrap_write(files_struct *fsp, int fd, char *data, size_t n)
 {
     ssize_t result;
 
@@ -182,7 +181,7 @@ ssize_t vfswrap_write(int fd, char *data, size_t n)
     return result;
 }
 
-SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence)
+SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
 {
     SMB_OFF_T result;
 
@@ -190,7 +189,7 @@ SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence)
     return result;
 }
 
-int vfswrap_rename(char *old, char *new)
+int vfswrap_rename(connection_struct *conn, char *old, char *new)
 {
     int result;
 
@@ -204,7 +203,7 @@ int vfswrap_rename(char *old, char *new)
     return result;
 }
 
-int vfswrap_fsync(int fd)
+int vfswrap_fsync(files_struct *fsp, int fd)
 {
 #ifdef HAVE_FSYNC
     return fsync(fd);
@@ -213,7 +212,7 @@ int vfswrap_fsync(int fd)
 #endif
 }
 
-int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf)
+int vfswrap_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf)
 {
     int result;
 
@@ -227,7 +226,7 @@ int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf)
     return result;
 }
 
-int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf)
+int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
 {
     int result;
 
@@ -241,8 +240,7 @@ int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf)
     return result;
 }
 
-int vfswrap_lstat(char *path, 
-                 SMB_STRUCT_STAT *sbuf)
+int vfswrap_lstat(connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf)
 {
     int result;
 
@@ -256,7 +254,7 @@ int vfswrap_lstat(char *path,
     return result;
 }
 
-int vfswrap_unlink(char *path)
+int vfswrap_unlink(connection_struct *conn, char *path)
 {
     int result;
 
@@ -270,7 +268,7 @@ int vfswrap_unlink(char *path)
     return result;
 }
 
-int vfswrap_chmod(char *path, mode_t mode)
+int vfswrap_chmod(connection_struct *conn, char *path, mode_t mode)
 {
     int result;
 
@@ -284,7 +282,7 @@ int vfswrap_chmod(char *path, mode_t mode)
     return result;
 }
 
-int vfswrap_chown(char *path, uid_t uid, gid_t gid)
+int vfswrap_chown(connection_struct *conn, char *path, uid_t uid, gid_t gid)
 {
     int result;
 
@@ -298,7 +296,7 @@ int vfswrap_chown(char *path, uid_t uid, gid_t gid)
     return result;
 }
 
-int vfswrap_chdir(char *path)
+int vfswrap_chdir(connection_struct *conn, char *path)
 {
 #ifdef VFS_CHECK_NULL
     if (path == NULL) {
@@ -309,7 +307,7 @@ int vfswrap_chdir(char *path)
        return chdir(path);
 }
 
-char *vfswrap_getwd(char *path)
+char *vfswrap_getwd(connection_struct *conn, char *path)
 {
 #ifdef VFS_CHECK_NULL
     if (path == NULL) {
@@ -320,7 +318,7 @@ char *vfswrap_getwd(char *path)
        return sys_getwd(path);
 }
 
-int vfswrap_utime(char *path, struct utimbuf *times)
+int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times)
 {
     int result;
 
@@ -334,7 +332,7 @@ int vfswrap_utime(char *path, struct utimbuf *times)
     return result;
 }
 
-int vfswrap_ftruncate(int fd, SMB_OFF_T offset)
+int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T offset)
 {
     int result;
 
@@ -342,7 +340,7 @@ int vfswrap_ftruncate(int fd, SMB_OFF_T offset)
     return result;
 }
 
-BOOL vfswrap_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
        return fcntl_lock(fd, op, offset, count,type);
 }
index 4a4b1b2..9117240 100644 (file)
@@ -83,7 +83,7 @@ int vfs_init_default(connection_struct *conn)
 {
     DEBUG(3, ("Initialising default vfs hooks\n"));
 
-    memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(conn->vfs_ops));
+    memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
     return True;
 }
 
@@ -94,7 +94,6 @@ int vfs_init_default(connection_struct *conn)
 #ifdef HAVE_LIBDL
 BOOL vfs_init_custom(connection_struct *conn)
 {
-    void *handle;
     struct vfs_ops *ops, *(*fptr)(struct vfs_options *options);
 
     DEBUG(3, ("Initialising custom vfs hooks from %s\n",
@@ -102,19 +101,15 @@ BOOL vfs_init_custom(connection_struct *conn)
 
     /* Open object file */
 
-    handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL);
-    conn->vfs_conn->dl_handle = handle;
-
-    if (!handle) {
-       DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)),
-                 dlerror()));
-       return False;
+    if ((conn->dl_handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL)) == NULL) {
+               DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)), dlerror()));
+               return False;
     }
 
     /* Get handle on vfs_init() symbol */
 
     fptr = (struct vfs_ops *(*)(struct vfs_options *))
-           dlsym(handle, "vfs_init");
+           dlsym(conn->dl_handle, "vfs_init");
 
     if (fptr == NULL) {
        DEBUG(0, ("No vfs_init() symbol found in %s\n", 
@@ -133,7 +128,7 @@ BOOL vfs_init_custom(connection_struct *conn)
        There's probably a neater way to do this then a whole bunch of
        if statements. */ 
 
-    memcpy(&conn->vfs_ops, ops, sizeof(conn->vfs_ops));
+    memcpy(&conn->vfs_ops, ops, sizeof(struct vfs_ops));
     
     if (conn->vfs_ops.connect == NULL) {
        conn->vfs_ops.connect = default_vfs_ops.connect;
@@ -265,16 +260,16 @@ BOOL vfs_init_custom(connection_struct *conn)
 
 int vfs_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *st)
 {
-       return(conn->vfs_ops.stat(dos_to_unix(fname,False),st));
+       return(conn->vfs_ops.stat(conn, dos_to_unix(fname,False),st));
 } 
 
 /*******************************************************************
  vfs fstat wrapper that calls dos_to_unix.
 ********************************************************************/
 
-int vfs_fstat(connection_struct *conn, int fd, SMB_STRUCT_STAT *st)
+int vfs_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *st)
 {
-       return(conn->vfs_ops.fstat(fd,st));
+       return(fsp->conn->vfs_ops.fstat(fsp,fd,st));
 } 
 
 /*******************************************************************
@@ -310,7 +305,7 @@ int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode)
        SMB_STRUCT_STAT sbuf;
 
        pstrcpy(name,dos_to_unix(fname,False)); /* paranoia copy */
-       if(!(ret=conn->vfs_ops.mkdir(name,mode))) {
+       if(!(ret=conn->vfs_ops.mkdir(conn,name,mode))) {
                /* 
                 * Check if high bits should have been set,
                 * then (if bits are missing): add them.
@@ -323,13 +318,22 @@ int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode)
        return ret;
 }
 
+/*******************************************************************
+ vfs rmdir wrapper that calls dos_to_unix.
+********************************************************************/
+
+int vfs_rmdir(connection_struct *conn, char *fname)
+{
+       return(conn->vfs_ops.rmdir(conn,dos_to_unix(fname,False)));
+} 
+
 /*******************************************************************
  vfs Unlink wrapper that calls dos_to_unix.
 ********************************************************************/
 
 int vfs_unlink(connection_struct *conn, char *fname)
 {
-       return(conn->vfs_ops.unlink(dos_to_unix(fname,False)));
+       return(conn->vfs_ops.unlink(conn,dos_to_unix(fname,False)));
 } 
 
 /*******************************************************************
@@ -338,7 +342,7 @@ int vfs_unlink(connection_struct *conn, char *fname)
 
 int vfs_chmod(connection_struct *conn, char *fname,mode_t mode)
 {
-       return(conn->vfs_ops.chmod(dos_to_unix(fname,False), mode));
+       return(conn->vfs_ops.chmod(conn,dos_to_unix(fname,False), mode));
 } 
 
 /*******************************************************************
@@ -347,7 +351,7 @@ int vfs_chmod(connection_struct *conn, char *fname,mode_t mode)
 
 int vfs_chown(connection_struct *conn, char *fname, uid_t uid, gid_t gid)
 {
-       return(conn->vfs_ops.chown(dos_to_unix(fname,False), uid, gid));
+       return(conn->vfs_ops.chown(conn,dos_to_unix(fname,False), uid, gid));
 } 
 
 /*******************************************************************
@@ -356,7 +360,7 @@ int vfs_chown(connection_struct *conn, char *fname, uid_t uid, gid_t gid)
 
 int vfs_chdir(connection_struct *conn, char *fname)
 {
-       return(conn->vfs_ops.chdir(dos_to_unix(fname,False)));
+       return(conn->vfs_ops.chdir(conn,dos_to_unix(fname,False)));
 } 
 
 /*******************************************************************
@@ -366,7 +370,7 @@ int vfs_chdir(connection_struct *conn, char *fname)
 char *vfs_getwd(connection_struct *conn, char *unix_path)
 {
     char *wd;
-    wd = conn->vfs_ops.getwd(unix_path);
+    wd = conn->vfs_ops.getwd(conn,unix_path);
     if (wd)
         unix_to_dos(wd, True);
     return wd;
@@ -400,7 +404,7 @@ ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N)
 
   while (total < N)
   {
-    ret = fsp->conn->vfs_ops.write(fsp->fd,buffer + total,N - total);
+    ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
 
     if (ret == -1) return -1;
     if (ret == 0) return total;
@@ -477,16 +481,14 @@ SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp,
 
     if (s > ret) {
       ret += in_fsp ? 
-         in_fsp->conn->vfs_ops.read(in_fsp->fd,buf1+ret,s-ret) : read(in_fd,buf1+ret,s-ret);
+         in_fsp->conn->vfs_ops.read(in_fsp,in_fsp->fd,buf1+ret,s-ret) : read(in_fd,buf1+ret,s-ret);
     }
 
-    if (ret > 0)
-    {
-       if (out_fsp) {
-           ret2 = out_fsp->conn->vfs_ops.write(out_fsp->fd,buf1,ret);
-       } else {
-           ret2= (out_fd != -1) ? write_data(out_fd,buf1,ret) : ret;
-       }
+    if (ret > 0) {
+               if (out_fsp)
+                   ret2 = out_fsp->conn->vfs_ops.write(out_fsp,out_fsp->fd,buf1,ret);
+               else
+                   ret2= (out_fd != -1) ? write_data(out_fd,buf1,ret) : ret;
     }
 
       if (ret2 > 0) total += ret2;
@@ -513,7 +515,7 @@ char *vfs_readdirname(connection_struct *conn, void *p)
        if (!p)
                return(NULL);
   
-       ptr = (struct dirent *)conn->vfs_ops.readdir(p);
+       ptr = (struct dirent *)conn->vfs_ops.readdir(conn,p);
        if (!ptr)
                return(NULL);