sock.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:20k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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