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