aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h5
-rw-r--r--fs/cifs/file.c28
-rw-r--r--fs/cifs/smb1ops.c10
3 files changed, 32 insertions, 11 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 330f6259bb6d..5b1751d81901 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -174,6 +174,7 @@ struct smb_vol;
174struct cifs_fid; 174struct cifs_fid;
175struct cifs_readdata; 175struct cifs_readdata;
176struct cifs_writedata; 176struct cifs_writedata;
177struct cifs_io_parms;
177 178
178struct smb_version_operations { 179struct smb_version_operations {
179 int (*send_cancel)(struct TCP_Server_Info *, void *, 180 int (*send_cancel)(struct TCP_Server_Info *, void *,
@@ -286,6 +287,10 @@ struct smb_version_operations {
286 int (*async_readv)(struct cifs_readdata *); 287 int (*async_readv)(struct cifs_readdata *);
287 /* async write to the server */ 288 /* async write to the server */
288 int (*async_writev)(struct cifs_writedata *); 289 int (*async_writev)(struct cifs_writedata *);
290 /* sync read from the server */
291 int (*sync_read)(const unsigned int, struct cifsFileInfo *,
292 struct cifs_io_parms *, unsigned int *, char **,
293 int *);
289}; 294};
290 295
291struct smb_version_values { 296struct smb_version_values {
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 703c1648b068..fae03c52f314 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2782,8 +2782,8 @@ ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
2782 return cifs_user_readv(iocb, iov, nr_segs, pos); 2782 return cifs_user_readv(iocb, iov, nr_segs, pos);
2783} 2783}
2784 2784
2785static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, 2785static ssize_t
2786 loff_t *poffset) 2786cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
2787{ 2787{
2788 int rc = -EACCES; 2788 int rc = -EACCES;
2789 unsigned int bytes_read = 0; 2789 unsigned int bytes_read = 0;
@@ -2792,8 +2792,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
2792 unsigned int rsize; 2792 unsigned int rsize;
2793 struct cifs_sb_info *cifs_sb; 2793 struct cifs_sb_info *cifs_sb;
2794 struct cifs_tcon *tcon; 2794 struct cifs_tcon *tcon;
2795 struct TCP_Server_Info *server;
2795 unsigned int xid; 2796 unsigned int xid;
2796 char *current_offset; 2797 char *cur_offset;
2797 struct cifsFileInfo *open_file; 2798 struct cifsFileInfo *open_file;
2798 struct cifs_io_parms io_parms; 2799 struct cifs_io_parms io_parms;
2799 int buf_type = CIFS_NO_BUFFER; 2800 int buf_type = CIFS_NO_BUFFER;
@@ -2812,6 +2813,12 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
2812 } 2813 }
2813 open_file = file->private_data; 2814 open_file = file->private_data;
2814 tcon = tlink_tcon(open_file->tlink); 2815 tcon = tlink_tcon(open_file->tlink);
2816 server = tcon->ses->server;
2817
2818 if (!server->ops->sync_read) {
2819 free_xid(xid);
2820 return -ENOSYS;
2821 }
2815 2822
2816 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2823 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2817 pid = open_file->pid; 2824 pid = open_file->pid;
@@ -2821,9 +2828,8 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
2821 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 2828 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
2822 cFYI(1, "attempting read on write only file instance"); 2829 cFYI(1, "attempting read on write only file instance");
2823 2830
2824 for (total_read = 0, current_offset = read_data; 2831 for (total_read = 0, cur_offset = read_data; read_size > total_read;
2825 read_size > total_read; 2832 total_read += bytes_read, cur_offset += bytes_read) {
2826 total_read += bytes_read, current_offset += bytes_read) {
2827 current_read_size = min_t(uint, read_size - total_read, rsize); 2833 current_read_size = min_t(uint, read_size - total_read, rsize);
2828 /* 2834 /*
2829 * For windows me and 9x we do not want to request more than it 2835 * For windows me and 9x we do not want to request more than it
@@ -2841,13 +2847,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
2841 if (rc != 0) 2847 if (rc != 0)
2842 break; 2848 break;
2843 } 2849 }
2844 io_parms.netfid = open_file->fid.netfid;
2845 io_parms.pid = pid; 2850 io_parms.pid = pid;
2846 io_parms.tcon = tcon; 2851 io_parms.tcon = tcon;
2847 io_parms.offset = *poffset; 2852 io_parms.offset = *offset;
2848 io_parms.length = current_read_size; 2853 io_parms.length = current_read_size;
2849 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, 2854 rc = server->ops->sync_read(xid, open_file, &io_parms,
2850 &current_offset, &buf_type); 2855 &bytes_read, &cur_offset,
2856 &buf_type);
2851 } 2857 }
2852 if (rc || (bytes_read == 0)) { 2858 if (rc || (bytes_read == 0)) {
2853 if (total_read) { 2859 if (total_read) {
@@ -2858,7 +2864,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
2858 } 2864 }
2859 } else { 2865 } else {
2860 cifs_stats_bytes_read(tcon, total_read); 2866 cifs_stats_bytes_read(tcon, total_read);
2861 *poffset += bytes_read; 2867 *offset += bytes_read;
2862 } 2868 }
2863 } 2869 }
2864 free_xid(xid); 2870 free_xid(xid);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 50c3697af5aa..cea958ee8b7a 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -739,6 +739,15 @@ cifs_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
739 return CIFSSMBFlush(xid, tcon, fid->netfid); 739 return CIFSSMBFlush(xid, tcon, fid->netfid);
740} 740}
741 741
742static int
743cifs_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
744 struct cifs_io_parms *parms, unsigned int *bytes_read,
745 char **buf, int *buf_type)
746{
747 parms->netfid = cfile->fid.netfid;
748 return CIFSSMBRead(xid, parms, bytes_read, buf, buf_type);
749}
750
742struct smb_version_operations smb1_operations = { 751struct smb_version_operations smb1_operations = {
743 .send_cancel = send_nt_cancel, 752 .send_cancel = send_nt_cancel,
744 .compare_fids = cifs_compare_fids, 753 .compare_fids = cifs_compare_fids,
@@ -787,6 +796,7 @@ struct smb_version_operations smb1_operations = {
787 .flush = cifs_flush_file, 796 .flush = cifs_flush_file,
788 .async_readv = cifs_async_readv, 797 .async_readv = cifs_async_readv,
789 .async_writev = cifs_async_writev, 798 .async_writev = cifs_async_writev,
799 .sync_read = cifs_sync_read,
790}; 800};
791 801
792struct smb_version_values smb1_values = { 802struct smb_version_values smb1_values = {