original development tree for Linux kernel GTP module; now long in mainline.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1403 lines
41 KiB

Query network adapter info at mount time for debugging When CONFIG_CIFS_STATS2 enabled query adapter info for debugging It is easy now in SMB3 to query the information about the server's network interfaces (and at least Windows 8 and above do this, if not other clients) there are some useful pieces of information you can get including: - all of the network interfaces that the server advertises (not just the one you are mounting over), and with SMB3 supporting multichannel this helps with more than just failover (also aggregating multiple sockets under one mount) - whether the adapter supports RSS (useful to know if you want to estimate whether setting up two or more socket connections to the same address is going to be faster due to RSS offload in the adapter) - whether the server supports RDMA - whether the server has IPv6 interfaces (if you connected over IPv4 but prefer IPv6 e.g.) - what the link speed is (you might want to reconnect over a higher speed interface if available) (Of course we could also rerequest this on every mount cheaplly to the same server, as Windows apparently does, so we can update the adapter info on new mounts, and also on every reconnect if the network interface drops temporarily - so we don't have to rely on info from the first mount to this server) It is trivial to request this information - and certainly will be useful when we get to the point of doing multichannel (and eventually RDMA), but some of this (linkspeed etc.) info may help for debugging in the meantime. Enable this request when CONFIG_CIFS_STATS2 is on (only for smb3 mounts since it is an SMB3 or later ioctl). Signed-off-by: Steve French <smfrench@gmail.com>
8 years ago
Query network adapter info at mount time for debugging When CONFIG_CIFS_STATS2 enabled query adapter info for debugging It is easy now in SMB3 to query the information about the server's network interfaces (and at least Windows 8 and above do this, if not other clients) there are some useful pieces of information you can get including: - all of the network interfaces that the server advertises (not just the one you are mounting over), and with SMB3 supporting multichannel this helps with more than just failover (also aggregating multiple sockets under one mount) - whether the adapter supports RSS (useful to know if you want to estimate whether setting up two or more socket connections to the same address is going to be faster due to RSS offload in the adapter) - whether the server supports RDMA - whether the server has IPv6 interfaces (if you connected over IPv4 but prefer IPv6 e.g.) - what the link speed is (you might want to reconnect over a higher speed interface if available) (Of course we could also rerequest this on every mount cheaplly to the same server, as Windows apparently does, so we can update the adapter info on new mounts, and also on every reconnect if the network interface drops temporarily - so we don't have to rely on info from the first mount to this server) It is trivial to request this information - and certainly will be useful when we get to the point of doing multichannel (and eventually RDMA), but some of this (linkspeed etc.) info may help for debugging in the meantime. Enable this request when CONFIG_CIFS_STATS2 is on (only for smb3 mounts since it is an SMB3 or later ioctl). Signed-off-by: Steve French <smfrench@gmail.com>
8 years ago
  1. /*
  2. * SMB2 version specific operations
  3. *
  4. * Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License v2 as published
  8. * by the Free Software Foundation.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  13. * the GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <linux/pagemap.h>
  20. #include <linux/vfs.h>
  21. #include "cifsglob.h"
  22. #include "smb2pdu.h"
  23. #include "smb2proto.h"
  24. #include "cifsproto.h"
  25. #include "cifs_debug.h"
  26. #include "cifs_unicode.h"
  27. #include "smb2status.h"
  28. #include "smb2glob.h"
  29. static int
  30. change_conf(struct TCP_Server_Info *server)
  31. {
  32. server->credits += server->echo_credits + server->oplock_credits;
  33. server->oplock_credits = server->echo_credits = 0;
  34. switch (server->credits) {
  35. case 0:
  36. return -1;
  37. case 1:
  38. server->echoes = false;
  39. server->oplocks = false;
  40. cifs_dbg(VFS, "disabling echoes and oplocks\n");
  41. break;
  42. case 2:
  43. server->echoes = true;
  44. server->oplocks = false;
  45. server->echo_credits = 1;
  46. cifs_dbg(FYI, "disabling oplocks\n");
  47. break;
  48. default:
  49. server->echoes = true;
  50. server->oplocks = true;
  51. server->echo_credits = 1;
  52. server->oplock_credits = 1;
  53. }
  54. server->credits -= server->echo_credits + server->oplock_credits;
  55. return 0;
  56. }
  57. static void
  58. smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
  59. const int optype)
  60. {
  61. int *val, rc = 0;
  62. spin_lock(&server->req_lock);
  63. val = server->ops->get_credits_field(server, optype);
  64. *val += add;
  65. server->in_flight--;
  66. if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
  67. rc = change_conf(server);
  68. /*
  69. * Sometimes server returns 0 credits on oplock break ack - we need to
  70. * rebalance credits in this case.
  71. */
  72. else if (server->in_flight > 0 && server->oplock_credits == 0 &&
  73. server->oplocks) {
  74. if (server->credits > 1) {
  75. server->credits--;
  76. server->oplock_credits++;
  77. }
  78. }
  79. spin_unlock(&server->req_lock);
  80. wake_up(&server->request_q);
  81. if (rc)
  82. cifs_reconnect(server);
  83. }
  84. static void
  85. smb2_set_credits(struct TCP_Server_Info *server, const int val)
  86. {
  87. spin_lock(&server->req_lock);
  88. server->credits = val;
  89. spin_unlock(&server->req_lock);
  90. }
  91. static int *
  92. smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
  93. {
  94. switch (optype) {
  95. case CIFS_ECHO_OP:
  96. return &server->echo_credits;
  97. case CIFS_OBREAK_OP:
  98. return &server->oplock_credits;
  99. default:
  100. return &server->credits;
  101. }
  102. }
  103. static unsigned int
  104. smb2_get_credits(struct mid_q_entry *mid)
  105. {
  106. return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
  107. }
  108. static __u64
  109. smb2_get_next_mid(struct TCP_Server_Info *server)
  110. {
  111. __u64 mid;
  112. /* for SMB2 we need the current value */
  113. spin_lock(&GlobalMid_Lock);
  114. mid = server->CurrentMid++;
  115. spin_unlock(&GlobalMid_Lock);
  116. return mid;
  117. }
  118. static struct mid_q_entry *
  119. smb2_find_mid(struct TCP_Server_Info *server, char *buf)
  120. {
  121. struct mid_q_entry *mid;
  122. struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
  123. spin_lock(&GlobalMid_Lock);
  124. list_for_each_entry(mid, &server->pending_mid_q, qhead) {
  125. if ((mid->mid == hdr->MessageId) &&
  126. (mid->mid_state == MID_REQUEST_SUBMITTED) &&
  127. (mid->command == hdr->Command)) {
  128. spin_unlock(&GlobalMid_Lock);
  129. return mid;
  130. }
  131. }
  132. spin_unlock(&GlobalMid_Lock);
  133. return NULL;
  134. }
  135. static void
  136. smb2_dump_detail(void *buf)
  137. {
  138. #ifdef CONFIG_CIFS_DEBUG2
  139. struct smb2_hdr *smb = (struct smb2_hdr *)buf;
  140. cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
  141. smb->Command, smb->Status, smb->Flags, smb->MessageId,
  142. smb->ProcessId);
  143. cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
  144. #endif
  145. }
  146. static bool
  147. smb2_need_neg(struct TCP_Server_Info *server)
  148. {
  149. return server->max_read == 0;
  150. }
  151. static int
  152. smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
  153. {
  154. int rc;
  155. ses->server->CurrentMid = 0;
  156. rc = SMB2_negotiate(xid, ses);
  157. /* BB we probably don't need to retry with modern servers */
  158. if (rc == -EAGAIN)
  159. rc = -EHOSTDOWN;
  160. return rc;
  161. }
  162. static unsigned int
  163. smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
  164. {
  165. struct TCP_Server_Info *server = tcon->ses->server;
  166. unsigned int wsize;
  167. /* start with specified wsize, or default */
  168. wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
  169. wsize = min_t(unsigned int, wsize, server->max_write);
  170. /*
  171. * limit write size to 2 ** 16, because we don't support multicredit
  172. * requests now.
  173. */
  174. wsize = min_t(unsigned int, wsize, 2 << 15);
  175. return wsize;
  176. }
  177. static unsigned int
  178. smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
  179. {
  180. struct TCP_Server_Info *server = tcon->ses->server;
  181. unsigned int rsize;
  182. /* start with specified rsize, or default */
  183. rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
  184. rsize = min_t(unsigned int, rsize, server->max_read);
  185. /*
  186. * limit write size to 2 ** 16, because we don't support multicredit
  187. * requests now.
  188. */
  189. rsize = min_t(unsigned int, rsize, 2 << 15);
  190. return rsize;
  191. }
  192. #ifdef CONFIG_CIFS_STATS2
  193. static int
  194. SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
  195. {
  196. int rc;
  197. unsigned int ret_data_len = 0;
  198. struct network_interface_info_ioctl_rsp *out_buf;
  199. rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
  200. FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
  201. NULL /* no data input */, 0 /* no data input */,
  202. (char **)&out_buf, &ret_data_len);
  203. if ((rc == 0) && (ret_data_len > 0)) {
  204. /* Dump info on first interface */
  205. cifs_dbg(FYI, "Adapter Capability 0x%x\t",
  206. le32_to_cpu(out_buf->Capability));
  207. cifs_dbg(FYI, "Link Speed %lld\n",
  208. le64_to_cpu(out_buf->LinkSpeed));
  209. } else
  210. cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
  211. return rc;
  212. }
  213. #endif /* STATS2 */
  214. static void
  215. smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
  216. {
  217. int rc;
  218. __le16 srch_path = 0; /* Null - open root of share */
  219. u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  220. struct cifs_open_parms oparms;
  221. struct cifs_fid fid;
  222. oparms.tcon = tcon;
  223. oparms.desired_access = FILE_READ_ATTRIBUTES;
  224. oparms.disposition = FILE_OPEN;
  225. oparms.create_options = 0;
  226. oparms.fid = &fid;
  227. oparms.reconnect = false;
  228. rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
  229. if (rc)
  230. return;
  231. #ifdef CONFIG_CIFS_STATS2
  232. SMB3_request_interfaces(xid, tcon);
  233. #endif /* STATS2 */
  234. SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  235. FS_ATTRIBUTE_INFORMATION);
  236. SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  237. FS_DEVICE_INFORMATION);
  238. SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  239. FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
  240. SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
  241. return;
  242. }
  243. static void
  244. smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
  245. {
  246. int rc;
  247. __le16 srch_path = 0; /* Null - open root of share */
  248. u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  249. struct cifs_open_parms oparms;
  250. struct cifs_fid fid;
  251. oparms.tcon = tcon;
  252. oparms.desired_access = FILE_READ_ATTRIBUTES;
  253. oparms.disposition = FILE_OPEN;
  254. oparms.create_options = 0;
  255. oparms.fid = &fid;
  256. oparms.reconnect = false;
  257. rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
  258. if (rc)
  259. return;
  260. SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  261. FS_ATTRIBUTE_INFORMATION);
  262. SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  263. FS_DEVICE_INFORMATION);
  264. SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
  265. return;
  266. }
  267. static int
  268. smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
  269. struct cifs_sb_info *cifs_sb, const char *full_path)
  270. {
  271. int rc;
  272. __le16 *utf16_path;
  273. __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  274. struct cifs_open_parms oparms;
  275. struct cifs_fid fid;
  276. utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
  277. if (!utf16_path)
  278. return -ENOMEM;
  279. oparms.tcon = tcon;
  280. oparms.desired_access = FILE_READ_ATTRIBUTES;
  281. oparms.disposition = FILE_OPEN;
  282. oparms.create_options = 0;
  283. oparms.fid = &fid;
  284. oparms.reconnect = false;
  285. rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
  286. if (rc) {
  287. kfree(utf16_path);
  288. return rc;
  289. }
  290. rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
  291. kfree(utf16_path);
  292. return rc;
  293. }
  294. static int
  295. smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
  296. struct cifs_sb_info *cifs_sb, const char *full_path,
  297. u64 *uniqueid, FILE_ALL_INFO *data)
  298. {
  299. *uniqueid = le64_to_cpu(data->IndexNumber);
  300. return 0;
  301. }
  302. static int
  303. smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
  304. struct cifs_fid *fid, FILE_ALL_INFO *data)
  305. {
  306. int rc;
  307. struct smb2_file_all_info *smb2_data;
  308. smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
  309. GFP_KERNEL);
  310. if (smb2_data == NULL)
  311. return -ENOMEM;
  312. rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
  313. smb2_data);
  314. if (!rc)
  315. move_smb2_info_to_cifs(data, smb2_data);
  316. kfree(smb2_data);
  317. return rc;
  318. }
  319. static bool
  320. smb2_can_echo(struct TCP_Server_Info *server)
  321. {
  322. return server->echoes;
  323. }
  324. static void
  325. smb2_clear_stats(struct cifs_tcon *tcon)
  326. {
  327. #ifdef CONFIG_CIFS_STATS
  328. int i;
  329. for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
  330. atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
  331. atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
  332. }
  333. #endif
  334. }
  335. static void
  336. smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
  337. {
  338. seq_puts(m, "\n\tShare Capabilities:");
  339. if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
  340. seq_puts(m, " DFS,");
  341. if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
  342. seq_puts(m, " CONTINUOUS AVAILABILITY,");
  343. if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
  344. seq_puts(m, " SCALEOUT,");
  345. if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
  346. seq_puts(m, " CLUSTER,");
  347. if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
  348. seq_puts(m, " ASYMMETRIC,");
  349. if (tcon->capabilities == 0)
  350. seq_puts(m, " None");
  351. if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
  352. seq_puts(m, " Aligned,");
  353. if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
  354. seq_puts(m, " Partition Aligned,");
  355. if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
  356. seq_puts(m, " SSD,");
  357. if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
  358. seq_puts(m, " TRIM-support,");
  359. seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
  360. if (tcon->perf_sector_size)
  361. seq_printf(m, "\tOptimal sector size: 0x%x",
  362. tcon->perf_sector_size);
  363. }
  364. static void
  365. smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
  366. {
  367. #ifdef CONFIG_CIFS_STATS
  368. atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
  369. atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
  370. seq_printf(m, "\nNegotiates: %d sent %d failed",
  371. atomic_read(&sent[SMB2_NEGOTIATE_HE]),
  372. atomic_read(&failed[SMB2_NEGOTIATE_HE]));
  373. seq_printf(m, "\nSessionSetups: %d sent %d failed",
  374. atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
  375. atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
  376. seq_printf(m, "\nLogoffs: %d sent %d failed",
  377. atomic_read(&sent[SMB2_LOGOFF_HE]),
  378. atomic_read(&failed[SMB2_LOGOFF_HE]));
  379. seq_printf(m, "\nTreeConnects: %d sent %d failed",
  380. atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
  381. atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
  382. seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
  383. atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
  384. atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
  385. seq_printf(m, "\nCreates: %d sent %d failed",
  386. atomic_read(&sent[SMB2_CREATE_HE]),
  387. atomic_read(&failed[SMB2_CREATE_HE]));
  388. seq_printf(m, "\nCloses: %d sent %d failed",
  389. atomic_read(&sent[SMB2_CLOSE_HE]),
  390. atomic_read(&failed[SMB2_CLOSE_HE]));
  391. seq_printf(m, "\nFlushes: %d sent %d failed",
  392. atomic_read(&sent[SMB2_FLUSH_HE]),
  393. atomic_read(&failed[SMB2_FLUSH_HE]));
  394. seq_printf(m, "\nReads: %d sent %d failed",
  395. atomic_read(&sent[SMB2_READ_HE]),
  396. atomic_read(&failed[SMB2_READ_HE]));
  397. seq_printf(m, "\nWrites: %d sent %d failed",
  398. atomic_read(&sent[SMB2_WRITE_HE]),
  399. atomic_read(&failed[SMB2_WRITE_HE]));
  400. seq_printf(m, "\nLocks: %d sent %d failed",
  401. atomic_read(&sent[SMB2_LOCK_HE]),
  402. atomic_read(&failed[SMB2_LOCK_HE]));
  403. seq_printf(m, "\nIOCTLs: %d sent %d failed",
  404. atomic_read(&sent[SMB2_IOCTL_HE]),
  405. atomic_read(&failed[SMB2_IOCTL_HE]));
  406. seq_printf(m, "\nCancels: %d sent %d failed",
  407. atomic_read(&sent[SMB2_CANCEL_HE]),
  408. atomic_read(&failed[SMB2_CANCEL_HE]));
  409. seq_printf(m, "\nEchos: %d sent %d failed",
  410. atomic_read(&sent[SMB2_ECHO_HE]),
  411. atomic_read(&failed[SMB2_ECHO_HE]));
  412. seq_printf(m, "\nQueryDirectories: %d sent %d failed",
  413. atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
  414. atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
  415. seq_printf(m, "\nChangeNotifies: %d sent %d failed",
  416. atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
  417. atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
  418. seq_printf(m, "\nQueryInfos: %d sent %d failed",
  419. atomic_read(&sent[SMB2_QUERY_INFO_HE]),
  420. atomic_read(&failed[SMB2_QUERY_INFO_HE]));
  421. seq_printf(m, "\nSetInfos: %d sent %d failed",
  422. atomic_read(&sent[SMB2_SET_INFO_HE]),
  423. atomic_read(&failed[SMB2_SET_INFO_HE]));
  424. seq_printf(m, "\nOplockBreaks: %d sent %d failed",
  425. atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
  426. atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
  427. #endif
  428. }
  429. static void
  430. smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
  431. {
  432. struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
  433. struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
  434. cfile->fid.persistent_fid = fid->persistent_fid;
  435. cfile->fid.volatile_fid = fid->volatile_fid;
  436. server->ops->set_oplock_level(cinode, oplock, fid->epoch,
  437. &fid->purge_cache);
  438. cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
  439. }
  440. static void
  441. smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
  442. struct cifs_fid *fid)
  443. {
  444. SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
  445. }
  446. static int
  447. SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
  448. u64 persistent_fid, u64 volatile_fid,
  449. struct copychunk_ioctl *pcchunk)
  450. {
  451. int rc;
  452. unsigned int ret_data_len;
  453. struct resume_key_req *res_key;
  454. rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
  455. FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */,
  456. NULL, 0 /* no input */,
  457. (char **)&res_key, &ret_data_len);
  458. if (rc) {
  459. cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc);
  460. goto req_res_key_exit;
  461. }
  462. if (ret_data_len < sizeof(struct resume_key_req)) {
  463. cifs_dbg(VFS, "Invalid refcopy resume key length\n");
  464. rc = -EINVAL;
  465. goto req_res_key_exit;
  466. }
  467. memcpy(pcchunk->SourceKey, res_key->ResumeKey, COPY_CHUNK_RES_KEY_SIZE);
  468. req_res_key_exit:
  469. kfree(res_key);
  470. return rc;
  471. }
  472. static int
  473. smb2_clone_range(const unsigned int xid,
  474. struct cifsFileInfo *srcfile,
  475. struct cifsFileInfo *trgtfile, u64 src_off,
  476. u64 len, u64 dest_off)
  477. {
  478. int rc;
  479. unsigned int ret_data_len;
  480. struct copychunk_ioctl *pcchunk;
  481. struct copychunk_ioctl_rsp *retbuf = NULL;
  482. struct cifs_tcon *tcon;
  483. int chunks_copied = 0;
  484. bool chunk_sizes_updated = false;
  485. pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
  486. if (pcchunk == NULL)
  487. return -ENOMEM;
  488. cifs_dbg(FYI, "in smb2_clone_range - about to call request res key\n");
  489. /* Request a key from the server to identify the source of the copy */
  490. rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
  491. srcfile->fid.persistent_fid,
  492. srcfile->fid.volatile_fid, pcchunk);
  493. /* Note: request_res_key sets res_key null only if rc !=0 */
  494. if (rc)
  495. goto cchunk_out;
  496. /* For now array only one chunk long, will make more flexible later */
  497. pcchunk->ChunkCount = __constant_cpu_to_le32(1);
  498. pcchunk->Reserved = 0;
  499. pcchunk->Reserved2 = 0;
  500. tcon = tlink_tcon(trgtfile->tlink);
  501. while (len > 0) {
  502. pcchunk->SourceOffset = cpu_to_le64(src_off);
  503. pcchunk->TargetOffset = cpu_to_le64(dest_off);
  504. pcchunk->Length =
  505. cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
  506. /* Request server copy to target from src identified by key */
  507. rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
  508. trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
  509. true /* is_fsctl */, (char *)pcchunk,
  510. sizeof(struct copychunk_ioctl), (char **)&retbuf,
  511. &ret_data_len);
  512. if (rc == 0) {
  513. if (ret_data_len !=
  514. sizeof(struct copychunk_ioctl_rsp)) {
  515. cifs_dbg(VFS, "invalid cchunk response size\n");
  516. rc = -EIO;
  517. goto cchunk_out;
  518. }
  519. if (retbuf->TotalBytesWritten == 0) {
  520. cifs_dbg(FYI, "no bytes copied\n");
  521. rc = -EIO;
  522. goto cchunk_out;
  523. }
  524. /*
  525. * Check if server claimed to write more than we asked
  526. */
  527. if (le32_to_cpu(retbuf->TotalBytesWritten) >
  528. le32_to_cpu(pcchunk->Length)) {
  529. cifs_dbg(VFS, "invalid copy chunk response\n");
  530. rc = -EIO;
  531. goto cchunk_out;
  532. }
  533. if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
  534. cifs_dbg(VFS, "invalid num chunks written\n");
  535. rc = -EIO;
  536. goto cchunk_out;
  537. }
  538. chunks_copied++;
  539. src_off += le32_to_cpu(retbuf->TotalBytesWritten);
  540. dest_off += le32_to_cpu(retbuf->TotalBytesWritten);
  541. len -= le32_to_cpu(retbuf->TotalBytesWritten);
  542. cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n",
  543. le32_to_cpu(retbuf->ChunksWritten),
  544. le32_to_cpu(retbuf->ChunkBytesWritten),
  545. le32_to_cpu(retbuf->TotalBytesWritten));
  546. } else if (rc == -EINVAL) {
  547. if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
  548. goto cchunk_out;
  549. cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
  550. le32_to_cpu(retbuf->ChunksWritten),
  551. le32_to_cpu(retbuf->ChunkBytesWritten),
  552. le32_to_cpu(retbuf->TotalBytesWritten));
  553. /*
  554. * Check if this is the first request using these sizes,
  555. * (ie check if copy succeed once with original sizes
  556. * and check if the server gave us different sizes after
  557. * we already updated max sizes on previous request).
  558. * if not then why is the server returning an error now
  559. */
  560. if ((chunks_copied != 0) || chunk_sizes_updated)
  561. goto cchunk_out;
  562. /* Check that server is not asking us to grow size */
  563. if (le32_to_cpu(retbuf->ChunkBytesWritten) <
  564. tcon->max_bytes_chunk)
  565. tcon->max_bytes_chunk =
  566. le32_to_cpu(retbuf->ChunkBytesWritten);
  567. else
  568. goto cchunk_out; /* server gave us bogus size */
  569. /* No need to change MaxChunks since already set to 1 */
  570. chunk_sizes_updated = true;
  571. }
  572. }
  573. cchunk_out:
  574. kfree(pcchunk);
  575. return rc;
  576. }
  577. static int
  578. smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
  579. struct cifs_fid *fid)
  580. {
  581. return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
  582. }
  583. static unsigned int
  584. smb2_read_data_offset(char *buf)
  585. {
  586. struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
  587. return rsp->DataOffset;
  588. }
  589. static unsigned int
  590. smb2_read_data_length(char *buf)
  591. {
  592. struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
  593. return le32_to_cpu(rsp->DataLength);
  594. }
  595. static int
  596. smb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
  597. struct cifs_io_parms *parms, unsigned int *bytes_read,
  598. char **buf, int *buf_type)
  599. {
  600. parms->persistent_fid = cfile->fid.persistent_fid;
  601. parms->volatile_fid = cfile->fid.volatile_fid;
  602. return SMB2_read(xid, parms, bytes_read, buf, buf_type);
  603. }
  604. static int
  605. smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
  606. struct cifs_io_parms *parms, unsigned int *written,
  607. struct kvec *iov, unsigned long nr_segs)
  608. {
  609. parms->persistent_fid = cfile->fid.persistent_fid;
  610. parms->volatile_fid = cfile->fid.volatile_fid;
  611. return SMB2_write(xid, parms, written, iov, nr_segs);
  612. }
  613. static int
  614. smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
  615. struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
  616. {
  617. __le64 eof = cpu_to_le64(size);
  618. return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
  619. cfile->fid.volatile_fid, cfile->pid, &eof);
  620. }
  621. static int
  622. smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
  623. struct cifsFileInfo *cfile)
  624. {
  625. return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
  626. cfile->fid.volatile_fid);
  627. }
  628. static int
  629. smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
  630. const char *path, struct cifs_sb_info *cifs_sb,
  631. struct cifs_fid *fid, __u16 search_flags,
  632. struct cifs_search_info *srch_inf)
  633. {
  634. __le16 *utf16_path;
  635. int rc;
  636. __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  637. struct cifs_open_parms oparms;
  638. utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
  639. if (!utf16_path)
  640. return -ENOMEM;
  641. oparms.tcon = tcon;
  642. oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
  643. oparms.disposition = FILE_OPEN;
  644. oparms.create_options = 0;
  645. oparms.fid = fid;
  646. oparms.reconnect = false;
  647. rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
  648. kfree(utf16_path);
  649. if (rc) {
  650. cifs_dbg(VFS, "open dir failed\n");
  651. return rc;
  652. }
  653. srch_inf->entries_in_buffer = 0;
  654. srch_inf->index_of_last_entry = 0;
  655. rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
  656. fid->volatile_fid, 0, srch_inf);
  657. if (rc) {
  658. cifs_dbg(VFS, "query directory failed\n");
  659. SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
  660. }
  661. return rc;
  662. }
  663. static int
  664. smb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
  665. struct cifs_fid *fid, __u16 search_flags,
  666. struct cifs_search_info *srch_inf)
  667. {
  668. return SMB2_query_directory(xid, tcon, fid->persistent_fid,
  669. fid->volatile_fid, 0, srch_inf);
  670. }
  671. static int
  672. smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
  673. struct cifs_fid *fid)
  674. {
  675. return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
  676. }
  677. /*
  678. * If we negotiate SMB2 protocol and get STATUS_PENDING - update
  679. * the number of credits and return true. Otherwise - return false.
  680. */
  681. static bool
  682. smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
  683. {
  684. struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
  685. if (hdr->Status != STATUS_PENDING)
  686. return false;
  687. if (!length) {
  688. spin_lock(&server->req_lock);
  689. server->credits += le16_to_cpu(hdr->CreditRequest);
  690. spin_unlock(&server->req_lock);
  691. wake_up(&server->request_q);
  692. }
  693. return true;
  694. }
  695. static int
  696. smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
  697. struct cifsInodeInfo *cinode)
  698. {
  699. if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
  700. return SMB2_lease_break(0, tcon, cinode->lease_key,
  701. smb2_get_lease_state(cinode));
  702. return SMB2_oplock_break(0, tcon, fid->persistent_fid,
  703. fid->volatile_fid,
  704. CIFS_CACHE_READ(cinode) ? 1 : 0);
  705. }
  706. static int
  707. smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
  708. struct kstatfs *buf)
  709. {
  710. int rc;
  711. __le16 srch_path = 0; /* Null - open root of share */
  712. u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  713. struct cifs_open_parms oparms;
  714. struct cifs_fid fid;
  715. oparms.tcon = tcon;
  716. oparms.desired_access = FILE_READ_ATTRIBUTES;
  717. oparms.disposition = FILE_OPEN;
  718. oparms.create_options = 0;
  719. oparms.fid = &fid;
  720. oparms.reconnect = false;
  721. rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
  722. if (rc)
  723. return rc;
  724. buf->f_type = SMB2_MAGIC_NUMBER;
  725. rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
  726. buf);
  727. SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
  728. return rc;
  729. }
  730. static bool
  731. smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
  732. {
  733. return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
  734. ob1->fid.volatile_fid == ob2->fid.volatile_fid;
  735. }
  736. static int
  737. smb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
  738. __u64 length, __u32 type, int lock, int unlock, bool wait)
  739. {
  740. if (unlock && !lock)
  741. type = SMB2_LOCKFLAG_UNLOCK;
  742. return SMB2_lock(xid, tlink_tcon(cfile->tlink),
  743. cfile->fid.persistent_fid, cfile->fid.volatile_fid,
  744. current->tgid, length, offset, type, wait);
  745. }
  746. static void
  747. smb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
  748. {
  749. memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
  750. }
  751. static void
  752. smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
  753. {
  754. memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
  755. }
  756. static void
  757. smb2_new_lease_key(struct cifs_fid *fid)
  758. {
  759. get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
  760. }
  761. static int
  762. smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
  763. const char *full_path, char **target_path,
  764. struct cifs_sb_info *cifs_sb)
  765. {
  766. int rc;
  767. __le16 *utf16_path;
  768. __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
  769. struct cifs_open_parms oparms;
  770. struct cifs_fid fid;
  771. struct smb2_err_rsp *err_buf = NULL;
  772. struct smb2_symlink_err_rsp *symlink;
  773. unsigned int sub_len, sub_offset;
  774. cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
  775. utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
  776. if (!utf16_path)
  777. return -ENOMEM;
  778. oparms.tcon = tcon;
  779. oparms.desired_access = FILE_READ_ATTRIBUTES;
  780. oparms.disposition = FILE_OPEN;
  781. oparms.create_options = 0;
  782. oparms.fid = &fid;
  783. oparms.reconnect = false;
  784. rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf);
  785. if (!rc || !err_buf) {
  786. kfree(utf16_path);
  787. return -ENOENT;
  788. }
  789. /* open must fail on symlink - reset rc */
  790. rc = 0;
  791. symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
  792. sub_len = le16_to_cpu(symlink->SubstituteNameLength);
  793. sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
  794. *target_path = cifs_strndup_from_utf16(
  795. (char *)symlink->PathBuffer + sub_offset,
  796. sub_len, true, cifs_sb->local_nls);
  797. if (!(*target_path)) {
  798. kfree(utf16_path);
  799. return -ENOMEM;
  800. }
  801. convert_delimiter(*target_path, '/');
  802. cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
  803. kfree(utf16_path);
  804. return rc;
  805. }
  806. static void
  807. smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
  808. unsigned int epoch, bool *purge_cache)
  809. {
  810. oplock &= 0xFF;
  811. if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
  812. return;
  813. if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
  814. cinode->oplock = CIFS_CACHE_RHW_FLG;
  815. cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
  816. &cinode->vfs_inode);
  817. } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
  818. cinode->oplock = CIFS_CACHE_RW_FLG;
  819. cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
  820. &cinode->vfs_inode);
  821. } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
  822. cinode->oplock = CIFS_CACHE_READ_FLG;
  823. cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
  824. &cinode->vfs_inode);
  825. } else
  826. cinode->oplock = 0;
  827. }
  828. static void
  829. smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
  830. unsigned int epoch, bool *purge_cache)
  831. {
  832. char message[5] = {0};
  833. oplock &= 0xFF;
  834. if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
  835. return;
  836. cinode->oplock = 0;
  837. if (oplock & SMB2_LEASE_READ_CACHING_HE) {
  838. cinode->oplock |= CIFS_CACHE_READ_FLG;
  839. strcat(message, "R");
  840. }
  841. if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
  842. cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
  843. strcat(message, "H");
  844. }
  845. if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
  846. cinode->oplock |= CIFS_CACHE_WRITE_FLG;
  847. strcat(message, "W");
  848. }
  849. if (!cinode->oplock)
  850. strcat(message, "None");
  851. cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
  852. &cinode->vfs_inode);
  853. }
  854. static void
  855. smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
  856. unsigned int epoch, bool *purge_cache)
  857. {
  858. unsigned int old_oplock = cinode->oplock;
  859. smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
  860. if (purge_cache) {
  861. *purge_cache = false;
  862. if (old_oplock == CIFS_CACHE_READ_FLG) {
  863. if (cinode->oplock == CIFS_CACHE_READ_FLG &&
  864. (epoch - cinode->epoch > 0))
  865. *purge_cache = true;
  866. else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
  867. (epoch - cinode->epoch > 1))
  868. *purge_cache = true;
  869. else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
  870. (epoch - cinode->epoch > 1))
  871. *purge_cache = true;
  872. else if (cinode->oplock == 0 &&
  873. (epoch - cinode->epoch > 0))
  874. *purge_cache = true;
  875. } else if (old_oplock == CIFS_CACHE_RH_FLG) {
  876. if (cinode->oplock == CIFS_CACHE_RH_FLG &&
  877. (epoch - cinode->epoch > 0))
  878. *purge_cache = true;
  879. else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
  880. (epoch - cinode->epoch > 1))
  881. *purge_cache = true;
  882. }
  883. cinode->epoch = epoch;
  884. }
  885. }
  886. static bool
  887. smb2_is_read_op(__u32 oplock)
  888. {
  889. return oplock == SMB2_OPLOCK_LEVEL_II;
  890. }
  891. static bool
  892. smb21_is_read_op(__u32 oplock)
  893. {
  894. return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
  895. !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
  896. }
  897. static __le32
  898. map_oplock_to_lease(u8 oplock)
  899. {
  900. if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
  901. return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
  902. else if (oplock == SMB2_OPLOCK_LEVEL_II)
  903. return SMB2_LEASE_READ_CACHING;
  904. else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
  905. return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
  906. SMB2_LEASE_WRITE_CACHING;
  907. return 0;
  908. }
  909. static char *
  910. smb2_create_lease_buf(u8 *lease_key, u8 oplock)
  911. {
  912. struct create_lease *buf;
  913. buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
  914. if (!buf)
  915. return NULL;
  916. buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
  917. buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
  918. buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
  919. buf->ccontext.DataOffset = cpu_to_le16(offsetof
  920. (struct create_lease, lcontext));
  921. buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
  922. buf->ccontext.NameOffset = cpu_to_le16(offsetof
  923. (struct create_lease, Name));
  924. buf->ccontext.NameLength = cpu_to_le16(4);
  925. buf->Name[0] = 'R';
  926. buf->Name[1] = 'q';
  927. buf->Name[2] = 'L';
  928. buf->Name[3] = 's';
  929. return (char *)buf;
  930. }
  931. static char *
  932. smb3_create_lease_buf(u8 *lease_key, u8 oplock)
  933. {
  934. struct create_lease_v2 *buf;
  935. buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
  936. if (!buf)
  937. return NULL;
  938. buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
  939. buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
  940. buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
  941. buf->ccontext.DataOffset = cpu_to_le16(offsetof
  942. (struct create_lease_v2, lcontext));
  943. buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
  944. buf->ccontext.NameOffset = cpu_to_le16(offsetof
  945. (struct create_lease_v2, Name));
  946. buf->ccontext.NameLength = cpu_to_le16(4);
  947. buf->Name[0] = 'R';
  948. buf->Name[1] = 'q';
  949. buf->Name[2] = 'L';
  950. buf->Name[3] = 's';
  951. return (char *)buf;
  952. }
  953. static __u8
  954. smb2_parse_lease_buf(void *buf, unsigned int *epoch)
  955. {
  956. struct create_lease *lc = (struct create_lease *)buf;
  957. *epoch = 0; /* not used */
  958. if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
  959. return SMB2_OPLOCK_LEVEL_NOCHANGE;
  960. return le32_to_cpu(lc->lcontext.LeaseState);
  961. }
  962. static __u8
  963. smb3_parse_lease_buf(void *buf, unsigned int *epoch)
  964. {
  965. struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
  966. *epoch = le16_to_cpu(lc->lcontext.Epoch);
  967. if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
  968. return SMB2_OPLOCK_LEVEL_NOCHANGE;
  969. return le32_to_cpu(lc->lcontext.LeaseState);
  970. }
  971. struct smb_version_operations smb20_operations = {
  972. .compare_fids = smb2_compare_fids,
  973. .setup_request = smb2_setup_request,
  974. .setup_async_request = smb2_setup_async_request,
  975. .check_receive = smb2_check_receive,
  976. .add_credits = smb2_add_credits,
  977. .set_credits = smb2_set_credits,
  978. .get_credits_field = smb2_get_credits_field,
  979. .get_credits = smb2_get_credits,
  980. .get_next_mid = smb2_get_next_mid,
  981. .read_data_offset = smb2_read_data_offset,
  982. .read_data_length = smb2_read_data_length,
  983. .map_error = map_smb2_to_linux_error,
  984. .find_mid = smb2_find_mid,
  985. .check_message = smb2_check_message,
  986. .dump_detail = smb2_dump_detail,
  987. .clear_stats = smb2_clear_stats,
  988. .print_stats = smb2_print_stats,
  989. .is_oplock_break = smb2_is_valid_oplock_break,
  990. .need_neg = smb2_need_neg,
  991. .negotiate = smb2_negotiate,
  992. .negotiate_wsize = smb2_negotiate_wsize,
  993. .negotiate_rsize = smb2_negotiate_rsize,
  994. .sess_setup = SMB2_sess_setup,
  995. .logoff = SMB2_logoff,
  996. .tree_connect = SMB2_tcon,
  997. .tree_disconnect = SMB2_tdis,
  998. .qfs_tcon = smb2_qfs_tcon,
  999. .is_path_accessible = smb2_is_path_accessible,
  1000. .can_echo = smb2_can_echo,
  1001. .echo = SMB2_echo,
  1002. .query_path_info = smb2_query_path_info,
  1003. .get_srv_inum = smb2_get_srv_inum,
  1004. .query_file_info = smb2_query_file_info,
  1005. .set_path_size = smb2_set_path_size,
  1006. .set_file_size = smb2_set_file_size,
  1007. .set_file_info = smb2_set_file_info,
  1008. .set_compression = smb2_set_compression,
  1009. .mkdir = smb2_mkdir,
  1010. .mkdir_setinfo = smb2_mkdir_setinfo,
  1011. .rmdir = smb2_rmdir,
  1012. .unlink = smb2_unlink,
  1013. .rename = smb2_rename_path,
  1014. .create_hardlink = smb2_create_hardlink,
  1015. .query_symlink = smb2_query_symlink,
  1016. .open = smb2_open_file,
  1017. .set_fid = smb2_set_fid,
  1018. .close = smb2_close_file,
  1019. .flush = smb2_flush_file,
  1020. .async_readv = smb2_async_readv,
  1021. .async_writev = smb2_async_writev,
  1022. .sync_read = smb2_sync_read,
  1023. .sync_write = smb2_sync_write,
  1024. .query_dir_first = smb2_query_dir_first,
  1025. .query_dir_next = smb2_query_dir_next,
  1026. .close_dir = smb2_close_dir,
  1027. .calc_smb_size = smb2_calc_size,
  1028. .is_status_pending = smb2_is_status_pending,
  1029. .oplock_response = smb2_oplock_response,
  1030. .queryfs = smb2_queryfs,
  1031. .mand_lock = smb2_mand_lock,
  1032. .mand_unlock_range = smb2_unlock_range,
  1033. .push_mand_locks = smb2_push_mandatory_locks,
  1034. .get_lease_key = smb2_get_lease_key,
  1035. .set_lease_key = smb2_set_lease_key,
  1036. .new_lease_key = smb2_new_lease_key,
  1037. .calc_signature = smb2_calc_signature,
  1038. .is_read_op = smb2_is_read_op,
  1039. .set_oplock_level = smb2_set_oplock_level,
  1040. .create_lease_buf = smb2_create_lease_buf,
  1041. .parse_lease_buf = smb2_parse_lease_buf,
  1042. .clone_range = smb2_clone_range,
  1043. };
  1044. struct smb_version_operations smb21_operations = {
  1045. .compare_fids = smb2_compare_fids,
  1046. .setup_request = smb2_setup_request,
  1047. .setup_async_request = smb2_setup_async_request,
  1048. .check_receive = smb2_check_receive,
  1049. .add_credits = smb2_add_credits,
  1050. .set_credits = smb2_set_credits,
  1051. .get_credits_field = smb2_get_credits_field,
  1052. .get_credits = smb2_get_credits,
  1053. .get_next_mid = smb2_get_next_mid,
  1054. .read_data_offset = smb2_read_data_offset,
  1055. .read_data_length = smb2_read_data_length,
  1056. .map_error = map_smb2_to_linux_error,
  1057. .find_mid = smb2_find_mid,
  1058. .check_message = smb2_check_message,
  1059. .dump_detail = smb2_dump_detail,
  1060. .clear_stats = smb2_clear_stats,
  1061. .print_stats = smb2_print_stats,
  1062. .is_oplock_break = smb2_is_valid_oplock_break,
  1063. .need_neg = smb2_need_neg,
  1064. .negotiate = smb2_negotiate,
  1065. .negotiate_wsize = smb2_negotiate_wsize,
  1066. .negotiate_rsize = smb2_negotiate_rsize,
  1067. .sess_setup = SMB2_sess_setup,
  1068. .logoff = SMB2_logoff,
  1069. .tree_connect = SMB2_tcon,
  1070. .tree_disconnect = SMB2_tdis,
  1071. .qfs_tcon = smb2_qfs_tcon,
  1072. .is_path_accessible = smb2_is_path_accessible,
  1073. .can_echo = smb2_can_echo,
  1074. .echo = SMB2_echo,
  1075. .query_path_info = smb2_query_path_info,
  1076. .get_srv_inum = smb2_get_srv_inum,
  1077. .query_file_info = smb2_query_file_info,
  1078. .set_path_size = smb2_set_path_size,
  1079. .set_file_size = smb2_set_file_size,
  1080. .set_file_info = smb2_set_file_info,
  1081. .set_compression = smb2_set_compression,
  1082. .mkdir = smb2_mkdir,
  1083. .mkdir_setinfo = smb2_mkdir_setinfo,
  1084. .rmdir = smb2_rmdir,
  1085. .unlink = smb2_unlink,
  1086. .rename = smb2_rename_path,
  1087. .create_hardlink = smb2_create_hardlink,
  1088. .query_symlink = smb2_query_symlink,
  1089. .open = smb2_open_file,
  1090. .set_fid = smb2_set_fid,
  1091. .close = smb2_close_file,
  1092. .flush = smb2_flush_file,
  1093. .async_readv = smb2_async_readv,
  1094. .async_writev = smb2_async_writev,
  1095. .sync_read = smb2_sync_read,
  1096. .sync_write = smb2_sync_write,
  1097. .query_dir_first = smb2_query_dir_first,
  1098. .query_dir_next = smb2_query_dir_next,
  1099. .close_dir = smb2_close_dir,
  1100. .calc_smb_size = smb2_calc_size,
  1101. .is_status_pending = smb2_is_status_pending,
  1102. .oplock_response = smb2_oplock_response,
  1103. .queryfs = smb2_queryfs,
  1104. .mand_lock = smb2_mand_lock,
  1105. .mand_unlock_range = smb2_unlock_range,
  1106. .push_mand_locks = smb2_push_mandatory_locks,
  1107. .get_lease_key = smb2_get_lease_key,
  1108. .set_lease_key = smb2_set_lease_key,
  1109. .new_lease_key = smb2_new_lease_key,
  1110. .calc_signature = smb2_calc_signature,
  1111. .is_read_op = smb21_is_read_op,
  1112. .set_oplock_level = smb21_set_oplock_level,
  1113. .create_lease_buf = smb2_create_lease_buf,
  1114. .parse_lease_buf = smb2_parse_lease_buf,
  1115. .clone_range = smb2_clone_range,
  1116. };
  1117. struct smb_version_operations smb30_operations = {
  1118. .compare_fids = smb2_compare_fids,
  1119. .setup_request = smb2_setup_request,
  1120. .setup_async_request = smb2_setup_async_request,
  1121. .check_receive = smb2_check_receive,
  1122. .add_credits = smb2_add_credits,
  1123. .set_credits = smb2_set_credits,
  1124. .get_credits_field = smb2_get_credits_field,
  1125. .get_credits = smb2_get_credits,
  1126. .get_next_mid = smb2_get_next_mid,
  1127. .read_data_offset = smb2_read_data_offset,
  1128. .read_data_length = smb2_read_data_length,
  1129. .map_error = map_smb2_to_linux_error,
  1130. .find_mid = smb2_find_mid,
  1131. .check_message = smb2_check_message,
  1132. .dump_detail = smb2_dump_detail,
  1133. .clear_stats = smb2_clear_stats,
  1134. .print_stats = smb2_print_stats,
  1135. .dump_share_caps = smb2_dump_share_caps,
  1136. .is_oplock_break = smb2_is_valid_oplock_break,
  1137. .need_neg = smb2_need_neg,
  1138. .negotiate = smb2_negotiate,
  1139. .negotiate_wsize = smb2_negotiate_wsize,
  1140. .negotiate_rsize = smb2_negotiate_rsize,
  1141. .sess_setup = SMB2_sess_setup,
  1142. .logoff = SMB2_logoff,
  1143. .tree_connect = SMB2_tcon,
  1144. .tree_disconnect = SMB2_tdis,
  1145. .qfs_tcon = smb3_qfs_tcon,
  1146. .is_path_accessible = smb2_is_path_accessible,
  1147. .can_echo = smb2_can_echo,
  1148. .echo = SMB2_echo,
  1149. .query_path_info = smb2_query_path_info,
  1150. .get_srv_inum = smb2_get_srv_inum,
  1151. .query_file_info = smb2_query_file_info,
  1152. .set_path_size = smb2_set_path_size,
  1153. .set_file_size = smb2_set_file_size,
  1154. .set_file_info = smb2_set_file_info,
  1155. .set_compression = smb2_set_compression,
  1156. .mkdir = smb2_mkdir,
  1157. .mkdir_setinfo = smb2_mkdir_setinfo,
  1158. .rmdir = smb2_rmdir,
  1159. .unlink = smb2_unlink,
  1160. .rename = smb2_rename_path,
  1161. .create_hardlink = smb2_create_hardlink,
  1162. .query_symlink = smb2_query_symlink,
  1163. .open = smb2_open_file,
  1164. .set_fid = smb2_set_fid,
  1165. .close = smb2_close_file,
  1166. .flush = smb2_flush_file,
  1167. .async_readv = smb2_async_readv,
  1168. .async_writev = smb2_async_writev,
  1169. .sync_read = smb2_sync_read,
  1170. .sync_write = smb2_sync_write,
  1171. .query_dir_first = smb2_query_dir_first,
  1172. .query_dir_next = smb2_query_dir_next,
  1173. .close_dir = smb2_close_dir,
  1174. .calc_smb_size = smb2_calc_size,
  1175. .is_status_pending = smb2_is_status_pending,
  1176. .oplock_response = smb2_oplock_response,
  1177. .queryfs = smb2_queryfs,
  1178. .mand_lock = smb2_mand_lock,
  1179. .mand_unlock_range = smb2_unlock_range,
  1180. .push_mand_locks = smb2_push_mandatory_locks,
  1181. .get_lease_key = smb2_get_lease_key,
  1182. .set_lease_key = smb2_set_lease_key,
  1183. .new_lease_key = smb2_new_lease_key,
  1184. .generate_signingkey = generate_smb3signingkey,
  1185. .calc_signature = smb3_calc_signature,
  1186. .is_read_op = smb21_is_read_op,
  1187. .set_oplock_level = smb3_set_oplock_level,
  1188. .create_lease_buf = smb3_create_lease_buf,
  1189. .parse_lease_buf = smb3_parse_lease_buf,
  1190. .clone_range = smb2_clone_range,
  1191. .validate_negotiate = smb3_validate_negotiate,
  1192. };
  1193. struct smb_version_values smb20_values = {
  1194. .version_string = SMB20_VERSION_STRING,
  1195. .protocol_id = SMB20_PROT_ID,
  1196. .req_capabilities = 0, /* MBZ */
  1197. .large_lock_type = 0,
  1198. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
  1199. .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
  1200. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  1201. .header_size = sizeof(struct smb2_hdr),
  1202. .max_header_size = MAX_SMB2_HDR_SIZE,
  1203. .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
  1204. .lock_cmd = SMB2_LOCK,
  1205. .cap_unix = 0,
  1206. .cap_nt_find = SMB2_NT_FIND,
  1207. .cap_large_files = SMB2_LARGE_FILES,
  1208. .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1209. .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1210. .create_lease_size = sizeof(struct create_lease),
  1211. };
  1212. struct smb_version_values smb21_values = {
  1213. .version_string = SMB21_VERSION_STRING,
  1214. .protocol_id = SMB21_PROT_ID,
  1215. .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
  1216. .large_lock_type = 0,
  1217. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
  1218. .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
  1219. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  1220. .header_size = sizeof(struct smb2_hdr),
  1221. .max_header_size = MAX_SMB2_HDR_SIZE,
  1222. .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
  1223. .lock_cmd = SMB2_LOCK,
  1224. .cap_unix = 0,
  1225. .cap_nt_find = SMB2_NT_FIND,
  1226. .cap_large_files = SMB2_LARGE_FILES,
  1227. .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1228. .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1229. .create_lease_size = sizeof(struct create_lease),
  1230. };
  1231. struct smb_version_values smb30_values = {
  1232. .version_string = SMB30_VERSION_STRING,
  1233. .protocol_id = SMB30_PROT_ID,
  1234. .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
  1235. .large_lock_type = 0,
  1236. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
  1237. .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
  1238. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  1239. .header_size = sizeof(struct smb2_hdr),
  1240. .max_header_size = MAX_SMB2_HDR_SIZE,
  1241. .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
  1242. .lock_cmd = SMB2_LOCK,
  1243. .cap_unix = 0,
  1244. .cap_nt_find = SMB2_NT_FIND,
  1245. .cap_large_files = SMB2_LARGE_FILES,
  1246. .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1247. .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1248. .create_lease_size = sizeof(struct create_lease_v2),
  1249. };
  1250. struct smb_version_values smb302_values = {
  1251. .version_string = SMB302_VERSION_STRING,
  1252. .protocol_id = SMB302_PROT_ID,
  1253. .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
  1254. .large_lock_type = 0,
  1255. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
  1256. .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
  1257. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  1258. .header_size = sizeof(struct smb2_hdr),
  1259. .max_header_size = MAX_SMB2_HDR_SIZE,
  1260. .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
  1261. .lock_cmd = SMB2_LOCK,
  1262. .cap_unix = 0,
  1263. .cap_nt_find = SMB2_NT_FIND,
  1264. .cap_large_files = SMB2_LARGE_FILES,
  1265. .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1266. .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
  1267. .create_lease_size = sizeof(struct create_lease_v2),
  1268. };