PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/release/src/linux/linux/fs/smbfs/sock.c

https://gitlab.com/envieidoc/tomato
C | 956 lines | 739 code | 114 blank | 103 comment | 119 complexity | 51edad350f12b3125766c6bc0ab0c514 MD5 | raw file
  1. /*
  2. * sock.c
  3. *
  4. * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  5. * Copyright (C) 1997 by Volker Lendecke
  6. *
  7. * Please add a note about your changes to smbfs in the ChangeLog file.
  8. */
  9. #include <linux/sched.h>
  10. #include <linux/errno.h>
  11. #include <linux/socket.h>
  12. #include <linux/fcntl.h>
  13. #include <linux/file.h>
  14. #include <linux/poll.h>
  15. #include <linux/in.h>
  16. #include <linux/net.h>
  17. #include <linux/mm.h>
  18. #include <linux/netdevice.h>
  19. #include <linux/smp_lock.h>
  20. #include <net/scm.h>
  21. #include <net/ip.h>
  22. #include <linux/smb_fs.h>
  23. #include <linux/smb.h>
  24. #include <linux/smbno.h>
  25. #include <asm/uaccess.h>
  26. #include "smb_debug.h"
  27. #include "proto.h"
  28. static int
  29. _recvfrom(struct socket *socket, unsigned char *ubuf, int size,
  30. unsigned flags)
  31. {
  32. struct iovec iov;
  33. struct msghdr msg;
  34. struct scm_cookie scm;
  35. msg.msg_name = NULL;
  36. msg.msg_namelen = 0;
  37. msg.msg_iov = &iov;
  38. msg.msg_iovlen = 1;
  39. msg.msg_control = NULL;
  40. iov.iov_base = ubuf;
  41. iov.iov_len = size;
  42. memset(&scm, 0,sizeof(scm));
  43. size=socket->ops->recvmsg(socket, &msg, size, flags, &scm);
  44. if(size>=0)
  45. scm_recv(socket,&msg,&scm,flags);
  46. return size;
  47. }
  48. static int
  49. _send(struct socket *socket, const void *buff, int len)
  50. {
  51. struct iovec iov;
  52. struct msghdr msg;
  53. struct scm_cookie scm;
  54. int err;
  55. msg.msg_name = NULL;
  56. msg.msg_namelen = 0;
  57. msg.msg_iov = &iov;
  58. msg.msg_iovlen = 1;
  59. msg.msg_control = NULL;
  60. msg.msg_controllen = 0;
  61. iov.iov_base = (void *)buff;
  62. iov.iov_len = len;
  63. msg.msg_flags = 0;
  64. err = scm_send(socket, &msg, &scm);
  65. if (err >= 0)
  66. {
  67. err = socket->ops->sendmsg(socket, &msg, len, &scm);
  68. scm_destroy(&scm);
  69. }
  70. return err;
  71. }
  72. struct data_callback {
  73. struct tq_struct cb;
  74. struct sock *sk;
  75. };
  76. /*
  77. * N.B. What happens if we're in here when the socket closes??
  78. */
  79. static void
  80. found_data(struct sock *sk)
  81. {
  82. /*
  83. * FIXME: copied from sock_def_readable, it should be a call to
  84. * server->data_ready() -- manfreds@colorfullife.com
  85. */
  86. read_lock(&sk->callback_lock);
  87. if(!sk->dead) {
  88. wake_up_interruptible(sk->sleep);
  89. sock_wake_async(sk->socket,1,POLL_IN);
  90. }
  91. read_unlock(&sk->callback_lock);
  92. }
  93. static void
  94. smb_data_callback(void* ptr)
  95. {
  96. struct data_callback* job=ptr;
  97. struct socket *socket = job->sk->socket;
  98. unsigned char peek_buf[4];
  99. int result = 0;
  100. mm_segment_t fs;
  101. int count = 100; /* this is a lot, we should have some data waiting */
  102. int found = 0;
  103. fs = get_fs();
  104. set_fs(get_ds());
  105. lock_kernel();
  106. while (count-- > 0) {
  107. peek_buf[0] = 0;
  108. result = -EIO;
  109. if (job->sk->dead) {
  110. PARANOIA("sock dead!\n");
  111. break;
  112. }
  113. result = _recvfrom(socket, (void *) peek_buf, 1,
  114. MSG_PEEK | MSG_DONTWAIT);
  115. if (result < 0)
  116. break;
  117. if (peek_buf[0] != 0x85)
  118. break;
  119. /* got SESSION KEEP ALIVE */
  120. result = _recvfrom(socket, (void *) peek_buf, 4,
  121. MSG_DONTWAIT);
  122. DEBUG1("got SESSION KEEPALIVE\n");
  123. if (result < 0)
  124. break;
  125. found = 1;
  126. }
  127. unlock_kernel();
  128. set_fs(fs);
  129. DEBUG1("found=%d, count=%d, result=%d\n", found, count, result);
  130. if (found)
  131. found_data(job->sk);
  132. smb_kfree(ptr);
  133. }
  134. static void
  135. smb_data_ready(struct sock *sk, int len)
  136. {
  137. struct data_callback* job;
  138. job = smb_kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
  139. if(job == 0) {
  140. printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n");
  141. found_data(sk);
  142. return;
  143. }
  144. INIT_LIST_HEAD(&job->cb.list);
  145. job->cb.sync = 0;
  146. job->cb.routine = smb_data_callback;
  147. job->cb.data = job;
  148. job->sk = sk;
  149. schedule_task(&job->cb);
  150. }
  151. int
  152. smb_valid_socket(struct inode * inode)
  153. {
  154. return (inode && S_ISSOCK(inode->i_mode) &&
  155. inode->u.socket_i.type == SOCK_STREAM);
  156. }
  157. static struct socket *
  158. server_sock(struct smb_sb_info *server)
  159. {
  160. struct file *file;
  161. if (server && (file = server->sock_file))
  162. {
  163. #ifdef SMBFS_PARANOIA
  164. if (!smb_valid_socket(file->f_dentry->d_inode))
  165. PARANOIA("bad socket!\n");
  166. #endif
  167. return &file->f_dentry->d_inode->u.socket_i;
  168. }
  169. return NULL;
  170. }
  171. int
  172. smb_catch_keepalive(struct smb_sb_info *server)
  173. {
  174. struct socket *socket;
  175. struct sock *sk;
  176. void *data_ready;
  177. int error;
  178. error = -EINVAL;
  179. socket = server_sock(server);
  180. if (!socket)
  181. {
  182. printk(KERN_DEBUG "smb_catch_keepalive: did not get valid server!\n");
  183. server->data_ready = NULL;
  184. goto out;
  185. }
  186. sk = socket->sk;
  187. if (sk == NULL)
  188. {
  189. DEBUG1("sk == NULL");
  190. server->data_ready = NULL;
  191. goto out;
  192. }
  193. DEBUG1("sk->d_r = %x, server->d_r = %x\n",
  194. (unsigned int) (sk->data_ready),
  195. (unsigned int) (server->data_ready));
  196. /*
  197. * Install the callback atomically to avoid races ...
  198. */
  199. data_ready = xchg(&sk->data_ready, smb_data_ready);
  200. if (data_ready != smb_data_ready) {
  201. server->data_ready = data_ready;
  202. error = 0;
  203. } else
  204. printk(KERN_ERR "smb_catch_keepalive: already done\n");
  205. out:
  206. return error;
  207. }
  208. int
  209. smb_dont_catch_keepalive(struct smb_sb_info *server)
  210. {
  211. struct socket *socket;
  212. struct sock *sk;
  213. void * data_ready;
  214. int error;
  215. error = -EINVAL;
  216. socket = server_sock(server);
  217. if (!socket)
  218. {
  219. printk(KERN_DEBUG "smb_dont_catch_keepalive: did not get valid server!\n");
  220. goto out;
  221. }
  222. sk = socket->sk;
  223. if (sk == NULL)
  224. {
  225. DEBUG1("sk == NULL");
  226. goto out;
  227. }
  228. /* Is this really an error?? */
  229. if (server->data_ready == NULL)
  230. {
  231. printk(KERN_DEBUG "smb_dont_catch_keepalive: "
  232. "server->data_ready == NULL\n");
  233. goto out;
  234. }
  235. DEBUG1("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
  236. (unsigned int) (sk->data_ready),
  237. (unsigned int) (server->data_ready));
  238. /*
  239. * Restore the original callback atomically to avoid races ...
  240. */
  241. data_ready = xchg(&sk->data_ready, server->data_ready);
  242. server->data_ready = NULL;
  243. if (data_ready != smb_data_ready)
  244. {
  245. printk(KERN_ERR "smb_dont_catch_keepalive: "
  246. "sk->data_ready != smb_data_ready\n");
  247. }
  248. error = 0;
  249. out:
  250. return error;
  251. }
  252. /*
  253. * Called with the server locked.
  254. */
  255. void
  256. smb_close_socket(struct smb_sb_info *server)
  257. {
  258. struct file * file = server->sock_file;
  259. if (file)
  260. {
  261. VERBOSE("closing socket %p\n", server_sock(server));
  262. #ifdef SMBFS_PARANOIA
  263. if (server_sock(server)->sk->data_ready == smb_data_ready)
  264. PARANOIA("still catching keepalives!\n");
  265. #endif
  266. server->sock_file = NULL;
  267. fput(file);
  268. }
  269. }
  270. /*
  271. * Poll the server->socket to allow receives to time out.
  272. * returns 0 when ok to continue, <0 on errors.
  273. */
  274. static int
  275. smb_receive_poll(struct smb_sb_info *server)
  276. {
  277. struct file *file = server->sock_file;
  278. poll_table wait_table;
  279. int result = 0;
  280. int timeout = server->mnt->timeo * HZ;
  281. int mask;
  282. for (;;) {
  283. poll_initwait(&wait_table);
  284. set_current_state(TASK_INTERRUPTIBLE);
  285. mask = file->f_op->poll(file, &wait_table);
  286. if (mask & POLLIN) {
  287. poll_freewait(&wait_table);
  288. current->state = TASK_RUNNING;
  289. break;
  290. }
  291. timeout = schedule_timeout(timeout);
  292. poll_freewait(&wait_table);
  293. set_current_state(TASK_RUNNING);
  294. if (wait_table.error) {
  295. result = wait_table.error;
  296. break;
  297. }
  298. if (signal_pending(current)) {
  299. /* we got a signal (which?) tell the caller to
  300. try again (on all signals?). */
  301. DEBUG1("got signal_pending()\n");
  302. result = -ERESTARTSYS;
  303. break;
  304. }
  305. if (!timeout) {
  306. printk(KERN_WARNING "SMB server not responding\n");
  307. result = -EIO;
  308. break;
  309. }
  310. }
  311. return result;
  312. }
  313. static int
  314. smb_send_raw(struct socket *socket, unsigned char *source, int length)
  315. {
  316. int result;
  317. int already_sent = 0;
  318. while (already_sent < length)
  319. {
  320. result = _send(socket,
  321. (void *) (source + already_sent),
  322. length - already_sent);
  323. if (result == 0)
  324. {
  325. return -EIO;
  326. }
  327. if (result < 0)
  328. {
  329. DEBUG1("smb_send_raw: sendto error = %d\n", -result);
  330. return result;
  331. }
  332. already_sent += result;
  333. }
  334. return already_sent;
  335. }
  336. static int
  337. smb_receive_raw(struct smb_sb_info *server, unsigned char *target, int length)
  338. {
  339. int result;
  340. int already_read = 0;
  341. struct socket *socket = server_sock(server);
  342. while (already_read < length)
  343. {
  344. result = smb_receive_poll(server);
  345. if (result < 0) {
  346. DEBUG1("poll error = %d\n", -result);
  347. return result;
  348. }
  349. result = _recvfrom(socket,
  350. (void *) (target + already_read),
  351. length - already_read, 0);
  352. if (result == 0)
  353. {
  354. return -EIO;
  355. }
  356. if (result < 0)
  357. {
  358. DEBUG1("recvfrom error = %d\n", -result);
  359. return result;
  360. }
  361. already_read += result;
  362. }
  363. return already_read;
  364. }
  365. static int
  366. smb_get_length(struct smb_sb_info *server, unsigned char *header)
  367. {
  368. int result;
  369. unsigned char peek_buf[4];
  370. mm_segment_t fs;
  371. re_recv:
  372. fs = get_fs();
  373. set_fs(get_ds());
  374. result = smb_receive_raw(server, peek_buf, 4);
  375. set_fs(fs);
  376. if (result < 0)
  377. {
  378. PARANOIA("recv error = %d\n", -result);
  379. return result;
  380. }
  381. switch (peek_buf[0])
  382. {
  383. case 0x00:
  384. case 0x82:
  385. break;
  386. case 0x85:
  387. DEBUG1("Got SESSION KEEP ALIVE\n");
  388. goto re_recv;
  389. default:
  390. PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]);
  391. return -EIO;
  392. }
  393. if (header != NULL)
  394. {
  395. memcpy(header, peek_buf, 4);
  396. }
  397. /* The length in the RFC NB header is the raw data length */
  398. return smb_len(peek_buf);
  399. }
  400. /*
  401. * Since we allocate memory in increments of PAGE_SIZE,
  402. * round up the packet length to the next multiple.
  403. */
  404. int
  405. smb_round_length(int len)
  406. {
  407. return (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
  408. }
  409. /*
  410. * smb_receive
  411. * fs points to the correct segment
  412. */
  413. static int
  414. smb_receive(struct smb_sb_info *server)
  415. {
  416. unsigned char * packet = server->packet;
  417. int len, result;
  418. unsigned char peek_buf[4];
  419. result = smb_get_length(server, peek_buf);
  420. if (result < 0)
  421. goto out;
  422. len = result;
  423. /*
  424. * Some servers do not respect our max_xmit and send
  425. * larger packets. Try to allocate a new packet,
  426. * but don't free the old one unless we succeed.
  427. */
  428. if (len + 4 > server->packet_size)
  429. {
  430. int new_len = smb_round_length(len + 4);
  431. result = -ENOMEM;
  432. packet = smb_vmalloc(new_len);
  433. if (packet == NULL)
  434. goto out;
  435. smb_vfree(server->packet);
  436. server->packet = packet;
  437. server->packet_size = new_len;
  438. }
  439. memcpy(packet, peek_buf, 4);
  440. result = smb_receive_raw(server, packet + 4, len);
  441. if (result < 0)
  442. {
  443. VERBOSE("receive error: %d\n", result);
  444. goto out;
  445. }
  446. server->rcls = *(packet + smb_rcls);
  447. server->err = WVAL(packet, smb_err);
  448. #ifdef SMBFS_DEBUG_VERBOSE
  449. if (server->rcls != 0)
  450. VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err);
  451. #endif
  452. out:
  453. return result;
  454. }
  455. /*
  456. * This routine checks first for "fast track" processing, as most
  457. * packets won't need to be copied. Otherwise, it allocates a new
  458. * packet to hold the incoming data.
  459. *
  460. * Note that the final server packet must be the larger of the two;
  461. * server packets aren't allowed to shrink.
  462. */
  463. static int
  464. smb_receive_trans2(struct smb_sb_info *server,
  465. int *ldata, unsigned char **data,
  466. int *lparm, unsigned char **parm)
  467. {
  468. unsigned char *inbuf, *base, *rcv_buf = NULL;
  469. unsigned int parm_disp, parm_offset, parm_count, parm_tot, parm_len = 0;
  470. unsigned int data_disp, data_offset, data_count, data_tot, data_len = 0;
  471. unsigned int total_p = 0, total_d = 0, buf_len = 0;
  472. int result;
  473. while (1) {
  474. result = smb_receive(server);
  475. if (result < 0)
  476. goto out;
  477. inbuf = server->packet;
  478. if (server->rcls != 0) {
  479. *parm = *data = inbuf;
  480. *ldata = *lparm = 0;
  481. goto out;
  482. }
  483. /*
  484. * Extract the control data from the packet.
  485. */
  486. data_tot = WVAL(inbuf, smb_tdrcnt);
  487. parm_tot = WVAL(inbuf, smb_tprcnt);
  488. parm_disp = WVAL(inbuf, smb_prdisp);
  489. parm_offset = WVAL(inbuf, smb_proff);
  490. parm_count = WVAL(inbuf, smb_prcnt);
  491. data_disp = WVAL(inbuf, smb_drdisp);
  492. data_offset = WVAL(inbuf, smb_droff);
  493. data_count = WVAL(inbuf, smb_drcnt);
  494. base = smb_base(inbuf);
  495. /*
  496. * Assume success and increment lengths.
  497. */
  498. parm_len += parm_count;
  499. data_len += data_count;
  500. if (!rcv_buf) {
  501. /*
  502. * Check for fast track processing ... just this packet.
  503. */
  504. if (parm_count == parm_tot && data_count == data_tot) {
  505. VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n",
  506. parm_disp, parm_offset, parm_count,
  507. data_disp, data_offset, data_count);
  508. *parm = base + parm_offset;
  509. if (*parm - inbuf + parm_tot > server->packet_size)
  510. goto out_bad_parm;
  511. *data = base + data_offset;
  512. if (*data - inbuf + data_tot > server->packet_size)
  513. goto out_bad_data;
  514. goto success;
  515. }
  516. /*
  517. * Save the total parameter and data length.
  518. */
  519. total_d = data_tot;
  520. total_p = parm_tot;
  521. buf_len = total_d + total_p;
  522. if (server->packet_size > buf_len)
  523. buf_len = server->packet_size;
  524. buf_len = smb_round_length(buf_len);
  525. if (buf_len > SMB_MAX_PACKET_SIZE)
  526. goto out_too_long;
  527. rcv_buf = smb_vmalloc(buf_len);
  528. if (!rcv_buf)
  529. goto out_no_mem;
  530. memset(rcv_buf, 0, buf_len);
  531. *parm = rcv_buf;
  532. *data = rcv_buf + total_p;
  533. } else if (data_tot > total_d || parm_tot > total_p)
  534. goto out_data_grew;
  535. if (parm_disp + parm_count > total_p)
  536. goto out_bad_parm;
  537. if (parm_offset + parm_count > server->packet_size)
  538. goto out_bad_parm;
  539. if (data_disp + data_count > total_d)
  540. goto out_bad_data;
  541. if (data_offset + data_count > server->packet_size)
  542. goto out_bad_data;
  543. memcpy(*parm + parm_disp, base + parm_offset, parm_count);
  544. memcpy(*data + data_disp, base + data_offset, data_count);
  545. PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
  546. parm_len, parm_tot, data_len, data_tot);
  547. /*
  548. * Check whether we've received all of the data. Note that
  549. * we use the packet totals -- total lengths might shrink!
  550. */
  551. if (data_len >= data_tot && parm_len >= parm_tot) {
  552. data_len = data_tot;
  553. parm_len = parm_tot;
  554. break;
  555. }
  556. }
  557. /*
  558. * Install the new packet. Note that it's possible, though
  559. * unlikely, that the new packet could be smaller than the
  560. * old one, in which case we just copy the data.
  561. */
  562. inbuf = server->packet;
  563. if (buf_len >= server->packet_size) {
  564. server->packet_size = buf_len;
  565. server->packet = rcv_buf;
  566. rcv_buf = inbuf;
  567. } else {
  568. if (parm_len + data_len > buf_len)
  569. goto out_data_grew;
  570. PARANOIA("copying data, old size=%d, new size=%u\n",
  571. server->packet_size, buf_len);
  572. memcpy(inbuf, rcv_buf, parm_len + data_len);
  573. }
  574. success:
  575. *ldata = data_len;
  576. *lparm = parm_len;
  577. out:
  578. if (rcv_buf)
  579. smb_vfree(rcv_buf);
  580. return result;
  581. out_no_mem:
  582. PARANOIA("couldn't allocate data area\n");
  583. result = -ENOMEM;
  584. goto out;
  585. out_too_long:
  586. printk(KERN_ERR "smb_receive_trans2: data/param too long, data=%d, parm=%d\n",
  587. data_tot, parm_tot);
  588. goto out_error;
  589. out_data_grew:
  590. printk(KERN_ERR "smb_receive_trans2: data/params grew!\n");
  591. goto out_error;
  592. out_bad_parm:
  593. printk(KERN_ERR "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
  594. parm_disp, parm_count, parm_tot);
  595. goto out_error;
  596. out_bad_data:
  597. printk(KERN_ERR "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
  598. data_disp, data_count, data_tot);
  599. out_error:
  600. result = -EIO;
  601. goto out;
  602. }
  603. /*
  604. * Called with the server locked
  605. */
  606. int
  607. smb_request(struct smb_sb_info *server)
  608. {
  609. unsigned long flags, sigpipe;
  610. mm_segment_t fs;
  611. sigset_t old_set;
  612. int len, result;
  613. unsigned char *buffer;
  614. result = -EBADF;
  615. buffer = server->packet;
  616. if (!buffer)
  617. goto bad_no_packet;
  618. result = -EIO;
  619. if (server->state != CONN_VALID)
  620. goto bad_no_conn;
  621. if ((result = smb_dont_catch_keepalive(server)) != 0)
  622. goto bad_conn;
  623. len = smb_len(buffer) + 4;
  624. DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
  625. spin_lock_irqsave(&current->sigmask_lock, flags);
  626. sigpipe = sigismember(&current->pending.signal, SIGPIPE);
  627. old_set = current->blocked;
  628. siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
  629. recalc_sigpending(current);
  630. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  631. fs = get_fs();
  632. set_fs(get_ds());
  633. result = smb_send_raw(server_sock(server), (void *) buffer, len);
  634. if (result > 0)
  635. {
  636. result = smb_receive(server);
  637. }
  638. /* read/write errors are handled by errno */
  639. spin_lock_irqsave(&current->sigmask_lock, flags);
  640. if (result == -EPIPE && !sigpipe)
  641. sigdelset(&current->pending.signal, SIGPIPE);
  642. current->blocked = old_set;
  643. recalc_sigpending(current);
  644. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  645. set_fs(fs);
  646. if (result >= 0)
  647. {
  648. int result2 = smb_catch_keepalive(server);
  649. if (result2 < 0)
  650. {
  651. printk(KERN_ERR "smb_request: catch keepalive failed\n");
  652. result = result2;
  653. }
  654. }
  655. if (result < 0)
  656. goto bad_conn;
  657. /*
  658. * Check for fatal server errors ...
  659. */
  660. if (server->rcls) {
  661. int error = smb_errno(server);
  662. if (error == -EBADSLT) {
  663. printk(KERN_ERR "smb_request: tree ID invalid\n");
  664. result = error;
  665. goto bad_conn;
  666. }
  667. }
  668. out:
  669. DEBUG1("result = %d\n", result);
  670. return result;
  671. bad_conn:
  672. PARANOIA("result %d, setting invalid\n", result);
  673. server->state = CONN_INVALID;
  674. smb_invalidate_inodes(server);
  675. goto out;
  676. bad_no_packet:
  677. printk(KERN_ERR "smb_request: no packet!\n");
  678. goto out;
  679. bad_no_conn:
  680. printk(KERN_ERR "smb_request: connection %d not valid!\n",
  681. server->state);
  682. goto out;
  683. }
  684. #define ROUND_UP(x) (((x)+3) & ~3)
  685. static int
  686. smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command,
  687. int ldata, unsigned char *data,
  688. int lparam, unsigned char *param)
  689. {
  690. struct socket *sock = server_sock(server);
  691. struct scm_cookie scm;
  692. int err;
  693. int mparam, mdata;
  694. /* I know the following is very ugly, but I want to build the
  695. smb packet as efficiently as possible. */
  696. const int smb_parameters = 15;
  697. const int oparam =
  698. ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3);
  699. const int odata =
  700. ROUND_UP(oparam + lparam);
  701. const int bcc =
  702. odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2);
  703. const int packet_length =
  704. SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2;
  705. unsigned char padding[4] =
  706. {0,};
  707. char *p;
  708. struct iovec iov[4];
  709. struct msghdr msg;
  710. /* FIXME! this test needs to include SMB overhead too, I think ... */
  711. if ((bcc + oparam) > server->opt.max_xmit)
  712. return -ENOMEM;
  713. p = smb_setup_header(server, SMBtrans2, smb_parameters, bcc);
  714. /*
  715. * max parameters + max data + max setup == max_xmit to make NT4 happy
  716. * and not abort the transfer or split into multiple responses.
  717. *
  718. * -100 is to make room for headers, which OS/2 seems to include in the
  719. * size calculation while NT4 does not?
  720. */
  721. mparam = SMB_TRANS2_MAX_PARAM;
  722. mdata = server->opt.max_xmit - mparam - 100;
  723. if (mdata < 1024) {
  724. mdata = 1024;
  725. mparam = 20;
  726. }
  727. WSET(server->packet, smb_tpscnt, lparam);
  728. WSET(server->packet, smb_tdscnt, ldata);
  729. WSET(server->packet, smb_mprcnt, mparam);
  730. WSET(server->packet, smb_mdrcnt, mdata);
  731. WSET(server->packet, smb_msrcnt, 0); /* max setup always 0 ? */
  732. WSET(server->packet, smb_flags, 0);
  733. DSET(server->packet, smb_timeout, 0);
  734. WSET(server->packet, smb_pscnt, lparam);
  735. WSET(server->packet, smb_psoff, oparam - 4);
  736. WSET(server->packet, smb_dscnt, ldata);
  737. WSET(server->packet, smb_dsoff, odata - 4);
  738. WSET(server->packet, smb_suwcnt, 1);
  739. WSET(server->packet, smb_setup0, trans2_command);
  740. *p++ = 0; /* null smb_name for trans2 */
  741. *p++ = 'D'; /* this was added because OS/2 does it */
  742. *p++ = ' ';
  743. msg.msg_name = NULL;
  744. msg.msg_namelen = 0;
  745. msg.msg_control = NULL;
  746. msg.msg_controllen = 0;
  747. msg.msg_iov = iov;
  748. msg.msg_iovlen = 4;
  749. msg.msg_flags = 0;
  750. iov[0].iov_base = (void *) server->packet;
  751. iov[0].iov_len = oparam;
  752. iov[1].iov_base = (param == NULL) ? padding : param;
  753. iov[1].iov_len = lparam;
  754. iov[2].iov_base = padding;
  755. iov[2].iov_len = odata - oparam - lparam;
  756. iov[3].iov_base = (data == NULL) ? padding : data;
  757. iov[3].iov_len = ldata;
  758. err = scm_send(sock, &msg, &scm);
  759. if (err >= 0) {
  760. err = sock->ops->sendmsg(sock, &msg, packet_length, &scm);
  761. scm_destroy(&scm);
  762. }
  763. return err;
  764. }
  765. /*
  766. * This is not really a trans2 request, we assume that you only have
  767. * one packet to send.
  768. */
  769. int
  770. smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
  771. int ldata, unsigned char *data,
  772. int lparam, unsigned char *param,
  773. int *lrdata, unsigned char **rdata,
  774. int *lrparam, unsigned char **rparam)
  775. {
  776. sigset_t old_set;
  777. unsigned long flags, sigpipe;
  778. mm_segment_t fs;
  779. int result;
  780. DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
  781. /*
  782. * These are initialized in smb_request_ok, but not here??
  783. */
  784. server->rcls = 0;
  785. server->err = 0;
  786. result = -EIO;
  787. if (server->state != CONN_VALID)
  788. goto out;
  789. if ((result = smb_dont_catch_keepalive(server)) != 0)
  790. goto bad_conn;
  791. spin_lock_irqsave(&current->sigmask_lock, flags);
  792. sigpipe = sigismember(&current->pending.signal, SIGPIPE);
  793. old_set = current->blocked;
  794. siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
  795. recalc_sigpending(current);
  796. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  797. fs = get_fs();
  798. set_fs(get_ds());
  799. result = smb_send_trans2(server, trans2_command,
  800. ldata, data, lparam, param);
  801. if (result >= 0)
  802. {
  803. result = smb_receive_trans2(server,
  804. lrdata, rdata, lrparam, rparam);
  805. }
  806. /* read/write errors are handled by errno */
  807. spin_lock_irqsave(&current->sigmask_lock, flags);
  808. if (result == -EPIPE && !sigpipe)
  809. sigdelset(&current->pending.signal, SIGPIPE);
  810. current->blocked = old_set;
  811. recalc_sigpending(current);
  812. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  813. set_fs(fs);
  814. if (result >= 0)
  815. {
  816. int result2 = smb_catch_keepalive(server);
  817. if (result2 < 0)
  818. {
  819. result = result2;
  820. }
  821. }
  822. if (result < 0)
  823. goto bad_conn;
  824. /*
  825. * Check for fatal server errors ...
  826. */
  827. if (server->rcls) {
  828. int error = smb_errno(server);
  829. if (error == -EBADSLT) {
  830. printk(KERN_ERR "smb_request: tree ID invalid\n");
  831. result = error;
  832. goto bad_conn;
  833. }
  834. }
  835. out:
  836. return result;
  837. bad_conn:
  838. PARANOIA("result=%d, setting invalid\n", result);
  839. server->state = CONN_INVALID;
  840. smb_invalidate_inodes(server);
  841. goto out;
  842. }