diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/connect.c | 120 | ||||
-rw-r--r-- | fs/cifs/file.c | 14 |
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 | ||
2931 | static unsigned int | 2919 | static unsigned int |
2932 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | 2920 | cifs_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 | ||
2948 | static unsigned int | ||
2949 | cifs_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 | |||
2960 | static int | 2992 | static int |
2961 | is_path_accessible(int xid, struct cifs_tcon *tcon, | 2993 | is_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 | ||
3246 | remote_path_check: | 3272 | remote_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) && |