r3642: Extend vfs to add seekdir/telldir/rewinddir. Yes I know I have to
authorJeremy Allison <jra@samba.org>
Tue, 9 Nov 2004 22:49:28 +0000 (22:49 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:11 +0000 (10:53 -0500)
fix the modules too... First step in fixing out large directories
problem.
Jeremy.
(This used to be commit 344e9dd33a936b429fefb67cd748ac009a1bab10)

source3/include/smbprofile.h
source3/include/trans2.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/lib/system.c
source3/smbd/trans2.c
source3/smbd/vfs-wrap.c
source3/smbd/vfs.c

index e494faf7da6358f0b5ca9261ac4eb9ec27cdb792..ed6fce9a6d6c76c6a550a08c9d8cbbd0116adaa3 100644 (file)
@@ -34,7 +34,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
 
 #define PROF_SHMEM_KEY ((key_t)0x07021999)
 #define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 9
+#define PROF_SHM_VERSION 10
 
 /* time values in the following structure are in microseconds */
 
@@ -47,6 +47,12 @@ struct profile_stats {
        unsigned syscall_opendir_time;
        unsigned syscall_readdir_count;
        unsigned syscall_readdir_time;
+       unsigned syscall_seekdir_count;
+       unsigned syscall_seekdir_time;
+       unsigned syscall_telldir_count;
+       unsigned syscall_telldir_time;
+       unsigned syscall_rewinddir_count;
+       unsigned syscall_rewinddir_time;
        unsigned syscall_mkdir_count;
        unsigned syscall_mkdir_time;
        unsigned syscall_rmdir_count;
index 3106cd092ab018505031d2c429cecb371218b92b..37b3cb24b14575f91f3fd479d1e748fb93297938 100644 (file)
@@ -329,6 +329,13 @@ Byte offset   Type     name                description
 #define SMB_FS_FULL_SIZE_INFORMATION                   1007
 #define SMB_FS_OBJECTID_INFORMATION                    1008
 
+/* flags on trans2 findfirst/findnext that control search */
+#define FLAG_TRANS2_FIND_CLOSE          0x1
+#define FLAG_TRANS2_FIND_CLOSE_IF_END   0x2
+#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4
+#define FLAG_TRANS2_FIND_CONTINUE       0x8
+#define FLAG_TRANS2_FIND_BACKUP_INTENT  0x10
+
 /* UNIX CIFS Extensions - created by HP */
 /*
  * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.
index db766b985d98c1349fb897917e76f290d619cfb2..babf18ec81f73b40299eeb3187511c60c9db20c0 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    VFS structures and parameters
-   Copyright (C) Jeremy Allison                         1999-2003
+   Copyright (C) Jeremy Allison                         1999-2004
    Copyright (C) Tim Potter                            1999
    Copyright (C) Alexander Bokovoy                     2002
    Copyright (C) Stefan (metze) Metzmacher             2003
@@ -55,7 +55,8 @@
 /* Changed to version 8 includes EA calls. JRA. */
 /* Changed to version 9 to include the get_shadow_data call. --metze */
 /* Changed to version 10 to include pread/pwrite calls. */
-#define SMB_VFS_INTERFACE_VERSION 10
+/* Changed to version 11 to include seekdir/telldir/rewinddir calls. JRA */
+#define SMB_VFS_INTERFACE_VERSION 11
 
 
 /* to bug old modules witch are trying to compile with the old functions */
@@ -102,6 +103,9 @@ typedef enum _vfs_op_type {
 
        SMB_VFS_OP_OPENDIR,
        SMB_VFS_OP_READDIR,
+       SMB_VFS_OP_SEEKDIR,
+       SMB_VFS_OP_TELLDIR,
+       SMB_VFS_OP_REWINDDIR,
        SMB_VFS_OP_MKDIR,
        SMB_VFS_OP_RMDIR,
        SMB_VFS_OP_CLOSEDIR,
@@ -209,7 +213,10 @@ struct vfs_ops {
                /* Directory operations */
                
                DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname);
-               struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+               SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+               void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp, long offset);
+               long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+               void (*rewinddir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
                int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
                int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
                int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir);
@@ -310,6 +317,9 @@ struct vfs_ops {
 
                struct vfs_handle_struct *opendir;
                struct vfs_handle_struct *readdir;
+               struct vfs_handle_struct *seekdir;
+               struct vfs_handle_struct *telldir;
+               struct vfs_handle_struct *rewinddir;
                struct vfs_handle_struct *mkdir;
                struct vfs_handle_struct *rmdir;
                struct vfs_handle_struct *closedir;
index 1ec1c5a7789517c58baf7e56fd97ab80689a15b6..a149db53b1e2b21a335616526acd3b40ebae9b00 100644 (file)
@@ -38,6 +38,9 @@
 /* Directory operations */
 #define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
 #define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp))) 
+#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewinddir((conn)->vfs.handles.rewinddir, (conn), (dirp)))
 #define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
 #define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
 #define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
 /* Directory operations */
 #define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
 #define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp))) 
+#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset))) 
+#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp))) 
+#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewinddir((conn)->vfs_opaque.handles.rewinddir, (conn), (dirp))) 
 #define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
 #define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
 #define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
 /* Directory operations */
 #define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
 #define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp))) 
+#define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset))) 
+#define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp))) 
+#define SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp) ((handle)->vfs_next.ops.rewinddir((handle)->vfs_next.handles.rewinddir, (conn), (dirp))) 
+#define SMB_VFS_NEXT_DIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp))) 
 #define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode)))
 #define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path)))
 #define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir))
index b27ac5c00ad51cc31a2cc1075302ca13ea4960f4..f33d1ae7d576737b474ddacdd1236291237458ae 100644 (file)
@@ -361,6 +361,19 @@ FILE *sys_fopen(const char *path, const char *type)
 #endif
 }
 
+/*******************************************************************
+ An opendir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+DIR *sys_opendir(const char *name)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
+       return opendir64(name);
+#else
+       return opendir(name);
+#endif
+}
+
 /*******************************************************************
  A readdir wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
@@ -374,6 +387,58 @@ SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
 #endif
 }
 
+/*******************************************************************
+ A seekdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_seekdir(DIR *dirp, long offset)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
+       seekdir64(dirp, offset);
+#else
+       seekdir(dirp, offset);
+#endif
+}
+
+/*******************************************************************
+ A telldir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+long sys_telldir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
+       return (long)telldir64(dirp);
+#else
+       return (long)telldir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A rewinddir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_rewinddir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
+       rewinddir64(dirp);
+#else
+       rewinddir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A close wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+int sys_closedir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
+       return closedir64(dirp);
+#else
+       return closedir(dirp);
+#endif
+}
+
 /*******************************************************************
  An mknod() wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
index ac282ed95fc48db3a7cd625cb2b2ded800a79efc..4c0d5731eb8bc52da41010ea7efc28016af5f60c 100644 (file)
@@ -1329,9 +1329,10 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
        char *pdata = *ppdata;
        int dirtype = SVAL(params,0);
        int maxentries = SVAL(params,2);
-       BOOL close_after_first = BITSETW(params+4,0);
-       BOOL close_if_end = BITSETW(params+4,1);
-       BOOL requires_resume_key = BITSETW(params+4,2);
+       uint16 findfirst_flags = SVAL(params,4);
+       BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
+       BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+       BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
        int info_level = SVAL(params,6);
        pstring directory;
        pstring mask;
@@ -1555,10 +1556,11 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
        int maxentries = SVAL(params,2);
        uint16 info_level = SVAL(params,4);
        uint32 resume_key = IVAL(params,6);
-       BOOL close_after_request = BITSETW(params+10,0);
-       BOOL close_if_end = BITSETW(params+10,1);
-       BOOL requires_resume_key = BITSETW(params+10,2);
-       BOOL continue_bit = BITSETW(params+10,3);
+       uint16 findnext_flags = SVAL(params,10);
+       BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
+       BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+       BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
+       BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
        pstring resume_name;
        pstring mask;
        pstring directory;
index 5393dfc75563b64ba6bfca5015ca5123db59e8a1..1444d0e875aed5b89fe67d172931f45fbe3d6fe1 100644 (file)
@@ -93,21 +93,44 @@ DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const c
        DIR *result;
 
        START_PROFILE(syscall_opendir);
-       result = opendir(fname);
+       result = sys_opendir(fname);
        END_PROFILE(syscall_opendir);
        return result;
 }
 
-struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
 {
        struct dirent *result;
 
        START_PROFILE(syscall_readdir);
-       result = readdir(dirp);
+       result = sys_readdir(dirp);
        END_PROFILE(syscall_readdir);
        return result;
 }
 
+void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+       START_PROFILE(syscall_seekdir);
+       sys_seekdir(dirp, offset);
+       END_PROFILE(syscall_seekdir);
+}
+
+long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+       long result;
+       START_PROFILE(syscall_telldir);
+       result = sys_telldir(dirp);
+       END_PROFILE(syscall_telldir);
+       return result;
+}
+
+void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+       START_PROFILE(syscall_rewinddir);
+       sys_rewinddir(dirp);
+       END_PROFILE(syscall_rewinddir);
+}
+
 int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
 {
        int result;
@@ -152,7 +175,7 @@ int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *di
        int result;
 
        START_PROFILE(syscall_closedir);
-       result = closedir(dirp);
+       result = sys_closedir(dirp);
        END_PROFILE(syscall_closedir);
        return result;
 }
index 0328558fe88740a2bfc97088d3160400ef8f7ccc..f30a5559006864b2fb92f8b6889114992c2a4649 100644 (file)
@@ -62,6 +62,9 @@ static struct vfs_ops default_vfs = {
        
                vfswrap_opendir,
                vfswrap_readdir,
+               vfswrap_seekdir,
+               vfswrap_telldir,
+               vfswrap_rewinddir,
                vfswrap_mkdir,
                vfswrap_rmdir,
                vfswrap_closedir,
@@ -611,13 +614,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
 
 char *vfs_readdirname(connection_struct *conn, void *p)
 {
-       struct dirent *ptr= NULL;
+       SMB_STRUCT_DIRENT *ptr= NULL;
        char *dname;
 
        if (!p)
                return(NULL);
 
-       ptr = (struct dirent *)SMB_VFS_READDIR(conn,p);
+       ptr = SMB_VFS_READDIR(conn,p);
        if (!ptr)
                return(NULL);