diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:28 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:27 -0400 |
commit | 24985c53d5b04a56ac7c8ae7f74b8cb807e2ed2f (patch) | |
tree | e3864d9504852a5c7410cb9bae4cc9e0249cce1e /fs/cifs/connect.c | |
parent | 7a5cfb1965854132f2f382eade8c6ce2eeb6f692 (diff) |
CIFS: Move r/wsize negotiating to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 144 |
1 files changed, 2 insertions, 142 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6df6fa14cba8..c31b30b572e0 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -3261,146 +3261,6 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3261 | "mount option supported"); | 3261 | "mount option supported"); |
3262 | } | 3262 | } |
3263 | 3263 | ||
3264 | /* | ||
3265 | * When the server supports very large reads and writes via POSIX extensions, | ||
3266 | * we can allow up to 2^24-1, minus the size of a READ/WRITE_AND_X header, not | ||
3267 | * including the RFC1001 length. | ||
3268 | * | ||
3269 | * Note that this might make for "interesting" allocation problems during | ||
3270 | * writeback however as we have to allocate an array of pointers for the | ||
3271 | * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. | ||
3272 | * | ||
3273 | * For reads, there is a similar problem as we need to allocate an array | ||
3274 | * of kvecs to handle the receive, though that should only need to be done | ||
3275 | * once. | ||
3276 | */ | ||
3277 | #define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) | ||
3278 | #define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4) | ||
3279 | |||
3280 | /* | ||
3281 | * When the server doesn't allow large posix writes, only allow a rsize/wsize | ||
3282 | * of 2^17-1 minus the size of the call header. That allows for a read or | ||
3283 | * write up to the maximum size described by RFC1002. | ||
3284 | */ | ||
3285 | #define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4) | ||
3286 | #define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4) | ||
3287 | |||
3288 | /* | ||
3289 | * The default wsize is 1M. find_get_pages seems to return a maximum of 256 | ||
3290 | * pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill | ||
3291 | * a single wsize request with a single call. | ||
3292 | */ | ||
3293 | #define CIFS_DEFAULT_IOSIZE (1024 * 1024) | ||
3294 | |||
3295 | /* | ||
3296 | * Windows only supports a max of 60kb reads and 65535 byte writes. Default to | ||
3297 | * those values when posix extensions aren't in force. In actuality here, we | ||
3298 | * use 65536 to allow for a write that is a multiple of 4k. Most servers seem | ||
3299 | * to be ok with the extra byte even though Windows doesn't send writes that | ||
3300 | * are that large. | ||
3301 | * | ||
3302 | * Citation: | ||
3303 | * | ||
3304 | * http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx | ||
3305 | */ | ||
3306 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) | ||
3307 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) | ||
3308 | |||
3309 | /* | ||
3310 | * On hosts with high memory, we can't currently support wsize/rsize that are | ||
3311 | * larger than we can kmap at once. Cap the rsize/wsize at | ||
3312 | * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request | ||
3313 | * larger than that anyway. | ||
3314 | */ | ||
3315 | #ifdef CONFIG_HIGHMEM | ||
3316 | #define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE) | ||
3317 | #else /* CONFIG_HIGHMEM */ | ||
3318 | #define CIFS_KMAP_SIZE_LIMIT (1<<24) | ||
3319 | #endif /* CONFIG_HIGHMEM */ | ||
3320 | |||
3321 | static unsigned int | ||
3322 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | ||
3323 | { | ||
3324 | __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
3325 | struct TCP_Server_Info *server = tcon->ses->server; | ||
3326 | unsigned int wsize; | ||
3327 | |||
3328 | /* start with specified wsize, or default */ | ||
3329 | if (pvolume_info->wsize) | ||
3330 | wsize = pvolume_info->wsize; | ||
3331 | else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) | ||
3332 | wsize = CIFS_DEFAULT_IOSIZE; | ||
3333 | else | ||
3334 | wsize = CIFS_DEFAULT_NON_POSIX_WSIZE; | ||
3335 | |||
3336 | /* can server support 24-bit write sizes? (via UNIX extensions) */ | ||
3337 | if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) | ||
3338 | wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); | ||
3339 | |||
3340 | /* | ||
3341 | * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? | ||
3342 | * Limit it to max buffer offered by the server, minus the size of the | ||
3343 | * WRITEX header, not including the 4 byte RFC1001 length. | ||
3344 | */ | ||
3345 | if (!(server->capabilities & CAP_LARGE_WRITE_X) || | ||
3346 | (!(server->capabilities & CAP_UNIX) && | ||
3347 | (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) | ||
3348 | wsize = min_t(unsigned int, wsize, | ||
3349 | server->maxBuf - sizeof(WRITE_REQ) + 4); | ||
3350 | |||
3351 | /* limit to the amount that we can kmap at once */ | ||
3352 | wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT); | ||
3353 | |||
3354 | /* hard limit of CIFS_MAX_WSIZE */ | ||
3355 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); | ||
3356 | |||
3357 | return wsize; | ||
3358 | } | ||
3359 | |||
3360 | static unsigned int | ||
3361 | cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | ||
3362 | { | ||
3363 | __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); | ||
3364 | struct TCP_Server_Info *server = tcon->ses->server; | ||
3365 | unsigned int rsize, defsize; | ||
3366 | |||
3367 | /* | ||
3368 | * Set default value... | ||
3369 | * | ||
3370 | * HACK alert! Ancient servers have very small buffers. Even though | ||
3371 | * MS-CIFS indicates that servers are only limited by the client's | ||
3372 | * bufsize for reads, testing against win98se shows that it throws | ||
3373 | * INVALID_PARAMETER errors if you try to request too large a read. | ||
3374 | * OS/2 just sends back short reads. | ||
3375 | * | ||
3376 | * If the server doesn't advertise CAP_LARGE_READ_X, then assume that | ||
3377 | * it can't handle a read request larger than its MaxBufferSize either. | ||
3378 | */ | ||
3379 | if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) | ||
3380 | defsize = CIFS_DEFAULT_IOSIZE; | ||
3381 | else if (server->capabilities & CAP_LARGE_READ_X) | ||
3382 | defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; | ||
3383 | else | ||
3384 | defsize = server->maxBuf - sizeof(READ_RSP); | ||
3385 | |||
3386 | rsize = pvolume_info->rsize ? pvolume_info->rsize : defsize; | ||
3387 | |||
3388 | /* | ||
3389 | * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to | ||
3390 | * the client's MaxBufferSize. | ||
3391 | */ | ||
3392 | if (!(server->capabilities & CAP_LARGE_READ_X)) | ||
3393 | rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); | ||
3394 | |||
3395 | /* limit to the amount that we can kmap at once */ | ||
3396 | rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT); | ||
3397 | |||
3398 | /* hard limit of CIFS_MAX_RSIZE */ | ||
3399 | rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); | ||
3400 | |||
3401 | return rsize; | ||
3402 | } | ||
3403 | |||
3404 | static void | 3264 | static void |
3405 | cleanup_volume_info_contents(struct smb_vol *volume_info) | 3265 | cleanup_volume_info_contents(struct smb_vol *volume_info) |
3406 | { | 3266 | { |
@@ -3651,8 +3511,8 @@ try_mount_again: | |||
3651 | if (!tcon->ipc && server->ops->qfs_tcon) | 3511 | if (!tcon->ipc && server->ops->qfs_tcon) |
3652 | server->ops->qfs_tcon(xid, tcon); | 3512 | server->ops->qfs_tcon(xid, tcon); |
3653 | 3513 | ||
3654 | cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info); | 3514 | cifs_sb->wsize = server->ops->negotiate_wsize(tcon, volume_info); |
3655 | cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info); | 3515 | cifs_sb->rsize = server->ops->negotiate_rsize(tcon, volume_info); |
3656 | 3516 | ||
3657 | /* tune readahead according to rsize */ | 3517 | /* tune readahead according to rsize */ |
3658 | cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; | 3518 | cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; |