aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c120
-rw-r--r--fs/cifs/file.c14
2 files changed, 84 insertions, 50 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3d518b9e8c18..06dfaacfea5d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2310,16 +2310,16 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
2310 (new->mnt_cifs_flags & CIFS_MOUNT_MASK)) 2310 (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
2311 return 0; 2311 return 0;
2312 2312
2313 if (old->rsize != new->rsize)
2314 return 0;
2315
2316 /* 2313 /*
2317 * We want to share sb only if we don't specify wsize or specified wsize 2314 * We want to share sb only if we don't specify an r/wsize or
2318 * is greater or equal than existing one. 2315 * specified r/wsize is greater than or equal to existing one.
2319 */ 2316 */
2320 if (new->wsize && new->wsize < old->wsize) 2317 if (new->wsize && new->wsize < old->wsize)
2321 return 0; 2318 return 0;
2322 2319
2320 if (new->rsize && new->rsize < old->rsize)
2321 return 0;
2322
2323 if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid) 2323 if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
2324 return 0; 2324 return 0;
2325 2325
@@ -2757,14 +2757,6 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2757 CIFS_MOUNT_POSIX_PATHS; 2757 CIFS_MOUNT_POSIX_PATHS;
2758 } 2758 }
2759 2759
2760 if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) {
2761 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2762 cifs_sb->rsize = 127 * 1024;
2763 cFYI(DBG2, "larger reads not supported by srv");
2764 }
2765 }
2766
2767
2768 cFYI(1, "Negotiate caps 0x%x", (int)cap); 2760 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2769#ifdef CONFIG_CIFS_DEBUG2 2761#ifdef CONFIG_CIFS_DEBUG2
2770 if (cap & CIFS_UNIX_FCNTL_CAP) 2762 if (cap & CIFS_UNIX_FCNTL_CAP)
@@ -2809,27 +2801,11 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2809 spin_lock_init(&cifs_sb->tlink_tree_lock); 2801 spin_lock_init(&cifs_sb->tlink_tree_lock);
2810 cifs_sb->tlink_tree = RB_ROOT; 2802 cifs_sb->tlink_tree = RB_ROOT;
2811 2803
2812 if (pvolume_info->rsize > CIFSMaxBufSize) {
2813 cERROR(1, "rsize %d too large, using MaxBufSize",
2814 pvolume_info->rsize);
2815 cifs_sb->rsize = CIFSMaxBufSize;
2816 } else if ((pvolume_info->rsize) &&
2817 (pvolume_info->rsize <= CIFSMaxBufSize))
2818 cifs_sb->rsize = pvolume_info->rsize;
2819 else /* default */
2820 cifs_sb->rsize = CIFSMaxBufSize;
2821
2822 if (cifs_sb->rsize < 2048) {
2823 cifs_sb->rsize = 2048;
2824 /* Windows ME may prefer this */
2825 cFYI(1, "readsize set to minimum: 2048");
2826 }
2827
2828 /* 2804 /*
2829 * Temporarily set wsize for matching superblock. If we end up using 2805 * Temporarily set r/wsize for matching superblock. If we end up using
2830 * new sb then cifs_negotiate_wsize will later negotiate it downward 2806 * new sb then client will later negotiate it downward if needed.
2831 * if needed.
2832 */ 2807 */
2808 cifs_sb->rsize = pvolume_info->rsize;
2833 cifs_sb->wsize = pvolume_info->wsize; 2809 cifs_sb->wsize = pvolume_info->wsize;
2834 2810
2835 cifs_sb->mnt_uid = pvolume_info->linux_uid; 2811 cifs_sb->mnt_uid = pvolume_info->linux_uid;
@@ -2904,29 +2880,41 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2904} 2880}
2905 2881
2906/* 2882/*
2907 * When the server supports very large writes via POSIX extensions, we can 2883 * When the server supports very large reads and writes via POSIX extensions,
2908 * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including 2884 * we can allow up to 2^24-1, minus the size of a READ/WRITE_AND_X header, not
2909 * the RFC1001 length. 2885 * including the RFC1001 length.
2910 * 2886 *
2911 * Note that this might make for "interesting" allocation problems during 2887 * Note that this might make for "interesting" allocation problems during
2912 * writeback however as we have to allocate an array of pointers for the 2888 * writeback however as we have to allocate an array of pointers for the
2913 * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. 2889 * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096.
2890 *
2891 * For reads, there is a similar problem as we need to allocate an array
2892 * of kvecs to handle the receive, though that should only need to be done
2893 * once.
2914 */ 2894 */
2915#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) 2895#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4)
2896#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4)
2916 2897
2917/* 2898/*
2918 * When the server doesn't allow large posix writes, only allow a wsize of 2899 * When the server doesn't allow large posix writes, only allow a rsize/wsize
2919 * 2^17-1 minus the size of the WRITE_AND_X header. That allows for a write up 2900 * of 2^17-1 minus the size of the call header. That allows for a read or
2920 * to the maximum size described by RFC1002. 2901 * write up to the maximum size described by RFC1002.
2921 */ 2902 */
2922#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4) 2903#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
2904#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
2923 2905
2924/* 2906/*
2925 * The default wsize is 1M. find_get_pages seems to return a maximum of 256 2907 * The default wsize is 1M. find_get_pages seems to return a maximum of 256
2926 * pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill 2908 * pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill
2927 * a single wsize request with a single call. 2909 * a single wsize request with a single call.
2928 */ 2910 */
2929#define CIFS_DEFAULT_WSIZE (1024 * 1024) 2911#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
2912
2913/*
2914 * Windows only supports a max of 60k reads. Default to that when posix
2915 * extensions aren't in force.
2916 */
2917#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
2930 2918
2931static unsigned int 2919static unsigned int
2932cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) 2920cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
@@ -2934,7 +2922,7 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
2934 __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 2922 __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2935 struct TCP_Server_Info *server = tcon->ses->server; 2923 struct TCP_Server_Info *server = tcon->ses->server;
2936 unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize : 2924 unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
2937 CIFS_DEFAULT_WSIZE; 2925 CIFS_DEFAULT_IOSIZE;
2938 2926
2939 /* can server support 24-bit write sizes? (via UNIX extensions) */ 2927 /* can server support 24-bit write sizes? (via UNIX extensions) */
2940 if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) 2928 if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
@@ -2957,6 +2945,50 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
2957 return wsize; 2945 return wsize;
2958} 2946}
2959 2947
2948static unsigned int
2949cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
2950{
2951 __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2952 struct TCP_Server_Info *server = tcon->ses->server;
2953 unsigned int rsize, defsize;
2954
2955 /*
2956 * Set default value...
2957 *
2958 * HACK alert! Ancient servers have very small buffers. Even though
2959 * MS-CIFS indicates that servers are only limited by the client's
2960 * bufsize for reads, testing against win98se shows that it throws
2961 * INVALID_PARAMETER errors if you try to request too large a read.
2962 *
2963 * If the server advertises a MaxBufferSize of less than one page,
2964 * assume that it also can't satisfy reads larger than that either.
2965 *
2966 * FIXME: Is there a better heuristic for this?
2967 */
2968 if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
2969 defsize = CIFS_DEFAULT_IOSIZE;
2970 else if (server->capabilities & CAP_LARGE_READ_X)
2971 defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
2972 else if (server->maxBuf >= PAGE_CACHE_SIZE)
2973 defsize = CIFSMaxBufSize;
2974 else
2975 defsize = server->maxBuf - sizeof(READ_RSP);
2976
2977 rsize = pvolume_info->rsize ? pvolume_info->rsize : defsize;
2978
2979 /*
2980 * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to
2981 * the client's MaxBufferSize.
2982 */
2983 if (!(server->capabilities & CAP_LARGE_READ_X))
2984 rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
2985
2986 /* hard limit of CIFS_MAX_RSIZE */
2987 rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
2988
2989 return rsize;
2990}
2991
2960static int 2992static int
2961is_path_accessible(int xid, struct cifs_tcon *tcon, 2993is_path_accessible(int xid, struct cifs_tcon *tcon,
2962 struct cifs_sb_info *cifs_sb, const char *full_path) 2994 struct cifs_sb_info *cifs_sb, const char *full_path)
@@ -3234,14 +3266,8 @@ try_mount_again:
3234 CIFSSMBQFSAttributeInfo(xid, tcon); 3266 CIFSSMBQFSAttributeInfo(xid, tcon);
3235 } 3267 }
3236 3268
3237 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
3238 cifs_sb->rsize = 1024 * 127;
3239 cFYI(DBG2, "no very large read support, rsize now 127K");
3240 }
3241 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
3242 cifs_sb->rsize = min(cifs_sb->rsize, CIFSMaxBufSize);
3243
3244 cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info); 3269 cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
3270 cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info);
3245 3271
3246remote_path_check: 3272remote_path_check:
3247#ifdef CONFIG_CIFS_DFS_UPCALL 3273#ifdef CONFIG_CIFS_DFS_UPCALL
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8f6917816fec..a3b545ff5250 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1758,6 +1758,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1758 struct smb_com_read_rsp *pSMBr; 1758 struct smb_com_read_rsp *pSMBr;
1759 struct cifs_io_parms io_parms; 1759 struct cifs_io_parms io_parms;
1760 char *read_data; 1760 char *read_data;
1761 unsigned int rsize;
1761 __u32 pid; 1762 __u32 pid;
1762 1763
1763 if (!nr_segs) 1764 if (!nr_segs)
@@ -1770,6 +1771,9 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1770 xid = GetXid(); 1771 xid = GetXid();
1771 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1772 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1772 1773
1774 /* FIXME: set up handlers for larger reads and/or convert to async */
1775 rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
1776
1773 open_file = file->private_data; 1777 open_file = file->private_data;
1774 pTcon = tlink_tcon(open_file->tlink); 1778 pTcon = tlink_tcon(open_file->tlink);
1775 1779
@@ -1782,7 +1786,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1782 cFYI(1, "attempting read on write only file instance"); 1786 cFYI(1, "attempting read on write only file instance");
1783 1787
1784 for (total_read = 0; total_read < len; total_read += bytes_read) { 1788 for (total_read = 0; total_read < len; total_read += bytes_read) {
1785 cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize); 1789 cur_len = min_t(const size_t, len - total_read, rsize);
1786 rc = -EAGAIN; 1790 rc = -EAGAIN;
1787 read_data = NULL; 1791 read_data = NULL;
1788 1792
@@ -1874,6 +1878,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1874 unsigned int bytes_read = 0; 1878 unsigned int bytes_read = 0;
1875 unsigned int total_read; 1879 unsigned int total_read;
1876 unsigned int current_read_size; 1880 unsigned int current_read_size;
1881 unsigned int rsize;
1877 struct cifs_sb_info *cifs_sb; 1882 struct cifs_sb_info *cifs_sb;
1878 struct cifs_tcon *pTcon; 1883 struct cifs_tcon *pTcon;
1879 int xid; 1884 int xid;
@@ -1886,6 +1891,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1886 xid = GetXid(); 1891 xid = GetXid();
1887 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1892 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1888 1893
1894 /* FIXME: set up handlers for larger reads and/or convert to async */
1895 rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
1896
1889 if (file->private_data == NULL) { 1897 if (file->private_data == NULL) {
1890 rc = -EBADF; 1898 rc = -EBADF;
1891 FreeXid(xid); 1899 FreeXid(xid);
@@ -1905,8 +1913,8 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1905 for (total_read = 0, current_offset = read_data; 1913 for (total_read = 0, current_offset = read_data;
1906 read_size > total_read; 1914 read_size > total_read;
1907 total_read += bytes_read, current_offset += bytes_read) { 1915 total_read += bytes_read, current_offset += bytes_read) {
1908 current_read_size = min_t(uint, read_size - total_read, 1916 current_read_size = min_t(uint, read_size - total_read, rsize);
1909 cifs_sb->rsize); 1917
1910 /* For windows me and 9x we do not want to request more 1918 /* For windows me and 9x we do not want to request more
1911 than it negotiated since it will refuse the read then */ 1919 than it negotiated since it will refuse the read then */
1912 if ((pTcon->ses) && 1920 if ((pTcon->ses) &&