Patch based on work from James Peach <jpeach@sgi.com> to convert over to
authorJeremy Allison <jra@samba.org>
Tue, 6 Jan 2004 01:21:59 +0000 (01:21 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 6 Jan 2004 01:21:59 +0000 (01:21 +0000)
using pread/pwrite. Modified a little to ensure fsp->pos is correct.
Fix for #889.
Jeremy.
(This used to be commit 3a24dc868d95c9bcc2ac3a0dbd50e6e226ac0841)

examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/lib/system.c
source3/smbd/fileio.c
source3/smbd/vfs-wrap.c
source3/smbd/vfs.c
source3/utils/status.c

index de82801d858507b408e0de97afd90725d07a4113..310d305cee31bf2f65a1af869acf384af218498f 100644 (file)
@@ -111,11 +111,21 @@ static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, v
        return vfswrap_read(NULL, fsp, fd, data, n);
 }
 
+static ssize_t skel_pread(vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset)
+{
+       return vfswrap_pread(NULL, fsp, fd, data, n, offset);
+}
+
 static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
 {
        return vfswrap_write(NULL, fsp, fd, data, n);
 }
 
+ssize_t skel_pwrite(vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset)
+{
+       return vfswrap_pwrite(NULL, fsp, fd, data, n, offset);
+}
+
 static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
 {
        return vfswrap_lseek(NULL, fsp, filedes, offset, whence);
@@ -488,7 +498,9 @@ static vfs_op_tuple skel_op_tuples[] = {
        {SMB_VFS_OP(skel_open),                         SMB_VFS_OP_OPEN,                SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_close),                        SMB_VFS_OP_CLOSE,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_read),                         SMB_VFS_OP_READ,                SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(skel_pread),                        SMB_VFS_OP_PREAD,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_write),                        SMB_VFS_OP_WRITE,               SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(skel_pwrite),                       SMB_VFS_OP_PWRITE,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_lseek),                        SMB_VFS_OP_LSEEK,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_rename),                       SMB_VFS_OP_RENAME,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_fsync),                        SMB_VFS_OP_FSYNC,               SMB_VFS_LAYER_OPAQUE},
index 7a326741c5ba6dc1370b57da4a4060246a863e6e..448390e72f41751d3775ec9b808110dd36daa1d6 100644 (file)
@@ -110,11 +110,21 @@ static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, v
        return SMB_VFS_NEXT_READ(handle, fsp, fd, data, n);
 }
 
+static ssize_t skel_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset)
+{
+       return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, offset);
+}
+
 static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
 {
        return SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n);
 }
 
+static ssize_t skel_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset)
+{
+       return SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, offset);
+}
+
 static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
 {
        return SMB_VFS_NEXT_LSEEK(handle, fsp, filedes, offset, whence);
index a64c2ce69ececb603d0bfaddbfe3d56585c470f6..c29a630fe530f291c0d258ee312efc0d59c0f1c0 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 7
+#define PROF_SHM_VERSION 8
 
 /* time values in the following structure are in microseconds */
 
@@ -60,9 +60,15 @@ struct profile_stats {
        unsigned syscall_read_count;
        unsigned syscall_read_time;
        unsigned syscall_read_bytes;    /* bytes read with read syscall */
+       unsigned syscall_pread_count;
+       unsigned syscall_pread_time;
+       unsigned syscall_pread_bytes;   /* bytes read with pread syscall */
        unsigned syscall_write_count;
        unsigned syscall_write_time;
        unsigned syscall_write_bytes;   /* bytes written with write syscall */
+       unsigned syscall_pwrite_count;
+       unsigned syscall_pwrite_time;
+       unsigned syscall_pwrite_bytes;  /* bytes written with pwrite syscall */
        unsigned syscall_lseek_count;
        unsigned syscall_lseek_time;
        unsigned syscall_sendfile_count;
index dd489702aa9a5d62b2f1532e52f1f02128b8a45e..8caf64fd99d3f6ee3c5e7ffd2e0057ce46e16142 100644 (file)
@@ -51,7 +51,8 @@
 /* Changed to version 7 to include the get_nt_acl info parameter. JRA. */
 /* Changed to version 8 includes EA calls. JRA. */
 /* Changed to version 9 to include the get_shadow_data call. --metze */
-#define SMB_VFS_INTERFACE_VERSION 9
+/* Changed to version 10 to include pread/pwrite calls. */
+#define SMB_VFS_INTERFACE_VERSION 10
 
 
 /* to bug old modules witch are trying to compile with the old functions */
@@ -107,7 +108,9 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_OPEN,
        SMB_VFS_OP_CLOSE,
        SMB_VFS_OP_READ,
+       SMB_VFS_OP_PREAD,
        SMB_VFS_OP_WRITE,
+       SMB_VFS_OP_PWRITE,
        SMB_VFS_OP_LSEEK,
        SMB_VFS_OP_SENDFILE,
        SMB_VFS_OP_RENAME,
@@ -213,7 +216,9 @@ struct vfs_ops {
                int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode);
                int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
                ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n);
+               ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset);
                ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n);
+               ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset);
                SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence);
                ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
                int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new);
@@ -311,7 +316,9 @@ struct vfs_ops {
                struct vfs_handle_struct *open;
                struct vfs_handle_struct *close;
                struct vfs_handle_struct *read;
+               struct vfs_handle_struct *pread;
                struct vfs_handle_struct *write;
+               struct vfs_handle_struct *pwrite;
                struct vfs_handle_struct *lseek;
                struct vfs_handle_struct *sendfile;
                struct vfs_handle_struct *rename;
index c4f63c352e4c335679029c19d937d8fb995eea9b..1ec1c5a7789517c58baf7e56fd97ab80689a15b6 100644 (file)
@@ -46,7 +46,9 @@
 #define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode)))
 #define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close((fsp)->conn->vfs.handles.close, (fsp), (fd)))
 #define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n)))
+#define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs.ops.write((fsp)->conn->vfs.handles.write, (fsp), (fd), (data), (n)))
+#define SMB_VFS_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pwrite((fsp)->conn->vfs.handles.pwrite, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs.ops.lseek((fsp)->conn->vfs.handles.lseek, (fsp), (fd), (offset), (whence)))
 #define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs.ops.sendfile((fsp)->conn->vfs.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
 #define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (conn), (old), (new)))
 #define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode)))
 #define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close((fsp)->conn->vfs_opaque.handles.close, (fsp), (fd)))
 #define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n)))
+#define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.write((fsp)->conn->vfs_opaque.handles.write, (fsp), (fd), (data), (n)))
+#define SMB_VFS_OPAQUE_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pwrite((fsp)->conn->vfs_opaque.handles.pwrite, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs_opaque.ops.lseek((fsp)->conn->vfs_opaque.handles.lseek, (fsp), (fd), (offset), (whence)))
 #define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs_opaque.ops.sendfile((fsp)->conn->vfs_opaque.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
 #define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (conn), (old), (new)))
 #define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode)))
 #define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close((handle)->vfs_next.handles.close, (fsp), (fd)))
 #define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n)))
+#define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.write((handle)->vfs_next.handles.write, (fsp), (fd), (data), (n)))
+#define SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pwrite((handle)->vfs_next.handles.pwrite, (fsp), (fd), (data), (n), (off)))
 #define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) ((handle)->vfs_next.ops.lseek((handle)->vfs_next.handles.lseek, (fsp), (fd), (offset), (whence)))
 #define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) ((handle)->vfs_next.ops.sendfile((handle)->vfs_next.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
 #define SMB_VFS_NEXT_RENAME(handle, conn, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (conn), (old), (new)))
index 577f0b9a206cf418360675eaa78bef5b9a0d1001..16384c8bdf5a2ccc90d9204d6ecfbe7c6a947374 100644 (file)
@@ -100,6 +100,47 @@ ssize_t sys_write(int fd, const void *buf, size_t count)
        return ret;
 }
 
+
+/*******************************************************************
+A pread wrapper that will deal with EINTR and 64-bit file offsets.
+********************************************************************/
+
+#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
+ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
+{
+       ssize_t ret;
+
+       do {
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
+               ret = pread64(fd, buf, count, off);
+#else
+               ret = pread(fd, buf, count, off);
+#endif
+       } while (ret == -1 && errno == EINTR);
+       return ret;
+}
+#endif
+
+/*******************************************************************
+A write wrapper that will deal with EINTR and 64-bit file offsets.
+********************************************************************/
+
+#if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
+ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
+{
+       ssize_t ret;
+
+       do {
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
+               ret = pwrite64(fd, buf, count, off);
+#else
+               ret = pwrite(fd, buf, count, off);
+#endif
+       } while (ret == -1 && errno == EINTR);
+       return ret;
+}
+#endif
+
 /*******************************************************************
 A send wrapper that will deal with EINTR.
 ********************************************************************/
index 84339c3a6fc48cf9f3f933438df50b9f0a2450e8..f395954d053b94ad74a4f5792e2587a4f6faaba4 100644 (file)
@@ -95,16 +95,14 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
 
        flush_write_cache(fsp, READ_FLUSH);
 
-       if (seek_file(fsp,pos) == -1) {
-               DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
-               return(ret);
-       }
-  
+       fsp->pos = pos;
+
        if (n > 0) {
 #ifdef DMF_FIX
                int numretries = 3;
 tryagain:
-               readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
+               readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
+
                if (readret == -1) {
                        if ((errno == EAGAIN) && numretries) {
                                DEBUG(3,("read_file EAGAIN retry in 10 seconds\n"));
@@ -115,7 +113,8 @@ tryagain:
                        return -1;
                }
 #else /* NO DMF fix. */
-               readret = SMB_VFS_READ(fsp,fsp->fd,data,n);
+               readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos);
+
                if (readret == -1)
                        return -1;
 #endif
@@ -143,10 +142,12 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
 {
        ssize_t ret;
 
-       if ((pos != -1) && (seek_file(fsp,pos) == -1))
-               return -1;
-
-       ret = vfs_write_data(fsp,data,n);
+        if (pos == -1)
+                ret = vfs_write_data(fsp, data, n);
+        else {
+               fsp->pos = pos;
+                ret = vfs_pwrite_data(fsp, data, n, pos);
+       }
 
        DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
                fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
index 378a0a1e53cce96e1b8763902c626fa615198d2c..4f2d82734f7258505dfd1803434a3e2fb570263e 100644 (file)
@@ -44,10 +44,10 @@ void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn
 SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                               SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
-    SMB_BIG_UINT result;
+       SMB_BIG_UINT result;
 
-    result = sys_disk_free(path, small_query, bsize, dfree, dsize);
-    return result;
+       result = sys_disk_free(path, small_query, bsize, dfree, dsize);
+       return result;
 }
 
 int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
@@ -90,22 +90,22 @@ int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_
 
 DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
 {
-    DIR *result;
+       DIR *result;
 
-    START_PROFILE(syscall_opendir);
-    result = opendir(fname);
-    END_PROFILE(syscall_opendir);
-    return result;
+       START_PROFILE(syscall_opendir);
+       result = opendir(fname);
+       END_PROFILE(syscall_opendir);
+       return result;
 }
 
 struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
 {
-    struct dirent *result;
+       struct dirent *result;
 
-    START_PROFILE(syscall_readdir);
-    result = readdir(dirp);
-    END_PROFILE(syscall_readdir);
-    return result;
+       START_PROFILE(syscall_readdir);
+       result = readdir(dirp);
+       END_PROFILE(syscall_readdir);
+       return result;
 }
 
 int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
@@ -133,71 +133,154 @@ int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char
                        errno = saved_errno;
        }
 
-    END_PROFILE(syscall_mkdir);
-    return result;
+       END_PROFILE(syscall_mkdir);
+       return result;
 }
 
 int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_rmdir);
-    result = rmdir(path);
-    END_PROFILE(syscall_rmdir);
-    return result;
+       START_PROFILE(syscall_rmdir);
+       result = rmdir(path);
+       END_PROFILE(syscall_rmdir);
+       return result;
 }
 
 int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_closedir);
-    result = closedir(dirp);
-    END_PROFILE(syscall_closedir);
-    return result;
+       START_PROFILE(syscall_closedir);
+       result = closedir(dirp);
+       END_PROFILE(syscall_closedir);
+       return result;
 }
 
 /* File operations */
     
 int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_open);
-    result = sys_open(fname, flags, mode);
-    END_PROFILE(syscall_open);
-    return result;
+       START_PROFILE(syscall_open);
+       result = sys_open(fname, flags, mode);
+       END_PROFILE(syscall_open);
+       return result;
 }
 
 int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_close);
+       START_PROFILE(syscall_close);
 
-    result = close(fd);
-    END_PROFILE(syscall_close);
-    return result;
+       result = close(fd);
+       END_PROFILE(syscall_close);
+       return result;
 }
 
 ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
 {
-    ssize_t result;
+       ssize_t result;
 
-    START_PROFILE_BYTES(syscall_read, n);
-    result = sys_read(fd, data, n);
-    END_PROFILE(syscall_read);
-    return result;
+       START_PROFILE_BYTES(syscall_read, n);
+       result = sys_read(fd, data, n);
+       END_PROFILE(syscall_read);
+       return result;
+}
+
+ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data,
+                       size_t n, SMB_OFF_T offset)
+{
+       ssize_t result;
+
+#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
+       START_PROFILE_BYTES(syscall_pread, n);
+       result = sys_pread(fd, data, n, offset);
+       END_PROFILE(syscall_pread);
+       if (result == -1 && errno == ESPIPE) {
+               /* Maintain the fiction that pipes can be seeked (sought?) on. */
+               result = SMB_VFS_READ(fsp, fd, data, n);
+               fsp->pos = 0;
+       }
+
+#else /* HAVE_PREAD */
+       SMB_OFF_T   curr;
+       int lerrno;
+   
+       curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+       if (curr == -1 && errno == ESPIPE) {
+               /* Maintain the fiction that pipes can be seeked (sought?) on. */
+               result = SMB_VFS_READ(fsp, fd, data, n);
+               fsp->pos = 0;
+               return result;
+       }
+
+       if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
+               return -1;
+       }
+
+       errno = 0;
+       result = SMB_VFS_READ(fsp, fd, data, n);
+       lerrno = errno;
+
+       SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
+       errno = lerrno;
+
+#endif /* HAVE_PREAD */
+
+       return result;
 }
 
 ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
 {
-    ssize_t result;
+       ssize_t result;
+
+       START_PROFILE_BYTES(syscall_write, n);
+       result = sys_write(fd, data, n);
+       END_PROFILE(syscall_write);
+       return result;
+}
+
+ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data,
+                       size_t n, SMB_OFF_T offset)
+{
+       ssize_t result;
+
+#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
+       START_PROFILE_BYTES(syscall_pwrite, n);
+       result = sys_pwrite(fd, data, n, offset);
+       END_PROFILE(syscall_pwrite);
+
+       if (result == -1 && errno == ESPIPE) {
+               /* Maintain the fiction that pipes can be sought on. */
+               result = SMB_VFS_WRITE(fsp, fd, data, n);
+       }
+
+#else /* HAVE_PWRITE */
+       SMB_OFF_T   curr;
+       int         lerrno;
 
-    START_PROFILE_BYTES(syscall_write, n);
-    result = sys_write(fd, data, n);
-    END_PROFILE(syscall_write);
-    return result;
+       curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+       if (curr == -1) {
+               return -1;
+       }
+
+       if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
+               return -1;
+       }
+
+       result = SMB_VFS_WRITE(fsp, fd, data, n);
+       lerrno = errno;
+
+       SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
+       errno = lerrno;
+
+#endif /* HAVE_PWRITE */
+
+       return result;
 }
 
 SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
@@ -340,13 +423,12 @@ int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const cha
 int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
 {
 #ifdef HAVE_FSYNC
-    int result;
-
-    START_PROFILE(syscall_fsync);
+       int result;
 
-    result = fsync(fd);
-    END_PROFILE(syscall_fsync);
-    return result;
+       START_PROFILE(syscall_fsync);
+       result = fsync(fd);
+       END_PROFILE(syscall_fsync);
+       return result;
 #else
        return 0;
 #endif
@@ -354,49 +436,49 @@ int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
 
 int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_stat);
-    result = sys_stat(fname, sbuf);
-    END_PROFILE(syscall_stat);
-    return result;
+       START_PROFILE(syscall_stat);
+       result = sys_stat(fname, sbuf);
+       END_PROFILE(syscall_stat);
+       return result;
 }
 
 int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_fstat);
-    result = sys_fstat(fd, sbuf);
-    END_PROFILE(syscall_fstat);
-    return result;
+       START_PROFILE(syscall_fstat);
+       result = sys_fstat(fd, sbuf);
+       END_PROFILE(syscall_fstat);
+       return result;
 }
 
 int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_lstat);
-    result = sys_lstat(path, sbuf);
-    END_PROFILE(syscall_lstat);
-    return result;
+       START_PROFILE(syscall_lstat);
+       result = sys_lstat(path, sbuf);
+       END_PROFILE(syscall_lstat);
+       return result;
 }
 
 int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_unlink);
-    result = unlink(path);
-    END_PROFILE(syscall_unlink);
-    return result;
+       START_PROFILE(syscall_unlink);
+       result = unlink(path);
+       END_PROFILE(syscall_unlink);
+       return result;
 }
 
 int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_chmod);
+       START_PROFILE(syscall_chmod);
 
        /*
         * We need to do this due to the fact that the default POSIX ACL
@@ -415,9 +497,9 @@ int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char
                errno = saved_errno;
        }
 
-    result = chmod(path, mode);
-    END_PROFILE(syscall_chmod);
-    return result;
+       result = chmod(path, mode);
+       END_PROFILE(syscall_chmod);
+       return result;
 }
 
 int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
@@ -455,58 +537,57 @@ int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t
 
 int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_chown);
-    result = sys_chown(path, uid, gid);
-    END_PROFILE(syscall_chown);
-    return result;
+       START_PROFILE(syscall_chown);
+       result = sys_chown(path, uid, gid);
+       END_PROFILE(syscall_chown);
+       return result;
 }
 
 int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
 {
 #ifdef HAVE_FCHOWN
-    int result;
-
-    START_PROFILE(syscall_fchown);
+       int result;
 
-    result = fchown(fd, uid, gid);
-    END_PROFILE(syscall_fchown);
-    return result;
+       START_PROFILE(syscall_fchown);
+       result = fchown(fd, uid, gid);
+       END_PROFILE(syscall_fchown);
+       return result;
 #else
-    errno = ENOSYS;
-    return -1;
+       errno = ENOSYS;
+       return -1;
 #endif
 }
 
 int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_chdir);
-    result = chdir(path);
-    END_PROFILE(syscall_chdir);
-    return result;
+       START_PROFILE(syscall_chdir);
+       result = chdir(path);
+       END_PROFILE(syscall_chdir);
+       return result;
 }
 
 char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path)
 {
-    char *result;
+       char *result;
 
-    START_PROFILE(syscall_getwd);
-    result = sys_getwd(path);
-    END_PROFILE(syscall_getwd);
-    return result;
+       START_PROFILE(syscall_getwd);
+       result = sys_getwd(path);
+       END_PROFILE(syscall_getwd);
+       return result;
 }
 
 int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_utime);
-    result = utime(path, times);
-    END_PROFILE(syscall_utime);
-    return result;
+       START_PROFILE(syscall_utime);
+       result = utime(path, times);
+       END_PROFILE(syscall_utime);
+       return result;
 }
 
 /*********************************************************************
@@ -643,33 +724,32 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_
 
 BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
-    BOOL result;
-
-    START_PROFILE(syscall_fcntl_lock);
+       BOOL result;
 
-    result =  fcntl_lock(fd, op, offset, count,type);
-    END_PROFILE(syscall_fcntl_lock);
-    return result;
+       START_PROFILE(syscall_fcntl_lock);
+       result =  fcntl_lock(fd, op, offset, count,type);
+       END_PROFILE(syscall_fcntl_lock);
+       return result;
 }
 
 int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_symlink);
-    result = sys_symlink(oldpath, newpath);
-    END_PROFILE(syscall_symlink);
-    return result;
+       START_PROFILE(syscall_symlink);
+       result = sys_symlink(oldpath, newpath);
+       END_PROFILE(syscall_symlink);
+       return result;
 }
 
 int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_readlink);
-    result = sys_readlink(path, buf, bufsiz);
-    END_PROFILE(syscall_readlink);
-    return result;
+       START_PROFILE(syscall_readlink);
+       result = sys_readlink(path, buf, bufsiz);
+       END_PROFILE(syscall_readlink);
+       return result;
 }
 
 int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
index 753db4cece385e28ec9647c080fdde3ee968ee9f..2f981c743f277044abcd1ecfea05a7c0ea6a9cba 100644 (file)
@@ -71,7 +71,9 @@ static struct vfs_ops default_vfs = {
                vfswrap_open,
                vfswrap_close,
                vfswrap_read,
+               vfswrap_pread,
                vfswrap_write,
+               vfswrap_pwrite,
                vfswrap_lseek,
                vfswrap_sendfile,
                vfswrap_rename,
@@ -429,6 +431,28 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
        return (ssize_t)total;
 }
 
+ssize_t vfs_pread_data(files_struct *fsp, char *buf,
+                size_t byte_count, SMB_OFF_T offset)
+{
+       size_t total=0;
+
+       while (total < byte_count)
+       {
+               ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fd, buf + total,
+                                       byte_count - total, offset + total);
+
+               if (ret == 0) return total;
+               if (ret == -1) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               return -1;
+               }
+               total += ret;
+       }
+       return (ssize_t)total;
+}
+
 /****************************************************************************
  Write data to a fd on the vfs.
 ****************************************************************************/
@@ -451,6 +475,25 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
        return (ssize_t)total;
 }
 
+ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer,
+                size_t N, SMB_OFF_T offset)
+{
+       size_t total=0;
+       ssize_t ret;
+
+       while (total < N) {
+               ret = SMB_VFS_PWRITE(fsp, fsp->fd, buffer + total,
+                                N - total, offset + total);
+
+               if (ret == -1)
+                       return -1;
+               if (ret == 0)
+                       return total;
+
+               total += ret;
+       }
+       return (ssize_t)total;
+}
 /****************************************************************************
  An allocate file space call using the vfs interface.
  Allocates space for a file from a filedescriptor.
index 54dce1ecf0f43f3bd8a00965e38919be9dda9e44..4585b101b28d5631c02ef5516ba9e9479a85e1b6 100644 (file)
@@ -197,6 +197,12 @@ static int profile_dump(void)
        d_printf("write_count:                    %u\n", profile_p->syscall_write_count);
        d_printf("write_time:                     %u\n", profile_p->syscall_write_time);
        d_printf("write_bytes:                    %u\n", profile_p->syscall_write_bytes);
+       d_printf("pread_count:                    %u\n", profile_p->syscall_pread_count);
+       d_printf("pread_time:                     %u\n", profile_p->syscall_pread_time);
+       d_printf("pread_bytes:                    %u\n", profile_p->syscall_pread_bytes);
+       d_printf("pwrite_count:                   %u\n", profile_p->syscall_pwrite_count);
+       d_printf("pwrite_time:                    %u\n", profile_p->syscall_pwrite_time);
+       d_printf("pwrite_bytes:                   %u\n", profile_p->syscall_pwrite_bytes);
 #ifdef WITH_SENDFILE
        d_printf("sendfile_count:                 %u\n", profile_p->syscall_sendfile_count);
        d_printf("sendfile_time:                  %u\n", profile_p->syscall_sendfile_time);