s3:util: use pread/pwrite in transfer_file
authorRalph Boehme <slow@samba.org>
Mon, 27 Apr 2015 10:16:16 +0000 (12:16 +0200)
committerRalph Böhme <slow@samba.org>
Tue, 23 Jun 2015 09:45:23 +0000 (11:45 +0200)
read/write aren't overloaded in the streams VFS modules, using
pread/pwrite instead this makes it possible to use transfer_file() with
named streams.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11317

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/include/transfer_file.h
source3/lib/util_transfer_file.c
source3/smbd/vfs.c

index 546104f8f37b746181c343083e6c791950877134..2f1bff4bf112bdb49d63ed56ce62b71258cd9ab4 100644 (file)
@@ -24,8 +24,8 @@
 ssize_t transfer_file_internal(void *in_file,
                               void *out_file,
                               size_t n,
-                              ssize_t (*read_fn)(void *, void *, size_t),
-                              ssize_t (*write_fn)(void *, const void *, size_t));
+                              ssize_t (*pread_fn)(void *, void *, size_t, off_t),
+                              ssize_t (*pwrite_fn)(void *, const void *, size_t, off_t));
 
 off_t transfer_file(int infd, int outfd, off_t n);
 
index d415d7f98e0d1b0b25a15d4f0bcc7d291ea2f7cd..91f4f6f7f2e43d482134e4fa8ef927d3a153ddd5 100644 (file)
@@ -36,8 +36,8 @@
 ssize_t transfer_file_internal(void *in_file,
                               void *out_file,
                               size_t n,
-                              ssize_t (*read_fn)(void *, void *, size_t),
-                              ssize_t (*write_fn)(void *, const void *, size_t))
+                              ssize_t (*pread_fn)(void *, void *, size_t, off_t),
+                              ssize_t (*pwrite_fn)(void *, const void *, size_t, off_t))
 {
        char *buf;
        size_t total = 0;
@@ -45,6 +45,7 @@ ssize_t transfer_file_internal(void *in_file,
        ssize_t write_ret;
        size_t num_to_read_thistime;
        size_t num_written = 0;
+       off_t offset = 0;
 
        if (n == 0) {
                return 0;
@@ -57,7 +58,7 @@ ssize_t transfer_file_internal(void *in_file,
        do {
                num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
 
-               read_ret = (*read_fn)(in_file, buf, num_to_read_thistime);
+               read_ret = (*pread_fn)(in_file, buf, num_to_read_thistime, offset);
                if (read_ret == -1) {
                        DEBUG(0,("transfer_file_internal: read failure. "
                                 "Error = %s\n", strerror(errno) ));
@@ -71,8 +72,9 @@ ssize_t transfer_file_internal(void *in_file,
                num_written = 0;
 
                while (num_written < read_ret) {
-                       write_ret = (*write_fn)(out_file, buf + num_written,
-                                               read_ret - num_written);
+                       write_ret = (*pwrite_fn)(out_file, buf + num_written,
+                                               read_ret - num_written,
+                                               offset + num_written);
 
                        if (write_ret == -1) {
                                DEBUG(0,("transfer_file_internal: "
@@ -89,28 +91,29 @@ ssize_t transfer_file_internal(void *in_file,
                }
 
                total += (size_t)read_ret;
+               offset += (off_t)read_ret;
        } while (total < n);
 
        SAFE_FREE(buf);
        return (ssize_t)total;
 }
 
-static ssize_t sys_read_fn(void *file, void *buf, size_t len)
+static ssize_t sys_pread_fn(void *file, void *buf, size_t len, off_t offset)
 {
        int *fd = (int *)file;
 
-       return sys_read(*fd, buf, len);
+       return sys_pread(*fd, buf, len, offset);
 }
 
-static ssize_t sys_write_fn(void *file, const void *buf, size_t len)
+static ssize_t sys_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
 {
        int *fd = (int *)file;
 
-       return sys_write(*fd, buf, len);
+       return sys_pwrite(*fd, buf, len, offset);
 }
 
 off_t transfer_file(int infd, int outfd, off_t n)
 {
        return (off_t)transfer_file_internal(&infd, &outfd, (size_t)n,
-                                                sys_read_fn, sys_write_fn);
+                                                sys_pread_fn, sys_pwrite_fn);
 }
index 4ab7723aefccf809e71a6086839f60c45ae195ad..b2673879f5a4aa64f8b2607df45f064e2815d794 100644 (file)
@@ -756,24 +756,24 @@ int vfs_fill_sparse(files_struct *fsp, off_t len)
  Transfer some data (n bytes) between two file_struct's.
 ****************************************************************************/
 
-static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
+static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
 {
        struct files_struct *fsp = (struct files_struct *)file;
 
-       return SMB_VFS_READ(fsp, buf, len);
+       return SMB_VFS_PREAD(fsp, buf, len, offset);
 }
 
-static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
+static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
 {
        struct files_struct *fsp = (struct files_struct *)file;
 
-       return SMB_VFS_WRITE(fsp, buf, len);
+       return SMB_VFS_PWRITE(fsp, buf, len, offset);
 }
 
 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
 {
        return transfer_file_internal((void *)in, (void *)out, n,
-                                     vfs_read_fn, vfs_write_fn);
+                                     vfs_pread_fn, vfs_pwrite_fn);
 }
 
 /*******************************************************************