more changes on original files
[linux-2.4.git] / 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                                 if (*parm - inbuf + parm_tot > server->packet_size)
575                                         goto out_bad_parm;
576                                 *data  = base + data_offset;
577                                 if (*data - inbuf + data_tot > server->packet_size)
578                                         goto out_bad_data;
579                                 goto success;
580                         }
581
582                         /*
583                          * Save the total parameter and data length.
584                          */
585                         total_d = data_tot;
586                         total_p = parm_tot;
587
588                         buf_len = total_d + total_p;
589                         if (server->packet_size > buf_len)
590                                 buf_len = server->packet_size;
591                         buf_len = smb_round_length(buf_len);
592                         if (buf_len > SMB_MAX_PACKET_SIZE)
593                                 goto out_too_long;
594
595                         rcv_buf = smb_vmalloc(buf_len);
596                         if (!rcv_buf)
597                                 goto out_no_mem;
598                         memset(rcv_buf, 0, buf_len);
599                         
600                         *parm = rcv_buf;
601                         *data = rcv_buf + total_p;
602                 } else if (data_tot > total_d || parm_tot > total_p)
603                         goto out_data_grew;
604
605                 if (parm_disp + parm_count > total_p)
606                         goto out_bad_parm;
607                 if (parm_offset + parm_count > server->packet_size)     
608                         goto out_bad_parm;
609                 if (data_disp + data_count > total_d)
610                         goto out_bad_data;
611                 if (data_offset + data_count > server->packet_size)     
612                         goto out_bad_data;
613                 memcpy(*parm + parm_disp, base + parm_offset, parm_count);
614                 memcpy(*data + data_disp, base + data_offset, data_count);
615
616                 PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
617                          parm_len, parm_tot, data_len, data_tot);
618
619                 /*
620                  * Check whether we've received all of the data. Note that
621                  * we use the packet totals -- total lengths might shrink!
622                  */
623                 if (data_len >= data_tot && parm_len >= parm_tot) {
624                         data_len = data_tot;
625                         parm_len = parm_tot;
626                         break;
627                 }
628         }
629
630         /*
631          * Install the new packet.  Note that it's possible, though
632          * unlikely, that the new packet could be smaller than the
633          * old one, in which case we just copy the data.
634          */
635         inbuf = server->packet;
636         if (buf_len >= server->packet_size) {
637                 server->packet_size = buf_len;
638                 server->packet = rcv_buf;
639                 rcv_buf = inbuf;
640         } else {
641                 if (parm_len + data_len > buf_len)
642                         goto out_data_grew;
643
644                 PARANOIA("copying data, old size=%d, new size=%u\n",
645                          server->packet_size, buf_len);
646                 memcpy(inbuf, rcv_buf, parm_len + data_len);
647         }
648
649 success:
650         *ldata = data_len;
651         *lparm = parm_len;
652 out:
653         if (rcv_buf)
654                 smb_vfree(rcv_buf);
655         return result;
656
657 out_no_mem:
658         PARANOIA("couldn't allocate data area\n");
659         result = -ENOMEM;
660         goto out;
661 out_too_long:
662         printk(KERN_ERR "smb_receive_trans2: data/param too long, data=%d, parm=%d\n",
663                 data_tot, parm_tot);
664         goto out_error;
665 out_data_grew:
666         printk(KERN_ERR "smb_receive_trans2: data/params grew!\n");
667         goto out_error;
668 out_bad_parm:
669         printk(KERN_ERR "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
670                 parm_disp, parm_count, parm_tot);
671         goto out_error;
672 out_bad_data:
673         printk(KERN_ERR "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
674                 data_disp, data_count, data_tot);
675 out_error:
676         result = -EIO;
677         goto out;
678 }
679
680 /*
681  * Called with the server locked
682  */
683 int
684 smb_request(struct smb_sb_info *server)
685 {
686         unsigned long flags, sigpipe;
687         mm_segment_t fs;
688         sigset_t old_set;
689         int len, result;
690         unsigned char *buffer;
691
692         result = -EBADF;
693         buffer = server->packet;
694         if (!buffer)
695                 goto bad_no_packet;
696
697         result = -EIO;
698         if (server->state != CONN_VALID)
699                 goto bad_no_conn;
700
701         if ((result = smb_dont_catch_keepalive(server)) != 0)
702                 goto bad_conn;
703
704         len = smb_len(buffer) + 4;
705         DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
706
707         spin_lock_irqsave(&current->sigmask_lock, flags);
708         sigpipe = sigismember(&current->pending.signal, SIGPIPE);
709         old_set = current->blocked;
710         siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
711         recalc_sigpending(current);
712         spin_unlock_irqrestore(&current->sigmask_lock, flags);
713
714         fs = get_fs();
715         set_fs(get_ds());
716
717         result = smb_send_raw(server_sock(server), (void *) buffer, len);
718         if (result > 0)
719         {
720                 result = smb_receive(server);
721         }
722
723         /* read/write errors are handled by errno */
724         spin_lock_irqsave(&current->sigmask_lock, flags);
725         if (result == -EPIPE && !sigpipe)
726                 sigdelset(&current->pending.signal, SIGPIPE);
727         current->blocked = old_set;
728         recalc_sigpending(current);
729         spin_unlock_irqrestore(&current->sigmask_lock, flags);
730
731         set_fs(fs);
732
733         if (result >= 0)
734         {
735                 int result2 = smb_catch_keepalive(server);
736                 if (result2 < 0)
737                 {
738                         printk(KERN_ERR "smb_request: catch keepalive failed\n");
739                         result = result2;
740                 }
741         }
742         if (result < 0)
743                 goto bad_conn;
744         /*
745          * Check for fatal server errors ...
746          */
747         if (server->rcls) {
748                 int error = smb_errno(server);
749                 if (error == -EBADSLT) {
750                         printk(KERN_ERR "smb_request: tree ID invalid\n");
751                         result = error;
752                         goto bad_conn;
753                 }
754         }
755
756 out:
757         DEBUG1("result = %d\n", result);
758         return result;
759         
760 bad_conn:
761         PARANOIA("result %d, setting invalid\n", result);
762         server->state = CONN_INVALID;
763         smb_invalidate_inodes(server);
764         goto out;               
765 bad_no_packet:
766         printk(KERN_ERR "smb_request: no packet!\n");
767         goto out;
768 bad_no_conn:
769         printk(KERN_ERR "smb_request: connection %d not valid!\n",
770                server->state);
771         goto out;
772 }
773
774 #define ROUND_UP(x) (((x)+3) & ~3)
775 static int
776 smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command,
777                 int ldata, unsigned char *data,
778                 int lparam, unsigned char *param)
779 {
780         struct socket *sock = server_sock(server);
781         struct scm_cookie scm;
782         int err;
783         int mparam, mdata;
784
785         /* I know the following is very ugly, but I want to build the
786            smb packet as efficiently as possible. */
787
788         const int smb_parameters = 15;
789         const int oparam =
790                 ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3);
791         const int odata =
792                 ROUND_UP(oparam + lparam);
793         const int bcc =
794                 odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2);
795         const int packet_length =
796                 SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2;
797
798         unsigned char padding[4] =
799         {0,};
800         char *p;
801
802         struct iovec iov[4];
803         struct msghdr msg;
804
805         /* FIXME! this test needs to include SMB overhead too, I think ... */
806         if ((bcc + oparam) > server->opt.max_xmit)
807                 return -ENOMEM;
808         p = smb_setup_header(server, SMBtrans2, smb_parameters, bcc);
809
810         /*
811          * max parameters + max data + max setup == max_xmit to make NT4 happy
812          * and not abort the transfer or split into multiple responses.
813          *
814          * -100 is to make room for headers, which OS/2 seems to include in the
815          * size calculation while NT4 does not?
816          */
817         mparam = SMB_TRANS2_MAX_PARAM;
818         mdata = server->opt.max_xmit - mparam - 100;
819         if (mdata < 1024) {
820                 mdata = 1024;
821                 mparam = 20;
822         }
823
824         WSET(server->packet, smb_tpscnt, lparam);
825         WSET(server->packet, smb_tdscnt, ldata);
826         WSET(server->packet, smb_mprcnt, mparam);
827         WSET(server->packet, smb_mdrcnt, mdata);
828         WSET(server->packet, smb_msrcnt, 0);    /* max setup always 0 ? */
829         WSET(server->packet, smb_flags, 0);
830         DSET(server->packet, smb_timeout, 0);
831         WSET(server->packet, smb_pscnt, lparam);
832         WSET(server->packet, smb_psoff, oparam - 4);
833         WSET(server->packet, smb_dscnt, ldata);
834         WSET(server->packet, smb_dsoff, odata - 4);
835         WSET(server->packet, smb_suwcnt, 1);
836         WSET(server->packet, smb_setup0, trans2_command);
837         *p++ = 0;               /* null smb_name for trans2 */
838         *p++ = 'D';             /* this was added because OS/2 does it */
839         *p++ = ' ';
840
841
842         msg.msg_name = NULL;
843         msg.msg_namelen = 0;
844         msg.msg_control = NULL;
845         msg.msg_controllen = 0;
846         msg.msg_iov = iov;
847         msg.msg_iovlen = 4;
848         msg.msg_flags = 0;
849         
850         iov[0].iov_base = (void *) server->packet;
851         iov[0].iov_len = oparam;
852         iov[1].iov_base = (param == NULL) ? padding : param;
853         iov[1].iov_len = lparam;
854         iov[2].iov_base = padding;
855         iov[2].iov_len = odata - oparam - lparam;
856         iov[3].iov_base = (data == NULL) ? padding : data;
857         iov[3].iov_len = ldata;
858
859         err = scm_send(sock, &msg, &scm);
860         if (err >= 0) {
861                 err = sock->ops->sendmsg(sock, &msg, packet_length, &scm);
862                 scm_destroy(&scm);
863         }
864         return err;
865 }
866
867 /*
868  * This is not really a trans2 request, we assume that you only have
869  * one packet to send.
870  */
871 int
872 smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
873                    int ldata, unsigned char *data,
874                    int lparam, unsigned char *param,
875                    int *lrdata, unsigned char **rdata,
876                    int *lrparam, unsigned char **rparam)
877 {
878         sigset_t old_set;
879         unsigned long flags, sigpipe;
880         mm_segment_t fs;
881         int result;
882
883         DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
884
885         /*
886          * These are initialized in smb_request_ok, but not here??
887          */
888         server->rcls = 0;
889         server->err = 0;
890
891         result = -EIO;
892         if (server->state != CONN_VALID)
893                 goto out;
894
895         if ((result = smb_dont_catch_keepalive(server)) != 0)
896                 goto bad_conn;
897
898         spin_lock_irqsave(&current->sigmask_lock, flags);
899         sigpipe = sigismember(&current->pending.signal, SIGPIPE);
900         old_set = current->blocked;
901         siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
902         recalc_sigpending(current);
903         spin_unlock_irqrestore(&current->sigmask_lock, flags);
904
905         fs = get_fs();
906         set_fs(get_ds());
907
908         result = smb_send_trans2(server, trans2_command,
909                                  ldata, data, lparam, param);
910         if (result >= 0)
911         {
912                 result = smb_receive_trans2(server,
913                                             lrdata, rdata, lrparam, rparam);
914         }
915
916         /* read/write errors are handled by errno */
917         spin_lock_irqsave(&current->sigmask_lock, flags);
918         if (result == -EPIPE && !sigpipe)
919                 sigdelset(&current->pending.signal, SIGPIPE);
920         current->blocked = old_set;
921         recalc_sigpending(current);
922         spin_unlock_irqrestore(&current->sigmask_lock, flags);
923
924         set_fs(fs);
925
926         if (result >= 0)
927         {
928                 int result2 = smb_catch_keepalive(server);
929                 if (result2 < 0)
930                 {
931                         result = result2;
932                 }
933         }
934         if (result < 0)
935                 goto bad_conn;
936         /*
937          * Check for fatal server errors ...
938          */
939         if (server->rcls) {
940                 int error = smb_errno(server);
941                 if (error == -EBADSLT) {
942                         printk(KERN_ERR "smb_request: tree ID invalid\n");
943                         result = error;
944                         goto bad_conn;
945                 }
946         }
947
948 out:
949         return result;
950
951 bad_conn:
952         PARANOIA("result=%d, setting invalid\n", result);
953         server->state = CONN_INVALID;
954         smb_invalidate_inodes(server);
955         goto out;
956 }