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