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