diff options
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r-- | fs/cifs/smb2pdu.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 21ac19ff19cb..21ad01d55ab2 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1002,7 +1002,8 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) | |||
1002 | 1002 | ||
1003 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, | 1003 | rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, |
1004 | FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, | 1004 | FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, |
1005 | (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen); | 1005 | (char *)pneg_inbuf, inbuflen, CIFSMaxBufSize, |
1006 | (char **)&pneg_rsp, &rsplen); | ||
1006 | if (rc == -EOPNOTSUPP) { | 1007 | if (rc == -EOPNOTSUPP) { |
1007 | /* | 1008 | /* |
1008 | * Old Windows versions or Netapp SMB server can return | 1009 | * Old Windows versions or Netapp SMB server can return |
@@ -1858,8 +1859,9 @@ add_lease_context(struct TCP_Server_Info *server, struct kvec *iov, | |||
1858 | } | 1859 | } |
1859 | 1860 | ||
1860 | static struct create_durable_v2 * | 1861 | static struct create_durable_v2 * |
1861 | create_durable_v2_buf(struct cifs_fid *pfid) | 1862 | create_durable_v2_buf(struct cifs_open_parms *oparms) |
1862 | { | 1863 | { |
1864 | struct cifs_fid *pfid = oparms->fid; | ||
1863 | struct create_durable_v2 *buf; | 1865 | struct create_durable_v2 *buf; |
1864 | 1866 | ||
1865 | buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL); | 1867 | buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL); |
@@ -1873,7 +1875,14 @@ create_durable_v2_buf(struct cifs_fid *pfid) | |||
1873 | (struct create_durable_v2, Name)); | 1875 | (struct create_durable_v2, Name)); |
1874 | buf->ccontext.NameLength = cpu_to_le16(4); | 1876 | buf->ccontext.NameLength = cpu_to_le16(4); |
1875 | 1877 | ||
1876 | buf->dcontext.Timeout = 0; /* Should this be configurable by workload */ | 1878 | /* |
1879 | * NB: Handle timeout defaults to 0, which allows server to choose | ||
1880 | * (most servers default to 120 seconds) and most clients default to 0. | ||
1881 | * This can be overridden at mount ("handletimeout=") if the user wants | ||
1882 | * a different persistent (or resilient) handle timeout for all opens | ||
1883 | * opens on a particular SMB3 mount. | ||
1884 | */ | ||
1885 | buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout); | ||
1877 | buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); | 1886 | buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); |
1878 | generate_random_uuid(buf->dcontext.CreateGuid); | 1887 | generate_random_uuid(buf->dcontext.CreateGuid); |
1879 | memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16); | 1888 | memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16); |
@@ -1926,7 +1935,7 @@ add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec, | |||
1926 | struct smb2_create_req *req = iov[0].iov_base; | 1935 | struct smb2_create_req *req = iov[0].iov_base; |
1927 | unsigned int num = *num_iovec; | 1936 | unsigned int num = *num_iovec; |
1928 | 1937 | ||
1929 | iov[num].iov_base = create_durable_v2_buf(oparms->fid); | 1938 | iov[num].iov_base = create_durable_v2_buf(oparms); |
1930 | if (iov[num].iov_base == NULL) | 1939 | if (iov[num].iov_base == NULL) |
1931 | return -ENOMEM; | 1940 | return -ENOMEM; |
1932 | iov[num].iov_len = sizeof(struct create_durable_v2); | 1941 | iov[num].iov_len = sizeof(struct create_durable_v2); |
@@ -2478,7 +2487,8 @@ creat_exit: | |||
2478 | int | 2487 | int |
2479 | SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | 2488 | SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, |
2480 | u64 persistent_fid, u64 volatile_fid, u32 opcode, | 2489 | u64 persistent_fid, u64 volatile_fid, u32 opcode, |
2481 | bool is_fsctl, char *in_data, u32 indatalen) | 2490 | bool is_fsctl, char *in_data, u32 indatalen, |
2491 | __u32 max_response_size) | ||
2482 | { | 2492 | { |
2483 | struct smb2_ioctl_req *req; | 2493 | struct smb2_ioctl_req *req; |
2484 | struct kvec *iov = rqst->rq_iov; | 2494 | struct kvec *iov = rqst->rq_iov; |
@@ -2520,16 +2530,21 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | |||
2520 | req->OutputCount = 0; /* MBZ */ | 2530 | req->OutputCount = 0; /* MBZ */ |
2521 | 2531 | ||
2522 | /* | 2532 | /* |
2523 | * Could increase MaxOutputResponse, but that would require more | 2533 | * In most cases max_response_size is set to 16K (CIFSMaxBufSize) |
2524 | * than one credit. Windows typically sets this smaller, but for some | 2534 | * We Could increase default MaxOutputResponse, but that could require |
2535 | * more credits. Windows typically sets this smaller, but for some | ||
2525 | * ioctls it may be useful to allow server to send more. No point | 2536 | * ioctls it may be useful to allow server to send more. No point |
2526 | * limiting what the server can send as long as fits in one credit | 2537 | * limiting what the server can send as long as fits in one credit |
2527 | * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE | 2538 | * We can not handle more than CIFS_MAX_BUF_SIZE yet but may want |
2528 | * (by default, note that it can be overridden to make max larger) | 2539 | * to increase this limit up in the future. |
2529 | * in responses (except for read responses which can be bigger. | 2540 | * Note that for snapshot queries that servers like Azure expect that |
2530 | * We may want to bump this limit up | 2541 | * the first query be minimal size (and just used to get the number/size |
2542 | * of previous versions) so response size must be specified as EXACTLY | ||
2543 | * sizeof(struct snapshot_array) which is 16 when rounded up to multiple | ||
2544 | * of eight bytes. Currently that is the only case where we set max | ||
2545 | * response size smaller. | ||
2531 | */ | 2546 | */ |
2532 | req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize); | 2547 | req->MaxOutputResponse = cpu_to_le32(max_response_size); |
2533 | 2548 | ||
2534 | if (is_fsctl) | 2549 | if (is_fsctl) |
2535 | req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); | 2550 | req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); |
@@ -2550,13 +2565,14 @@ SMB2_ioctl_free(struct smb_rqst *rqst) | |||
2550 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | 2565 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ |
2551 | } | 2566 | } |
2552 | 2567 | ||
2568 | |||
2553 | /* | 2569 | /* |
2554 | * SMB2 IOCTL is used for both IOCTLs and FSCTLs | 2570 | * SMB2 IOCTL is used for both IOCTLs and FSCTLs |
2555 | */ | 2571 | */ |
2556 | int | 2572 | int |
2557 | SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | 2573 | SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, |
2558 | u64 volatile_fid, u32 opcode, bool is_fsctl, | 2574 | u64 volatile_fid, u32 opcode, bool is_fsctl, |
2559 | char *in_data, u32 indatalen, | 2575 | char *in_data, u32 indatalen, u32 max_out_data_len, |
2560 | char **out_data, u32 *plen /* returned data len */) | 2576 | char **out_data, u32 *plen /* returned data len */) |
2561 | { | 2577 | { |
2562 | struct smb_rqst rqst; | 2578 | struct smb_rqst rqst; |
@@ -2593,8 +2609,8 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |||
2593 | rqst.rq_iov = iov; | 2609 | rqst.rq_iov = iov; |
2594 | rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE; | 2610 | rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE; |
2595 | 2611 | ||
2596 | rc = SMB2_ioctl_init(tcon, &rqst, persistent_fid, volatile_fid, | 2612 | rc = SMB2_ioctl_init(tcon, &rqst, persistent_fid, volatile_fid, opcode, |
2597 | opcode, is_fsctl, in_data, indatalen); | 2613 | is_fsctl, in_data, indatalen, max_out_data_len); |
2598 | if (rc) | 2614 | if (rc) |
2599 | goto ioctl_exit; | 2615 | goto ioctl_exit; |
2600 | 2616 | ||
@@ -2672,7 +2688,8 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | |||
2672 | rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, | 2688 | rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, |
2673 | FSCTL_SET_COMPRESSION, true /* is_fsctl */, | 2689 | FSCTL_SET_COMPRESSION, true /* is_fsctl */, |
2674 | (char *)&fsctl_input /* data input */, | 2690 | (char *)&fsctl_input /* data input */, |
2675 | 2 /* in data len */, &ret_data /* out data */, NULL); | 2691 | 2 /* in data len */, CIFSMaxBufSize /* max out data */, |
2692 | &ret_data /* out data */, NULL); | ||
2676 | 2693 | ||
2677 | cifs_dbg(FYI, "set compression rc %d\n", rc); | 2694 | cifs_dbg(FYI, "set compression rc %d\n", rc); |
2678 | 2695 | ||