Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '5.1-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb3 fixes from Steve French:
"Four smb3 fixes for stable:

- fix an open path where we had an unitialized structure

- fix for snapshot (previous version) enumeration

- allow reconnect timeout on handles to be configurable to better
handle network or server crash

- correctly handle lack of file_all_info structure"

* tag '5.1-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: a smb2_validate_and_copy_iov failure does not mean the handle is invalid.
SMB3: Allow persistent handle timeout to be configurable on mount
smb3: Fix enumerating snapshots to Azure
cifs: fix kref underflow in close_shroot()

+121 -47
+2
fs/cifs/cifsfs.c
··· 559 559 tcon->ses->server->echo_interval / HZ); 560 560 if (tcon->snapshot_time) 561 561 seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); 562 + if (tcon->handle_timeout) 563 + seq_printf(s, ",handletimeout=%u", tcon->handle_timeout); 562 564 /* convert actimeo and display it in seconds */ 563 565 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); 564 566
+8
fs/cifs/cifsglob.h
··· 60 60 #define CIFS_MAX_ACTIMEO (1 << 30) 61 61 62 62 /* 63 + * Max persistent and resilient handle timeout (milliseconds). 64 + * Windows durable max was 960000 (16 minutes) 65 + */ 66 + #define SMB3_MAX_HANDLE_TIMEOUT 960000 67 + 68 + /* 63 69 * MAX_REQ is the maximum number of requests that WE will send 64 70 * on one socket concurrently. 65 71 */ ··· 592 586 struct nls_table *local_nls; 593 587 unsigned int echo_interval; /* echo interval in secs */ 594 588 __u64 snapshot_time; /* needed for timewarp tokens */ 589 + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ 595 590 unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ 596 591 }; 597 592 ··· 1065 1058 __u32 vol_serial_number; 1066 1059 __le64 vol_create_time; 1067 1060 __u64 snapshot_time; /* for timewarp tokens - timestamp of snapshot */ 1061 + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ 1068 1062 __u32 ss_flags; /* sector size flags */ 1069 1063 __u32 perf_sector_size; /* best sector size for perf */ 1070 1064 __u32 max_chunks;
+29 -1
fs/cifs/connect.c
··· 103 103 Opt_cruid, Opt_gid, Opt_file_mode, 104 104 Opt_dirmode, Opt_port, 105 105 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, 106 - Opt_echo_interval, Opt_max_credits, 106 + Opt_echo_interval, Opt_max_credits, Opt_handletimeout, 107 107 Opt_snapshot, 108 108 109 109 /* Mount options which take string value */ ··· 208 208 { Opt_rsize, "rsize=%s" }, 209 209 { Opt_wsize, "wsize=%s" }, 210 210 { Opt_actimeo, "actimeo=%s" }, 211 + { Opt_handletimeout, "handletimeout=%s" }, 211 212 { Opt_echo_interval, "echo_interval=%s" }, 212 213 { Opt_max_credits, "max_credits=%s" }, 213 214 { Opt_snapshot, "snapshot=%s" }, ··· 1620 1619 1621 1620 vol->actimeo = CIFS_DEF_ACTIMEO; 1622 1621 1622 + /* Most clients set timeout to 0, allows server to use its default */ 1623 + vol->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ 1624 + 1623 1625 /* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */ 1624 1626 vol->ops = &smb30_operations; 1625 1627 vol->vals = &smbdefault_values; ··· 2018 2014 vol->actimeo = HZ * option; 2019 2015 if (vol->actimeo > CIFS_MAX_ACTIMEO) { 2020 2016 cifs_dbg(VFS, "attribute cache timeout too large\n"); 2017 + goto cifs_parse_mount_err; 2018 + } 2019 + break; 2020 + case Opt_handletimeout: 2021 + if (get_option_ul(args, &option)) { 2022 + cifs_dbg(VFS, "%s: Invalid handletimeout value\n", 2023 + __func__); 2024 + goto cifs_parse_mount_err; 2025 + } 2026 + vol->handle_timeout = option; 2027 + if (vol->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { 2028 + cifs_dbg(VFS, "Invalid handle cache timeout, longer than 16 minutes\n"); 2021 2029 goto cifs_parse_mount_err; 2022 2030 } 2023 2031 break; ··· 3199 3183 return 0; 3200 3184 if (tcon->snapshot_time != volume_info->snapshot_time) 3201 3185 return 0; 3186 + if (tcon->handle_timeout != volume_info->handle_timeout) 3187 + return 0; 3202 3188 return 1; 3203 3189 } 3204 3190 ··· 3313 3295 goto out_fail; 3314 3296 } else 3315 3297 tcon->snapshot_time = volume_info->snapshot_time; 3298 + } 3299 + 3300 + if (volume_info->handle_timeout) { 3301 + if (ses->server->vals->protocol_id == 0) { 3302 + cifs_dbg(VFS, 3303 + "Use SMB2.1 or later for handle timeout option\n"); 3304 + rc = -EOPNOTSUPP; 3305 + goto out_fail; 3306 + } else 3307 + tcon->handle_timeout = volume_info->handle_timeout; 3316 3308 } 3317 3309 3318 3310 tcon->ses = ses;
+4 -2
fs/cifs/smb2file.c
··· 68 68 69 69 70 70 if (oparms->tcon->use_resilient) { 71 - nr_ioctl_req.Timeout = 0; /* use server default (120 seconds) */ 71 + /* default timeout is 0, servers pick default (120 seconds) */ 72 + nr_ioctl_req.Timeout = 73 + cpu_to_le32(oparms->tcon->handle_timeout); 72 74 nr_ioctl_req.Reserved = 0; 73 75 rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid, 74 76 fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY, 75 77 true /* is_fsctl */, 76 78 (char *)&nr_ioctl_req, sizeof(nr_ioctl_req), 77 - NULL, NULL /* no return info */); 79 + CIFSMaxBufSize, NULL, NULL /* no return info */); 78 80 if (rc == -EOPNOTSUPP) { 79 81 cifs_dbg(VFS, 80 82 "resiliency not supported by server, disabling\n");
+42 -26
fs/cifs/smb2ops.c
··· 581 581 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 582 582 FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */, 583 583 NULL /* no data input */, 0 /* no data input */, 584 - (char **)&out_buf, &ret_data_len); 584 + CIFSMaxBufSize, (char **)&out_buf, &ret_data_len); 585 585 if (rc == -EOPNOTSUPP) { 586 586 cifs_dbg(FYI, 587 587 "server does not support query network interfaces\n"); ··· 717 717 oparms.fid->mid = le64_to_cpu(o_rsp->sync_hdr.MessageId); 718 718 #endif /* CIFS_DEBUG2 */ 719 719 720 - if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) 721 - oplock = smb2_parse_lease_state(server, o_rsp, 722 - &oparms.fid->epoch, 723 - oparms.fid->lease_key); 724 - else 725 - goto oshr_exit; 726 - 727 - 728 720 memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid)); 729 721 tcon->crfid.tcon = tcon; 730 722 tcon->crfid.is_valid = true; 731 723 kref_init(&tcon->crfid.refcount); 732 - kref_get(&tcon->crfid.refcount); 733 724 725 + if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) { 726 + kref_get(&tcon->crfid.refcount); 727 + oplock = smb2_parse_lease_state(server, o_rsp, 728 + &oparms.fid->epoch, 729 + oparms.fid->lease_key); 730 + } else 731 + goto oshr_exit; 734 732 735 733 qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; 736 734 if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) 737 735 goto oshr_exit; 738 - rc = smb2_validate_and_copy_iov( 736 + if (!smb2_validate_and_copy_iov( 739 737 le16_to_cpu(qi_rsp->OutputBufferOffset), 740 738 sizeof(struct smb2_file_all_info), 741 739 &rsp_iov[1], sizeof(struct smb2_file_all_info), 742 - (char *)&tcon->crfid.file_all_info); 743 - if (rc) 744 - goto oshr_exit; 745 - tcon->crfid.file_all_info_is_valid = 1; 740 + (char *)&tcon->crfid.file_all_info)) 741 + tcon->crfid.file_all_info_is_valid = 1; 746 742 747 743 oshr_exit: 748 744 mutex_unlock(&tcon->crfid.fid_mutex); ··· 1295 1299 1296 1300 rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, 1297 1301 FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */, 1298 - NULL, 0 /* no input */, 1302 + NULL, 0 /* no input */, CIFSMaxBufSize, 1299 1303 (char **)&res_key, &ret_data_len); 1300 1304 1301 1305 if (rc) { ··· 1400 1404 rc = SMB2_ioctl_init(tcon, &rqst[1], 1401 1405 COMPOUND_FID, COMPOUND_FID, 1402 1406 qi.info_type, true, NULL, 1403 - 0); 1407 + 0, CIFSMaxBufSize); 1404 1408 } 1405 1409 } else if (qi.flags == PASSTHRU_QUERY_INFO) { 1406 1410 memset(&qi_iov, 0, sizeof(qi_iov)); ··· 1528 1532 rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, 1529 1533 trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE, 1530 1534 true /* is_fsctl */, (char *)pcchunk, 1531 - sizeof(struct copychunk_ioctl), (char **)&retbuf, 1532 - &ret_data_len); 1535 + sizeof(struct copychunk_ioctl), CIFSMaxBufSize, 1536 + (char **)&retbuf, &ret_data_len); 1533 1537 if (rc == 0) { 1534 1538 if (ret_data_len != 1535 1539 sizeof(struct copychunk_ioctl_rsp)) { ··· 1689 1693 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 1690 1694 cfile->fid.volatile_fid, FSCTL_SET_SPARSE, 1691 1695 true /* is_fctl */, 1692 - &setsparse, 1, NULL, NULL); 1696 + &setsparse, 1, CIFSMaxBufSize, NULL, NULL); 1693 1697 if (rc) { 1694 1698 tcon->broken_sparse_sup = true; 1695 1699 cifs_dbg(FYI, "set sparse rc = %d\n", rc); ··· 1762 1766 true /* is_fsctl */, 1763 1767 (char *)&dup_ext_buf, 1764 1768 sizeof(struct duplicate_extents_to_file), 1765 - NULL, 1769 + CIFSMaxBufSize, NULL, 1766 1770 &ret_data_len); 1767 1771 1768 1772 if (ret_data_len > 0) ··· 1797 1801 true /* is_fsctl */, 1798 1802 (char *)&integr_info, 1799 1803 sizeof(struct fsctl_set_integrity_information_req), 1800 - NULL, 1804 + CIFSMaxBufSize, NULL, 1801 1805 &ret_data_len); 1802 1806 1803 1807 } 1804 1808 1805 1809 /* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */ 1806 1810 #define GMT_TOKEN_SIZE 50 1811 + 1812 + #define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */ 1807 1813 1808 1814 /* 1809 1815 * Input buffer contains (empty) struct smb_snapshot array with size filled in ··· 1818 1820 char *retbuf = NULL; 1819 1821 unsigned int ret_data_len = 0; 1820 1822 int rc; 1823 + u32 max_response_size; 1821 1824 struct smb_snapshot_array snapshot_in; 1825 + 1826 + if (get_user(ret_data_len, (unsigned int __user *)ioc_buf)) 1827 + return -EFAULT; 1828 + 1829 + /* 1830 + * Note that for snapshot queries that servers like Azure expect that 1831 + * the first query be minimal size (and just used to get the number/size 1832 + * of previous versions) so response size must be specified as EXACTLY 1833 + * sizeof(struct snapshot_array) which is 16 when rounded up to multiple 1834 + * of eight bytes. 1835 + */ 1836 + if (ret_data_len == 0) 1837 + max_response_size = MIN_SNAPSHOT_ARRAY_SIZE; 1838 + else 1839 + max_response_size = CIFSMaxBufSize; 1822 1840 1823 1841 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 1824 1842 cfile->fid.volatile_fid, 1825 1843 FSCTL_SRV_ENUMERATE_SNAPSHOTS, 1826 1844 true /* is_fsctl */, 1827 - NULL, 0 /* no input data */, 1845 + NULL, 0 /* no input data */, max_response_size, 1828 1846 (char **)&retbuf, 1829 1847 &ret_data_len); 1830 1848 cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n", ··· 2318 2304 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 2319 2305 FSCTL_DFS_GET_REFERRALS, 2320 2306 true /* is_fsctl */, 2321 - (char *)dfs_req, dfs_req_size, 2307 + (char *)dfs_req, dfs_req_size, CIFSMaxBufSize, 2322 2308 (char **)&dfs_rsp, &dfs_rsp_size); 2323 2309 } while (rc == -EAGAIN); 2324 2310 ··· 2672 2658 rc = SMB2_ioctl_init(tcon, &rqst[num++], cfile->fid.persistent_fid, 2673 2659 cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, 2674 2660 true /* is_fctl */, (char *)&fsctl_buf, 2675 - sizeof(struct file_zero_data_information)); 2661 + sizeof(struct file_zero_data_information), 2662 + CIFSMaxBufSize); 2676 2663 if (rc) 2677 2664 goto zero_range_exit; 2678 2665 ··· 2750 2735 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 2751 2736 cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, 2752 2737 true /* is_fctl */, (char *)&fsctl_buf, 2753 - sizeof(struct file_zero_data_information), NULL, NULL); 2738 + sizeof(struct file_zero_data_information), 2739 + CIFSMaxBufSize, NULL, NULL); 2754 2740 free_xid(xid); 2755 2741 return rc; 2756 2742 }
+33 -16
fs/cifs/smb2pdu.c
··· 1002 1002 1003 1003 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 1004 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 1007 if (rc == -EOPNOTSUPP) { 1007 1008 /* 1008 1009 * Old Windows versions or Netapp SMB server can return ··· 1859 1858 } 1860 1859 1861 1860 static struct create_durable_v2 * 1862 - create_durable_v2_buf(struct cifs_fid *pfid) 1861 + create_durable_v2_buf(struct cifs_open_parms *oparms) 1863 1862 { 1863 + struct cifs_fid *pfid = oparms->fid; 1864 1864 struct create_durable_v2 *buf; 1865 1865 1866 1866 buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL); ··· 1875 1873 (struct create_durable_v2, Name)); 1876 1874 buf->ccontext.NameLength = cpu_to_le16(4); 1877 1875 1878 - buf->dcontext.Timeout = 0; /* Should this be configurable by workload */ 1876 + /* 1877 + * NB: Handle timeout defaults to 0, which allows server to choose 1878 + * (most servers default to 120 seconds) and most clients default to 0. 1879 + * This can be overridden at mount ("handletimeout=") if the user wants 1880 + * a different persistent (or resilient) handle timeout for all opens 1881 + * opens on a particular SMB3 mount. 1882 + */ 1883 + buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout); 1879 1884 buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); 1880 1885 generate_random_uuid(buf->dcontext.CreateGuid); 1881 1886 memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16); ··· 1935 1926 struct smb2_create_req *req = iov[0].iov_base; 1936 1927 unsigned int num = *num_iovec; 1937 1928 1938 - iov[num].iov_base = create_durable_v2_buf(oparms->fid); 1929 + iov[num].iov_base = create_durable_v2_buf(oparms); 1939 1930 if (iov[num].iov_base == NULL) 1940 1931 return -ENOMEM; 1941 1932 iov[num].iov_len = sizeof(struct create_durable_v2); ··· 2487 2478 int 2488 2479 SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 2489 2480 u64 persistent_fid, u64 volatile_fid, u32 opcode, 2490 - bool is_fsctl, char *in_data, u32 indatalen) 2481 + bool is_fsctl, char *in_data, u32 indatalen, 2482 + __u32 max_response_size) 2491 2483 { 2492 2484 struct smb2_ioctl_req *req; 2493 2485 struct kvec *iov = rqst->rq_iov; ··· 2530 2520 req->OutputCount = 0; /* MBZ */ 2531 2521 2532 2522 /* 2533 - * Could increase MaxOutputResponse, but that would require more 2534 - * than one credit. Windows typically sets this smaller, but for some 2523 + * In most cases max_response_size is set to 16K (CIFSMaxBufSize) 2524 + * We Could increase default MaxOutputResponse, but that could require 2525 + * more credits. Windows typically sets this smaller, but for some 2535 2526 * ioctls it may be useful to allow server to send more. No point 2536 2527 * limiting what the server can send as long as fits in one credit 2537 - * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE 2538 - * (by default, note that it can be overridden to make max larger) 2539 - * in responses (except for read responses which can be bigger. 2540 - * We may want to bump this limit up 2528 + * We can not handle more than CIFS_MAX_BUF_SIZE yet but may want 2529 + * to increase this limit up in the future. 2530 + * Note that for snapshot queries that servers like Azure expect that 2531 + * the first query be minimal size (and just used to get the number/size 2532 + * of previous versions) so response size must be specified as EXACTLY 2533 + * sizeof(struct snapshot_array) which is 16 when rounded up to multiple 2534 + * of eight bytes. Currently that is the only case where we set max 2535 + * response size smaller. 2541 2536 */ 2542 - req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize); 2537 + req->MaxOutputResponse = cpu_to_le32(max_response_size); 2543 2538 2544 2539 if (is_fsctl) 2545 2540 req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); ··· 2565 2550 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ 2566 2551 } 2567 2552 2553 + 2568 2554 /* 2569 2555 * SMB2 IOCTL is used for both IOCTLs and FSCTLs 2570 2556 */ 2571 2557 int 2572 2558 SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, 2573 2559 u64 volatile_fid, u32 opcode, bool is_fsctl, 2574 - char *in_data, u32 indatalen, 2560 + char *in_data, u32 indatalen, u32 max_out_data_len, 2575 2561 char **out_data, u32 *plen /* returned data len */) 2576 2562 { 2577 2563 struct smb_rqst rqst; ··· 2609 2593 rqst.rq_iov = iov; 2610 2594 rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE; 2611 2595 2612 - rc = SMB2_ioctl_init(tcon, &rqst, persistent_fid, volatile_fid, 2613 - opcode, is_fsctl, in_data, indatalen); 2596 + rc = SMB2_ioctl_init(tcon, &rqst, persistent_fid, volatile_fid, opcode, 2597 + is_fsctl, in_data, indatalen, max_out_data_len); 2614 2598 if (rc) 2615 2599 goto ioctl_exit; 2616 2600 ··· 2688 2672 rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, 2689 2673 FSCTL_SET_COMPRESSION, true /* is_fsctl */, 2690 2674 (char *)&fsctl_input /* data input */, 2691 - 2 /* in data len */, &ret_data /* out data */, NULL); 2675 + 2 /* in data len */, CIFSMaxBufSize /* max out data */, 2676 + &ret_data /* out data */, NULL); 2692 2677 2693 2678 cifs_dbg(FYI, "set compression rc %d\n", rc); 2694 2679
+3 -2
fs/cifs/smb2proto.h
··· 142 142 extern void SMB2_open_free(struct smb_rqst *rqst); 143 143 extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, 144 144 u64 persistent_fid, u64 volatile_fid, u32 opcode, 145 - bool is_fsctl, char *in_data, u32 indatalen, 145 + bool is_fsctl, char *in_data, u32 indatalen, u32 maxoutlen, 146 146 char **out_data, u32 *plen /* returned data len */); 147 147 extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 148 148 u64 persistent_fid, u64 volatile_fid, u32 opcode, 149 - bool is_fsctl, char *in_data, u32 indatalen); 149 + bool is_fsctl, char *in_data, u32 indatalen, 150 + __u32 max_response_size); 150 151 extern void SMB2_ioctl_free(struct smb_rqst *rqst); 151 152 extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, 152 153 u64 persistent_file_id, u64 volatile_file_id);