make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / fs / smbfs / proc.c
1 /*
2  *  proc.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/types.h>
11 #include <linux/errno.h>
12 #include <linux/slab.h>
13 #include <linux/fs.h>
14 #include <linux/file.h>
15 #include <linux/stat.h>
16 #include <linux/fcntl.h>
17 #include <linux/dcache.h>
18 #include <linux/dirent.h>
19 #include <linux/nls.h>
20
21 #include <linux/smb_fs.h>
22 #include <linux/smbno.h>
23 #include <linux/smb_mount.h>
24
25 #include <asm/string.h>
26 #include <asm/div64.h>
27
28 #include "smb_debug.h"
29 #include "proto.h"
30
31
32 /* Features. Undefine if they cause problems, this should perhaps be a
33    config option. */
34 #define SMBFS_POSIX_UNLINK 1
35
36 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
37 #define SMB_CMD(packet)  (*(packet+8))
38 #define SMB_WCT(packet)  (*(packet+SMB_HEADER_LEN - 1))
39 #define SMB_BCC(packet)  smb_bcc(packet)
40 #define SMB_BUF(packet)  ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
41
42 #define SMB_DIRINFO_SIZE 43
43 #define SMB_STATUS_SIZE  21
44
45 #define SMB_ST_BLKSIZE  (PAGE_SIZE)
46 #define SMB_ST_BLKSHIFT (PAGE_SHIFT)
47
48 static int
49 smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
50                      struct smb_fattr *);
51 static int
52 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
53                       __u16 attr);
54 static int
55 smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir,
56                     struct smb_fattr *fattr);
57
58
59
60 static void
61 str_upper(char *name, int len)
62 {
63         while (len--)
64         {
65                 if (*name >= 'a' && *name <= 'z')
66                         *name -= ('a' - 'A');
67                 name++;
68         }
69 }
70
71 #if 0
72 static void
73 str_lower(char *name, int len)
74 {
75         while (len--)
76         {
77                 if (*name >= 'A' && *name <= 'Z')
78                         *name += ('a' - 'A');
79                 name++;
80         }
81 }
82 #endif
83
84 /* reverse a string inline. This is used by the dircache walking routines */
85 static void reverse_string(char *buf, int len)
86 {
87         char c;
88         char *end = buf+len-1;
89
90         while(buf < end) {
91                 c = *buf;
92                 *(buf++) = *end;
93                 *(end--) = c;
94         }
95 }
96
97 /* no conversion, just a wrapper for memcpy. */
98 static int convert_memcpy(char *output, int olen,
99                           const char *input, int ilen,
100                           struct nls_table *nls_from,
101                           struct nls_table *nls_to)
102 {
103         if (olen < ilen)
104                 return -ENAMETOOLONG;
105         memcpy(output, input, ilen);
106         return ilen;
107 }
108
109 static inline int write_char(unsigned char ch, char *output, int olen)
110 {
111         if (olen < 4)
112                 return -ENAMETOOLONG;
113         sprintf(output, ":x%02x", ch);
114         return 4;
115 }
116
117 static inline int write_unichar(wchar_t ch, char *output, int olen)
118 {
119         if (olen < 5)
120                 return -ENAMETOOLONG;
121         sprintf(output, ":%04x", ch);
122         return 5;
123 }
124
125 /* convert from one "codepage" to another (possibly being utf8). */
126 static int convert_cp(char *output, int olen,
127                       const char *input, int ilen,
128                       struct nls_table *nls_from,
129                       struct nls_table *nls_to)
130 {
131         int len = 0;
132         int n;
133         wchar_t ch;
134
135         while (ilen > 0) {
136                 /* convert by changing to unicode and back to the new cp */
137                 n = nls_from->char2uni((unsigned char *)input, ilen, &ch);
138                 if (n == -EINVAL) {
139                         ilen--;
140                         n = write_char(*input++, output, olen);
141                         if (n < 0)
142                                 goto fail;
143                         output += n;
144                         olen -= n;
145                         len += n;
146                         continue;
147                 } else if (n < 0)
148                         goto fail;
149                 input += n;
150                 ilen -= n;
151
152                 n = nls_to->uni2char(ch, output, olen);
153                 if (n == -EINVAL)
154                         n = write_unichar(ch, output, olen);
155                 if (n < 0)
156                         goto fail;
157                 output += n;
158                 olen -= n;
159
160                 len += n;
161         }
162         return len;
163 fail:
164         return n;
165 }
166
167 static int setcodepage(struct nls_table **p, char *name)
168 {
169         struct nls_table *nls;
170
171         if (!name || !*name) {
172                 nls = NULL;
173         } else if ( (nls = load_nls(name)) == NULL) {
174                 printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name);
175                 return -EINVAL;
176         }
177
178         /* if already set, unload the previous one. */
179         if (*p)
180                 unload_nls(*p);
181         *p = nls;
182
183         return 0;
184 }
185
186 /* Handles all changes to codepage settings. */
187 int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
188 {
189         int n = 0;
190
191         smb_lock_server(server);
192
193         /* Don't load any nls_* at all, if no remote is requested */
194         if (!*cp->remote_name)
195                 goto out;
196
197         n = setcodepage(&server->local_nls, cp->local_name);
198         if (n != 0)
199                 goto out;
200         n = setcodepage(&server->remote_nls, cp->remote_name);
201         if (n != 0)
202                 setcodepage(&server->local_nls, NULL);
203
204 out:
205         if (server->local_nls != NULL && server->remote_nls != NULL)
206                 server->convert = convert_cp;
207         else
208                 server->convert = convert_memcpy;
209
210         smb_unlock_server(server);
211         return n;
212 }
213
214
215 /*****************************************************************************/
216 /*                                                                           */
217 /*  Encoding/Decoding section                                                */
218 /*                                                                           */
219 /*****************************************************************************/
220
221 static __u8 *
222 smb_encode_smb_length(__u8 * p, __u32 len)
223 {
224         *p = 0;
225         *(p+1) = 0;
226         *(p+2) = (len & 0xFF00) >> 8;
227         *(p+3) = (len & 0xFF);
228         if (len > 0xFFFF)
229         {
230                 *(p+1) = 1;
231         }
232         return p + 4;
233 }
234
235 /*
236  * smb_build_path: build the path to entry and name storing it in buf.
237  * The path returned will have the trailing '\0'.
238  */
239 static int smb_build_path(struct smb_sb_info *server, char * buf, int maxlen,
240                           struct dentry * entry, struct qstr * name)
241 {
242         char *path = buf;
243         int len;
244
245         if (maxlen < 2)
246                 return -ENAMETOOLONG;
247
248         if (maxlen > SMB_MAXPATHLEN + 1)
249                 maxlen = SMB_MAXPATHLEN + 1;
250
251         if (entry == NULL)
252                 goto test_name_and_out;
253
254         /*
255          * If IS_ROOT, we have to do no walking at all.
256          */
257         if (IS_ROOT(entry) && !name) {
258                 *path++ = '\\';
259                 *path++ = '\0';
260                 return 2;
261         }
262
263         /*
264          * Build the path string walking the tree backward from end to ROOT
265          * and store it in reversed order [see reverse_string()]
266          */
267         while (!IS_ROOT(entry)) {
268                 if (maxlen < 3)
269                         return -ENAMETOOLONG;
270
271                 len = server->convert(path, maxlen-2, 
272                                       entry->d_name.name, entry->d_name.len,
273                                       server->local_nls, server->remote_nls);
274                 if (len < 0)
275                         return len;
276                 reverse_string(path, len);
277                 path += len;
278                 *path++ = '\\';
279                 maxlen -= len+1;
280
281                 entry = entry->d_parent;
282                 if (IS_ROOT(entry))
283                         break;
284         }
285         reverse_string(buf, path-buf);
286
287         /* maxlen is at least 1 */
288 test_name_and_out:
289         if (name) {
290                 if (maxlen < 3)
291                         return -ENAMETOOLONG;
292                 *path++ = '\\';
293                 len = server->convert(path, maxlen-2, 
294                                       name->name, name->len,
295                                       server->local_nls, server->remote_nls);
296                 if (len < 0)
297                         return len;
298                 path += len;
299                 maxlen -= len+1;
300         }
301         /* maxlen is at least 1 */
302         *path++ = '\0';
303         return path-buf;
304 }
305
306 static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen,
307                            struct dentry *dir, struct qstr *name)
308 {
309         int result;
310
311         result = smb_build_path(server, buf, maxlen, dir, name);
312         if (result < 0)
313                 goto out;
314         if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
315                 str_upper(buf, result);
316 out:
317         return result;
318 }
319
320 static int smb_simple_encode_path(struct smb_sb_info *server, char **p,
321                           struct dentry * entry, struct qstr * name)
322 {
323         char *s = *p;
324         int res;
325         int maxlen = ((char *)server->packet + server->packet_size) - s;
326
327         if (!maxlen)
328                 return -ENAMETOOLONG;
329         *s++ = 4;
330         res = smb_encode_path(server, s, maxlen-1, entry, name);
331         if (res < 0)
332                 return res;
333         *p = s + res;
334         return 0;
335 }
336
337 /* The following are taken directly from msdos-fs */
338
339 /* Linear day numbers of the respective 1sts in non-leap years. */
340
341 static int day_n[] =
342 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
343                   /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
344
345
346 static time_t
347 utc2local(struct smb_sb_info *server, time_t time)
348 {
349         return time - server->opt.serverzone*60;
350 }
351
352 static time_t
353 local2utc(struct smb_sb_info *server, time_t time)
354 {
355         return time + server->opt.serverzone*60;
356 }
357
358 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
359
360 static time_t
361 date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
362 {
363         int month, year;
364         time_t secs;
365
366         /* first subtract and mask after that... Otherwise, if
367            date == 0, bad things happen */
368         month = ((date >> 5) - 1) & 15;
369         year = date >> 9;
370         secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
371             ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
372                                                    month < 2 ? 1 : 0) + 3653);
373         /* days since 1.1.70 plus 80's leap day */
374         return local2utc(server, secs);
375 }
376
377
378 /* Convert linear UNIX date to a MS-DOS time/date pair. */
379
380 static void
381 date_unix2dos(struct smb_sb_info *server,
382               int unix_date, __u16 *date, __u16 *time)
383 {
384         int day, year, nl_day, month;
385
386         unix_date = utc2local(server, unix_date);
387         if (unix_date < 315532800)
388                 unix_date = 315532800;
389
390         *time = (unix_date % 60) / 2 +
391                 (((unix_date / 60) % 60) << 5) +
392                 (((unix_date / 3600) % 24) << 11);
393
394         day = unix_date / 86400 - 3652;
395         year = day / 365;
396         if ((year + 3) / 4 + 365 * year > day)
397                 year--;
398         day -= (year + 3) / 4 + 365 * year;
399         if (day == 59 && !(year & 3)) {
400                 nl_day = day;
401                 month = 2;
402         } else {
403                 nl_day = (year & 3) || day <= 59 ? day : day - 1;
404                 for (month = 0; month < 12; month++)
405                         if (day_n[month] > nl_day)
406                                 break;
407         }
408         *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
409 }
410
411 /* The following are taken from fs/ntfs/util.c */
412
413 #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
414
415 /*
416  * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
417  * into Unix UTC (based 1970-01-01, in seconds).
418  */
419 static time_t
420 smb_ntutc2unixutc(u64 ntutc)
421 {
422         /* FIXME: what about the timezone difference? */
423         /* Subtract the NTFS time offset, then convert to 1s intervals. */
424         u64 t = ntutc - NTFS_TIME_OFFSET;
425         do_div(t, 10000000);
426         return (time_t)t;
427 }
428
429 #if 0
430 /* Convert the Unix UTC into NT time */
431 static u64
432 smb_unixutc2ntutc(struct smb_sb_info *server, time_t t)
433 {
434         /* Note: timezone conversion is probably wrong. */
435         return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET;
436 }
437 #endif
438
439
440 /*****************************************************************************/
441 /*                                                                           */
442 /*  Support section.                                                         */
443 /*                                                                           */
444 /*****************************************************************************/
445
446 __u32
447 smb_len(__u8 * p)
448 {
449         return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
450 }
451
452 static __u16
453 smb_bcc(__u8 * packet)
454 {
455         int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
456         return WVAL(packet, pos);
457 }
458
459 /* smb_valid_packet: We check if packet fulfills the basic
460    requirements of a smb packet */
461
462 static int
463 smb_valid_packet(__u8 * packet)
464 {
465         return (packet[4] == 0xff
466                 && packet[5] == 'S'
467                 && packet[6] == 'M'
468                 && packet[7] == 'B'
469                 && (smb_len(packet) + 4 == SMB_HEADER_LEN
470                     + SMB_WCT(packet) * 2 + SMB_BCC(packet)));
471 }
472
473 /* smb_verify: We check if we got the answer we expected, and if we
474    got enough data. If bcc == -1, we don't care. */
475
476 static int
477 smb_verify(__u8 * packet, int command, int wct, int bcc)
478 {
479         if (SMB_CMD(packet) != command)
480                 goto bad_command;
481         if (SMB_WCT(packet) < wct)
482                 goto bad_wct;
483         if (bcc != -1 && SMB_BCC(packet) < bcc)
484                 goto bad_bcc;
485         return 0;
486
487 bad_command:
488         printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
489                command, SMB_CMD(packet));
490         goto fail;
491 bad_wct:
492         printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
493                command, wct, SMB_WCT(packet));
494         goto fail;
495 bad_bcc:
496         printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
497                command, bcc, SMB_BCC(packet));
498 fail:
499         return -EIO;
500 }
501
502 /*
503  * Returns the maximum read or write size for the "payload". Making all of the
504  * packet fit within the negotiated max_xmit size.
505  *
506  * N.B. Since this value is usually computed before locking the server,
507  * the server's packet size must never be decreased!
508  */
509 static inline int
510 smb_get_xmitsize(struct smb_sb_info *server, int overhead)
511 {
512         return server->opt.max_xmit - overhead;
513 }
514
515 /*
516  * Calculate the maximum read size
517  */
518 int
519 smb_get_rsize(struct smb_sb_info *server)
520 {
521         int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
522         int size = smb_get_xmitsize(server, overhead);
523
524         VERBOSE("packet=%d, xmit=%d, size=%d\n",
525                 server->packet_size, server->opt.max_xmit, size);
526
527         return size;
528 }
529
530 /*
531  * Calculate the maximum write size
532  */
533 int
534 smb_get_wsize(struct smb_sb_info *server)
535 {
536         int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
537         int size = smb_get_xmitsize(server, overhead);
538
539         VERBOSE("packet=%d, xmit=%d, size=%d\n",
540                 server->packet_size, server->opt.max_xmit, size);
541
542         return size;
543 }
544
545 /*
546  * Convert SMB error codes to -E... errno values.
547  */
548 int
549 smb_errno(struct smb_sb_info *server)
550 {
551         int errcls = server->rcls;
552         int error  = server->err;
553         char *class = "Unknown";
554
555         VERBOSE("errcls %d  code %d  from command 0x%x\n",
556                 errcls, error, SMB_CMD(server->packet));
557
558         if (errcls == ERRDOS) {
559                 switch (error) {
560                 case ERRbadfunc:
561                         return -EINVAL;
562                 case ERRbadfile:
563                 case ERRbadpath:
564                         return -ENOENT;
565                 case ERRnofids:
566                         return -EMFILE;
567                 case ERRnoaccess:
568                         return -EACCES;
569                 case ERRbadfid:
570                         return -EBADF;
571                 case ERRbadmcb:
572                         return -EREMOTEIO;
573                 case ERRnomem:
574                         return -ENOMEM;
575                 case ERRbadmem:
576                         return -EFAULT;
577                 case ERRbadenv:
578                 case ERRbadformat:
579                         return -EREMOTEIO;
580                 case ERRbadaccess:
581                         return -EACCES;
582                 case ERRbaddata:
583                         return -E2BIG;
584                 case ERRbaddrive:
585                         return -ENXIO;
586                 case ERRremcd:
587                         return -EREMOTEIO;
588                 case ERRdiffdevice:
589                         return -EXDEV;
590                 case ERRnofiles:
591                         return -ENOENT;
592                 case ERRbadshare:
593                         return -ETXTBSY;
594                 case ERRlock:
595                         return -EDEADLK;
596                 case ERRfilexists:
597                         return -EEXIST;
598                 case ERROR_INVALID_PARAMETER:
599                         return -EINVAL;
600                 case ERROR_DISK_FULL:
601                         return -ENOSPC;
602                 case ERROR_INVALID_NAME:
603                         return -ENOENT;
604                 case ERROR_DIR_NOT_EMPTY:
605                         return -ENOTEMPTY;
606                 case ERROR_NOT_LOCKED:
607                        return -ENOLCK;
608                 case ERROR_ALREADY_EXISTS:
609                         return -EEXIST;
610                 default:
611                         class = "ERRDOS";
612                         goto err_unknown;
613                 }
614         } else if (errcls == ERRSRV) {
615                 switch (error) {
616                 /* N.B. This is wrong ... EIO ? */
617                 case ERRerror:
618                         return -ENFILE;
619                 case ERRbadpw:
620                         return -EINVAL;
621                 case ERRbadtype:
622                         return -EIO;
623                 case ERRaccess:
624                         return -EACCES;
625                 /*
626                  * This is a fatal error, as it means the "tree ID"
627                  * for this connection is no longer valid. We map
628                  * to a special error code and get a new connection.
629                  */
630                 case ERRinvnid:
631                         return -EBADSLT;
632                 default:
633                         class = "ERRSRV";
634                         goto err_unknown;
635                 }
636         } else if (errcls == ERRHRD) {
637                 switch (error) {
638                 case ERRnowrite:
639                         return -EROFS;
640                 case ERRbadunit:
641                         return -ENODEV;
642                 case ERRnotready:
643                         return -EUCLEAN;
644                 case ERRbadcmd:
645                 case ERRdata:
646                         return -EIO;
647                 case ERRbadreq:
648                         return -ERANGE;
649                 case ERRbadshare:
650                         return -ETXTBSY;
651                 case ERRlock:
652                         return -EDEADLK;
653                 case ERRdiskfull:
654                         return -ENOSPC;
655                 default:
656                         class = "ERRHRD";
657                         goto err_unknown;
658                 }
659         } else if (errcls == ERRCMD) {
660                 class = "ERRCMD";
661         } else if (errcls == SUCCESS) {
662                 return 0;       /* This is the only valid 0 return */
663         }
664
665 err_unknown:
666         printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
667                class, error, SMB_CMD(server->packet));
668         return -EIO;
669 }
670
671 /*
672  * smb_retry: This function should be called when smb_request_ok has
673  * indicated an error. If the error was indicated because the
674  * connection was killed, we try to reconnect. If smb_retry returns 0,
675  * the error was indicated for another reason, so a retry would not be
676  * of any use.
677  * N.B. The server must be locked for this call.
678  */
679 static int
680 smb_retry(struct smb_sb_info *server)
681 {
682         pid_t pid = server->conn_pid;
683         int error, result = 0;
684
685         if (server->state == CONN_VALID || server->state == CONN_RETRYING)
686                 goto out;
687
688         smb_close_socket(server);
689
690         if (pid == 0) {
691                 printk(KERN_ERR "smb_retry: no connection process\n");
692                 server->state = CONN_RETRIED;
693                 goto out;
694         }
695
696         /*
697          * Change state so that only one retry per server will be started.
698          */
699         server->state = CONN_RETRYING;
700
701         /*
702          * Note: use the "priv" flag, as a user process may need to reconnect.
703          */
704         error = kill_proc(pid, SIGUSR1, 1);
705         if (error) {
706                 /* FIXME: this is fatal */
707                 printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
708                 goto out;
709         }
710         VERBOSE("signalled pid %d, waiting for new connection\n", pid);
711
712         /*
713          * Wait for the new connection.
714          */
715         smb_unlock_server(server);
716         interruptible_sleep_on_timeout(&server->wait, server->mnt->timeo*HZ);
717         smb_lock_server(server);
718         if (signal_pending(current))
719                 printk(KERN_INFO "smb_retry: caught signal\n");
720
721         /*
722          * Check for a valid connection.
723          */
724         if (server->state == CONN_VALID) {
725                 /* This should be changed to VERBOSE, except many smbfs
726                    problems is with the userspace daemon not reconnecting. */
727                 PARANOIA("successful, new pid=%d, generation=%d\n",
728                          server->conn_pid, server->generation);
729                 result = 1;
730         } else if (server->state == CONN_RETRYING) {
731                 /* allow further attempts later */
732                 server->state = CONN_RETRIED;
733         }
734
735 out:
736         return result;
737 }
738
739 /* smb_request_ok: We expect the server to be locked. Then we do the
740    request and check the answer completely. When smb_request_ok
741    returns 0, you can be quite sure that everything went well. When
742    the answer is <=0, the returned number is a valid unix errno. */
743
744 static int
745 smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc)
746 {
747         int result = -EIO;
748
749         s->rcls = 0;
750         s->err = 0;
751
752         /* Make sure we have a connection */
753         if (s->state != CONN_VALID) {
754                 if (!smb_retry(s))
755                         goto out;
756         }
757
758         if (smb_request(s) < 0) {
759                 DEBUG1("smb_request failed\n");
760                 goto out;
761         }
762         if (smb_valid_packet(s->packet) != 0) {
763                 PARANOIA("invalid packet!\n");
764                 goto out;
765         }
766
767         /*
768          * Check for server errors.
769          */
770         if (s->rcls != 0) {
771                 result = smb_errno(s);
772                 if (!result)
773                         printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n",
774                                 s->rcls, s->err);
775                 /*
776                  * Exit now even if the error was squashed ...
777                  * packet verify will fail anyway.
778                  */
779                 goto out;
780         }
781         result = smb_verify(s->packet, command, wct, bcc);
782
783 out:
784         return result;
785 }
786
787 /*
788  * This implements the NEWCONN ioctl. It installs the server pid,
789  * sets server->state to CONN_VALID, and wakes up the waiting process.
790  */
791 int
792 smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
793 {
794         struct file *filp;
795         int error;
796
797         VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
798
799         smb_lock_server(server);
800
801         /*
802          * Make sure we don't already have a valid connection ...
803          */
804         error = -EINVAL;
805         if (server->state == CONN_VALID)
806                 goto out;
807
808         error = -EACCES;
809         if (current->uid != server->mnt->mounted_uid && 
810             !capable(CAP_SYS_ADMIN))
811                 goto out;
812
813         error = -EBADF;
814         filp = fget(opt->fd);
815         if (!filp)
816                 goto out;
817         if (!smb_valid_socket(filp->f_dentry->d_inode))
818                 goto out_putf;
819
820         server->sock_file = filp;
821         server->conn_pid = current->pid;
822         smb_catch_keepalive(server);
823         server->opt = *opt;
824         server->generation += 1;
825         server->state = CONN_VALID;
826         error = 0;
827
828         /* check if we have an old smbmount that uses seconds for the 
829            serverzone */
830         if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
831                 server->opt.serverzone /= 60;
832
833         /* now that we have an established connection we can detect the server
834            type and enable bug workarounds */
835         if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
836             (server->opt.max_xmit < 0x1000) &&
837             !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
838                 server->mnt->flags |= SMB_MOUNT_WIN95;
839                 VERBOSE("smb_newconn: detected WIN95 server\n");
840         }
841
842         VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
843                 server->opt.protocol, server->opt.max_xmit, server->conn_pid,
844                 server->opt.capabilities);
845
846         /* Make sure we can fit a message of the negotiated size in our
847            packet buffer. */
848         if (server->opt.max_xmit > server->packet_size) {
849                 int len = smb_round_length(server->opt.max_xmit);
850                 char *buf = smb_vmalloc(len);
851                 if (buf) {
852                         if (server->packet)
853                                 smb_vfree(server->packet);
854                         server->packet = buf;
855                         server->packet_size = len;
856                 } else {
857                         /* else continue with the too small buffer? */
858                         PARANOIA("Failed to allocate new packet buffer: "
859                                  "max_xmit=%d, packet_size=%d\n",
860                                  server->opt.max_xmit, server->packet_size);
861                         server->opt.max_xmit = server->packet_size;
862                 }
863         }
864
865 out:
866         smb_unlock_server(server);
867         smb_wakeup(server);
868         return error;
869
870 out_putf:
871         fput(filp);
872         goto out;
873 }
874
875 int
876 smb_wakeup(struct smb_sb_info *server)
877 {
878         wake_up_interruptible(&server->wait);
879         return 0;
880 }
881
882 /* smb_setup_header: We completely set up the packet. You only have to
883    insert the command-specific fields */
884
885 __u8 *
886 smb_setup_header(struct smb_sb_info * server, __u8 command, __u16 wct, __u16 bcc)
887 {
888         __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
889         __u8 *p = server->packet;
890         __u8 *buf = server->packet;
891
892         if (xmit_len > server->packet_size)
893                 printk(KERN_DEBUG "smb_setup_header: "
894                        "Aieee, xmit len > packet! len=%d, size=%d\n",
895                        xmit_len, server->packet_size);
896
897         p = smb_encode_smb_length(p, xmit_len - 4);
898
899         *p++ = 0xff;
900         *p++ = 'S';
901         *p++ = 'M';
902         *p++ = 'B';
903         *p++ = command;
904
905         memset(p, '\0', 19);
906         p += 19;
907         p += 8;
908
909         WSET(buf, smb_tid, server->opt.tid);
910         WSET(buf, smb_pid, 1);
911         WSET(buf, smb_uid, server->opt.server_uid);
912         WSET(buf, smb_mid, 1);
913
914         if (server->opt.protocol > SMB_PROTOCOL_CORE)
915         {
916                 *(buf+smb_flg) = 0x8;
917                 WSET(buf, smb_flg2, 0x3);
918         }
919         *p++ = wct;             /* wct */
920         p += 2 * wct;
921         WSET(p, 0, bcc);
922         return p + 2;
923 }
924
925 static void
926 smb_setup_bcc(struct smb_sb_info *server, __u8 * p)
927 {
928         __u8 *packet = server->packet;
929         __u8 *pbcc = packet + SMB_HEADER_LEN + 2 * SMB_WCT(packet);
930         __u16 bcc = p - (pbcc + 2);
931
932         WSET(pbcc, 0, bcc);
933         smb_encode_smb_length(packet,
934                               SMB_HEADER_LEN + 2 * SMB_WCT(packet) - 2 + bcc);
935 }
936
937 /*
938  * Called with the server locked
939  */
940 static int
941 smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
942               __u16 mode, off_t offset)
943 {
944         int result;
945
946         smb_setup_header(server, SMBlseek, 4, 0);
947         WSET(server->packet, smb_vwv0, fileid);
948         WSET(server->packet, smb_vwv1, mode);
949         DSET(server->packet, smb_vwv2, offset);
950
951         result = smb_request_ok(server, SMBlseek, 2, 0);
952         if (result < 0) {
953                 result = 0;
954                 goto out;
955         }
956
957         result = DVAL(server->packet, smb_vwv0);
958 out:
959         return result;
960 }
961
962 /*
963  * We're called with the server locked, and we leave it that way.
964  */
965 static int
966 smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
967 {
968         struct inode *ino = dentry->d_inode;
969         int mode, read_write = 0x42, read_only = 0x40;
970         int res;
971         char *p;
972
973         /*
974          * Attempt to open r/w, unless there are no write privileges.
975          */
976         mode = read_write;
977         if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
978                 mode = read_only;
979 #if 0
980         /* FIXME: why is this code not in? below we fix it so that a caller
981            wanting RO doesn't get RW. smb_revalidate_inode does some 
982            optimization based on access mode. tail -f needs it to be correct.
983
984            We must open rw since we don't do the open if called a second time
985            with different 'wish'. Is that not supported by smb servers? */
986         if (!(wish & (O_WRONLY | O_RDWR)))
987                 mode = read_only;
988 #endif
989
990       retry:
991         p = smb_setup_header(server, SMBopen, 2, 0);
992         WSET(server->packet, smb_vwv0, mode);
993         WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
994         res = smb_simple_encode_path(server, &p, dentry, NULL);
995         if (res < 0)
996                 goto out;
997         smb_setup_bcc(server, p);
998
999         res = smb_request_ok(server, SMBopen, 7, 0);
1000         if (res != 0) {
1001                 if (smb_retry(server))
1002                         goto retry;
1003
1004                 if (mode == read_write &&
1005                     (res == -EACCES || res == -ETXTBSY || res == -EROFS))
1006                 {
1007                         VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
1008                                 DENTRY_PATH(dentry), res);
1009                         mode = read_only;
1010                         goto retry;
1011                 }
1012                 goto out;
1013         }
1014         /* We should now have data in vwv[0..6]. */
1015
1016         ino->u.smbfs_i.fileid = WVAL(server->packet, smb_vwv0);
1017         ino->u.smbfs_i.attr   = WVAL(server->packet, smb_vwv1);
1018         /* smb_vwv2 has mtime */
1019         /* smb_vwv4 has size  */
1020         ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK);
1021         ino->u.smbfs_i.open = server->generation;
1022
1023 out:
1024         return res;
1025 }
1026
1027 /*
1028  * Make sure the file is open, and check that the access
1029  * is compatible with the desired access.
1030  */
1031 int
1032 smb_open(struct dentry *dentry, int wish)
1033 {
1034         struct inode *inode = dentry->d_inode;
1035         int result;
1036
1037         result = -ENOENT;
1038         if (!inode) {
1039                 printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
1040                        DENTRY_PATH(dentry));
1041                 goto out;
1042         }
1043
1044         if (!smb_is_open(inode)) {
1045                 struct smb_sb_info *server = server_from_inode(inode);
1046                 smb_lock_server(server);
1047                 result = 0;
1048                 if (!smb_is_open(inode))
1049                         result = smb_proc_open(server, dentry, wish);
1050                 smb_unlock_server(server);
1051                 if (result) {
1052                         PARANOIA("%s/%s open failed, result=%d\n",
1053                                  DENTRY_PATH(dentry), result);
1054                         goto out;
1055                 }
1056                 /*
1057                  * A successful open means the path is still valid ...
1058                  */
1059                 smb_renew_times(dentry);
1060         }
1061
1062         /*
1063          * Check whether the access is compatible with the desired mode.
1064          */
1065         result = 0;
1066         if (inode->u.smbfs_i.access != wish && 
1067             inode->u.smbfs_i.access != SMB_O_RDWR)
1068         {
1069                 PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
1070                          DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
1071                 result = -EACCES;
1072         }
1073 out:
1074         return result;
1075 }
1076
1077 /* We're called with the server locked */
1078
1079 static int 
1080 smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
1081 {
1082         smb_setup_header(server, SMBclose, 3, 0);
1083         WSET(server->packet, smb_vwv0, fileid);
1084         DSET(server->packet, smb_vwv1, utc2local(server, mtime));
1085         return smb_request_ok(server, SMBclose, 0, 0);
1086 }
1087
1088 /*
1089  * Called with the server locked.
1090  *
1091  * Win NT 4.0 has an apparent bug in that it fails to update the
1092  * modify time when writing to a file. As a workaround, we update
1093  * both modify and access time locally, and post the times to the
1094  * server when closing the file.
1095  */
1096 static int 
1097 smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino)
1098 {
1099         int result = 0;
1100         if (smb_is_open(ino))
1101         {
1102                 /*
1103                  * We clear the open flag in advance, in case another
1104                  * process observes the value while we block below.
1105                  */
1106                 ino->u.smbfs_i.open = 0;
1107
1108                 /*
1109                  * Kludge alert: SMB timestamps are accurate only to
1110                  * two seconds ... round the times to avoid needless
1111                  * cache invalidations!
1112                  */
1113                 if (ino->i_mtime & 1)
1114                         ino->i_mtime--;
1115                 if (ino->i_atime & 1)
1116                         ino->i_atime--;
1117                 /*
1118                  * If the file is open with write permissions,
1119                  * update the time stamps to sync mtime and atime.
1120                  */
1121                 if ((server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
1122                     !(ino->u.smbfs_i.access == SMB_O_RDONLY))
1123                 {
1124                         struct smb_fattr fattr;
1125                         smb_get_inode_attr(ino, &fattr);
1126                         smb_proc_setattr_ext(server, ino, &fattr);
1127                 }
1128
1129                 result = smb_proc_close(server, ino->u.smbfs_i.fileid,
1130                                                 ino->i_mtime);
1131                 /*
1132                  * Force a revalidation after closing ... some servers
1133                  * don't post the size until the file has been closed.
1134                  */
1135                 if (server->opt.protocol < SMB_PROTOCOL_NT1)
1136                         ino->u.smbfs_i.oldmtime = 0;
1137                 ino->u.smbfs_i.closed = jiffies;
1138         }
1139         return result;
1140 }
1141
1142 int
1143 smb_close(struct inode *ino)
1144 {
1145         int result = 0;
1146
1147         if (smb_is_open(ino)) {
1148                 struct smb_sb_info *server = server_from_inode(ino);
1149                 smb_lock_server(server);
1150                 result = smb_proc_close_inode(server, ino);
1151                 smb_unlock_server(server);
1152         }
1153         return result;
1154 }
1155
1156 /*
1157  * This is used to close a file following a failed instantiate.
1158  * Since we don't have an inode, we can't use any of the above.
1159  */
1160 int
1161 smb_close_fileid(struct dentry *dentry, __u16 fileid)
1162 {
1163         struct smb_sb_info *server = server_from_dentry(dentry);
1164         int result;
1165
1166         smb_lock_server(server);
1167         result = smb_proc_close(server, fileid, CURRENT_TIME);
1168         smb_unlock_server(server);
1169         return result;
1170 }
1171
1172 /* In smb_proc_read and smb_proc_write we do not retry, because the
1173    file-id would not be valid after a reconnection. */
1174
1175 int
1176 smb_proc_read(struct inode *inode, off_t offset, int count, char *data)
1177 {
1178         struct smb_sb_info *server = server_from_inode(inode);
1179         __u16 returned_count, data_len;
1180         unsigned char *buf;
1181         int result;
1182
1183         smb_lock_server(server);
1184         smb_setup_header(server, SMBread, 5, 0);
1185         buf = server->packet;
1186         WSET(buf, smb_vwv0, inode->u.smbfs_i.fileid);
1187         WSET(buf, smb_vwv1, count);
1188         DSET(buf, smb_vwv2, offset);
1189         WSET(buf, smb_vwv4, 0);
1190
1191         result = smb_request_ok(server, SMBread, 5, -1);
1192         if (result < 0)
1193                 goto out;
1194         returned_count = WVAL(server->packet, smb_vwv0);
1195
1196         buf = SMB_BUF(server->packet);
1197         data_len = WVAL(buf, 1);
1198
1199         /* we can NOT simply trust the data_len given by the server ... */
1200         if (data_len > server->packet_size - (buf+3 - server->packet)) {
1201                 printk(KERN_ERR "smb_proc_read: invalid data length!! "
1202                        "%d > %d - (%p - %p)\n",
1203                        data_len, server->packet_size, buf+3, server->packet);
1204                 result = -EIO;
1205                 goto out;
1206         }
1207
1208         memcpy(data, buf+3, data_len);
1209
1210         if (returned_count != data_len) {
1211                 printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
1212                 printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
1213                        returned_count, data_len);
1214         }
1215         result = data_len;
1216
1217 out:
1218         VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1219                 inode->i_ino, inode->u.smbfs_i.fileid, count, result);
1220         smb_unlock_server(server);
1221         return result;
1222 }
1223
1224 int
1225 smb_proc_write(struct inode *inode, off_t offset, int count, const char *data)
1226 {
1227         struct smb_sb_info *server = server_from_inode(inode);
1228         int result;
1229         __u8 *p;
1230         __u16 fileid = inode->u.smbfs_i.fileid;
1231
1232         VERBOSE("ino=%ld, fileid=%d, count=%d@%ld, packet_size=%d\n",
1233                 inode->i_ino, inode->u.smbfs_i.fileid, count, offset,
1234                 server->packet_size);
1235
1236         smb_lock_server(server);
1237         p = smb_setup_header(server, SMBwrite, 5, count + 3);
1238         WSET(server->packet, smb_vwv0, fileid);
1239         WSET(server->packet, smb_vwv1, count);
1240         DSET(server->packet, smb_vwv2, offset);
1241         WSET(server->packet, smb_vwv4, 0);
1242
1243         *p++ = 1;
1244         WSET(p, 0, count);
1245         memcpy(p+2, data, count);
1246
1247         result = smb_request_ok(server, SMBwrite, 1, 0);
1248         if (result >= 0)
1249                 result = WVAL(server->packet, smb_vwv0);
1250
1251         smb_unlock_server(server);
1252         return result;
1253 }
1254
1255 int
1256 smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
1257 {
1258         struct smb_sb_info *server = server_from_dentry(dentry);
1259         char *p;
1260         int result;
1261
1262         smb_lock_server(server);
1263
1264       retry:
1265         p = smb_setup_header(server, SMBcreate, 3, 0);
1266         WSET(server->packet, smb_vwv0, attr);
1267         DSET(server->packet, smb_vwv1, utc2local(server, ctime));
1268         result = smb_simple_encode_path(server, &p, dentry, NULL);
1269         if (result < 0)
1270                 goto out;
1271         smb_setup_bcc(server, p);
1272
1273         result = smb_request_ok(server, SMBcreate, 1, 0);
1274         if (result < 0) {
1275                 if (smb_retry(server))
1276                         goto retry;
1277                 goto out;
1278         }
1279         *fileid = WVAL(server->packet, smb_vwv0);
1280         result = 0;
1281
1282 out:
1283         smb_unlock_server(server);
1284         return result;
1285 }
1286
1287 int
1288 smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
1289 {
1290         struct smb_sb_info *server = server_from_dentry(old_dentry);
1291         char *p;
1292         int result;
1293
1294         smb_lock_server(server);
1295
1296       retry:
1297         p = smb_setup_header(server, SMBmv, 1, 0);
1298         WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
1299         result = smb_simple_encode_path(server, &p, old_dentry, NULL);
1300         if (result < 0)
1301                 goto out;
1302         result = smb_simple_encode_path(server, &p, new_dentry, NULL);
1303         if (result < 0)
1304                 goto out;
1305         smb_setup_bcc(server, p);
1306
1307         if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) {
1308                 if (smb_retry(server))
1309                         goto retry;
1310                 goto out;
1311         }
1312         result = 0;
1313 out:
1314         smb_unlock_server(server);
1315         return result;
1316 }
1317
1318 /*
1319  * Code common to mkdir and rmdir.
1320  */
1321 static int
1322 smb_proc_generic_command(struct dentry *dentry, __u8 command)
1323 {
1324         struct smb_sb_info *server = server_from_dentry(dentry);
1325         char *p;
1326         int result;
1327
1328         smb_lock_server(server);
1329
1330       retry:
1331         p = smb_setup_header(server, command, 0, 0);
1332         result = smb_simple_encode_path(server, &p, dentry, NULL);
1333         if (result < 0)
1334                 goto out;
1335         smb_setup_bcc(server, p);
1336
1337         result = smb_request_ok(server, command, 0, 0);
1338         if (result < 0) {
1339                 if (smb_retry(server))
1340                         goto retry;
1341                 goto out;
1342         }
1343         result = 0;
1344 out:
1345         smb_unlock_server(server);
1346         return result;
1347 }
1348
1349 int
1350 smb_proc_mkdir(struct dentry *dentry)
1351 {
1352         return smb_proc_generic_command(dentry, SMBmkdir);
1353 }
1354
1355 int
1356 smb_proc_rmdir(struct dentry *dentry)
1357 {
1358         return smb_proc_generic_command(dentry, SMBrmdir);
1359 }
1360
1361 #if SMBFS_POSIX_UNLINK
1362 /*
1363  * Removes readonly attribute from a file. Used by unlink to give posix
1364  * semantics.
1365  * Note: called with the server locked.
1366  */
1367 static int
1368 smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
1369 {
1370         int result;
1371         struct smb_fattr fattr;
1372
1373         /* first get current attribute */
1374         result = smb_proc_do_getattr(server, dentry, &fattr);
1375         if (result < 0)
1376                 return result;
1377
1378         /* if RONLY attribute is set, remove it */
1379         if (fattr.attr & aRONLY) {  /* read only attribute is set */
1380                 fattr.attr &= ~aRONLY;
1381                 result = smb_proc_setattr_core(server, dentry, fattr.attr);
1382         }
1383         return result;
1384 }
1385 #endif
1386
1387 int
1388 smb_proc_unlink(struct dentry *dentry)
1389 {
1390         struct smb_sb_info *server = server_from_dentry(dentry);
1391         int flag = 0;
1392         char *p;
1393         int result;
1394
1395         smb_lock_server(server);
1396
1397       retry:
1398         p = smb_setup_header(server, SMBunlink, 1, 0);
1399         WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
1400         result = smb_simple_encode_path(server, &p, dentry, NULL);
1401         if (result < 0)
1402                 goto out;
1403         smb_setup_bcc(server, p);
1404
1405         if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) {
1406 #if SMBFS_POSIX_UNLINK
1407                 if (result == -EACCES && !flag) {
1408                         /* Posix semantics is for the read-only state
1409                            of a file to be ignored in unlink(). In the
1410                            SMB world a unlink() is refused on a
1411                            read-only file. To make things easier for
1412                            unix users we try to override the files
1413                            permission if the unlink fails with the
1414                            right error.
1415                            This introduces a race condition that could
1416                            lead to a file being written by someone who
1417                            shouldn't have access, but as far as I can
1418                            tell that is unavoidable */
1419
1420                         /* remove RONLY attribute and try again */
1421                         result = smb_set_rw(dentry,server);
1422                         if (result == 0) {
1423                                 flag = 1;
1424                                 goto retry;
1425                         }
1426                 }
1427 #endif
1428                 if (smb_retry(server))
1429                         goto retry;
1430                 goto out;
1431         }
1432         result = 0;
1433 out:
1434         smb_unlock_server(server);
1435         return result;
1436 }
1437
1438 /*
1439  * Called with the server locked
1440  */
1441 int
1442 smb_proc_flush(struct smb_sb_info *server, __u16 fileid)
1443 {
1444         smb_setup_header(server, SMBflush, 1, 0);
1445         WSET(server->packet, smb_vwv0, fileid);
1446         return smb_request_ok(server, SMBflush, 0, 0);
1447 }
1448
1449 int
1450 smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length)
1451 {
1452         char *p;
1453         int result;
1454
1455         smb_lock_server(server);
1456
1457 retry:
1458         p = smb_setup_header(server, SMBwrite, 5, 3);
1459         WSET(server->packet, smb_vwv0, fid);
1460         WSET(server->packet, smb_vwv1, 0);
1461         DSET(server->packet, smb_vwv2, length);
1462         WSET(server->packet, smb_vwv4, 0);
1463         *p++ = 1;
1464         WSET(p, 0, 0);
1465
1466         if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) {
1467                 if (smb_retry(server))
1468                         goto retry;
1469                 goto out;
1470         }
1471
1472         /*
1473          * win9x doesn't appear to update the size immediately.
1474          * It will return the old file size after the truncate,
1475          * confusing smbfs.
1476          * NT and Samba return the new value immediately.
1477          */
1478         if (server->mnt->flags & SMB_MOUNT_WIN95)
1479                 smb_proc_flush(server, fid);
1480 out:
1481         smb_unlock_server(server);
1482         return result;
1483 }
1484
1485 static void
1486 smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1487 {
1488         memset(fattr, 0, sizeof(*fattr));
1489
1490         fattr->f_nlink = 1;
1491         fattr->f_uid = server->mnt->uid;
1492         fattr->f_gid = server->mnt->gid;
1493         fattr->f_blksize = SMB_ST_BLKSIZE;
1494 }
1495
1496 static void
1497 smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1498 {
1499         fattr->f_mode = server->mnt->file_mode;
1500         if (fattr->attr & aDIR)
1501         {
1502                 fattr->f_mode = server->mnt->dir_mode;
1503                 fattr->f_size = SMB_ST_BLKSIZE;
1504         }
1505         /* Check the read-only flag */
1506         if (fattr->attr & aRONLY)
1507                 fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
1508
1509         /* How many 512 byte blocks do we need for this file? */
1510         fattr->f_blocks = 0;
1511         if (fattr->f_size != 0)
1512                 fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
1513         return;
1514 }
1515
1516 void
1517 smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1518 {
1519         smb_init_dirent(server, fattr);
1520         fattr->attr = aDIR;
1521         fattr->f_ino = 2; /* traditional root inode number */
1522         fattr->f_mtime = CURRENT_TIME;
1523         smb_finish_dirent(server, fattr);
1524 }
1525
1526 /*
1527  * Decode a dirent for old protocols
1528  *
1529  * qname is filled with the decoded, and possibly translated, name.
1530  * fattr receives decoded attributes
1531  *
1532  * Bugs Noted:
1533  * (1) Pathworks servers may pad the name with extra spaces.
1534  */
1535 static char *
1536 smb_decode_short_dirent(struct smb_sb_info *server, char *p,
1537                         struct qstr *qname, struct smb_fattr *fattr)
1538 {
1539         int len;
1540
1541         /*
1542          * SMB doesn't have a concept of inode numbers ...
1543          */
1544         smb_init_dirent(server, fattr);
1545         fattr->f_ino = 0;       /* FIXME: do we need this? */
1546
1547         p += SMB_STATUS_SIZE;   /* reserved (search_status) */
1548         fattr->attr = *p;
1549         fattr->f_mtime = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1));
1550         fattr->f_size = DVAL(p, 5);
1551         fattr->f_ctime = fattr->f_mtime;
1552         fattr->f_atime = fattr->f_mtime;
1553         qname->name = p + 9;
1554         len = strnlen(qname->name, 12);
1555
1556         /*
1557          * Trim trailing blanks for Pathworks servers
1558          */
1559         while (len > 2 && qname->name[len-1] == ' ')
1560                 len--;
1561         qname->len = len;
1562
1563         smb_finish_dirent(server, fattr);
1564
1565 #if 0
1566         /* FIXME: These only work for ascii chars, and recent smbmount doesn't
1567            allow the flag to be set anyway. It kills const. Remove? */
1568         switch (server->opt.case_handling) {
1569         case SMB_CASE_UPPER:
1570                 str_upper(entry->name, len);
1571                 break;
1572         case SMB_CASE_LOWER:
1573                 str_lower(entry->name, len);
1574                 break;
1575         default:
1576                 break;
1577         }
1578 #endif
1579
1580         qname->len = 0;
1581         len = server->convert(server->name_buf, SMB_MAXNAMELEN,
1582                             qname->name, len,
1583                             server->remote_nls, server->local_nls);
1584         if (len > 0) {
1585                 qname->len = len;
1586                 qname->name = server->name_buf;
1587                 DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
1588         }
1589
1590         return p + 22;
1591 }
1592
1593 /*
1594  * This routine is used to read in directory entries from the network.
1595  * Note that it is for short directory name seeks, i.e.: protocol <
1596  * SMB_PROTOCOL_LANMAN2
1597  */
1598 static int
1599 smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
1600                        struct smb_cache_control *ctl)
1601 {
1602         struct dentry *dir = filp->f_dentry;
1603         struct smb_sb_info *server = server_from_dentry(dir);
1604         struct qstr qname;
1605         struct smb_fattr fattr;
1606         char *p;
1607         int result;
1608         int i, first, entries_seen, entries;
1609         int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
1610         __u16 bcc;
1611         __u16 count;
1612         char status[SMB_STATUS_SIZE];
1613         static struct qstr mask = { "*.*", 3, 0 };
1614         unsigned char *last_status;
1615
1616         VERBOSE("%s/%s\n", DENTRY_PATH(dir));
1617
1618         smb_lock_server(server);
1619
1620         first = 1;
1621         entries = 0;
1622         entries_seen = 2; /* implicit . and .. */
1623
1624         while (1) {
1625                 p = smb_setup_header(server, SMBsearch, 2, 0);
1626                 WSET(server->packet, smb_vwv0, entries_asked);
1627                 WSET(server->packet, smb_vwv1, aDIR);
1628                 if (first == 1) {
1629                         result = smb_simple_encode_path(server, &p, dir, &mask);
1630                         if (result < 0)
1631                                 goto unlock_return;
1632                         if (p + 3 > (char*)server->packet+server->packet_size) {
1633                                 result = -ENAMETOOLONG;
1634                                 goto unlock_return;
1635                         }
1636                         *p++ = 5;
1637                         WSET(p, 0, 0);
1638                         p += 2;
1639                         first = 0;
1640                 } else {
1641                         if (p + 5 + SMB_STATUS_SIZE >
1642                             (char*)server->packet + server->packet_size) {
1643                                 result = -ENAMETOOLONG;
1644                                 goto unlock_return;
1645                         }
1646                                 
1647                         *p++ = 4;
1648                         *p++ = 0;
1649                         *p++ = 5;
1650                         WSET(p, 0, SMB_STATUS_SIZE);
1651                         p += 2;
1652                         memcpy(p, status, SMB_STATUS_SIZE);
1653                         p += SMB_STATUS_SIZE;
1654                 }
1655
1656                 smb_setup_bcc(server, p);
1657
1658                 result = smb_request_ok(server, SMBsearch, 1, -1);
1659                 if (result < 0) {
1660                         if ((server->rcls == ERRDOS) && 
1661                             (server->err  == ERRnofiles))
1662                                 break;
1663                         if (smb_retry(server)) {
1664                                 ctl->idx = -1;  /* retry */
1665                                 result = 0;
1666                         }
1667                         goto unlock_return;
1668                 }
1669                 p = SMB_VWV(server->packet);
1670                 count = WVAL(p, 0);
1671                 if (count <= 0)
1672                         break;
1673
1674                 result = -EIO;
1675                 bcc = WVAL(p, 2);
1676                 if (bcc != count * SMB_DIRINFO_SIZE + 3)
1677                         goto unlock_return;
1678                 p += 7;
1679
1680
1681                 /* Make sure the response fits in the buffer. Fixed sized 
1682                    entries means we don't have to check in the decode loop. */
1683
1684                 last_status = SMB_BUF(server->packet) + 3 + (count - 1) *
1685                         SMB_DIRINFO_SIZE;
1686
1687                 if (last_status + SMB_DIRINFO_SIZE >=
1688                     server->packet + server->packet_size) {
1689                         printk(KERN_ERR "smb_proc_readdir_short: "
1690                                "last dir entry outside buffer! "
1691                                "%d@%p  %d@%p\n", SMB_DIRINFO_SIZE, last_status,
1692                                server->packet_size, server->packet);
1693                         goto unlock_return;
1694                 }
1695
1696                 /* Read the last entry into the status field. */
1697                 memcpy(status, last_status, SMB_STATUS_SIZE);
1698
1699
1700                 /* Now we are ready to parse smb directory entries. */
1701
1702                 for (i = 0; i < count; i++) {
1703                         p = smb_decode_short_dirent(server, p, 
1704                                                     &qname, &fattr);
1705                         if (qname.len == 0)
1706                                 continue;
1707                         if (entries_seen == 2 && qname.name[0] == '.') {
1708                                 if (qname.len == 1)
1709                                         continue;
1710                                 if (qname.name[1] == '.' && qname.len == 2)
1711                                         continue;
1712                         }
1713                         if (!smb_fill_cache(filp, dirent, filldir, ctl, 
1714                                             &qname, &fattr))
1715                                 ;       /* stop reading? */
1716                         entries_seen++;
1717                 }
1718         }
1719         result = entries;
1720
1721 unlock_return:
1722         smb_unlock_server(server);
1723         return result;
1724 }
1725
1726 /*
1727  * Interpret a long filename structure using the specified info level:
1728  *   level 1 for anything below NT1 protocol
1729  *   level 260 for NT1 protocol
1730  *
1731  * qname is filled with the decoded, and possibly translated, name
1732  * fattr receives decoded attributes.
1733  *
1734  * Bugs Noted:
1735  * (1) Win NT 4.0 appends a null byte to names and counts it in the length!
1736  */
1737 static char *
1738 smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
1739                        struct qstr *qname, struct smb_fattr *fattr)
1740 {
1741         char *result;
1742         unsigned int len = 0;
1743         int n;
1744         __u16 date, time;
1745
1746         /*
1747          * SMB doesn't have a concept of inode numbers ...
1748          */
1749         smb_init_dirent(server, fattr);
1750         fattr->f_ino = 0;       /* FIXME: do we need this? */
1751
1752         switch (level) {
1753         case 1:
1754                 len = *((unsigned char *) p + 22);
1755                 qname->name = p + 23;
1756                 result = p + 24 + len;
1757
1758                 date = WVAL(p, 0);
1759                 time = WVAL(p, 2);
1760                 fattr->f_ctime = date_dos2unix(server, date, time);
1761
1762                 date = WVAL(p, 4);
1763                 time = WVAL(p, 6);
1764                 fattr->f_atime = date_dos2unix(server, date, time);
1765
1766                 date = WVAL(p, 8);
1767                 time = WVAL(p, 10);
1768                 fattr->f_mtime = date_dos2unix(server, date, time);
1769                 fattr->f_size = DVAL(p, 12);
1770                 /* ULONG allocation size */
1771                 fattr->attr = WVAL(p, 20);
1772
1773                 VERBOSE("info 1 at %p, len=%d, name=%.*s\n",
1774                         p, len, len, qname->name);
1775                 break;
1776         case 260:
1777                 result = p + WVAL(p, 0);
1778                 len = DVAL(p, 60);
1779                 if (len > 255) len = 255;
1780                 /* NT4 null terminates */
1781                 qname->name = p + 94;
1782                 if (len && qname->name[len-1] == '\0')
1783                         len--;
1784
1785                 fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
1786                 fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
1787                 fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
1788                 /* change time (32) */
1789                 fattr->f_size = DVAL(p, 40);
1790                 /* alloc size (48) */
1791                 fattr->attr = DVAL(p, 56);
1792
1793                 VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
1794                         p, len, len, qname->name);
1795                 break;
1796         default:
1797                 PARANOIA("Unknown info level %d\n", level);
1798                 result = p + WVAL(p, 0);
1799                 goto out;
1800         }
1801
1802         smb_finish_dirent(server, fattr);
1803
1804 #if 0
1805         /* FIXME: These only work for ascii chars, and recent smbmount doesn't
1806            allow the flag to be set anyway. Remove? */
1807         switch (server->opt.case_handling) {
1808         case SMB_CASE_UPPER:
1809                 str_upper(qname->name, len);
1810                 break;
1811         case SMB_CASE_LOWER:
1812                 str_lower(qname->name, len);
1813                 break;
1814         default:
1815                 break;
1816         }
1817 #endif
1818
1819         qname->len = 0;
1820         n = server->convert(server->name_buf, SMB_MAXNAMELEN,
1821                             qname->name, len,
1822                             server->remote_nls, server->local_nls);
1823         if (n > 0) {
1824                 qname->len = n;
1825                 qname->name = server->name_buf;
1826         }
1827
1828 out:
1829         return result;
1830 }
1831
1832 /* findfirst/findnext flags */
1833 #define SMB_CLOSE_AFTER_FIRST (1<<0)
1834 #define SMB_CLOSE_IF_END (1<<1)
1835 #define SMB_REQUIRE_RESUME_KEY (1<<2)
1836 #define SMB_CONTINUE_BIT (1<<3)
1837
1838 /*
1839  * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in
1840  * source/libsmb/clilist.c. When looking for smb bugs in the readdir code,
1841  * go there for advise.
1842  *
1843  * Bugs Noted:
1844  * (1) When using Info Level 1 Win NT 4.0 truncates directory listings 
1845  * for certain patterns of names and/or lengths. The breakage pattern
1846  * is completely reproducible and can be toggled by the creation of a
1847  * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
1848  */
1849 static int
1850 smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
1851                       struct smb_cache_control *ctl)
1852 {
1853         struct dentry *dir = filp->f_dentry;
1854         struct smb_sb_info *server = server_from_dentry(dir);
1855         struct qstr qname;
1856         struct smb_fattr fattr;
1857
1858         unsigned char *p, *lastname;
1859         char *mask, *param = server->temp_buf;
1860         __u16 command;
1861         int first, entries_seen;
1862
1863         /* Both NT and OS/2 accept info level 1 (but see note below). */
1864         int info_level = 260;
1865         const int max_matches = 512;
1866
1867         unsigned char *resp_data = NULL;
1868         unsigned char *resp_param = NULL;
1869         int resp_data_len = 0;
1870         int resp_param_len = 0;
1871         int ff_searchcount = 0;
1872         int ff_eos = 0;
1873         int ff_lastname = 0;
1874         int ff_dir_handle = 0;
1875         int loop_count = 0;
1876         int mask_len, i, result;
1877         static struct qstr star = { "*", 1, 0 };
1878
1879         /*
1880          * use info level 1 for older servers that don't do 260
1881          */
1882         if (server->opt.protocol < SMB_PROTOCOL_NT1)
1883                 info_level = 1;
1884
1885         smb_lock_server(server);
1886
1887         /*
1888          * Encode the initial path
1889          */
1890         mask = param + 12;
1891
1892         mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
1893         if (mask_len < 0) {
1894                 result = mask_len;
1895                 goto unlock_return;
1896         }
1897         mask_len--;     /* mask_len is strlen, not #bytes */
1898         first = 1;
1899         VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
1900
1901         result = 0;
1902         entries_seen = 2;
1903         ff_eos = 0;
1904
1905         while (ff_eos == 0) {
1906                 loop_count += 1;
1907                 if (loop_count > 10) {
1908                         printk(KERN_WARNING "smb_proc_readdir_long: "
1909                                "Looping in FIND_NEXT??\n");
1910                         result = -EIO;
1911                         break;
1912                 }
1913
1914                 if (first != 0) {
1915                         command = TRANSACT2_FINDFIRST;
1916                         WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
1917                         WSET(param, 2, max_matches);    /* max count */
1918                         WSET(param, 4, SMB_CLOSE_IF_END);
1919                         WSET(param, 6, info_level);
1920                         DSET(param, 8, 0);
1921                 } else {
1922                         command = TRANSACT2_FINDNEXT;
1923
1924                         VERBOSE("handle=0x%X, lastname=%d, mask=%s\n",
1925                                 ff_dir_handle, ff_lastname, mask);
1926
1927                         WSET(param, 0, ff_dir_handle);  /* search handle */
1928                         WSET(param, 2, max_matches);    /* max count */
1929                         WSET(param, 4, info_level);
1930                         DSET(param, 6, 0);
1931                         WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
1932                 }
1933
1934                 result = smb_trans2_request(server, command,
1935                                             0, NULL, 12 + mask_len + 1, param,
1936                                             &resp_data_len, &resp_data,
1937                                             &resp_param_len, &resp_param);
1938
1939                 if (result < 0) {
1940                         if (smb_retry(server)) {
1941                                 PARANOIA("error=%d, retrying\n", result);
1942                                 ctl->idx = -1;  /* retry */
1943                                 result = 0;
1944                                 goto unlock_return;
1945                         }
1946                         PARANOIA("error=%d, breaking\n", result);
1947                         break;
1948                 }
1949
1950                 if (server->rcls == ERRSRV && server->err == ERRerror) {
1951                         /* a damn Win95 bug - sometimes it clags if you 
1952                            ask it too fast */
1953                         current->state = TASK_INTERRUPTIBLE;
1954                         schedule_timeout(HZ/5);
1955                         continue;
1956                 }
1957
1958                 if (server->rcls != 0) {
1959                         result = smb_errno(server);
1960                         PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
1961                                  mask, result, server->rcls, server->err);
1962                         break;
1963                 }
1964
1965                 /* parse out some important return info */
1966                 if (first != 0) {
1967                         ff_dir_handle = WVAL(resp_param, 0);
1968                         ff_searchcount = WVAL(resp_param, 2);
1969                         ff_eos = WVAL(resp_param, 4);
1970                         ff_lastname = WVAL(resp_param, 8);
1971                 } else {
1972                         ff_searchcount = WVAL(resp_param, 0);
1973                         ff_eos = WVAL(resp_param, 2);
1974                         ff_lastname = WVAL(resp_param, 6);
1975                 }
1976
1977                 if (ff_searchcount == 0)
1978                         break;
1979
1980                 /*
1981                  * We might need the lastname for continuations.
1982                  *
1983                  * Note that some servers (win95?) point to the filename and
1984                  * others (NT4, Samba using NT1) to the dir entry. We assume
1985                  * here that those who do not point to a filename do not need
1986                  * this info to continue the listing.
1987                  *
1988                  * OS/2 needs this and talks infolevel 1
1989                  * NetApps want lastname with infolevel 260
1990                  *
1991                  * Both are happy if we return the data they point to. So we do.
1992                  */
1993                 mask_len = 0;
1994                 if (ff_lastname > 0 && ff_lastname < resp_data_len) {
1995                         lastname = resp_data + ff_lastname;
1996
1997                         switch (info_level) {
1998                         case 260:
1999                                 mask_len = resp_data_len - ff_lastname;
2000                                 break;
2001                         case 1:
2002                                 /* lastname points to a length byte */
2003                                 mask_len = *lastname++;
2004                                 if (ff_lastname + 1 + mask_len > resp_data_len)
2005                                         mask_len = resp_data_len - ff_lastname - 1;
2006                                 break;
2007                         }
2008
2009                         /*
2010                          * Update the mask string for the next message.
2011                          */
2012                         if (mask_len < 0)
2013                                 mask_len = 0;
2014                         if (mask_len > 255)
2015                                 mask_len = 255;
2016                         if (mask_len)
2017                                 strncpy(mask, lastname, mask_len);
2018                 }
2019                 mask_len = strnlen(mask, mask_len);
2020                 VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
2021                         mask_len, ff_lastname, resp_data_len, mask_len, mask);
2022
2023                 /* Now we are ready to parse smb directory entries. */
2024
2025                 /* point to the data bytes */
2026                 p = resp_data;
2027                 for (i = 0; i < ff_searchcount; i++) {
2028                         /* make sure we stay within the buffer */
2029                         if (p >= resp_data + resp_data_len) {
2030                                 printk(KERN_ERR "smb_proc_readdir_long: "
2031                                        "dirent pointer outside buffer! "
2032                                        "%p  %d@%p  %d@%p\n",
2033                                        p, resp_data_len, resp_data,
2034                                        server->packet_size, server->packet);
2035                                 result = -EIO; /* always a comm. error? */
2036                                 goto unlock_return;
2037                         }
2038
2039                         p = smb_decode_long_dirent(server, p, info_level,
2040                                                    &qname, &fattr);
2041                         if (qname.len == 0)
2042                                 continue;
2043
2044                         /* ignore . and .. from the server */
2045                         if (entries_seen == 2 && qname.name[0] == '.') {
2046                                 if (qname.len == 1)
2047                                         continue;
2048                                 if (qname.name[1] == '.' && qname.len == 2)
2049                                         continue;
2050                         }
2051
2052                         if (!smb_fill_cache(filp, dirent, filldir, ctl, 
2053                                             &qname, &fattr))
2054                                 ;       /* stop reading? */
2055                         entries_seen++;
2056                 }
2057
2058                 VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);
2059
2060                 first = 0;
2061                 loop_count = 0;
2062         }
2063
2064 unlock_return:
2065         smb_unlock_server(server);
2066         return result;
2067 }
2068
2069 int
2070 smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir,
2071                  struct smb_cache_control *ctl)
2072 {
2073         struct smb_sb_info *server = server_from_dentry(filp->f_dentry);
2074
2075         if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
2076                 return smb_proc_readdir_long(filp, dirent, filldir, ctl);
2077         else
2078                 return smb_proc_readdir_short(filp, dirent, filldir, ctl);
2079 }
2080
2081 /*
2082  * This version uses the trans2 TRANSACT2_FINDFIRST message 
2083  * to get the attribute data.
2084  * Note: called with the server locked.
2085  *
2086  * Bugs Noted:
2087  */
2088 static int
2089 smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
2090                         struct smb_fattr *fattr)
2091 {
2092         char *param = server->temp_buf, *mask = param + 12;
2093         __u16 date, time;
2094         unsigned char *resp_data = NULL;
2095         unsigned char *resp_param = NULL;
2096         int resp_data_len = 0;
2097         int resp_param_len = 0;
2098         int mask_len, result;
2099
2100 retry:
2101         mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry, NULL);
2102         if (mask_len < 0) {
2103                 result = mask_len;
2104                 goto out;
2105         }
2106         VERBOSE("name=%s, len=%d\n", mask, mask_len);
2107         WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2108         WSET(param, 2, 1);      /* max count */
2109         WSET(param, 4, 1);      /* close after this call */
2110         WSET(param, 6, 1);      /* info_level */
2111         DSET(param, 8, 0);
2112
2113         result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
2114                                     0, NULL, 12 + mask_len, param,
2115                                     &resp_data_len, &resp_data,
2116                                     &resp_param_len, &resp_param);
2117         if (result < 0)
2118         {
2119                 if (smb_retry(server))
2120                         goto retry;
2121                 goto out;
2122         }
2123         if (server->rcls != 0)
2124         { 
2125                 result = smb_errno(server);
2126 #ifdef SMBFS_PARANOIA
2127                 if (result != -ENOENT)
2128                         PARANOIA("error for %s, rcls=%d, err=%d\n",
2129                                  mask, server->rcls, server->err);
2130 #endif
2131                 goto out;
2132         }
2133         /* Make sure we got enough data ... */
2134         result = -EINVAL;
2135         if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
2136         {
2137                 PARANOIA("bad result for %s, len=%d, count=%d\n",
2138                          mask, resp_data_len, WVAL(resp_param, 2));
2139                 goto out;
2140         }
2141
2142         /*
2143          * Decode the response into the fattr ...
2144          */
2145         date = WVAL(resp_data, 0);
2146         time = WVAL(resp_data, 2);
2147         fattr->f_ctime = date_dos2unix(server, date, time);
2148
2149         date = WVAL(resp_data, 4);
2150         time = WVAL(resp_data, 6);
2151         fattr->f_atime = date_dos2unix(server, date, time);
2152
2153         date = WVAL(resp_data, 8);
2154         time = WVAL(resp_data, 10);
2155         fattr->f_mtime = date_dos2unix(server, date, time);
2156         VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
2157                 mask, date, time, fattr->f_mtime);
2158         fattr->f_size = DVAL(resp_data, 12);
2159         /* ULONG allocation size */
2160         fattr->attr = WVAL(resp_data, 20);
2161         result = 0;
2162
2163 out:
2164         return result;
2165 }
2166
2167 /*
2168  * Note: called with the server locked.
2169  */
2170 static int
2171 smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
2172                       struct smb_fattr *fattr)
2173 {
2174         int result;
2175         char *p;
2176
2177       retry:
2178         p = smb_setup_header(server, SMBgetatr, 0, 0);
2179         result = smb_simple_encode_path(server, &p, dir, NULL);
2180         if (result < 0)
2181                 goto out;
2182         smb_setup_bcc(server, p);
2183
2184         if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
2185         {
2186                 if (smb_retry(server))
2187                         goto retry;
2188                 goto out;
2189         }
2190         fattr->attr    = WVAL(server->packet, smb_vwv0);
2191         fattr->f_mtime = local2utc(server, DVAL(server->packet, smb_vwv1));
2192         fattr->f_size  = DVAL(server->packet, smb_vwv3);
2193         fattr->f_ctime = fattr->f_mtime; 
2194         fattr->f_atime = fattr->f_mtime; 
2195 #ifdef SMBFS_DEBUG_TIMESTAMP
2196         printk("getattr_core: %s/%s, mtime=%ld\n",
2197                DENTRY_PATH(dir), fattr->f_mtime);
2198 #endif
2199         result = 0;
2200
2201 out:
2202         return result;
2203 }
2204
2205 /*
2206  * Note: called with the server locked.
2207  *
2208  * Bugs Noted:
2209  * (1) Win 95 swaps the date and time fields in the standard info level.
2210  */
2211 static int
2212 smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
2213                         struct smb_fattr *attr)
2214 {
2215         char *p, *param = server->temp_buf;
2216         __u16 date, time;
2217         int off_date = 0, off_time = 2;
2218         unsigned char *resp_data = NULL;
2219         unsigned char *resp_param = NULL;
2220         int resp_data_len = 0;
2221         int resp_param_len = 0;
2222         int result;
2223
2224       retry:
2225         WSET(param, 0, 1);      /* Info level SMB_INFO_STANDARD */
2226         DSET(param, 2, 0);
2227         result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2228         if (result < 0)
2229                 goto out;
2230         p = param + 6 + result;
2231
2232         result = smb_trans2_request(server, TRANSACT2_QPATHINFO,
2233                                     0, NULL, p - param, param,
2234                                     &resp_data_len, &resp_data,
2235                                     &resp_param_len, &resp_param);
2236         if (result < 0)
2237         {
2238                 if (smb_retry(server))
2239                         goto retry;
2240                 goto out;
2241         }
2242         if (server->rcls != 0)
2243         {
2244                 VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2245                         &param[6], result, server->rcls, server->err);
2246                 result = smb_errno(server);
2247                 goto out;
2248         }
2249         result = -ENOENT;
2250         if (resp_data_len < 22)
2251         {
2252                 PARANOIA("not enough data for %s, len=%d\n",
2253                          &param[6], resp_data_len);
2254                 goto out;
2255         }
2256
2257         /*
2258          * Kludge alert: Win 95 swaps the date and time field,
2259          * contrary to the CIFS docs and Win NT practice.
2260          */
2261         if (server->mnt->flags & SMB_MOUNT_WIN95) {
2262                 off_date = 2;
2263                 off_time = 0;
2264         }
2265         date = WVAL(resp_data, off_date);
2266         time = WVAL(resp_data, off_time);
2267         attr->f_ctime = date_dos2unix(server, date, time);
2268
2269         date = WVAL(resp_data, 4 + off_date);
2270         time = WVAL(resp_data, 4 + off_time);
2271         attr->f_atime = date_dos2unix(server, date, time);
2272
2273         date = WVAL(resp_data, 8 + off_date);
2274         time = WVAL(resp_data, 8 + off_time);
2275         attr->f_mtime = date_dos2unix(server, date, time);
2276 #ifdef SMBFS_DEBUG_TIMESTAMP
2277         printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2278                DENTRY_PATH(dir), date, time, attr->f_mtime);
2279 #endif
2280         attr->f_size = DVAL(resp_data, 12);
2281         attr->attr = WVAL(resp_data, 20);
2282         result = 0;
2283
2284 out:
2285         return result;
2286 }
2287
2288 /*
2289  * Note: called with the server locked
2290  */
2291 static int
2292 smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir,
2293                     struct smb_fattr *fattr)
2294 {
2295         int result;
2296         struct inode *inode = dir->d_inode;
2297
2298         smb_init_dirent(server, fattr);
2299
2300         /*
2301          * Select whether to use core or trans2 getattr.
2302          * Win 95 appears to break with the trans2 getattr.
2303          */
2304         if (server->opt.protocol < SMB_PROTOCOL_LANMAN2 ||
2305             (server->mnt->flags & (SMB_MOUNT_OLDATTR|SMB_MOUNT_WIN95)) ) {
2306                 result = smb_proc_getattr_core(server, dir, fattr);
2307         } else {
2308                 if (server->mnt->flags & SMB_MOUNT_DIRATTR)
2309                         result = smb_proc_getattr_ff(server, dir, fattr);
2310                 else
2311                         result = smb_proc_getattr_trans2(server, dir, fattr);
2312         }
2313
2314         /*
2315          * None of the getattr versions here can make win9x return the right
2316          * filesize if there are changes made to an open file.
2317          * A seek-to-end does return the right size, but we only need to do
2318          * that on files we have written.
2319          */
2320         if (server->mnt->flags & SMB_MOUNT_WIN95 &&
2321             inode &&
2322             inode->u.smbfs_i.flags & SMB_F_LOCALWRITE &&
2323             smb_is_open(inode))
2324         {
2325                 __u16 fileid = inode->u.smbfs_i.fileid;
2326                 fattr->f_size = smb_proc_seek(server, fileid, 2, 0);
2327         }
2328
2329         smb_finish_dirent(server, fattr);
2330         return result;
2331 }
2332
2333 int
2334 smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
2335 {
2336         struct smb_sb_info *server = server_from_dentry(dir);
2337         int result;
2338
2339         smb_lock_server(server);
2340         result = smb_proc_do_getattr(server, dir, fattr);
2341         smb_unlock_server(server);
2342         return result;
2343 }
2344
2345
2346 /*
2347  * Called with the server locked. Because of bugs in the
2348  * core protocol, we use this only to set attributes. See
2349  * smb_proc_settime() below for timestamp handling.
2350  *
2351  * Bugs Noted:
2352  * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail
2353  * with an undocumented error (ERRDOS code 50). Setting
2354  * mtime to 0 allows the attributes to be set.
2355  * (2) The extra parameters following the name string aren't
2356  * in the CIFS docs, but seem to be necessary for operation.
2357  */
2358 static int
2359 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
2360                       __u16 attr)
2361 {
2362         char *p;
2363         int result;
2364
2365       retry:
2366         p = smb_setup_header(server, SMBsetatr, 8, 0);
2367         WSET(server->packet, smb_vwv0, attr);
2368         DSET(server->packet, smb_vwv1, 0); /* mtime */
2369         WSET(server->packet, smb_vwv3, 0); /* reserved values */
2370         WSET(server->packet, smb_vwv4, 0);
2371         WSET(server->packet, smb_vwv5, 0);
2372         WSET(server->packet, smb_vwv6, 0);
2373         WSET(server->packet, smb_vwv7, 0);
2374         result = smb_simple_encode_path(server, &p, dentry, NULL);
2375         if (result < 0)
2376                 goto out;
2377         if (p + 2 > (char *)server->packet + server->packet_size) {
2378                 result = -ENAMETOOLONG;
2379                 goto out;
2380         }
2381         *p++ = 4;
2382         *p++ = 0;
2383         smb_setup_bcc(server, p);
2384
2385         result = smb_request_ok(server, SMBsetatr, 0, 0);
2386         if (result < 0) {
2387                 if (smb_retry(server))
2388                         goto retry;
2389                 goto out;
2390         }
2391         result = 0;
2392 out:
2393         return result;
2394 }
2395
2396 /*
2397  * Because of bugs in the trans2 setattr messages, we must set
2398  * attributes and timestamps separately. The core SMBsetatr
2399  * message seems to be the only reliable way to set attributes.
2400  */
2401 int
2402 smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
2403 {
2404         struct smb_sb_info *server = server_from_dentry(dir);
2405         int result;
2406
2407         VERBOSE("setting %s/%s, open=%d\n", 
2408                 DENTRY_PATH(dir), smb_is_open(dir->d_inode));
2409         smb_lock_server(server);
2410         result = smb_proc_setattr_core(server, dir, fattr->attr);
2411         smb_unlock_server(server);
2412         return result;
2413 }
2414
2415 /*
2416  * Called with the server locked. Sets the timestamps for an
2417  * file open with write permissions.
2418  */
2419 static int
2420 smb_proc_setattr_ext(struct smb_sb_info *server,
2421                       struct inode *inode, struct smb_fattr *fattr)
2422 {
2423         __u16 date, time;
2424         int result;
2425
2426       retry:
2427         smb_setup_header(server, SMBsetattrE, 7, 0);
2428         WSET(server->packet, smb_vwv0, inode->u.smbfs_i.fileid);
2429         /* We don't change the creation time */
2430         WSET(server->packet, smb_vwv1, 0);
2431         WSET(server->packet, smb_vwv2, 0);
2432         date_unix2dos(server, fattr->f_atime, &date, &time);
2433         WSET(server->packet, smb_vwv3, date);
2434         WSET(server->packet, smb_vwv4, time);
2435         date_unix2dos(server, fattr->f_mtime, &date, &time);
2436         WSET(server->packet, smb_vwv5, date);
2437         WSET(server->packet, smb_vwv6, time);
2438 #ifdef SMBFS_DEBUG_TIMESTAMP
2439         printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",
2440                date, time, fattr->f_mtime);
2441 #endif
2442
2443         result = smb_request_ok(server, SMBsetattrE, 0, 0);
2444         if (result < 0) {
2445                 if (smb_retry(server))
2446                         goto retry;
2447                 goto out;
2448         }
2449         result = 0;
2450 out:
2451         return result;
2452 }
2453
2454 /*
2455  * Note: called with the server locked.
2456  *
2457  * Bugs Noted:
2458  * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't
2459  * set the file's attribute flags.
2460  */
2461 static int
2462 smb_proc_setattr_trans2(struct smb_sb_info *server,
2463                         struct dentry *dir, struct smb_fattr *fattr)
2464 {
2465         __u16 date, time;
2466         char *p, *param = server->temp_buf;
2467         unsigned char *resp_data = NULL;
2468         unsigned char *resp_param = NULL;
2469         int resp_data_len = 0;
2470         int resp_param_len = 0;
2471         int result;
2472         char data[26];
2473
2474       retry:
2475         WSET(param, 0, 1);      /* Info level SMB_INFO_STANDARD */
2476         DSET(param, 2, 0);
2477         result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2478         if (result < 0)
2479                 goto out;
2480         p = param + 6 + result;
2481
2482         WSET(data, 0, 0); /* creation time */
2483         WSET(data, 2, 0);
2484         date_unix2dos(server, fattr->f_atime, &date, &time);
2485         WSET(data, 4, date);
2486         WSET(data, 6, time);
2487         date_unix2dos(server, fattr->f_mtime, &date, &time);
2488         WSET(data, 8, date);
2489         WSET(data, 10, time);
2490 #ifdef SMBFS_DEBUG_TIMESTAMP
2491         printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 
2492                DENTRY_PATH(dir), date, time, fattr->f_mtime);
2493 #endif
2494         DSET(data, 12, 0); /* size */
2495         DSET(data, 16, 0); /* blksize */
2496         WSET(data, 20, 0); /* attr */
2497         DSET(data, 22, 0); /* ULONG EA size */
2498
2499         result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,
2500                                     26, data, p - param, param,
2501                                     &resp_data_len, &resp_data,
2502                                     &resp_param_len, &resp_param);
2503         if (result < 0)
2504         {
2505                 if (smb_retry(server))
2506                         goto retry;
2507                 goto out;
2508         }
2509         result = 0;
2510         if (server->rcls != 0)
2511                 result = smb_errno(server);
2512
2513 out:
2514         return result;
2515 }
2516
2517 /*
2518  * Set the modify and access timestamps for a file.
2519  *
2520  * Incredibly enough, in all of SMB there is no message to allow
2521  * setting both attributes and timestamps at once. 
2522  *
2523  * Bugs Noted:
2524  * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message 
2525  * with info level 1 (INFO_STANDARD).
2526  * (2) Win 95 seems not to support setting directory timestamps.
2527  * (3) Under the core protocol apparently the only way to set the
2528  * timestamp is to open and close the file.
2529  */
2530 int
2531 smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
2532 {
2533         struct smb_sb_info *server = server_from_dentry(dentry);
2534         struct inode *inode = dentry->d_inode;
2535         int result;
2536
2537         VERBOSE("setting %s/%s, open=%d\n",
2538                 DENTRY_PATH(dentry), smb_is_open(inode));
2539
2540         smb_lock_server(server);
2541         /* setting the time on a Win95 server fails (tridge) */
2542         if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && 
2543             !(server->mnt->flags & SMB_MOUNT_WIN95)) {
2544                 if (smb_is_open(inode) &&
2545                     inode->u.smbfs_i.access != SMB_O_RDONLY)
2546                         result = smb_proc_setattr_ext(server, inode, fattr);
2547                 else
2548                         result = smb_proc_setattr_trans2(server, dentry, fattr);
2549         } else {
2550                 /*
2551                  * Fail silently on directories ... timestamp can't be set?
2552                  */
2553                 result = 0;
2554                 if (S_ISREG(inode->i_mode)) {
2555                         /*
2556                          * Set the mtime by opening and closing the file.
2557                          * Note that the file is opened read-only, but this
2558                          * still allows us to set the date (tridge)
2559                          */
2560                         result = -EACCES;
2561                         if (!smb_is_open(inode))
2562                                 smb_proc_open(server, dentry, SMB_O_RDONLY);
2563                         if (smb_is_open(inode)) {
2564                                 inode->i_mtime = fattr->f_mtime;
2565                                 result = smb_proc_close_inode(server, inode);
2566                         }
2567                 }
2568         }
2569
2570         smb_unlock_server(server);
2571         return result;
2572 }
2573
2574 int
2575 smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
2576 {
2577         struct smb_sb_info *server = &(sb->u.smbfs_sb);
2578         int result;
2579         char *p;
2580         long unit;
2581
2582         smb_lock_server(server);
2583
2584       retry:
2585         smb_setup_header(server, SMBdskattr, 0, 0);
2586
2587         if ((result = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
2588                 if (smb_retry(server))
2589                         goto retry;
2590                 goto out;
2591         }
2592         p = SMB_VWV(server->packet);
2593         unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
2594         attr->f_blocks = WVAL(p, 0) * unit;
2595         attr->f_bsize  = SMB_ST_BLKSIZE;
2596         attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
2597         result = 0;
2598
2599 out:
2600         smb_unlock_server(server);
2601         return result;
2602 }