diff options
-rw-r--r-- | fs/cifs/cifsglob.h | 5 | ||||
-rw-r--r-- | fs/cifs/file.c | 28 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 10 |
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; | |||
174 | struct cifs_fid; | 174 | struct cifs_fid; |
175 | struct cifs_readdata; | 175 | struct cifs_readdata; |
176 | struct cifs_writedata; | 176 | struct cifs_writedata; |
177 | struct cifs_io_parms; | ||
177 | 178 | ||
178 | struct smb_version_operations { | 179 | struct 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 | ||
291 | struct smb_version_values { | 296 | struct 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 | ||
2785 | static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | 2785 | static ssize_t |
2786 | loff_t *poffset) | 2786 | cifs_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 | ¤t_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 | ||
742 | static int | ||
743 | cifs_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 | |||
742 | struct smb_version_operations smb1_operations = { | 751 | struct 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 | ||
792 | struct smb_version_values smb1_values = { | 802 | struct smb_version_values smb1_values = { |