4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
7 * 28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
10 #include <linux/config.h>
12 #include <linux/smbno.h>
13 #include <linux/smb_fs.h>
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/malloc.h>
17 #include <linux/stat.h>
18 #include <linux/fcntl.h>
20 #include <asm/uaccess.h>
21 #include <asm/string.h>
23 #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
24 #define SMB_CMD(packet) (*(packet+8))
25 #define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1))
26 #define SMB_BCC(packet) smb_bcc(packet)
27 #define SMB_BUF(packet) ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
29 #define SMB_DIRINFO_SIZE 43
30 #define SMB_STATUS_SIZE 21
32 static int smb_request_ok(struct smb_sb_info
*s
, int command
, int wct
, int bcc
);
45 if (*name
>= 'a' && *name
<= 'z')
56 if (*name
>= 'A' && *name
<= 'Z')
62 /*****************************************************************************/
64 /* Encoding/Decoding section */
66 /*****************************************************************************/
69 smb_encode_smb_length(__u8
* p
, __u32 len
)
73 *(p
+2) = (len
& 0xFF00) >> 8;
74 *(p
+3) = (len
& 0xFF);
82 static int smb_d_path(struct dentry
* entry
, char * buf
)
88 int len
= smb_d_path(entry
->d_parent
, buf
);
95 memcpy(buf
, entry
->d_name
.name
, entry
->d_name
.len
);
96 return len
+ entry
->d_name
.len
;
100 static char *smb_encode_path(struct smb_sb_info
*server
, char *buf
,
101 struct dentry
*dir
, struct qstr
*name
)
106 buf
+= smb_d_path(dir
, buf
);
110 memcpy(buf
, name
->name
, name
->len
);
115 if (server
->opt
.protocol
<= SMB_PROTOCOL_COREPLUS
)
121 /* The following are taken directly from msdos-fs */
123 /* Linear day numbers of the respective 1sts in non-leap years. */
126 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
127 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
130 extern struct timezone sys_tz
;
135 return time
- sys_tz
.tz_minuteswest
* 60;
141 return time
+ sys_tz
.tz_minuteswest
* 60;
144 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
147 date_dos2unix(unsigned short time
, unsigned short date
)
149 int month
, year
, secs
;
151 month
= ((date
>> 5) & 15) - 1;
153 secs
= (time
& 31) * 2 + 60 * ((time
>> 5) & 63) + (time
>> 11) * 3600 + 86400 *
154 ((date
& 31) - 1 + day_n
[month
] + (year
/ 4) + year
* 365 - ((year
& 3) == 0 &&
155 month
< 2 ? 1 : 0) + 3653);
156 /* days since 1.1.70 plus 80's leap day */
157 return local2utc(secs
);
161 /* Convert linear UNIX date to a MS-DOS time/date pair. */
164 date_unix2dos(int unix_date
, __u8
* date
, __u8
* time
)
166 int day
, year
, nl_day
, month
;
168 unix_date
= utc2local(unix_date
);
170 (unix_date
% 60) / 2 + (((unix_date
/ 60) % 60) << 5) +
171 (((unix_date
/ 3600) % 24) << 11));
172 day
= unix_date
/ 86400 - 3652;
174 if ((year
+ 3) / 4 + 365 * year
> day
)
176 day
-= (year
+ 3) / 4 + 365 * year
;
177 if (day
== 59 && !(year
& 3))
183 nl_day
= (year
& 3) || day
<= 59 ? day
: day
- 1;
184 for (month
= 0; month
< 12; month
++)
185 if (day_n
[month
] > nl_day
)
189 nl_day
- day_n
[month
- 1] + 1 + (month
<< 5) + (year
<< 9));
194 /*****************************************************************************/
196 /* Support section. */
198 /*****************************************************************************/
203 return ((*(p
+1) & 0x1) << 16L) | (*(p
+2) << 8L) | *(p
+3);
207 smb_bcc(__u8
* packet
)
209 int pos
= SMB_HEADER_LEN
+ SMB_WCT(packet
) * sizeof(__u16
);
210 return WVAL(packet
, pos
);
213 /* smb_valid_packet: We check if packet fulfills the basic
214 requirements of a smb packet */
217 smb_valid_packet(__u8
* packet
)
219 return (packet
[4] == 0xff
223 && (smb_len(packet
) + 4 == SMB_HEADER_LEN
224 + SMB_WCT(packet
) * 2 + SMB_BCC(packet
)));
227 /* smb_verify: We check if we got the answer we expected, and if we
228 got enough data. If bcc == -1, we don't care. */
231 smb_verify(__u8
* packet
, int command
, int wct
, int bcc
)
233 return (SMB_CMD(packet
) == command
&&
234 SMB_WCT(packet
) >= wct
&&
235 (bcc
== -1 || SMB_BCC(packet
) >= bcc
)) ? 0 : -EIO
;
239 smb_errno(int errcls
, int error
)
241 if (errcls
== ERRDOS
)
285 return 0; /* Unknown error!! */
286 /* This next error seems to occur on an mv when
287 * the destination exists */
292 } else if (errcls
== ERRSRV
)
305 } else if (errcls
== ERRHRD
)
326 } else if (errcls
== ERRCMD
)
332 smb_lock_server(struct smb_sb_info
*server
)
334 down(&(server
->sem
));
338 smb_unlock_server(struct smb_sb_info
*server
)
343 /* smb_request_ok: We expect the server to be locked. Then we do the
344 request and check the answer completely. When smb_request_ok
345 returns 0, you can be quite sure that everything went well. When
346 the answer is <=0, the returned number is a valid unix errno. */
349 smb_request_ok(struct smb_sb_info
*s
, int command
, int wct
, int bcc
)
355 if (smb_request(s
) < 0)
357 pr_debug("smb_request failed\n");
359 } else if (smb_valid_packet(s
->packet
) != 0)
361 pr_debug("not a valid packet!\n");
363 } else if (s
->rcls
!= 0)
365 result
= -smb_errno(s
->rcls
, s
->err
);
366 } else if (smb_verify(s
->packet
, command
, wct
, bcc
) != 0)
368 pr_debug("smb_verify failed\n");
374 /* smb_retry: This function should be called when smb_request_ok has
375 indicated an error. If the error was indicated because the
376 connection was killed, we try to reconnect. If smb_retry returns 0,
377 the error was indicated for another reason, so a retry would not be
381 smb_retry(struct smb_sb_info
*server
)
383 if (server
->state
!= CONN_INVALID
)
387 if (server
->sock_file
!= NULL
)
389 close_fp(server
->sock_file
);
390 server
->sock_file
= NULL
;
393 if (server
->conn_pid
== 0)
395 server
->state
= CONN_RETRIED
;
399 kill_proc(server
->conn_pid
, SIGUSR1
, 0);
400 server
->conn_pid
= 0;
402 smb_lock_server(server
);
404 if (server
->sock_file
!= NULL
)
406 server
->state
= CONN_VALID
;
413 smb_offerconn(struct smb_sb_info
*server
)
415 if (!suser() && (current
->uid
!= server
->m
.mounted_uid
))
419 server
->conn_pid
= current
->pid
;
424 smb_newconn(struct smb_sb_info
*server
, struct smb_conn_opt
*opt
)
428 if (opt
->fd
>= NR_OPEN
|| !(filp
= current
->files
->fd
[opt
->fd
]))
432 if (!S_ISSOCK(filp
->f_dentry
->d_inode
->i_mode
))
436 if (!suser() && (current
->uid
!= server
->m
.mounted_uid
))
440 if (server
->sock_file
!= NULL
)
442 close_fp(server
->sock_file
);
443 server
->sock_file
= NULL
;
446 server
->sock_file
= filp
;
447 smb_catch_keepalive(server
);
449 pr_debug("smb_newconn: protocol = %d\n", server
->opt
.protocol
);
450 server
->conn_pid
= 0;
451 server
->generation
+= 1;
452 smb_unlock_server(server
);
456 /* smb_setup_header: We completely set up the packet. You only have to
457 insert the command-specific fields */
460 smb_setup_header(struct smb_sb_info
* server
, __u8 command
, __u16 wct
, __u16 bcc
)
462 __u32 xmit_len
= SMB_HEADER_LEN
+ wct
* sizeof(__u16
) + bcc
+ 2;
463 __u8
*p
= server
->packet
;
464 __u8
*buf
= server
->packet
;
466 p
= smb_encode_smb_length(p
, xmit_len
- 4);
478 WSET(buf
, smb_tid
, server
->opt
.tid
);
479 WSET(buf
, smb_pid
, 1);
480 WSET(buf
, smb_uid
, server
->opt
.server_uid
);
481 WSET(buf
, smb_mid
, 1);
483 if (server
->opt
.protocol
> SMB_PROTOCOL_CORE
)
485 *(buf
+smb_flg
) = 0x8;
486 WSET(buf
, smb_flg2
, 0x3);
488 *p
++ = wct
; /* wct */
495 smb_setup_bcc(struct smb_sb_info
*server
, __u8
* p
)
497 __u8
*packet
= server
->packet
;
498 __u8
*pbcc
= packet
+ SMB_HEADER_LEN
+ 2 * SMB_WCT(packet
);
499 __u16 bcc
= p
- (pbcc
+ 2);
502 smb_encode_smb_length(packet
,
503 SMB_HEADER_LEN
+ 2 * SMB_WCT(packet
) - 2 + bcc
);
508 * We're called with the server locked, and we leave it that way. We
509 * try maximum permissions.
513 smb_proc_open(struct dentry
*dir
)
515 struct inode
*ino
= dir
->d_inode
;
516 struct smb_sb_info
*server
= SMB_SERVER(ino
);
521 p
= smb_setup_header(server
, SMBopen
, 2, 0);
522 WSET(server
->packet
, smb_vwv0
, 0x42); /* read/write */
523 WSET(server
->packet
, smb_vwv1
, aSYSTEM
| aHIDDEN
| aDIR
);
525 p
= smb_encode_path(server
, p
, dir
, NULL
);
526 smb_setup_bcc(server
, p
);
528 if ((error
= smb_request_ok(server
, SMBopen
, 7, 0)) != 0)
530 if (smb_retry(server
))
533 if ((error
!= -EACCES
) && (error
!= -ETXTBSY
)
534 && (error
!= -EROFS
))
537 p
= smb_setup_header(server
, SMBopen
, 2, 0);
538 WSET(server
->packet
, smb_vwv0
, 0x40); /* read only */
539 WSET(server
->packet
, smb_vwv1
, aSYSTEM
| aHIDDEN
| aDIR
);
541 p
= smb_encode_path(server
, p
, dir
, NULL
);
542 smb_setup_bcc(server
, p
);
544 if ((error
= smb_request_ok(server
, SMBopen
, 7, 0)) != 0)
546 if (smb_retry(server
))
552 /* We should now have data in vwv[0..6]. */
554 ino
->u
.smbfs_i
.fileid
= WVAL(server
->packet
, smb_vwv0
);
555 ino
->u
.smbfs_i
.attr
= WVAL(server
->packet
, smb_vwv1
);
556 ino
->u
.smbfs_i
.access
= WVAL(server
->packet
, smb_vwv6
);
557 ino
->u
.smbfs_i
.access
&= 3;
559 ino
->u
.smbfs_i
.open
= server
->generation
;
561 pr_debug("smb_proc_open: entry->access = %d\n", ino
->u
.smbfs_i
.access
);
566 smb_open(struct dentry
*dir
, int wish
)
568 struct inode
*i
=dir
->d_inode
;
569 struct smb_sb_info
*server
= SMB_SERVER(i
);
570 int result
= -EACCES
;
572 smb_lock_server(server
);
574 if (!smb_is_open(i
)) {
575 int error
= smb_proc_open(dir
);
577 smb_unlock_server(server
);
582 if (((wish
== O_RDONLY
) && ((i
->u
.smbfs_i
.access
== O_RDONLY
)
583 || (i
->u
.smbfs_i
.access
== O_RDWR
)))
584 || ((wish
== O_WRONLY
) && ((i
->u
.smbfs_i
.access
== O_WRONLY
)
585 || (i
->u
.smbfs_i
.access
== O_RDWR
)))
586 || ((wish
== O_RDWR
) && (i
->u
.smbfs_i
.access
== O_RDWR
)))
589 smb_unlock_server(server
);
593 /* We're called with the server locked */
595 static int smb_proc_close(struct smb_sb_info
*server
,
596 __u16 fileid
, __u32 mtime
)
598 smb_setup_header(server
, SMBclose
, 3, 0);
599 WSET(server
->packet
, smb_vwv0
, fileid
);
600 DSET(server
->packet
, smb_vwv1
, mtime
);
601 return smb_request_ok(server
, SMBclose
, 0, 0);
605 int smb_close(struct dentry
*dir
)
607 struct inode
*ino
= dir
->d_inode
;
608 struct smb_sb_info
*server
= SMB_SERVER(ino
);
611 smb_lock_server(server
);
613 if (!smb_is_open(ino
)) {
614 smb_unlock_server(server
);
618 result
= smb_proc_close(server
, ino
->u
.smbfs_i
.fileid
, ino
->i_mtime
);
619 ino
->u
.smbfs_i
.open
= 0;
620 smb_unlock_server(server
);
624 /* In smb_proc_read and smb_proc_write we do not retry, because the
625 file-id would not be valid after a reconnection. */
627 /* smb_proc_read: fs indicates if it should be copied with
631 smb_proc_read(struct inode
*ino
, off_t offset
, long count
, char *data
)
633 struct smb_sb_info
*server
= SMB_SERVER(ino
);
634 __u16 returned_count
, data_len
;
638 smb_lock_server(server
);
639 smb_setup_header(server
, SMBread
, 5, 0);
640 buf
= server
->packet
;
642 WSET(buf
, smb_vwv0
, ino
->u
.smbfs_i
.fileid
);
643 WSET(buf
, smb_vwv1
, count
);
644 DSET(buf
, smb_vwv2
, offset
);
645 WSET(buf
, smb_vwv4
, 0);
647 if ((error
= smb_request_ok(server
, SMBread
, 5, -1)) < 0)
649 smb_unlock_server(server
);
652 returned_count
= WVAL(buf
, smb_vwv0
);
654 buf
= SMB_BUF(server
->packet
);
655 data_len
= WVAL(buf
, 1);
657 memcpy(data
, buf
+3, data_len
);
659 smb_unlock_server(server
);
661 if (returned_count
!= data_len
)
663 printk(KERN_NOTICE
"smb_proc_read: returned != data_len\n");
664 printk(KERN_NOTICE
"smb_proc_read: ret_c=%d, data_len=%d\n",
665 returned_count
, data_len
);
671 smb_proc_write(struct inode
*ino
, off_t offset
, int count
, const char *data
)
673 struct smb_sb_info
*server
= SMB_SERVER(ino
);
677 smb_lock_server(server
);
678 p
= smb_setup_header(server
, SMBwrite
, 5, count
+ 3);
679 WSET(server
->packet
, smb_vwv0
, ino
->u
.smbfs_i
.fileid
);
680 WSET(server
->packet
, smb_vwv1
, count
);
681 DSET(server
->packet
, smb_vwv2
, offset
);
682 WSET(server
->packet
, smb_vwv4
, 0);
686 memcpy(p
+2, data
, count
);
688 if ((res
= smb_request_ok(server
, SMBwrite
, 1, 0)) >= 0)
689 res
= WVAL(server
->packet
, smb_vwv0
);
691 smb_unlock_server(server
);
697 smb_proc_create(struct dentry
*dir
, struct qstr
*name
,
698 __u16 attr
, time_t ctime
)
702 struct inode
*i
=dir
->d_inode
;
703 struct smb_sb_info
*server
= SMB_SERVER(i
);
706 smb_lock_server(server
);
708 buf
= server
->packet
;
709 p
= smb_setup_header(server
, SMBcreate
, 3, 0);
710 WSET(buf
, smb_vwv0
, attr
);
711 DSET(buf
, smb_vwv1
, utc2local(ctime
));
713 p
= smb_encode_path(server
, p
, dir
, name
);
714 smb_setup_bcc(server
, p
);
716 if ((error
= smb_request_ok(server
, SMBcreate
, 1, 0)) < 0)
718 if (smb_retry(server
))
722 smb_unlock_server(server
);
725 smb_proc_close(server
, WVAL(buf
, smb_vwv0
), CURRENT_TIME
);
726 smb_unlock_server(server
);
732 smb_proc_mv(struct dentry
*odir
, struct qstr
*oname
,
733 struct dentry
*ndir
, struct qstr
*nname
)
736 struct smb_sb_info
*server
= SMB_SERVER(odir
->d_inode
);
739 smb_lock_server(server
);
742 p
= smb_setup_header(server
, SMBmv
, 1, 0);
743 WSET(server
->packet
, smb_vwv0
, aSYSTEM
| aHIDDEN
);
745 p
= smb_encode_path(server
, p
, odir
, oname
);
747 p
= smb_encode_path(server
, p
, ndir
, nname
);
748 smb_setup_bcc(server
, p
);
750 if ((result
= smb_request_ok(server
, SMBmv
, 0, 0)) < 0)
752 if (smb_retry(server
))
757 smb_unlock_server(server
);
762 smb_proc_mkdir(struct dentry
*dir
, struct qstr
*name
)
766 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
768 smb_lock_server(server
);
771 p
= smb_setup_header(server
, SMBmkdir
, 0, 0);
773 p
= smb_encode_path(server
, p
, dir
, name
);
774 smb_setup_bcc(server
, p
);
776 if ((result
= smb_request_ok(server
, SMBmkdir
, 0, 0)) < 0)
778 if (smb_retry(server
))
783 smb_unlock_server(server
);
788 smb_proc_rmdir(struct dentry
*dir
, struct qstr
*name
)
792 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
794 smb_lock_server(server
);
797 p
= smb_setup_header(server
, SMBrmdir
, 0, 0);
799 p
= smb_encode_path(server
, p
, dir
, name
);
800 smb_setup_bcc(server
, p
);
802 if ((result
= smb_request_ok(server
, SMBrmdir
, 0, 0)) < 0)
804 if (smb_retry(server
))
809 smb_unlock_server(server
);
814 smb_proc_unlink(struct dentry
*dir
, struct qstr
*name
)
817 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
820 smb_lock_server(server
);
823 p
= smb_setup_header(server
, SMBunlink
, 1, 0);
824 WSET(server
->packet
, smb_vwv0
, aSYSTEM
| aHIDDEN
);
826 p
= smb_encode_path(server
, p
, dir
, name
);
827 smb_setup_bcc(server
, p
);
829 if ((result
= smb_request_ok(server
, SMBunlink
, 0, 0)) < 0)
831 if (smb_retry(server
))
836 smb_unlock_server(server
);
841 smb_proc_trunc(struct smb_sb_info
*server
, __u16 fid
, __u32 length
)
847 smb_lock_server(server
);
850 buf
= server
->packet
;
851 p
= smb_setup_header(server
, SMBwrite
, 5, 0);
852 WSET(buf
, smb_vwv0
, fid
);
853 WSET(buf
, smb_vwv1
, 0);
854 DSET(buf
, smb_vwv2
, length
);
855 WSET(buf
, smb_vwv4
, 0);
858 smb_setup_bcc(server
, p
);
860 if ((result
= smb_request_ok(server
, SMBwrite
, 1, 0)) < 0)
862 if (smb_retry(server
))
867 smb_unlock_server(server
);
872 smb_init_dirent(struct smb_sb_info
*server
, struct smb_fattr
*fattr
)
874 memset(fattr
, 0, sizeof(*fattr
));
877 fattr
->f_uid
= server
->m
.uid
;
878 fattr
->f_gid
= server
->m
.gid
;
879 fattr
->f_blksize
= 512;
883 smb_finish_dirent(struct smb_sb_info
*server
, struct smb_fattr
*fattr
)
885 if (fattr
->attr
& aDIR
)
887 fattr
->f_mode
= server
->m
.dir_mode
;
891 fattr
->f_mode
= server
->m
.file_mode
;
894 if ((fattr
->f_blksize
!= 0) && (fattr
->f_size
!= 0))
897 (fattr
->f_size
- 1) / fattr
->f_blksize
+ 1;
906 smb_init_root_dirent(struct smb_sb_info
*server
, struct smb_fattr
*fattr
)
908 smb_init_dirent(server
, fattr
);
911 smb_finish_dirent(server
, fattr
);
916 smb_decode_dirent(struct smb_sb_info
*server
, __u8
*p
,
917 struct smb_dirent
*entry
)
919 smb_init_dirent(server
, &(entry
->attr
));
921 p
+= SMB_STATUS_SIZE
; /* reserved (search_status) */
922 entry
->attr
.attr
= *p
;
923 entry
->attr
.f_mtime
= entry
->attr
.f_atime
= entry
->attr
.f_ctime
=
924 date_dos2unix(WVAL(p
, 1), WVAL(p
, 3));
925 entry
->attr
.f_size
= DVAL(p
, 5);
926 entry
->len
= strlen(p
+ 9);
931 memcpy(entry
->name
, p
+ 9, entry
->len
);
932 entry
->name
[entry
->len
] = '\0';
933 while (entry
->len
> 2)
935 /* Pathworks fills names with spaces */
937 if (entry
->name
[entry
->len
] == ' ')
939 entry
->name
[entry
->len
] = '\0';
942 switch (server
->opt
.case_handling
)
945 str_upper(entry
->name
);
948 str_lower(entry
->name
);
953 pr_debug("smb_decode_dirent: name = %s\n", entry
->name
);
954 smb_finish_dirent(server
, &(entry
->attr
));
958 /* This routine is used to read in directory entries from the network.
959 Note that it is for short directory name seeks, i.e.: protocol <
960 SMB_PROTOCOL_LANMAN2 */
963 smb_proc_readdir_short(struct smb_sb_info
*server
, struct dentry
*dir
, int fpos
,
964 int cache_size
, struct smb_dirent
*entry
)
971 int first
, total_count
;
972 struct smb_dirent
*current_entry
;
975 char status
[SMB_STATUS_SIZE
];
976 int entries_asked
= (server
->opt
.max_xmit
- 100) / SMB_DIRINFO_SIZE
;
978 static struct qstr mask
= { "*.*", 3, 0 };
980 pr_debug("SMB call readdir %d @ %d\n", cache_size
, fpos
);
982 smb_lock_server(server
);
985 buf
= server
->packet
;
988 current_entry
= entry
;
994 p
= smb_setup_header(server
, SMBsearch
, 2, 0);
995 WSET(buf
, smb_vwv0
, entries_asked
);
996 WSET(buf
, smb_vwv1
, aDIR
);
998 p
= smb_encode_path(server
, p
, dir
, &mask
);
1004 p
= smb_setup_header(server
, SMBsearch
, 2, 0);
1005 WSET(buf
, smb_vwv0
, entries_asked
);
1006 WSET(buf
, smb_vwv1
, aDIR
);
1010 WSET(p
, 0, SMB_STATUS_SIZE
);
1012 memcpy(p
, status
, SMB_STATUS_SIZE
);
1013 p
+= SMB_STATUS_SIZE
;
1016 smb_setup_bcc(server
, p
);
1018 if ((error
= smb_request_ok(server
, SMBsearch
, 1, -1)) < 0)
1020 if ((server
->rcls
== ERRDOS
)
1021 && (server
->err
== ERRnofiles
))
1023 result
= total_count
- fpos
;
1027 if (smb_retry(server
))
1035 p
= SMB_VWV(server
->packet
);
1043 result
= total_count
- fpos
;
1046 if (bcc
!= count
* SMB_DIRINFO_SIZE
+ 3)
1053 /* Read the last entry into the status field. */
1055 SMB_BUF(server
->packet
) + 3 +
1056 (count
- 1) * SMB_DIRINFO_SIZE
,
1059 /* Now we are ready to parse smb directory entries. */
1061 for (i
= 0; i
< count
; i
++)
1063 if (total_count
< fpos
)
1065 p
+= SMB_DIRINFO_SIZE
;
1066 pr_debug("smb_proc_readdir: skipped entry.\n");
1067 pr_debug(" total_count = %d\n"
1068 " i = %d, fpos = %d\n",
1069 total_count
, i
, fpos
);
1070 } else if (total_count
>= fpos
+ cache_size
)
1072 result
= total_count
- fpos
;
1076 p
= smb_decode_dirent(server
, p
,
1078 current_entry
->f_pos
= total_count
;
1079 pr_debug("smb_proc_readdir: entry->f_pos = "
1080 "%u\n", entry
->f_pos
);
1087 smb_unlock_server(server
);
1091 /* interpret a long filename structure - this is mostly guesses at the
1092 moment. The length of the structure is returned. The structure of
1093 a long filename depends on the info level. 260 is used by NT and 2
1097 smb_decode_long_dirent(struct smb_sb_info
*server
, char *p
,
1098 struct smb_dirent
*entry
, int level
)
1102 smb_init_dirent(server
, &(entry
->attr
));
1106 /* We might add more levels later... */
1108 entry
->len
= *(p
+26);
1109 strncpy(entry
->name
, p
+ 27, entry
->len
);
1110 entry
->name
[entry
->len
] = '\0';
1111 entry
->attr
.f_size
= DVAL(p
, 16);
1112 entry
->attr
.attr
= *(p
+24);
1114 entry
->attr
.f_ctime
= date_dos2unix(WVAL(p
, 6), WVAL(p
, 4));
1115 entry
->attr
.f_atime
= date_dos2unix(WVAL(p
, 10), WVAL(p
, 8));
1116 entry
->attr
.f_mtime
= date_dos2unix(WVAL(p
, 14), WVAL(p
, 12));
1117 result
= p
+ 28 + *(p
+26);
1121 pr_debug("Unknown long filename format %d\n", level
);
1122 result
= p
+ WVAL(p
, 0);
1125 switch (server
->opt
.case_handling
)
1127 case SMB_CASE_UPPER
:
1128 str_upper(entry
->name
);
1130 case SMB_CASE_LOWER
:
1131 str_lower(entry
->name
);
1137 smb_finish_dirent(server
, &(entry
->attr
));
1142 smb_proc_readdir_long(struct smb_sb_info
*server
, struct dentry
*dir
, int fpos
,
1143 int cache_size
, struct smb_dirent
*cache
)
1145 /* NT uses 260, OS/2 uses 2. Both accept 1. */
1146 const int info_level
= 1;
1147 const int max_matches
= 512;
1153 int first
, entries
, entries_seen
;
1155 unsigned char *resp_data
= NULL
;
1156 unsigned char *resp_param
= NULL
;
1157 int resp_data_len
= 0;
1158 int resp_param_len
= 0;
1164 int ff_resume_key
= 0;
1165 int ff_searchcount
= 0;
1167 int ff_lastname
= 0;
1168 int ff_dir_handle
= 0;
1171 char param
[SMB_MAXPATHLEN
+ 2 + 12];
1173 char *mask
= &(param
[12]);
1175 static struct qstr star
= { "*", 1, 0 };
1177 mask_len
= smb_encode_path(server
, mask
, dir
, &star
) - mask
;
1180 mask
[mask_len
+ 1] = 0;
1182 pr_debug("smb_readdir_long cache=%d, fpos=%d, mask=%s\n",
1183 cache_size
, fpos
, mask
);
1185 smb_lock_server(server
);
1196 if (loop_count
> 200)
1198 printk(KERN_WARNING
"smb_proc_readdir_long: "
1199 "Looping in FIND_NEXT??\n");
1204 command
= TRANSACT2_FINDFIRST
;
1205 WSET(param
, 0, aSYSTEM
| aHIDDEN
| aDIR
);
1206 WSET(param
, 2, max_matches
); /* max count */
1207 WSET(param
, 4, 8 + 4 + 2); /* resume required +
1210 WSET(param
, 6, info_level
);
1214 command
= TRANSACT2_FINDNEXT
;
1215 pr_debug("hand=0x%X resume=%d ff_lastnm=%d mask=%s\n",
1216 ff_dir_handle
, ff_resume_key
, ff_lastname
,
1218 WSET(param
, 0, ff_dir_handle
);
1219 WSET(param
, 2, max_matches
); /* max count */
1220 WSET(param
, 4, info_level
);
1221 DSET(param
, 6, ff_resume_key
); /* ff_resume_key */
1222 WSET(param
, 10, 8 + 4 + 2); /* resume required +
1225 #ifdef CONFIG_SMB_WIN95
1226 /* Windows 95 is not able to deliver answers
1227 to FIND_NEXT fast enough, so sleep 0.2 seconds */
1228 current
->timeout
= jiffies
+ HZ
/ 5;
1229 current
->state
= TASK_INTERRUPTIBLE
;
1231 current
->timeout
= 0;
1235 result
= smb_trans2_request(server
, command
,
1236 0, NULL
, 12 + mask_len
+ 2, param
,
1237 &resp_data_len
, &resp_data
,
1238 &resp_param_len
, &resp_param
);
1242 if (smb_retry(server
))
1246 pr_debug("smb_proc_readdir_long: "
1247 "got error from trans2_request\n");
1250 if (server
->rcls
!= 0)
1255 /* parse out some important return info */
1258 ff_dir_handle
= WVAL(resp_param
, 0);
1259 ff_searchcount
= WVAL(resp_param
, 2);
1260 ff_eos
= WVAL(resp_param
, 4);
1261 ff_lastname
= WVAL(resp_param
, 8);
1264 ff_searchcount
= WVAL(resp_param
, 0);
1265 ff_eos
= WVAL(resp_param
, 2);
1266 ff_lastname
= WVAL(resp_param
, 6);
1269 if (ff_searchcount
== 0)
1273 /* point to the data bytes */
1276 /* we might need the lastname for continuations */
1279 if (ff_lastname
> 0)
1284 lastname
= p
+ ff_lastname
;
1285 lastname_len
= resp_data_len
- ff_lastname
;
1289 lastname
= p
+ ff_lastname
+ 1;
1290 lastname_len
= *(p
+ff_lastname
);
1295 lastname_len
= min(lastname_len
, 256);
1296 strncpy(mask
, lastname
, lastname_len
);
1297 mask
[lastname_len
] = '\0';
1299 /* Now we are ready to parse smb directory entries. */
1301 for (i
= 0; i
< ff_searchcount
; i
++)
1303 struct smb_dirent
*entry
= &(cache
[entries
]);
1305 p
= smb_decode_long_dirent(server
, p
,
1308 pr_debug("smb_readdir_long: got %s\n", entry
->name
);
1310 if ((entry
->name
[0] == '.')
1311 && ((entry
->name
[1] == '\0')
1312 || ((entry
->name
[1] == '.')
1313 && (entry
->name
[2] == '\0'))))
1315 /* ignore . and .. from the server */
1318 if (entries_seen
>= fpos
)
1320 entry
->f_pos
= entries_seen
;
1323 if (entries
>= cache_size
)
1330 pr_debug("received %d entries (eos=%d resume=%d)\n",
1331 ff_searchcount
, ff_eos
, ff_resume_key
);
1337 smb_unlock_server(server
);
1342 smb_proc_readdir(struct dentry
*dir
, int fpos
,
1343 int cache_size
, struct smb_dirent
*entry
)
1345 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
1347 if (server
->opt
.protocol
>= SMB_PROTOCOL_LANMAN2
)
1348 return smb_proc_readdir_long(server
, dir
, fpos
, cache_size
,
1351 return smb_proc_readdir_short(server
, dir
, fpos
, cache_size
,
1356 smb_proc_getattr_core(struct dentry
*dir
, struct qstr
*name
,
1357 struct smb_fattr
*attr
)
1361 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
1364 smb_lock_server(server
);
1367 buf
= server
->packet
;
1368 p
= smb_setup_header(server
, SMBgetatr
, 0, 0);
1370 p
= smb_encode_path(server
, p
, dir
, name
);
1371 smb_setup_bcc(server
, p
);
1373 if ((result
= smb_request_ok(server
, SMBgetatr
, 10, 0)) < 0)
1375 if (smb_retry(server
))
1379 smb_unlock_server(server
);
1382 attr
->attr
= WVAL(buf
, smb_vwv0
);
1383 attr
->f_ctime
= attr
->f_atime
=
1384 attr
->f_mtime
= local2utc(DVAL(buf
, smb_vwv1
));
1386 attr
->f_size
= DVAL(buf
, smb_vwv3
);
1387 smb_unlock_server(server
);
1392 smb_proc_getattr_trans2(struct dentry
*dir
, struct qstr
*name
,
1393 struct smb_fattr
*attr
)
1395 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
1396 char param
[SMB_MAXPATHLEN
+ 20];
1400 unsigned char *resp_data
= NULL
;
1401 unsigned char *resp_param
= NULL
;
1402 int resp_data_len
= 0;
1403 int resp_param_len
= 0;
1405 WSET(param
, 0, 1); /* Info level SMB_INFO_STANDARD */
1407 p
= smb_encode_path(server
, param
+ 6, dir
, name
);
1409 smb_lock_server(server
);
1411 result
= smb_trans2_request(server
, TRANSACT2_QPATHINFO
,
1412 0, NULL
, p
- param
, param
,
1413 &resp_data_len
, &resp_data
,
1414 &resp_param_len
, &resp_param
);
1416 if (server
->rcls
!= 0)
1418 smb_unlock_server(server
);
1419 return -smb_errno(server
->rcls
, server
->err
);
1423 if (smb_retry(server
))
1427 smb_unlock_server(server
);
1430 if (resp_data_len
< 22)
1432 smb_unlock_server(server
);
1435 attr
->f_ctime
= date_dos2unix(WVAL(resp_data
, 2),
1436 WVAL(resp_data
, 0));
1437 attr
->f_atime
= date_dos2unix(WVAL(resp_data
, 6),
1438 WVAL(resp_data
, 4));
1439 attr
->f_mtime
= date_dos2unix(WVAL(resp_data
, 10),
1440 WVAL(resp_data
, 8));
1441 attr
->f_size
= DVAL(resp_data
, 12);
1442 attr
->attr
= WVAL(resp_data
, 20);
1443 smb_unlock_server(server
);
1448 int smb_proc_getattr(struct dentry
*dir
, struct qstr
*name
,
1449 struct smb_fattr
*fattr
)
1451 struct smb_sb_info
*server
= SMB_SERVER(dir
->d_inode
);
1454 smb_init_dirent(server
, fattr
);
1456 if (server
->opt
.protocol
>= SMB_PROTOCOL_LANMAN2
)
1457 result
= smb_proc_getattr_trans2(dir
, name
, fattr
);
1459 if ((server
->opt
.protocol
< SMB_PROTOCOL_LANMAN2
) || (result
< 0))
1460 result
= smb_proc_getattr_core(dir
, name
, fattr
);
1462 smb_finish_dirent(server
, fattr
);
1468 /* In core protocol, there is only 1 time to be set, we use
1469 entry->f_mtime, to make touch work. */
1471 smb_proc_setattr_core(struct smb_sb_info
*server
,
1472 struct dentry
*dir
, struct smb_fattr
*fattr
)
1478 smb_lock_server(server
);
1481 buf
= server
->packet
;
1482 p
= smb_setup_header(server
, SMBsetatr
, 8, 0);
1483 WSET(buf
, smb_vwv0
, fattr
->attr
);
1484 DSET(buf
, smb_vwv1
, utc2local(fattr
->f_mtime
));
1486 p
= smb_encode_path(server
, p
, dir
, NULL
);
1490 smb_setup_bcc(server
, p
);
1491 if ((result
= smb_request_ok(server
, SMBsetatr
, 0, 0)) < 0)
1492 if (smb_retry(server
))
1495 smb_unlock_server(server
);
1500 smb_proc_setattr_trans2(struct smb_sb_info
*server
,
1501 struct dentry
*dir
, struct smb_fattr
*fattr
)
1503 char param
[SMB_MAXPATHLEN
+ 20];
1508 unsigned char *resp_data
= NULL
;
1509 unsigned char *resp_param
= NULL
;
1510 int resp_data_len
= 0;
1511 int resp_param_len
= 0;
1513 WSET(param
, 0, 1); /* Info level SMB_INFO_STANDARD */
1515 p
= smb_encode_path(server
, param
+ 6, dir
, NULL
);
1517 date_unix2dos(fattr
->f_ctime
, &(data
[0]), &(data
[2]));
1518 date_unix2dos(fattr
->f_atime
, &(data
[4]), &(data
[6]));
1519 date_unix2dos(fattr
->f_mtime
, &(data
[8]), &(data
[10]));
1520 DSET(data
, 12, fattr
->f_size
);
1521 DSET(data
, 16, fattr
->f_blksize
);
1522 WSET(data
, 20, fattr
->attr
);
1525 smb_lock_server(server
);
1527 result
= smb_trans2_request(server
, TRANSACT2_SETPATHINFO
,
1528 26, data
, p
- param
, param
,
1529 &resp_data_len
, &resp_data
,
1530 &resp_param_len
, &resp_param
);
1532 if (server
->rcls
!= 0)
1534 smb_unlock_server(server
);
1535 return -smb_errno(server
->rcls
, server
->err
);
1538 if (smb_retry(server
))
1541 smb_unlock_server(server
);
1546 smb_proc_setattr(struct smb_sb_info
*server
, struct dentry
*dir
,
1547 struct smb_fattr
*fattr
)
1551 if (server
->opt
.protocol
>= SMB_PROTOCOL_LANMAN2
)
1552 result
= smb_proc_setattr_trans2(server
, dir
, fattr
);
1554 if ((server
->opt
.protocol
< SMB_PROTOCOL_LANMAN2
) || (result
< 0))
1555 result
= smb_proc_setattr_core(server
, dir
, fattr
);
1561 smb_proc_dskattr(struct super_block
*sb
, struct statfs
*attr
)
1565 struct smb_sb_info
*server
= &(sb
->u
.smbfs_sb
);
1567 smb_lock_server(server
);
1570 smb_setup_header(server
, SMBdskattr
, 0, 0);
1572 if ((error
= smb_request_ok(server
, SMBdskattr
, 5, 0)) < 0)
1574 if (smb_retry(server
))
1577 smb_unlock_server(server
);
1580 p
= SMB_VWV(server
->packet
);
1581 attr
->f_bsize
= WVAL(p
, 2) * WVAL(p
, 4);
1582 attr
->f_blocks
= WVAL(p
, 0);
1583 attr
->f_bavail
= attr
->f_bfree
= WVAL(p
, 6);
1584 smb_unlock_server(server
);
1589 smb_proc_disconnect(struct smb_sb_info
*server
)
1592 smb_lock_server(server
);
1593 smb_setup_header(server
, SMBtdis
, 0, 0);
1594 result
= smb_request_ok(server
, SMBtdis
, 0, 0);
1595 smb_unlock_server(server
);