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