summaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r--fs/cifs/smb2pdu.c49
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
1860static struct create_durable_v2 * 1861static struct create_durable_v2 *
1861create_durable_v2_buf(struct cifs_fid *pfid) 1862create_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:
2478int 2487int
2479SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 2488SMB2_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 */
2556int 2572int
2557SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, 2573SMB2_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