at v2.6.21 86 kB view raw
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/capability.h> 12#include <linux/errno.h> 13#include <linux/slab.h> 14#include <linux/fs.h> 15#include <linux/file.h> 16#include <linux/stat.h> 17#include <linux/fcntl.h> 18#include <linux/dcache.h> 19#include <linux/dirent.h> 20#include <linux/nls.h> 21#include <linux/smp_lock.h> 22#include <linux/net.h> 23#include <linux/vfs.h> 24#include <linux/smb_fs.h> 25#include <linux/smbno.h> 26#include <linux/smb_mount.h> 27 28#include <net/sock.h> 29 30#include <asm/string.h> 31#include <asm/div64.h> 32 33#include "smb_debug.h" 34#include "proto.h" 35#include "request.h" 36 37 38/* Features. Undefine if they cause problems, this should perhaps be a 39 config option. */ 40#define SMBFS_POSIX_UNLINK 1 41 42/* Allow smb_retry to be interrupted. */ 43#define SMB_RETRY_INTR 44 45#define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN) 46#define SMB_CMD(packet) (*(packet+8)) 47#define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1)) 48 49#define SMB_DIRINFO_SIZE 43 50#define SMB_STATUS_SIZE 21 51 52#define SMB_ST_BLKSIZE (PAGE_SIZE) 53#define SMB_ST_BLKSHIFT (PAGE_SHIFT) 54 55static struct smb_ops smb_ops_core; 56static struct smb_ops smb_ops_os2; 57static struct smb_ops smb_ops_win95; 58static struct smb_ops smb_ops_winNT; 59static struct smb_ops smb_ops_unix; 60static struct smb_ops smb_ops_null; 61 62static void 63smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr); 64static void 65smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr); 66static int 67smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, 68 struct smb_fattr *fattr); 69static int 70smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, 71 struct smb_fattr *fattr); 72static int 73smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, 74 u16 attr); 75static int 76smb_proc_setattr_ext(struct smb_sb_info *server, 77 struct inode *inode, struct smb_fattr *fattr); 78static int 79smb_proc_query_cifsunix(struct smb_sb_info *server); 80static void 81install_ops(struct smb_ops *dst, struct smb_ops *src); 82 83 84static void 85str_upper(char *name, int len) 86{ 87 while (len--) 88 { 89 if (*name >= 'a' && *name <= 'z') 90 *name -= ('a' - 'A'); 91 name++; 92 } 93} 94 95#if 0 96static void 97str_lower(char *name, int len) 98{ 99 while (len--) 100 { 101 if (*name >= 'A' && *name <= 'Z') 102 *name += ('a' - 'A'); 103 name++; 104 } 105} 106#endif 107 108/* reverse a string inline. This is used by the dircache walking routines */ 109static void reverse_string(char *buf, int len) 110{ 111 char c; 112 char *end = buf+len-1; 113 114 while(buf < end) { 115 c = *buf; 116 *(buf++) = *end; 117 *(end--) = c; 118 } 119} 120 121/* no conversion, just a wrapper for memcpy. */ 122static int convert_memcpy(unsigned char *output, int olen, 123 const unsigned char *input, int ilen, 124 struct nls_table *nls_from, 125 struct nls_table *nls_to) 126{ 127 if (olen < ilen) 128 return -ENAMETOOLONG; 129 memcpy(output, input, ilen); 130 return ilen; 131} 132 133static inline int write_char(unsigned char ch, char *output, int olen) 134{ 135 if (olen < 4) 136 return -ENAMETOOLONG; 137 sprintf(output, ":x%02x", ch); 138 return 4; 139} 140 141static inline int write_unichar(wchar_t ch, char *output, int olen) 142{ 143 if (olen < 5) 144 return -ENAMETOOLONG; 145 sprintf(output, ":%04x", ch); 146 return 5; 147} 148 149/* convert from one "codepage" to another (possibly being utf8). */ 150static int convert_cp(unsigned char *output, int olen, 151 const unsigned char *input, int ilen, 152 struct nls_table *nls_from, 153 struct nls_table *nls_to) 154{ 155 int len = 0; 156 int n; 157 wchar_t ch; 158 159 while (ilen > 0) { 160 /* convert by changing to unicode and back to the new cp */ 161 n = nls_from->char2uni(input, ilen, &ch); 162 if (n == -EINVAL) { 163 ilen--; 164 n = write_char(*input++, output, olen); 165 if (n < 0) 166 goto fail; 167 output += n; 168 olen -= n; 169 len += n; 170 continue; 171 } else if (n < 0) 172 goto fail; 173 input += n; 174 ilen -= n; 175 176 n = nls_to->uni2char(ch, output, olen); 177 if (n == -EINVAL) 178 n = write_unichar(ch, output, olen); 179 if (n < 0) 180 goto fail; 181 output += n; 182 olen -= n; 183 184 len += n; 185 } 186 return len; 187fail: 188 return n; 189} 190 191/* ----------------------------------------------------------- */ 192 193/* 194 * nls_unicode 195 * 196 * This encodes/decodes little endian unicode format 197 */ 198 199static int uni2char(wchar_t uni, unsigned char *out, int boundlen) 200{ 201 if (boundlen < 2) 202 return -EINVAL; 203 *out++ = uni & 0xff; 204 *out++ = uni >> 8; 205 return 2; 206} 207 208static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni) 209{ 210 if (boundlen < 2) 211 return -EINVAL; 212 *uni = (rawstring[1] << 8) | rawstring[0]; 213 return 2; 214} 215 216static struct nls_table unicode_table = { 217 .charset = "unicode", 218 .uni2char = uni2char, 219 .char2uni = char2uni, 220}; 221 222/* ----------------------------------------------------------- */ 223 224static int setcodepage(struct nls_table **p, char *name) 225{ 226 struct nls_table *nls; 227 228 if (!name || !*name) { 229 nls = NULL; 230 } else if ( (nls = load_nls(name)) == NULL) { 231 printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name); 232 return -EINVAL; 233 } 234 235 /* if already set, unload the previous one. */ 236 if (*p && *p != &unicode_table) 237 unload_nls(*p); 238 *p = nls; 239 240 return 0; 241} 242 243/* Handles all changes to codepage settings. */ 244int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp) 245{ 246 int n = 0; 247 248 smb_lock_server(server); 249 250 /* Don't load any nls_* at all, if no remote is requested */ 251 if (!*cp->remote_name) 252 goto out; 253 254 /* local */ 255 n = setcodepage(&server->local_nls, cp->local_name); 256 if (n != 0) 257 goto out; 258 259 /* remote */ 260 if (!strcmp(cp->remote_name, "unicode")) { 261 server->remote_nls = &unicode_table; 262 } else { 263 n = setcodepage(&server->remote_nls, cp->remote_name); 264 if (n != 0) 265 setcodepage(&server->local_nls, NULL); 266 } 267 268out: 269 if (server->local_nls != NULL && server->remote_nls != NULL) 270 server->ops->convert = convert_cp; 271 else 272 server->ops->convert = convert_memcpy; 273 274 smb_unlock_server(server); 275 return n; 276} 277 278 279/*****************************************************************************/ 280/* */ 281/* Encoding/Decoding section */ 282/* */ 283/*****************************************************************************/ 284 285static __u8 * 286smb_encode_smb_length(__u8 * p, __u32 len) 287{ 288 *p = 0; 289 *(p+1) = 0; 290 *(p+2) = (len & 0xFF00) >> 8; 291 *(p+3) = (len & 0xFF); 292 if (len > 0xFFFF) 293 { 294 *(p+1) = 1; 295 } 296 return p + 4; 297} 298 299/* 300 * smb_build_path: build the path to entry and name storing it in buf. 301 * The path returned will have the trailing '\0'. 302 */ 303static int smb_build_path(struct smb_sb_info *server, unsigned char *buf, 304 int maxlen, 305 struct dentry *entry, struct qstr *name) 306{ 307 unsigned char *path = buf; 308 int len; 309 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE) != 0; 310 311 if (maxlen < (2<<unicode)) 312 return -ENAMETOOLONG; 313 314 if (maxlen > SMB_MAXPATHLEN + 1) 315 maxlen = SMB_MAXPATHLEN + 1; 316 317 if (entry == NULL) 318 goto test_name_and_out; 319 320 /* 321 * If IS_ROOT, we have to do no walking at all. 322 */ 323 if (IS_ROOT(entry) && !name) { 324 *path++ = '\\'; 325 if (unicode) *path++ = '\0'; 326 *path++ = '\0'; 327 if (unicode) *path++ = '\0'; 328 return path-buf; 329 } 330 331 /* 332 * Build the path string walking the tree backward from end to ROOT 333 * and store it in reversed order [see reverse_string()] 334 */ 335 dget(entry); 336 spin_lock(&entry->d_lock); 337 while (!IS_ROOT(entry)) { 338 struct dentry *parent; 339 340 if (maxlen < (3<<unicode)) { 341 spin_unlock(&entry->d_lock); 342 dput(entry); 343 return -ENAMETOOLONG; 344 } 345 346 len = server->ops->convert(path, maxlen-2, 347 entry->d_name.name, entry->d_name.len, 348 server->local_nls, server->remote_nls); 349 if (len < 0) { 350 spin_unlock(&entry->d_lock); 351 dput(entry); 352 return len; 353 } 354 reverse_string(path, len); 355 path += len; 356 if (unicode) { 357 /* Note: reverse order */ 358 *path++ = '\0'; 359 maxlen--; 360 } 361 *path++ = '\\'; 362 maxlen -= len+1; 363 364 parent = entry->d_parent; 365 dget(parent); 366 spin_unlock(&entry->d_lock); 367 dput(entry); 368 entry = parent; 369 spin_lock(&entry->d_lock); 370 } 371 spin_unlock(&entry->d_lock); 372 dput(entry); 373 reverse_string(buf, path-buf); 374 375 /* maxlen has space for at least one char */ 376test_name_and_out: 377 if (name) { 378 if (maxlen < (3<<unicode)) 379 return -ENAMETOOLONG; 380 *path++ = '\\'; 381 if (unicode) { 382 *path++ = '\0'; 383 maxlen--; 384 } 385 len = server->ops->convert(path, maxlen-2, 386 name->name, name->len, 387 server->local_nls, server->remote_nls); 388 if (len < 0) 389 return len; 390 path += len; 391 maxlen -= len+1; 392 } 393 /* maxlen has space for at least one char */ 394 *path++ = '\0'; 395 if (unicode) *path++ = '\0'; 396 return path-buf; 397} 398 399static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen, 400 struct dentry *dir, struct qstr *name) 401{ 402 int result; 403 404 result = smb_build_path(server, buf, maxlen, dir, name); 405 if (result < 0) 406 goto out; 407 if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS) 408 str_upper(buf, result); 409out: 410 return result; 411} 412 413/* encode_path for non-trans2 request SMBs */ 414static int smb_simple_encode_path(struct smb_request *req, char **p, 415 struct dentry * entry, struct qstr * name) 416{ 417 struct smb_sb_info *server = req->rq_server; 418 char *s = *p; 419 int res; 420 int maxlen = ((char *)req->rq_buffer + req->rq_bufsize) - s; 421 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE); 422 423 if (!maxlen) 424 return -ENAMETOOLONG; 425 *s++ = 4; /* ASCII data format */ 426 427 /* 428 * SMB Unicode strings must be 16bit aligned relative the start of the 429 * packet. If they are not they must be padded with 0. 430 */ 431 if (unicode) { 432 int align = s - (char *)req->rq_buffer; 433 if (!(align & 1)) { 434 *s++ = '\0'; 435 maxlen--; 436 } 437 } 438 439 res = smb_encode_path(server, s, maxlen-1, entry, name); 440 if (res < 0) 441 return res; 442 *p = s + res; 443 return 0; 444} 445 446/* The following are taken directly from msdos-fs */ 447 448/* Linear day numbers of the respective 1sts in non-leap years. */ 449 450static int day_n[] = 451{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; 452 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ 453 454 455static time_t 456utc2local(struct smb_sb_info *server, time_t time) 457{ 458 return time - server->opt.serverzone*60; 459} 460 461static time_t 462local2utc(struct smb_sb_info *server, time_t time) 463{ 464 return time + server->opt.serverzone*60; 465} 466 467/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ 468 469static time_t 470date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time) 471{ 472 int month, year; 473 time_t secs; 474 475 /* first subtract and mask after that... Otherwise, if 476 date == 0, bad things happen */ 477 month = ((date >> 5) - 1) & 15; 478 year = date >> 9; 479 secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 * 480 ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 && 481 month < 2 ? 1 : 0) + 3653); 482 /* days since 1.1.70 plus 80's leap day */ 483 return local2utc(server, secs); 484} 485 486 487/* Convert linear UNIX date to a MS-DOS time/date pair. */ 488 489static void 490date_unix2dos(struct smb_sb_info *server, 491 int unix_date, __u16 *date, __u16 *time) 492{ 493 int day, year, nl_day, month; 494 495 unix_date = utc2local(server, unix_date); 496 if (unix_date < 315532800) 497 unix_date = 315532800; 498 499 *time = (unix_date % 60) / 2 + 500 (((unix_date / 60) % 60) << 5) + 501 (((unix_date / 3600) % 24) << 11); 502 503 day = unix_date / 86400 - 3652; 504 year = day / 365; 505 if ((year + 3) / 4 + 365 * year > day) 506 year--; 507 day -= (year + 3) / 4 + 365 * year; 508 if (day == 59 && !(year & 3)) { 509 nl_day = day; 510 month = 2; 511 } else { 512 nl_day = (year & 3) || day <= 59 ? day : day - 1; 513 for (month = 0; month < 12; month++) 514 if (day_n[month] > nl_day) 515 break; 516 } 517 *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9); 518} 519 520/* The following are taken from fs/ntfs/util.c */ 521 522#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) 523 524/* 525 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) 526 * into Unix UTC (based 1970-01-01, in seconds). 527 */ 528static struct timespec 529smb_ntutc2unixutc(u64 ntutc) 530{ 531 struct timespec ts; 532 /* FIXME: what about the timezone difference? */ 533 /* Subtract the NTFS time offset, then convert to 1s intervals. */ 534 u64 t = ntutc - NTFS_TIME_OFFSET; 535 ts.tv_nsec = do_div(t, 10000000) * 100; 536 ts.tv_sec = t; 537 return ts; 538} 539 540/* Convert the Unix UTC into NT time */ 541static u64 542smb_unixutc2ntutc(struct timespec ts) 543{ 544 /* Note: timezone conversion is probably wrong. */ 545 /* return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET; */ 546 return ((u64)ts.tv_sec) * 10000000 + ts.tv_nsec/100 + NTFS_TIME_OFFSET; 547} 548 549#define MAX_FILE_MODE 6 550static mode_t file_mode[] = { 551 S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK 552}; 553 554static int smb_filetype_to_mode(u32 filetype) 555{ 556 if (filetype > MAX_FILE_MODE) { 557 PARANOIA("Filetype out of range: %d\n", filetype); 558 return S_IFREG; 559 } 560 return file_mode[filetype]; 561} 562 563static u32 smb_filetype_from_mode(int mode) 564{ 565 if (S_ISREG(mode)) 566 return UNIX_TYPE_FILE; 567 if (S_ISDIR(mode)) 568 return UNIX_TYPE_DIR; 569 if (S_ISLNK(mode)) 570 return UNIX_TYPE_SYMLINK; 571 if (S_ISCHR(mode)) 572 return UNIX_TYPE_CHARDEV; 573 if (S_ISBLK(mode)) 574 return UNIX_TYPE_BLKDEV; 575 if (S_ISFIFO(mode)) 576 return UNIX_TYPE_FIFO; 577 if (S_ISSOCK(mode)) 578 return UNIX_TYPE_SOCKET; 579 return UNIX_TYPE_UNKNOWN; 580} 581 582 583/*****************************************************************************/ 584/* */ 585/* Support section. */ 586/* */ 587/*****************************************************************************/ 588 589__u32 590smb_len(__u8 * p) 591{ 592 return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3); 593} 594 595static __u16 596smb_bcc(__u8 * packet) 597{ 598 int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16); 599 return WVAL(packet, pos); 600} 601 602/* smb_valid_packet: We check if packet fulfills the basic 603 requirements of a smb packet */ 604 605static int 606smb_valid_packet(__u8 * packet) 607{ 608 return (packet[4] == 0xff 609 && packet[5] == 'S' 610 && packet[6] == 'M' 611 && packet[7] == 'B' 612 && (smb_len(packet) + 4 == SMB_HEADER_LEN 613 + SMB_WCT(packet) * 2 + smb_bcc(packet))); 614} 615 616/* smb_verify: We check if we got the answer we expected, and if we 617 got enough data. If bcc == -1, we don't care. */ 618 619static int 620smb_verify(__u8 * packet, int command, int wct, int bcc) 621{ 622 if (SMB_CMD(packet) != command) 623 goto bad_command; 624 if (SMB_WCT(packet) < wct) 625 goto bad_wct; 626 if (bcc != -1 && smb_bcc(packet) < bcc) 627 goto bad_bcc; 628 return 0; 629 630bad_command: 631 printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n", 632 command, SMB_CMD(packet)); 633 goto fail; 634bad_wct: 635 printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n", 636 command, wct, SMB_WCT(packet)); 637 goto fail; 638bad_bcc: 639 printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n", 640 command, bcc, smb_bcc(packet)); 641fail: 642 return -EIO; 643} 644 645/* 646 * Returns the maximum read or write size for the "payload". Making all of the 647 * packet fit within the negotiated max_xmit size. 648 * 649 * N.B. Since this value is usually computed before locking the server, 650 * the server's packet size must never be decreased! 651 */ 652static inline int 653smb_get_xmitsize(struct smb_sb_info *server, int overhead) 654{ 655 return server->opt.max_xmit - overhead; 656} 657 658/* 659 * Calculate the maximum read size 660 */ 661int 662smb_get_rsize(struct smb_sb_info *server) 663{ 664 /* readX has 12 parameters, read has 5 */ 665 int overhead = SMB_HEADER_LEN + 12 * sizeof(__u16) + 2 + 1 + 2; 666 int size = smb_get_xmitsize(server, overhead); 667 668 VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size); 669 670 return size; 671} 672 673/* 674 * Calculate the maximum write size 675 */ 676int 677smb_get_wsize(struct smb_sb_info *server) 678{ 679 /* writeX has 14 parameters, write has 5 */ 680 int overhead = SMB_HEADER_LEN + 14 * sizeof(__u16) + 2 + 1 + 2; 681 int size = smb_get_xmitsize(server, overhead); 682 683 VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size); 684 685 return size; 686} 687 688/* 689 * Convert SMB error codes to -E... errno values. 690 */ 691int 692smb_errno(struct smb_request *req) 693{ 694 int errcls = req->rq_rcls; 695 int error = req->rq_err; 696 char *class = "Unknown"; 697 698 VERBOSE("errcls %d code %d from command 0x%x\n", 699 errcls, error, SMB_CMD(req->rq_header)); 700 701 if (errcls == ERRDOS) { 702 switch (error) { 703 case ERRbadfunc: 704 return -EINVAL; 705 case ERRbadfile: 706 case ERRbadpath: 707 return -ENOENT; 708 case ERRnofids: 709 return -EMFILE; 710 case ERRnoaccess: 711 return -EACCES; 712 case ERRbadfid: 713 return -EBADF; 714 case ERRbadmcb: 715 return -EREMOTEIO; 716 case ERRnomem: 717 return -ENOMEM; 718 case ERRbadmem: 719 return -EFAULT; 720 case ERRbadenv: 721 case ERRbadformat: 722 return -EREMOTEIO; 723 case ERRbadaccess: 724 return -EACCES; 725 case ERRbaddata: 726 return -E2BIG; 727 case ERRbaddrive: 728 return -ENXIO; 729 case ERRremcd: 730 return -EREMOTEIO; 731 case ERRdiffdevice: 732 return -EXDEV; 733 case ERRnofiles: 734 return -ENOENT; 735 case ERRbadshare: 736 return -ETXTBSY; 737 case ERRlock: 738 return -EDEADLK; 739 case ERRfilexists: 740 return -EEXIST; 741 case ERROR_INVALID_PARAMETER: 742 return -EINVAL; 743 case ERROR_DISK_FULL: 744 return -ENOSPC; 745 case ERROR_INVALID_NAME: 746 return -ENOENT; 747 case ERROR_DIR_NOT_EMPTY: 748 return -ENOTEMPTY; 749 case ERROR_NOT_LOCKED: 750 return -ENOLCK; 751 case ERROR_ALREADY_EXISTS: 752 return -EEXIST; 753 default: 754 class = "ERRDOS"; 755 goto err_unknown; 756 } 757 } else if (errcls == ERRSRV) { 758 switch (error) { 759 /* N.B. This is wrong ... EIO ? */ 760 case ERRerror: 761 return -ENFILE; 762 case ERRbadpw: 763 return -EINVAL; 764 case ERRbadtype: 765 case ERRtimeout: 766 return -EIO; 767 case ERRaccess: 768 return -EACCES; 769 /* 770 * This is a fatal error, as it means the "tree ID" 771 * for this connection is no longer valid. We map 772 * to a special error code and get a new connection. 773 */ 774 case ERRinvnid: 775 return -EBADSLT; 776 default: 777 class = "ERRSRV"; 778 goto err_unknown; 779 } 780 } else if (errcls == ERRHRD) { 781 switch (error) { 782 case ERRnowrite: 783 return -EROFS; 784 case ERRbadunit: 785 return -ENODEV; 786 case ERRnotready: 787 return -EUCLEAN; 788 case ERRbadcmd: 789 case ERRdata: 790 return -EIO; 791 case ERRbadreq: 792 return -ERANGE; 793 case ERRbadshare: 794 return -ETXTBSY; 795 case ERRlock: 796 return -EDEADLK; 797 case ERRdiskfull: 798 return -ENOSPC; 799 default: 800 class = "ERRHRD"; 801 goto err_unknown; 802 } 803 } else if (errcls == ERRCMD) { 804 class = "ERRCMD"; 805 } else if (errcls == SUCCESS) { 806 return 0; /* This is the only valid 0 return */ 807 } 808 809err_unknown: 810 printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n", 811 class, error, SMB_CMD(req->rq_header)); 812 return -EIO; 813} 814 815/* smb_request_ok: We expect the server to be locked. Then we do the 816 request and check the answer completely. When smb_request_ok 817 returns 0, you can be quite sure that everything went well. When 818 the answer is <=0, the returned number is a valid unix errno. */ 819 820static int 821smb_request_ok(struct smb_request *req, int command, int wct, int bcc) 822{ 823 int result; 824 825 req->rq_resp_wct = wct; 826 req->rq_resp_bcc = bcc; 827 828 result = smb_add_request(req); 829 if (result != 0) { 830 DEBUG1("smb_request failed\n"); 831 goto out; 832 } 833 834 if (smb_valid_packet(req->rq_header) != 0) { 835 PARANOIA("invalid packet!\n"); 836 goto out; 837 } 838 839 result = smb_verify(req->rq_header, command, wct, bcc); 840 841out: 842 return result; 843} 844 845/* 846 * This implements the NEWCONN ioctl. It installs the server pid, 847 * sets server->state to CONN_VALID, and wakes up the waiting process. 848 */ 849int 850smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) 851{ 852 struct file *filp; 853 struct sock *sk; 854 int error; 855 856 VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid); 857 858 smb_lock_server(server); 859 860 /* 861 * Make sure we don't already have a valid connection ... 862 */ 863 error = -EINVAL; 864 if (server->state == CONN_VALID) 865 goto out; 866 867 error = -EACCES; 868 if (current->uid != server->mnt->mounted_uid && 869 !capable(CAP_SYS_ADMIN)) 870 goto out; 871 872 error = -EBADF; 873 filp = fget(opt->fd); 874 if (!filp) 875 goto out; 876 if (!smb_valid_socket(filp->f_path.dentry->d_inode)) 877 goto out_putf; 878 879 server->sock_file = filp; 880 server->conn_pid = get_pid(task_pid(current)); 881 server->opt = *opt; 882 server->generation += 1; 883 server->state = CONN_VALID; 884 error = 0; 885 886 if (server->conn_error) { 887 /* 888 * conn_error is the returncode we originally decided to 889 * drop the old connection on. This message should be positive 890 * and not make people ask questions on why smbfs is printing 891 * error messages ... 892 */ 893 printk(KERN_INFO "SMB connection re-established (%d)\n", 894 server->conn_error); 895 server->conn_error = 0; 896 } 897 898 /* 899 * Store the server in sock user_data (Only used by sunrpc) 900 */ 901 sk = SOCKET_I(filp->f_path.dentry->d_inode)->sk; 902 sk->sk_user_data = server; 903 904 /* chain into the data_ready callback */ 905 server->data_ready = xchg(&sk->sk_data_ready, smb_data_ready); 906 907 /* check if we have an old smbmount that uses seconds for the 908 serverzone */ 909 if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60) 910 server->opt.serverzone /= 60; 911 912 /* now that we have an established connection we can detect the server 913 type and enable bug workarounds */ 914 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) 915 install_ops(server->ops, &smb_ops_core); 916 else if (server->opt.protocol == SMB_PROTOCOL_LANMAN2) 917 install_ops(server->ops, &smb_ops_os2); 918 else if (server->opt.protocol == SMB_PROTOCOL_NT1 && 919 (server->opt.max_xmit < 0x1000) && 920 !(server->opt.capabilities & SMB_CAP_NT_SMBS)) { 921 /* FIXME: can we kill the WIN95 flag now? */ 922 server->mnt->flags |= SMB_MOUNT_WIN95; 923 VERBOSE("detected WIN95 server\n"); 924 install_ops(server->ops, &smb_ops_win95); 925 } else { 926 /* 927 * Samba has max_xmit 65535 928 * NT4spX has max_xmit 4536 (or something like that) 929 * win2k has ... 930 */ 931 VERBOSE("detected NT1 (Samba, NT4/5) server\n"); 932 install_ops(server->ops, &smb_ops_winNT); 933 } 934 935 /* FIXME: the win9x code wants to modify these ... (seek/trunc bug) */ 936 if (server->mnt->flags & SMB_MOUNT_OLDATTR) { 937 server->ops->getattr = smb_proc_getattr_core; 938 } else if (server->mnt->flags & SMB_MOUNT_DIRATTR) { 939 server->ops->getattr = smb_proc_getattr_ff; 940 } 941 942 /* Decode server capabilities */ 943 if (server->opt.capabilities & SMB_CAP_LARGE_FILES) { 944 /* Should be ok to set this now, as no one can access the 945 mount until the connection has been established. */ 946 SB_of(server)->s_maxbytes = ~0ULL >> 1; 947 VERBOSE("LFS enabled\n"); 948 } 949 if (server->opt.capabilities & SMB_CAP_UNICODE) { 950 server->mnt->flags |= SMB_MOUNT_UNICODE; 951 VERBOSE("Unicode enabled\n"); 952 } else { 953 server->mnt->flags &= ~SMB_MOUNT_UNICODE; 954 } 955#if 0 956 /* flags we may test for other patches ... */ 957 if (server->opt.capabilities & SMB_CAP_LARGE_READX) { 958 VERBOSE("Large reads enabled\n"); 959 } 960 if (server->opt.capabilities & SMB_CAP_LARGE_WRITEX) { 961 VERBOSE("Large writes enabled\n"); 962 } 963#endif 964 if (server->opt.capabilities & SMB_CAP_UNIX) { 965 struct inode *inode; 966 VERBOSE("Using UNIX CIFS extensions\n"); 967 install_ops(server->ops, &smb_ops_unix); 968 inode = SB_of(server)->s_root->d_inode; 969 if (inode) 970 inode->i_op = &smb_dir_inode_operations_unix; 971 } 972 973 VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", 974 server->opt.protocol, server->opt.max_xmit, 975 pid_nr(server->conn_pid), server->opt.capabilities); 976 977 /* FIXME: this really should be done by smbmount. */ 978 if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) { 979 server->opt.max_xmit = SMB_MAX_PACKET_SIZE; 980 } 981 982 smb_unlock_server(server); 983 smbiod_wake_up(); 984 if (server->opt.capabilities & SMB_CAP_UNIX) 985 smb_proc_query_cifsunix(server); 986 987 server->conn_complete++; 988 wake_up_interruptible_all(&server->conn_wq); 989 return error; 990 991out: 992 smb_unlock_server(server); 993 smbiod_wake_up(); 994 return error; 995 996out_putf: 997 fput(filp); 998 goto out; 999} 1000 1001/* smb_setup_header: We completely set up the packet. You only have to 1002 insert the command-specific fields */ 1003 1004__u8 * 1005smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc) 1006{ 1007 __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2; 1008 __u8 *p = req->rq_header; 1009 struct smb_sb_info *server = req->rq_server; 1010 1011 p = smb_encode_smb_length(p, xmit_len - 4); 1012 1013 *p++ = 0xff; 1014 *p++ = 'S'; 1015 *p++ = 'M'; 1016 *p++ = 'B'; 1017 *p++ = command; 1018 1019 memset(p, '\0', 19); 1020 p += 19; 1021 p += 8; 1022 1023 if (server->opt.protocol > SMB_PROTOCOL_CORE) { 1024 int flags = SMB_FLAGS_CASELESS_PATHNAMES; 1025 int flags2 = SMB_FLAGS2_LONG_PATH_COMPONENTS | 1026 SMB_FLAGS2_EXTENDED_ATTRIBUTES; /* EA? not really ... */ 1027 1028 *(req->rq_header + smb_flg) = flags; 1029 if (server->mnt->flags & SMB_MOUNT_UNICODE) 1030 flags2 |= SMB_FLAGS2_UNICODE_STRINGS; 1031 WSET(req->rq_header, smb_flg2, flags2); 1032 } 1033 *p++ = wct; /* wct */ 1034 p += 2 * wct; 1035 WSET(p, 0, bcc); 1036 1037 /* Include the header in the data to send */ 1038 req->rq_iovlen = 1; 1039 req->rq_iov[0].iov_base = req->rq_header; 1040 req->rq_iov[0].iov_len = xmit_len - bcc; 1041 1042 return req->rq_buffer; 1043} 1044 1045static void 1046smb_setup_bcc(struct smb_request *req, __u8 *p) 1047{ 1048 u16 bcc = p - req->rq_buffer; 1049 u8 *pbcc = req->rq_header + SMB_HEADER_LEN + 2*SMB_WCT(req->rq_header); 1050 1051 WSET(pbcc, 0, bcc); 1052 1053 smb_encode_smb_length(req->rq_header, SMB_HEADER_LEN + 1054 2*SMB_WCT(req->rq_header) - 2 + bcc); 1055 1056 /* Include the "bytes" in the data to send */ 1057 req->rq_iovlen = 2; 1058 req->rq_iov[1].iov_base = req->rq_buffer; 1059 req->rq_iov[1].iov_len = bcc; 1060} 1061 1062static int 1063smb_proc_seek(struct smb_sb_info *server, __u16 fileid, 1064 __u16 mode, off_t offset) 1065{ 1066 int result; 1067 struct smb_request *req; 1068 1069 result = -ENOMEM; 1070 if (! (req = smb_alloc_request(server, 0))) 1071 goto out; 1072 1073 smb_setup_header(req, SMBlseek, 4, 0); 1074 WSET(req->rq_header, smb_vwv0, fileid); 1075 WSET(req->rq_header, smb_vwv1, mode); 1076 DSET(req->rq_header, smb_vwv2, offset); 1077 req->rq_flags |= SMB_REQ_NORETRY; 1078 1079 result = smb_request_ok(req, SMBlseek, 2, 0); 1080 if (result < 0) { 1081 result = 0; 1082 goto out_free; 1083 } 1084 1085 result = DVAL(req->rq_header, smb_vwv0); 1086out_free: 1087 smb_rput(req); 1088out: 1089 return result; 1090} 1091 1092static int 1093smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) 1094{ 1095 struct inode *ino = dentry->d_inode; 1096 struct smb_inode_info *ei = SMB_I(ino); 1097 int mode, read_write = 0x42, read_only = 0x40; 1098 int res; 1099 char *p; 1100 struct smb_request *req; 1101 1102 /* 1103 * Attempt to open r/w, unless there are no write privileges. 1104 */ 1105 mode = read_write; 1106 if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) 1107 mode = read_only; 1108#if 0 1109 /* FIXME: why is this code not in? below we fix it so that a caller 1110 wanting RO doesn't get RW. smb_revalidate_inode does some 1111 optimization based on access mode. tail -f needs it to be correct. 1112 1113 We must open rw since we don't do the open if called a second time 1114 with different 'wish'. Is that not supported by smb servers? */ 1115 if (!(wish & (O_WRONLY | O_RDWR))) 1116 mode = read_only; 1117#endif 1118 1119 res = -ENOMEM; 1120 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 1121 goto out; 1122 1123 retry: 1124 p = smb_setup_header(req, SMBopen, 2, 0); 1125 WSET(req->rq_header, smb_vwv0, mode); 1126 WSET(req->rq_header, smb_vwv1, aSYSTEM | aHIDDEN | aDIR); 1127 res = smb_simple_encode_path(req, &p, dentry, NULL); 1128 if (res < 0) 1129 goto out_free; 1130 smb_setup_bcc(req, p); 1131 1132 res = smb_request_ok(req, SMBopen, 7, 0); 1133 if (res != 0) { 1134 if (mode == read_write && 1135 (res == -EACCES || res == -ETXTBSY || res == -EROFS)) 1136 { 1137 VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n", 1138 DENTRY_PATH(dentry), res); 1139 mode = read_only; 1140 req->rq_flags = 0; 1141 goto retry; 1142 } 1143 goto out_free; 1144 } 1145 /* We should now have data in vwv[0..6]. */ 1146 1147 ei->fileid = WVAL(req->rq_header, smb_vwv0); 1148 ei->attr = WVAL(req->rq_header, smb_vwv1); 1149 /* smb_vwv2 has mtime */ 1150 /* smb_vwv4 has size */ 1151 ei->access = (WVAL(req->rq_header, smb_vwv6) & SMB_ACCMASK); 1152 ei->open = server->generation; 1153 1154out_free: 1155 smb_rput(req); 1156out: 1157 return res; 1158} 1159 1160/* 1161 * Make sure the file is open, and check that the access 1162 * is compatible with the desired access. 1163 */ 1164int 1165smb_open(struct dentry *dentry, int wish) 1166{ 1167 struct inode *inode = dentry->d_inode; 1168 int result; 1169 __u16 access; 1170 1171 result = -ENOENT; 1172 if (!inode) { 1173 printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n", 1174 DENTRY_PATH(dentry)); 1175 goto out; 1176 } 1177 1178 if (!smb_is_open(inode)) { 1179 struct smb_sb_info *server = server_from_inode(inode); 1180 result = 0; 1181 if (!smb_is_open(inode)) 1182 result = smb_proc_open(server, dentry, wish); 1183 if (result) 1184 goto out; 1185 /* 1186 * A successful open means the path is still valid ... 1187 */ 1188 smb_renew_times(dentry); 1189 } 1190 1191 /* 1192 * Check whether the access is compatible with the desired mode. 1193 */ 1194 result = 0; 1195 access = SMB_I(inode)->access; 1196 if (access != wish && access != SMB_O_RDWR) { 1197 PARANOIA("%s/%s access denied, access=%x, wish=%x\n", 1198 DENTRY_PATH(dentry), access, wish); 1199 result = -EACCES; 1200 } 1201out: 1202 return result; 1203} 1204 1205static int 1206smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime) 1207{ 1208 struct smb_request *req; 1209 int result = -ENOMEM; 1210 1211 if (! (req = smb_alloc_request(server, 0))) 1212 goto out; 1213 1214 smb_setup_header(req, SMBclose, 3, 0); 1215 WSET(req->rq_header, smb_vwv0, fileid); 1216 DSET(req->rq_header, smb_vwv1, utc2local(server, mtime)); 1217 req->rq_flags |= SMB_REQ_NORETRY; 1218 result = smb_request_ok(req, SMBclose, 0, 0); 1219 1220 smb_rput(req); 1221out: 1222 return result; 1223} 1224 1225/* 1226 * Win NT 4.0 has an apparent bug in that it fails to update the 1227 * modify time when writing to a file. As a workaround, we update 1228 * both modify and access time locally, and post the times to the 1229 * server when closing the file. 1230 */ 1231static int 1232smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino) 1233{ 1234 struct smb_inode_info *ei = SMB_I(ino); 1235 int result = 0; 1236 if (smb_is_open(ino)) 1237 { 1238 /* 1239 * We clear the open flag in advance, in case another 1240 * process observes the value while we block below. 1241 */ 1242 ei->open = 0; 1243 1244 /* 1245 * Kludge alert: SMB timestamps are accurate only to 1246 * two seconds ... round the times to avoid needless 1247 * cache invalidations! 1248 */ 1249 if (ino->i_mtime.tv_sec & 1) { 1250 ino->i_mtime.tv_sec--; 1251 ino->i_mtime.tv_nsec = 0; 1252 } 1253 if (ino->i_atime.tv_sec & 1) { 1254 ino->i_atime.tv_sec--; 1255 ino->i_atime.tv_nsec = 0; 1256 } 1257 /* 1258 * If the file is open with write permissions, 1259 * update the time stamps to sync mtime and atime. 1260 */ 1261 if ((server->opt.capabilities & SMB_CAP_UNIX) == 0 && 1262 (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) && 1263 !(ei->access == SMB_O_RDONLY)) 1264 { 1265 struct smb_fattr fattr; 1266 smb_get_inode_attr(ino, &fattr); 1267 smb_proc_setattr_ext(server, ino, &fattr); 1268 } 1269 1270 result = smb_proc_close(server, ei->fileid, ino->i_mtime.tv_sec); 1271 /* 1272 * Force a revalidation after closing ... some servers 1273 * don't post the size until the file has been closed. 1274 */ 1275 if (server->opt.protocol < SMB_PROTOCOL_NT1) 1276 ei->oldmtime = 0; 1277 ei->closed = jiffies; 1278 } 1279 return result; 1280} 1281 1282int 1283smb_close(struct inode *ino) 1284{ 1285 int result = 0; 1286 1287 if (smb_is_open(ino)) { 1288 struct smb_sb_info *server = server_from_inode(ino); 1289 result = smb_proc_close_inode(server, ino); 1290 } 1291 return result; 1292} 1293 1294/* 1295 * This is used to close a file following a failed instantiate. 1296 * Since we don't have an inode, we can't use any of the above. 1297 */ 1298int 1299smb_close_fileid(struct dentry *dentry, __u16 fileid) 1300{ 1301 struct smb_sb_info *server = server_from_dentry(dentry); 1302 int result; 1303 1304 result = smb_proc_close(server, fileid, get_seconds()); 1305 return result; 1306} 1307 1308/* In smb_proc_read and smb_proc_write we do not retry, because the 1309 file-id would not be valid after a reconnection. */ 1310 1311static void 1312smb_proc_read_data(struct smb_request *req) 1313{ 1314 req->rq_iov[0].iov_base = req->rq_buffer; 1315 req->rq_iov[0].iov_len = 3; 1316 1317 req->rq_iov[1].iov_base = req->rq_page; 1318 req->rq_iov[1].iov_len = req->rq_rsize; 1319 req->rq_iovlen = 2; 1320 1321 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; 1322} 1323 1324static int 1325smb_proc_read(struct inode *inode, loff_t offset, int count, char *data) 1326{ 1327 struct smb_sb_info *server = server_from_inode(inode); 1328 __u16 returned_count, data_len; 1329 unsigned char *buf; 1330 int result; 1331 struct smb_request *req; 1332 u8 rbuf[4]; 1333 1334 result = -ENOMEM; 1335 if (! (req = smb_alloc_request(server, 0))) 1336 goto out; 1337 1338 smb_setup_header(req, SMBread, 5, 0); 1339 buf = req->rq_header; 1340 WSET(buf, smb_vwv0, SMB_I(inode)->fileid); 1341 WSET(buf, smb_vwv1, count); 1342 DSET(buf, smb_vwv2, offset); 1343 WSET(buf, smb_vwv4, 0); 1344 1345 req->rq_page = data; 1346 req->rq_rsize = count; 1347 req->rq_callback = smb_proc_read_data; 1348 req->rq_buffer = rbuf; 1349 req->rq_flags |= SMB_REQ_NORETRY | SMB_REQ_STATIC; 1350 1351 result = smb_request_ok(req, SMBread, 5, -1); 1352 if (result < 0) 1353 goto out_free; 1354 returned_count = WVAL(req->rq_header, smb_vwv0); 1355 1356 data_len = WVAL(rbuf, 1); 1357 1358 if (returned_count != data_len) { 1359 printk(KERN_NOTICE "smb_proc_read: returned != data_len\n"); 1360 printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n", 1361 returned_count, data_len); 1362 } 1363 result = data_len; 1364 1365out_free: 1366 smb_rput(req); 1367out: 1368 VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n", 1369 inode->i_ino, SMB_I(inode)->fileid, count, result); 1370 return result; 1371} 1372 1373static int 1374smb_proc_write(struct inode *inode, loff_t offset, int count, const char *data) 1375{ 1376 struct smb_sb_info *server = server_from_inode(inode); 1377 int result; 1378 u16 fileid = SMB_I(inode)->fileid; 1379 u8 buf[4]; 1380 struct smb_request *req; 1381 1382 result = -ENOMEM; 1383 if (! (req = smb_alloc_request(server, 0))) 1384 goto out; 1385 1386 VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n", 1387 inode->i_ino, fileid, count, offset); 1388 1389 smb_setup_header(req, SMBwrite, 5, count + 3); 1390 WSET(req->rq_header, smb_vwv0, fileid); 1391 WSET(req->rq_header, smb_vwv1, count); 1392 DSET(req->rq_header, smb_vwv2, offset); 1393 WSET(req->rq_header, smb_vwv4, 0); 1394 1395 buf[0] = 1; 1396 WSET(buf, 1, count); /* yes, again ... */ 1397 req->rq_iov[1].iov_base = buf; 1398 req->rq_iov[1].iov_len = 3; 1399 req->rq_iov[2].iov_base = (char *) data; 1400 req->rq_iov[2].iov_len = count; 1401 req->rq_iovlen = 3; 1402 req->rq_flags |= SMB_REQ_NORETRY; 1403 1404 result = smb_request_ok(req, SMBwrite, 1, 0); 1405 if (result >= 0) 1406 result = WVAL(req->rq_header, smb_vwv0); 1407 1408 smb_rput(req); 1409out: 1410 return result; 1411} 1412 1413/* 1414 * In smb_proc_readX and smb_proc_writeX we do not retry, because the 1415 * file-id would not be valid after a reconnection. 1416 */ 1417 1418#define SMB_READX_MAX_PAD 64 1419static void 1420smb_proc_readX_data(struct smb_request *req) 1421{ 1422 /* header length, excluding the netbios length (-4) */ 1423 int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2; 1424 int data_off = WVAL(req->rq_header, smb_vwv6); 1425 1426 /* 1427 * Some genius made the padding to the data bytes arbitrary. 1428 * So we must first calculate the amount of padding used by the server. 1429 */ 1430 data_off -= hdrlen; 1431 if (data_off > SMB_READX_MAX_PAD || data_off < 0) { 1432 PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n"); 1433 PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off); 1434 req->rq_rlen = req->rq_bufsize + 1; 1435 return; 1436 } 1437 req->rq_iov[0].iov_base = req->rq_buffer; 1438 req->rq_iov[0].iov_len = data_off; 1439 1440 req->rq_iov[1].iov_base = req->rq_page; 1441 req->rq_iov[1].iov_len = req->rq_rsize; 1442 req->rq_iovlen = 2; 1443 1444 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; 1445} 1446 1447static int 1448smb_proc_readX(struct inode *inode, loff_t offset, int count, char *data) 1449{ 1450 struct smb_sb_info *server = server_from_inode(inode); 1451 unsigned char *buf; 1452 int result; 1453 struct smb_request *req; 1454 static char pad[SMB_READX_MAX_PAD]; 1455 1456 result = -ENOMEM; 1457 if (! (req = smb_alloc_request(server, 0))) 1458 goto out; 1459 1460 smb_setup_header(req, SMBreadX, 12, 0); 1461 buf = req->rq_header; 1462 WSET(buf, smb_vwv0, 0x00ff); 1463 WSET(buf, smb_vwv1, 0); 1464 WSET(buf, smb_vwv2, SMB_I(inode)->fileid); 1465 DSET(buf, smb_vwv3, (u32)offset); /* low 32 bits */ 1466 WSET(buf, smb_vwv5, count); 1467 WSET(buf, smb_vwv6, 0); 1468 DSET(buf, smb_vwv7, 0); 1469 WSET(buf, smb_vwv9, 0); 1470 DSET(buf, smb_vwv10, (u32)(offset >> 32)); /* high 32 bits */ 1471 WSET(buf, smb_vwv11, 0); 1472 1473 req->rq_page = data; 1474 req->rq_rsize = count; 1475 req->rq_callback = smb_proc_readX_data; 1476 req->rq_buffer = pad; 1477 req->rq_bufsize = SMB_READX_MAX_PAD; 1478 req->rq_flags |= SMB_REQ_STATIC | SMB_REQ_NORETRY; 1479 1480 result = smb_request_ok(req, SMBreadX, 12, -1); 1481 if (result < 0) 1482 goto out_free; 1483 result = WVAL(req->rq_header, smb_vwv5); 1484 1485out_free: 1486 smb_rput(req); 1487out: 1488 VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n", 1489 inode->i_ino, SMB_I(inode)->fileid, count, result); 1490 return result; 1491} 1492 1493static int 1494smb_proc_writeX(struct inode *inode, loff_t offset, int count, const char *data) 1495{ 1496 struct smb_sb_info *server = server_from_inode(inode); 1497 int result; 1498 u8 *p; 1499 static u8 pad[4]; 1500 struct smb_request *req; 1501 1502 result = -ENOMEM; 1503 if (! (req = smb_alloc_request(server, 0))) 1504 goto out; 1505 1506 VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n", 1507 inode->i_ino, SMB_I(inode)->fileid, count, offset); 1508 1509 p = smb_setup_header(req, SMBwriteX, 14, count + 1); 1510 WSET(req->rq_header, smb_vwv0, 0x00ff); 1511 WSET(req->rq_header, smb_vwv1, 0); 1512 WSET(req->rq_header, smb_vwv2, SMB_I(inode)->fileid); 1513 DSET(req->rq_header, smb_vwv3, (u32)offset); /* low 32 bits */ 1514 DSET(req->rq_header, smb_vwv5, 0); 1515 WSET(req->rq_header, smb_vwv7, 0); /* write mode */ 1516 WSET(req->rq_header, smb_vwv8, 0); 1517 WSET(req->rq_header, smb_vwv9, 0); 1518 WSET(req->rq_header, smb_vwv10, count); /* data length */ 1519 WSET(req->rq_header, smb_vwv11, smb_vwv12 + 2 + 1); 1520 DSET(req->rq_header, smb_vwv12, (u32)(offset >> 32)); 1521 1522 req->rq_iov[1].iov_base = pad; 1523 req->rq_iov[1].iov_len = 1; 1524 req->rq_iov[2].iov_base = (char *) data; 1525 req->rq_iov[2].iov_len = count; 1526 req->rq_iovlen = 3; 1527 req->rq_flags |= SMB_REQ_NORETRY; 1528 1529 result = smb_request_ok(req, SMBwriteX, 6, 0); 1530 if (result >= 0) 1531 result = WVAL(req->rq_header, smb_vwv2); 1532 1533 smb_rput(req); 1534out: 1535 return result; 1536} 1537 1538int 1539smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid) 1540{ 1541 struct smb_sb_info *server = server_from_dentry(dentry); 1542 char *p; 1543 int result; 1544 struct smb_request *req; 1545 1546 result = -ENOMEM; 1547 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 1548 goto out; 1549 1550 p = smb_setup_header(req, SMBcreate, 3, 0); 1551 WSET(req->rq_header, smb_vwv0, attr); 1552 DSET(req->rq_header, smb_vwv1, utc2local(server, ctime)); 1553 result = smb_simple_encode_path(req, &p, dentry, NULL); 1554 if (result < 0) 1555 goto out_free; 1556 smb_setup_bcc(req, p); 1557 1558 result = smb_request_ok(req, SMBcreate, 1, 0); 1559 if (result < 0) 1560 goto out_free; 1561 1562 *fileid = WVAL(req->rq_header, smb_vwv0); 1563 result = 0; 1564 1565out_free: 1566 smb_rput(req); 1567out: 1568 return result; 1569} 1570 1571int 1572smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry) 1573{ 1574 struct smb_sb_info *server = server_from_dentry(old_dentry); 1575 char *p; 1576 int result; 1577 struct smb_request *req; 1578 1579 result = -ENOMEM; 1580 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 1581 goto out; 1582 1583 p = smb_setup_header(req, SMBmv, 1, 0); 1584 WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN | aDIR); 1585 result = smb_simple_encode_path(req, &p, old_dentry, NULL); 1586 if (result < 0) 1587 goto out_free; 1588 result = smb_simple_encode_path(req, &p, new_dentry, NULL); 1589 if (result < 0) 1590 goto out_free; 1591 smb_setup_bcc(req, p); 1592 1593 if ((result = smb_request_ok(req, SMBmv, 0, 0)) < 0) 1594 goto out_free; 1595 result = 0; 1596 1597out_free: 1598 smb_rput(req); 1599out: 1600 return result; 1601} 1602 1603/* 1604 * Code common to mkdir and rmdir. 1605 */ 1606static int 1607smb_proc_generic_command(struct dentry *dentry, __u8 command) 1608{ 1609 struct smb_sb_info *server = server_from_dentry(dentry); 1610 char *p; 1611 int result; 1612 struct smb_request *req; 1613 1614 result = -ENOMEM; 1615 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 1616 goto out; 1617 1618 p = smb_setup_header(req, command, 0, 0); 1619 result = smb_simple_encode_path(req, &p, dentry, NULL); 1620 if (result < 0) 1621 goto out_free; 1622 smb_setup_bcc(req, p); 1623 1624 result = smb_request_ok(req, command, 0, 0); 1625 if (result < 0) 1626 goto out_free; 1627 result = 0; 1628 1629out_free: 1630 smb_rput(req); 1631out: 1632 return result; 1633} 1634 1635int 1636smb_proc_mkdir(struct dentry *dentry) 1637{ 1638 return smb_proc_generic_command(dentry, SMBmkdir); 1639} 1640 1641int 1642smb_proc_rmdir(struct dentry *dentry) 1643{ 1644 return smb_proc_generic_command(dentry, SMBrmdir); 1645} 1646 1647#if SMBFS_POSIX_UNLINK 1648/* 1649 * Removes readonly attribute from a file. Used by unlink to give posix 1650 * semantics. 1651 */ 1652static int 1653smb_set_rw(struct dentry *dentry,struct smb_sb_info *server) 1654{ 1655 int result; 1656 struct smb_fattr fattr; 1657 1658 /* FIXME: cifsUE should allow removing a readonly file. */ 1659 1660 /* first get current attribute */ 1661 smb_init_dirent(server, &fattr); 1662 result = server->ops->getattr(server, dentry, &fattr); 1663 smb_finish_dirent(server, &fattr); 1664 if (result < 0) 1665 return result; 1666 1667 /* if RONLY attribute is set, remove it */ 1668 if (fattr.attr & aRONLY) { /* read only attribute is set */ 1669 fattr.attr &= ~aRONLY; 1670 result = smb_proc_setattr_core(server, dentry, fattr.attr); 1671 } 1672 return result; 1673} 1674#endif 1675 1676int 1677smb_proc_unlink(struct dentry *dentry) 1678{ 1679 struct smb_sb_info *server = server_from_dentry(dentry); 1680 int flag = 0; 1681 char *p; 1682 int result; 1683 struct smb_request *req; 1684 1685 result = -ENOMEM; 1686 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 1687 goto out; 1688 1689 retry: 1690 p = smb_setup_header(req, SMBunlink, 1, 0); 1691 WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN); 1692 result = smb_simple_encode_path(req, &p, dentry, NULL); 1693 if (result < 0) 1694 goto out_free; 1695 smb_setup_bcc(req, p); 1696 1697 if ((result = smb_request_ok(req, SMBunlink, 0, 0)) < 0) { 1698#if SMBFS_POSIX_UNLINK 1699 if (result == -EACCES && !flag) { 1700 /* Posix semantics is for the read-only state 1701 of a file to be ignored in unlink(). In the 1702 SMB world a unlink() is refused on a 1703 read-only file. To make things easier for 1704 unix users we try to override the files 1705 permission if the unlink fails with the 1706 right error. 1707 This introduces a race condition that could 1708 lead to a file being written by someone who 1709 shouldn't have access, but as far as I can 1710 tell that is unavoidable */ 1711 1712 /* remove RONLY attribute and try again */ 1713 result = smb_set_rw(dentry,server); 1714 if (result == 0) { 1715 flag = 1; 1716 req->rq_flags = 0; 1717 goto retry; 1718 } 1719 } 1720#endif 1721 goto out_free; 1722 } 1723 result = 0; 1724 1725out_free: 1726 smb_rput(req); 1727out: 1728 return result; 1729} 1730 1731int 1732smb_proc_flush(struct smb_sb_info *server, __u16 fileid) 1733{ 1734 int result; 1735 struct smb_request *req; 1736 1737 result = -ENOMEM; 1738 if (! (req = smb_alloc_request(server, 0))) 1739 goto out; 1740 1741 smb_setup_header(req, SMBflush, 1, 0); 1742 WSET(req->rq_header, smb_vwv0, fileid); 1743 req->rq_flags |= SMB_REQ_NORETRY; 1744 result = smb_request_ok(req, SMBflush, 0, 0); 1745 1746 smb_rput(req); 1747out: 1748 return result; 1749} 1750 1751static int 1752smb_proc_trunc32(struct inode *inode, loff_t length) 1753{ 1754 /* 1755 * Writing 0bytes is old-SMB magic for truncating files. 1756 * MAX_NON_LFS should prevent this from being called with a too 1757 * large offset. 1758 */ 1759 return smb_proc_write(inode, length, 0, NULL); 1760} 1761 1762static int 1763smb_proc_trunc64(struct inode *inode, loff_t length) 1764{ 1765 struct smb_sb_info *server = server_from_inode(inode); 1766 int result; 1767 char *param; 1768 char *data; 1769 struct smb_request *req; 1770 1771 result = -ENOMEM; 1772 if (! (req = smb_alloc_request(server, 14))) 1773 goto out; 1774 1775 param = req->rq_buffer; 1776 data = req->rq_buffer + 6; 1777 1778 /* FIXME: must we also set allocation size? winNT seems to do that */ 1779 WSET(param, 0, SMB_I(inode)->fileid); 1780 WSET(param, 2, SMB_SET_FILE_END_OF_FILE_INFO); 1781 WSET(param, 4, 0); 1782 LSET(data, 0, length); 1783 1784 req->rq_trans2_command = TRANSACT2_SETFILEINFO; 1785 req->rq_ldata = 8; 1786 req->rq_data = data; 1787 req->rq_lparm = 6; 1788 req->rq_parm = param; 1789 req->rq_flags |= SMB_REQ_NORETRY; 1790 result = smb_add_request(req); 1791 if (result < 0) 1792 goto out_free; 1793 1794 result = 0; 1795 if (req->rq_rcls != 0) 1796 result = smb_errno(req); 1797 1798out_free: 1799 smb_rput(req); 1800out: 1801 return result; 1802} 1803 1804static int 1805smb_proc_trunc95(struct inode *inode, loff_t length) 1806{ 1807 struct smb_sb_info *server = server_from_inode(inode); 1808 int result = smb_proc_trunc32(inode, length); 1809 1810 /* 1811 * win9x doesn't appear to update the size immediately. 1812 * It will return the old file size after the truncate, 1813 * confusing smbfs. So we force an update. 1814 * 1815 * FIXME: is this still necessary? 1816 */ 1817 smb_proc_flush(server, SMB_I(inode)->fileid); 1818 return result; 1819} 1820 1821static void 1822smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr) 1823{ 1824 memset(fattr, 0, sizeof(*fattr)); 1825 1826 fattr->f_nlink = 1; 1827 fattr->f_uid = server->mnt->uid; 1828 fattr->f_gid = server->mnt->gid; 1829 fattr->f_unix = 0; 1830} 1831 1832static void 1833smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr) 1834{ 1835 if (fattr->f_unix) 1836 return; 1837 1838 fattr->f_mode = server->mnt->file_mode; 1839 if (fattr->attr & aDIR) { 1840 fattr->f_mode = server->mnt->dir_mode; 1841 fattr->f_size = SMB_ST_BLKSIZE; 1842 } 1843 /* Check the read-only flag */ 1844 if (fattr->attr & aRONLY) 1845 fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); 1846 1847 /* How many 512 byte blocks do we need for this file? */ 1848 fattr->f_blocks = 0; 1849 if (fattr->f_size != 0) 1850 fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9); 1851 return; 1852} 1853 1854void 1855smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr, 1856 struct super_block *sb) 1857{ 1858 smb_init_dirent(server, fattr); 1859 fattr->attr = aDIR; 1860 fattr->f_ino = 2; /* traditional root inode number */ 1861 fattr->f_mtime = current_fs_time(sb); 1862 smb_finish_dirent(server, fattr); 1863} 1864 1865/* 1866 * Decode a dirent for old protocols 1867 * 1868 * qname is filled with the decoded, and possibly translated, name. 1869 * fattr receives decoded attributes 1870 * 1871 * Bugs Noted: 1872 * (1) Pathworks servers may pad the name with extra spaces. 1873 */ 1874static char * 1875smb_decode_short_dirent(struct smb_sb_info *server, char *p, 1876 struct qstr *qname, struct smb_fattr *fattr, 1877 unsigned char *name_buf) 1878{ 1879 int len; 1880 1881 /* 1882 * SMB doesn't have a concept of inode numbers ... 1883 */ 1884 smb_init_dirent(server, fattr); 1885 fattr->f_ino = 0; /* FIXME: do we need this? */ 1886 1887 p += SMB_STATUS_SIZE; /* reserved (search_status) */ 1888 fattr->attr = *p; 1889 fattr->f_mtime.tv_sec = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1)); 1890 fattr->f_mtime.tv_nsec = 0; 1891 fattr->f_size = DVAL(p, 5); 1892 fattr->f_ctime = fattr->f_mtime; 1893 fattr->f_atime = fattr->f_mtime; 1894 qname->name = p + 9; 1895 len = strnlen(qname->name, 12); 1896 1897 /* 1898 * Trim trailing blanks for Pathworks servers 1899 */ 1900 while (len > 2 && qname->name[len-1] == ' ') 1901 len--; 1902 1903 smb_finish_dirent(server, fattr); 1904 1905#if 0 1906 /* FIXME: These only work for ascii chars, and recent smbmount doesn't 1907 allow the flag to be set anyway. It kills const. Remove? */ 1908 switch (server->opt.case_handling) { 1909 case SMB_CASE_UPPER: 1910 str_upper(entry->name, len); 1911 break; 1912 case SMB_CASE_LOWER: 1913 str_lower(entry->name, len); 1914 break; 1915 default: 1916 break; 1917 } 1918#endif 1919 1920 qname->len = 0; 1921 len = server->ops->convert(name_buf, SMB_MAXNAMELEN, 1922 qname->name, len, 1923 server->remote_nls, server->local_nls); 1924 if (len > 0) { 1925 qname->len = len; 1926 qname->name = name_buf; 1927 DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name); 1928 } 1929 1930 return p + 22; 1931} 1932 1933/* 1934 * This routine is used to read in directory entries from the network. 1935 * Note that it is for short directory name seeks, i.e.: protocol < 1936 * SMB_PROTOCOL_LANMAN2 1937 */ 1938static int 1939smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, 1940 struct smb_cache_control *ctl) 1941{ 1942 struct dentry *dir = filp->f_path.dentry; 1943 struct smb_sb_info *server = server_from_dentry(dir); 1944 struct qstr qname; 1945 struct smb_fattr fattr; 1946 char *p; 1947 int result; 1948 int i, first, entries_seen, entries; 1949 int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE; 1950 __u16 bcc; 1951 __u16 count; 1952 char status[SMB_STATUS_SIZE]; 1953 static struct qstr mask = { 1954 .name = "*.*", 1955 .len = 3, 1956 }; 1957 unsigned char *last_status; 1958 struct smb_request *req; 1959 unsigned char *name_buf; 1960 1961 VERBOSE("%s/%s\n", DENTRY_PATH(dir)); 1962 1963 lock_kernel(); 1964 1965 result = -ENOMEM; 1966 if (! (name_buf = kmalloc(SMB_MAXNAMELEN, GFP_KERNEL))) 1967 goto out; 1968 1969 first = 1; 1970 entries = 0; 1971 entries_seen = 2; /* implicit . and .. */ 1972 1973 result = -ENOMEM; 1974 if (! (req = smb_alloc_request(server, server->opt.max_xmit))) 1975 goto out_name; 1976 1977 while (1) { 1978 p = smb_setup_header(req, SMBsearch, 2, 0); 1979 WSET(req->rq_header, smb_vwv0, entries_asked); 1980 WSET(req->rq_header, smb_vwv1, aDIR); 1981 if (first == 1) { 1982 result = smb_simple_encode_path(req, &p, dir, &mask); 1983 if (result < 0) 1984 goto out_free; 1985 if (p + 3 > (char *)req->rq_buffer + req->rq_bufsize) { 1986 result = -ENAMETOOLONG; 1987 goto out_free; 1988 } 1989 *p++ = 5; 1990 WSET(p, 0, 0); 1991 p += 2; 1992 first = 0; 1993 } else { 1994 if (p + 5 + SMB_STATUS_SIZE > 1995 (char *)req->rq_buffer + req->rq_bufsize) { 1996 result = -ENAMETOOLONG; 1997 goto out_free; 1998 } 1999 2000 *p++ = 4; 2001 *p++ = 0; 2002 *p++ = 5; 2003 WSET(p, 0, SMB_STATUS_SIZE); 2004 p += 2; 2005 memcpy(p, status, SMB_STATUS_SIZE); 2006 p += SMB_STATUS_SIZE; 2007 } 2008 2009 smb_setup_bcc(req, p); 2010 2011 result = smb_request_ok(req, SMBsearch, 1, -1); 2012 if (result < 0) { 2013 if ((req->rq_rcls == ERRDOS) && 2014 (req->rq_err == ERRnofiles)) 2015 break; 2016 goto out_free; 2017 } 2018 count = WVAL(req->rq_header, smb_vwv0); 2019 if (count <= 0) 2020 break; 2021 2022 result = -EIO; 2023 bcc = smb_bcc(req->rq_header); 2024 if (bcc != count * SMB_DIRINFO_SIZE + 3) 2025 goto out_free; 2026 p = req->rq_buffer + 3; 2027 2028 2029 /* Make sure the response fits in the buffer. Fixed sized 2030 entries means we don't have to check in the decode loop. */ 2031 2032 last_status = req->rq_buffer + 3 + (count-1) * SMB_DIRINFO_SIZE; 2033 2034 if (last_status + SMB_DIRINFO_SIZE >= 2035 req->rq_buffer + req->rq_bufsize) { 2036 printk(KERN_ERR "smb_proc_readdir_short: " 2037 "last dir entry outside buffer! " 2038 "%d@%p %d@%p\n", SMB_DIRINFO_SIZE, last_status, 2039 req->rq_bufsize, req->rq_buffer); 2040 goto out_free; 2041 } 2042 2043 /* Read the last entry into the status field. */ 2044 memcpy(status, last_status, SMB_STATUS_SIZE); 2045 2046 2047 /* Now we are ready to parse smb directory entries. */ 2048 2049 for (i = 0; i < count; i++) { 2050 p = smb_decode_short_dirent(server, p, 2051 &qname, &fattr, name_buf); 2052 if (qname.len == 0) 2053 continue; 2054 2055 if (entries_seen == 2 && qname.name[0] == '.') { 2056 if (qname.len == 1) 2057 continue; 2058 if (qname.name[1] == '.' && qname.len == 2) 2059 continue; 2060 } 2061 if (!smb_fill_cache(filp, dirent, filldir, ctl, 2062 &qname, &fattr)) 2063 ; /* stop reading? */ 2064 entries_seen++; 2065 } 2066 } 2067 result = entries; 2068 2069out_free: 2070 smb_rput(req); 2071out_name: 2072 kfree(name_buf); 2073out: 2074 unlock_kernel(); 2075 return result; 2076} 2077 2078static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p) 2079{ 2080 u64 size, disk_bytes; 2081 2082 /* FIXME: verify nls support. all is sent as utf8? */ 2083 2084 fattr->f_unix = 1; 2085 fattr->f_mode = 0; 2086 2087 /* FIXME: use the uniqueID from the remote instead? */ 2088 /* 0 L file size in bytes */ 2089 /* 8 L file size on disk in bytes (block count) */ 2090 /* 40 L uid */ 2091 /* 48 L gid */ 2092 /* 56 W file type */ 2093 /* 60 L devmajor */ 2094 /* 68 L devminor */ 2095 /* 76 L unique ID (inode) */ 2096 /* 84 L permissions */ 2097 /* 92 L link count */ 2098 2099 size = LVAL(p, 0); 2100 disk_bytes = LVAL(p, 8); 2101 2102 /* 2103 * Some samba versions round up on-disk byte usage 2104 * to 1MB boundaries, making it useless. When seeing 2105 * that, use the size instead. 2106 */ 2107 if (!(disk_bytes & 0xfffff)) 2108 disk_bytes = size+511; 2109 2110 fattr->f_size = size; 2111 fattr->f_blocks = disk_bytes >> 9; 2112 fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16)); 2113 fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24)); 2114 fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32)); 2115 2116 if (server->mnt->flags & SMB_MOUNT_UID) 2117 fattr->f_uid = server->mnt->uid; 2118 else 2119 fattr->f_uid = LVAL(p, 40); 2120 2121 if (server->mnt->flags & SMB_MOUNT_GID) 2122 fattr->f_gid = server->mnt->gid; 2123 else 2124 fattr->f_gid = LVAL(p, 48); 2125 2126 fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56)); 2127 2128 if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) { 2129 __u64 major = LVAL(p, 60); 2130 __u64 minor = LVAL(p, 68); 2131 2132 fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff); 2133 if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) || 2134 MINOR(fattr->f_rdev) != (minor & 0xffffffff)) 2135 fattr->f_rdev = 0; 2136 } 2137 2138 fattr->f_mode |= LVAL(p, 84); 2139 2140 if ( (server->mnt->flags & SMB_MOUNT_DMODE) && 2141 (S_ISDIR(fattr->f_mode)) ) 2142 fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR; 2143 else if ( (server->mnt->flags & SMB_MOUNT_FMODE) && 2144 !(S_ISDIR(fattr->f_mode)) ) 2145 fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) | 2146 (fattr->f_mode & S_IFMT); 2147 2148} 2149 2150/* 2151 * Interpret a long filename structure using the specified info level: 2152 * level 1 for anything below NT1 protocol 2153 * level 260 for NT1 protocol 2154 * 2155 * qname is filled with the decoded, and possibly translated, name 2156 * fattr receives decoded attributes. 2157 * 2158 * Bugs Noted: 2159 * (1) Win NT 4.0 appends a null byte to names and counts it in the length! 2160 */ 2161static char * 2162smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level, 2163 struct qstr *qname, struct smb_fattr *fattr, 2164 unsigned char *name_buf) 2165{ 2166 char *result; 2167 unsigned int len = 0; 2168 int n; 2169 __u16 date, time; 2170 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE); 2171 2172 /* 2173 * SMB doesn't have a concept of inode numbers ... 2174 */ 2175 smb_init_dirent(server, fattr); 2176 fattr->f_ino = 0; /* FIXME: do we need this? */ 2177 2178 switch (level) { 2179 case 1: 2180 len = *((unsigned char *) p + 22); 2181 qname->name = p + 23; 2182 result = p + 24 + len; 2183 2184 date = WVAL(p, 0); 2185 time = WVAL(p, 2); 2186 fattr->f_ctime.tv_sec = date_dos2unix(server, date, time); 2187 fattr->f_ctime.tv_nsec = 0; 2188 2189 date = WVAL(p, 4); 2190 time = WVAL(p, 6); 2191 fattr->f_atime.tv_sec = date_dos2unix(server, date, time); 2192 fattr->f_atime.tv_nsec = 0; 2193 2194 date = WVAL(p, 8); 2195 time = WVAL(p, 10); 2196 fattr->f_mtime.tv_sec = date_dos2unix(server, date, time); 2197 fattr->f_mtime.tv_nsec = 0; 2198 fattr->f_size = DVAL(p, 12); 2199 /* ULONG allocation size */ 2200 fattr->attr = WVAL(p, 20); 2201 2202 VERBOSE("info 1 at %p, len=%d, name=%.*s\n", 2203 p, len, len, qname->name); 2204 break; 2205 case 260: 2206 result = p + WVAL(p, 0); 2207 len = DVAL(p, 60); 2208 if (len > 255) len = 255; 2209 /* NT4 null terminates, unless we are using unicode ... */ 2210 qname->name = p + 94; 2211 if (!unicode && len && qname->name[len-1] == '\0') 2212 len--; 2213 2214 fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8)); 2215 fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16)); 2216 fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24)); 2217 /* change time (32) */ 2218 fattr->f_size = LVAL(p, 40); 2219 /* alloc size (48) */ 2220 fattr->attr = DVAL(p, 56); 2221 2222 VERBOSE("info 260 at %p, len=%d, name=%.*s\n", 2223 p, len, len, qname->name); 2224 break; 2225 case SMB_FIND_FILE_UNIX: 2226 result = p + WVAL(p, 0); 2227 qname->name = p + 108; 2228 2229 len = strlen(qname->name); 2230 /* FIXME: should we check the length?? */ 2231 2232 p += 8; 2233 smb_decode_unix_basic(fattr, server, p); 2234 VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n", 2235 p, len, len, qname->name); 2236 break; 2237 default: 2238 PARANOIA("Unknown info level %d\n", level); 2239 result = p + WVAL(p, 0); 2240 goto out; 2241 } 2242 2243 smb_finish_dirent(server, fattr); 2244 2245#if 0 2246 /* FIXME: These only work for ascii chars, and recent smbmount doesn't 2247 allow the flag to be set anyway. Remove? */ 2248 switch (server->opt.case_handling) { 2249 case SMB_CASE_UPPER: 2250 str_upper(qname->name, len); 2251 break; 2252 case SMB_CASE_LOWER: 2253 str_lower(qname->name, len); 2254 break; 2255 default: 2256 break; 2257 } 2258#endif 2259 2260 qname->len = 0; 2261 n = server->ops->convert(name_buf, SMB_MAXNAMELEN, 2262 qname->name, len, 2263 server->remote_nls, server->local_nls); 2264 if (n > 0) { 2265 qname->len = n; 2266 qname->name = name_buf; 2267 } 2268 2269out: 2270 return result; 2271} 2272 2273/* findfirst/findnext flags */ 2274#define SMB_CLOSE_AFTER_FIRST (1<<0) 2275#define SMB_CLOSE_IF_END (1<<1) 2276#define SMB_REQUIRE_RESUME_KEY (1<<2) 2277#define SMB_CONTINUE_BIT (1<<3) 2278 2279/* 2280 * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in 2281 * source/libsmb/clilist.c. When looking for smb bugs in the readdir code, 2282 * go there for advise. 2283 * 2284 * Bugs Noted: 2285 * (1) When using Info Level 1 Win NT 4.0 truncates directory listings 2286 * for certain patterns of names and/or lengths. The breakage pattern 2287 * is completely reproducible and can be toggled by the creation of a 2288 * single file. (E.g. echo hi >foo breaks, rm -f foo works.) 2289 */ 2290static int 2291smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, 2292 struct smb_cache_control *ctl) 2293{ 2294 struct dentry *dir = filp->f_path.dentry; 2295 struct smb_sb_info *server = server_from_dentry(dir); 2296 struct qstr qname; 2297 struct smb_fattr fattr; 2298 2299 unsigned char *p, *lastname; 2300 char *mask, *param; 2301 __u16 command; 2302 int first, entries_seen; 2303 2304 /* Both NT and OS/2 accept info level 1 (but see note below). */ 2305 int info_level = 260; 2306 const int max_matches = 512; 2307 2308 unsigned int ff_searchcount = 0; 2309 unsigned int ff_eos = 0; 2310 unsigned int ff_lastname = 0; 2311 unsigned int ff_dir_handle = 0; 2312 unsigned int loop_count = 0; 2313 unsigned int mask_len, i; 2314 int result; 2315 struct smb_request *req; 2316 unsigned char *name_buf; 2317 static struct qstr star = { 2318 .name = "*", 2319 .len = 1, 2320 }; 2321 2322 lock_kernel(); 2323 2324 /* 2325 * We always prefer unix style. Use info level 1 for older 2326 * servers that don't do 260. 2327 */ 2328 if (server->opt.capabilities & SMB_CAP_UNIX) 2329 info_level = SMB_FIND_FILE_UNIX; 2330 else if (server->opt.protocol < SMB_PROTOCOL_NT1) 2331 info_level = 1; 2332 2333 result = -ENOMEM; 2334 if (! (name_buf = kmalloc(SMB_MAXNAMELEN+2, GFP_KERNEL))) 2335 goto out; 2336 if (! (req = smb_alloc_request(server, server->opt.max_xmit))) 2337 goto out_name; 2338 param = req->rq_buffer; 2339 2340 /* 2341 * Encode the initial path 2342 */ 2343 mask = param + 12; 2344 2345 result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star); 2346 if (result <= 0) 2347 goto out_free; 2348 mask_len = result - 1; /* mask_len is strlen, not #bytes */ 2349 result = 0; 2350 first = 1; 2351 VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask); 2352 2353 entries_seen = 2; 2354 ff_eos = 0; 2355 2356 while (ff_eos == 0) { 2357 loop_count += 1; 2358 if (loop_count > 10) { 2359 printk(KERN_WARNING "smb_proc_readdir_long: " 2360 "Looping in FIND_NEXT??\n"); 2361 result = -EIO; 2362 break; 2363 } 2364 2365 if (first != 0) { 2366 command = TRANSACT2_FINDFIRST; 2367 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); 2368 WSET(param, 2, max_matches); /* max count */ 2369 WSET(param, 4, SMB_CLOSE_IF_END); 2370 WSET(param, 6, info_level); 2371 DSET(param, 8, 0); 2372 } else { 2373 command = TRANSACT2_FINDNEXT; 2374 2375 VERBOSE("handle=0x%X, lastname=%d, mask=%.*s\n", 2376 ff_dir_handle, ff_lastname, mask_len, mask); 2377 2378 WSET(param, 0, ff_dir_handle); /* search handle */ 2379 WSET(param, 2, max_matches); /* max count */ 2380 WSET(param, 4, info_level); 2381 DSET(param, 6, 0); 2382 WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); 2383 } 2384 2385 req->rq_trans2_command = command; 2386 req->rq_ldata = 0; 2387 req->rq_data = NULL; 2388 req->rq_lparm = 12 + mask_len + 1; 2389 req->rq_parm = param; 2390 req->rq_flags = 0; 2391 result = smb_add_request(req); 2392 if (result < 0) { 2393 PARANOIA("error=%d, breaking\n", result); 2394 break; 2395 } 2396 2397 if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) { 2398 /* a damn Win95 bug - sometimes it clags if you 2399 ask it too fast */ 2400 schedule_timeout_interruptible(msecs_to_jiffies(200)); 2401 continue; 2402 } 2403 2404 if (req->rq_rcls != 0) { 2405 result = smb_errno(req); 2406 PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n", 2407 mask, result, req->rq_rcls, req->rq_err); 2408 break; 2409 } 2410 2411 /* parse out some important return info */ 2412 if (first != 0) { 2413 ff_dir_handle = WVAL(req->rq_parm, 0); 2414 ff_searchcount = WVAL(req->rq_parm, 2); 2415 ff_eos = WVAL(req->rq_parm, 4); 2416 ff_lastname = WVAL(req->rq_parm, 8); 2417 } else { 2418 ff_searchcount = WVAL(req->rq_parm, 0); 2419 ff_eos = WVAL(req->rq_parm, 2); 2420 ff_lastname = WVAL(req->rq_parm, 6); 2421 } 2422 2423 if (ff_searchcount == 0) 2424 break; 2425 2426 /* Now we are ready to parse smb directory entries. */ 2427 2428 /* point to the data bytes */ 2429 p = req->rq_data; 2430 for (i = 0; i < ff_searchcount; i++) { 2431 /* make sure we stay within the buffer */ 2432 if (p >= req->rq_data + req->rq_ldata) { 2433 printk(KERN_ERR "smb_proc_readdir_long: " 2434 "dirent pointer outside buffer! " 2435 "%p %d@%p\n", 2436 p, req->rq_ldata, req->rq_data); 2437 result = -EIO; /* always a comm. error? */ 2438 goto out_free; 2439 } 2440 2441 p = smb_decode_long_dirent(server, p, info_level, 2442 &qname, &fattr, name_buf); 2443 2444 /* ignore . and .. from the server */ 2445 if (entries_seen == 2 && qname.name[0] == '.') { 2446 if (qname.len == 1) 2447 continue; 2448 if (qname.name[1] == '.' && qname.len == 2) 2449 continue; 2450 } 2451 2452 if (!smb_fill_cache(filp, dirent, filldir, ctl, 2453 &qname, &fattr)) 2454 ; /* stop reading? */ 2455 entries_seen++; 2456 } 2457 2458 VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos); 2459 2460 /* 2461 * We might need the lastname for continuations. 2462 * 2463 * Note that some servers (win95?) point to the filename and 2464 * others (NT4, Samba using NT1) to the dir entry. We assume 2465 * here that those who do not point to a filename do not need 2466 * this info to continue the listing. 2467 * 2468 * OS/2 needs this and talks infolevel 1. 2469 * NetApps want lastname with infolevel 260. 2470 * win2k want lastname with infolevel 260, and points to 2471 * the record not to the name. 2472 * Samba+CifsUnixExt doesn't need lastname. 2473 * 2474 * Both are happy if we return the data they point to. So we do. 2475 * (FIXME: above is not true with win2k) 2476 */ 2477 mask_len = 0; 2478 if (info_level != SMB_FIND_FILE_UNIX && 2479 ff_lastname > 0 && ff_lastname < req->rq_ldata) { 2480 lastname = req->rq_data + ff_lastname; 2481 2482 switch (info_level) { 2483 case 260: 2484 mask_len = req->rq_ldata - ff_lastname; 2485 break; 2486 case 1: 2487 /* lastname points to a length byte */ 2488 mask_len = *lastname++; 2489 if (ff_lastname + 1 + mask_len > req->rq_ldata) 2490 mask_len = req->rq_ldata - ff_lastname - 1; 2491 break; 2492 } 2493 2494 /* 2495 * Update the mask string for the next message. 2496 */ 2497 if (mask_len > 255) 2498 mask_len = 255; 2499 if (mask_len) 2500 strncpy(mask, lastname, mask_len); 2501 } 2502 mask_len = strnlen(mask, mask_len); 2503 VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n", 2504 mask_len, ff_lastname, req->rq_ldata, mask_len, mask); 2505 2506 first = 0; 2507 loop_count = 0; 2508 } 2509 2510out_free: 2511 smb_rput(req); 2512out_name: 2513 kfree(name_buf); 2514out: 2515 unlock_kernel(); 2516 return result; 2517} 2518 2519/* 2520 * This version uses the trans2 TRANSACT2_FINDFIRST message 2521 * to get the attribute data. 2522 * 2523 * Bugs Noted: 2524 */ 2525static int 2526smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, 2527 struct smb_fattr *fattr) 2528{ 2529 char *param, *mask; 2530 __u16 date, time; 2531 int mask_len, result; 2532 struct smb_request *req; 2533 2534 result = -ENOMEM; 2535 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2536 goto out; 2537 param = req->rq_buffer; 2538 mask = param + 12; 2539 2540 mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry,NULL); 2541 if (mask_len < 0) { 2542 result = mask_len; 2543 goto out_free; 2544 } 2545 VERBOSE("name=%s, len=%d\n", mask, mask_len); 2546 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); 2547 WSET(param, 2, 1); /* max count */ 2548 WSET(param, 4, 1); /* close after this call */ 2549 WSET(param, 6, 1); /* info_level */ 2550 DSET(param, 8, 0); 2551 2552 req->rq_trans2_command = TRANSACT2_FINDFIRST; 2553 req->rq_ldata = 0; 2554 req->rq_data = NULL; 2555 req->rq_lparm = 12 + mask_len; 2556 req->rq_parm = param; 2557 req->rq_flags = 0; 2558 result = smb_add_request(req); 2559 if (result < 0) 2560 goto out_free; 2561 if (req->rq_rcls != 0) { 2562 result = smb_errno(req); 2563#ifdef SMBFS_PARANOIA 2564 if (result != -ENOENT) 2565 PARANOIA("error for %s, rcls=%d, err=%d\n", 2566 mask, req->rq_rcls, req->rq_err); 2567#endif 2568 goto out_free; 2569 } 2570 /* Make sure we got enough data ... */ 2571 result = -EINVAL; 2572 if (req->rq_ldata < 22 || WVAL(req->rq_parm, 2) != 1) { 2573 PARANOIA("bad result for %s, len=%d, count=%d\n", 2574 mask, req->rq_ldata, WVAL(req->rq_parm, 2)); 2575 goto out_free; 2576 } 2577 2578 /* 2579 * Decode the response into the fattr ... 2580 */ 2581 date = WVAL(req->rq_data, 0); 2582 time = WVAL(req->rq_data, 2); 2583 fattr->f_ctime.tv_sec = date_dos2unix(server, date, time); 2584 fattr->f_ctime.tv_nsec = 0; 2585 2586 date = WVAL(req->rq_data, 4); 2587 time = WVAL(req->rq_data, 6); 2588 fattr->f_atime.tv_sec = date_dos2unix(server, date, time); 2589 fattr->f_atime.tv_nsec = 0; 2590 2591 date = WVAL(req->rq_data, 8); 2592 time = WVAL(req->rq_data, 10); 2593 fattr->f_mtime.tv_sec = date_dos2unix(server, date, time); 2594 fattr->f_mtime.tv_nsec = 0; 2595 VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n", 2596 mask, date, time, fattr->f_mtime); 2597 fattr->f_size = DVAL(req->rq_data, 12); 2598 /* ULONG allocation size */ 2599 fattr->attr = WVAL(req->rq_data, 20); 2600 result = 0; 2601 2602out_free: 2603 smb_rput(req); 2604out: 2605 return result; 2606} 2607 2608static int 2609smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, 2610 struct smb_fattr *fattr) 2611{ 2612 int result; 2613 char *p; 2614 struct smb_request *req; 2615 2616 result = -ENOMEM; 2617 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2618 goto out; 2619 2620 p = smb_setup_header(req, SMBgetatr, 0, 0); 2621 result = smb_simple_encode_path(req, &p, dir, NULL); 2622 if (result < 0) 2623 goto out_free; 2624 smb_setup_bcc(req, p); 2625 2626 if ((result = smb_request_ok(req, SMBgetatr, 10, 0)) < 0) 2627 goto out_free; 2628 fattr->attr = WVAL(req->rq_header, smb_vwv0); 2629 fattr->f_mtime.tv_sec = local2utc(server, DVAL(req->rq_header, smb_vwv1)); 2630 fattr->f_mtime.tv_nsec = 0; 2631 fattr->f_size = DVAL(req->rq_header, smb_vwv3); 2632 fattr->f_ctime = fattr->f_mtime; 2633 fattr->f_atime = fattr->f_mtime; 2634#ifdef SMBFS_DEBUG_TIMESTAMP 2635 printk("getattr_core: %s/%s, mtime=%ld\n", 2636 DENTRY_PATH(dir), fattr->f_mtime); 2637#endif 2638 result = 0; 2639 2640out_free: 2641 smb_rput(req); 2642out: 2643 return result; 2644} 2645 2646/* 2647 * Bugs Noted: 2648 * (1) Win 95 swaps the date and time fields in the standard info level. 2649 */ 2650static int 2651smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir, 2652 struct smb_request *req, int infolevel) 2653{ 2654 char *p, *param; 2655 int result; 2656 2657 param = req->rq_buffer; 2658 WSET(param, 0, infolevel); 2659 DSET(param, 2, 0); 2660 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL); 2661 if (result < 0) 2662 goto out; 2663 p = param + 6 + result; 2664 2665 req->rq_trans2_command = TRANSACT2_QPATHINFO; 2666 req->rq_ldata = 0; 2667 req->rq_data = NULL; 2668 req->rq_lparm = p - param; 2669 req->rq_parm = param; 2670 req->rq_flags = 0; 2671 result = smb_add_request(req); 2672 if (result < 0) 2673 goto out; 2674 if (req->rq_rcls != 0) { 2675 VERBOSE("for %s: result=%d, rcls=%d, err=%d\n", 2676 &param[6], result, req->rq_rcls, req->rq_err); 2677 result = smb_errno(req); 2678 goto out; 2679 } 2680 result = -ENOENT; 2681 if (req->rq_ldata < 22) { 2682 PARANOIA("not enough data for %s, len=%d\n", 2683 &param[6], req->rq_ldata); 2684 goto out; 2685 } 2686 2687 result = 0; 2688out: 2689 return result; 2690} 2691 2692static int 2693smb_proc_getattr_trans2_std(struct smb_sb_info *server, struct dentry *dir, 2694 struct smb_fattr *attr) 2695{ 2696 u16 date, time; 2697 int off_date = 0, off_time = 2; 2698 int result; 2699 struct smb_request *req; 2700 2701 result = -ENOMEM; 2702 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2703 goto out; 2704 2705 result = smb_proc_getattr_trans2(server, dir, req, SMB_INFO_STANDARD); 2706 if (result < 0) 2707 goto out_free; 2708 2709 /* 2710 * Kludge alert: Win 95 swaps the date and time field, 2711 * contrary to the CIFS docs and Win NT practice. 2712 */ 2713 if (server->mnt->flags & SMB_MOUNT_WIN95) { 2714 off_date = 2; 2715 off_time = 0; 2716 } 2717 date = WVAL(req->rq_data, off_date); 2718 time = WVAL(req->rq_data, off_time); 2719 attr->f_ctime.tv_sec = date_dos2unix(server, date, time); 2720 attr->f_ctime.tv_nsec = 0; 2721 2722 date = WVAL(req->rq_data, 4 + off_date); 2723 time = WVAL(req->rq_data, 4 + off_time); 2724 attr->f_atime.tv_sec = date_dos2unix(server, date, time); 2725 attr->f_atime.tv_nsec = 0; 2726 2727 date = WVAL(req->rq_data, 8 + off_date); 2728 time = WVAL(req->rq_data, 8 + off_time); 2729 attr->f_mtime.tv_sec = date_dos2unix(server, date, time); 2730 attr->f_mtime.tv_nsec = 0; 2731#ifdef SMBFS_DEBUG_TIMESTAMP 2732 printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 2733 DENTRY_PATH(dir), date, time, attr->f_mtime); 2734#endif 2735 attr->f_size = DVAL(req->rq_data, 12); 2736 attr->attr = WVAL(req->rq_data, 20); 2737 2738out_free: 2739 smb_rput(req); 2740out: 2741 return result; 2742} 2743 2744static int 2745smb_proc_getattr_trans2_all(struct smb_sb_info *server, struct dentry *dir, 2746 struct smb_fattr *attr) 2747{ 2748 struct smb_request *req; 2749 int result; 2750 2751 result = -ENOMEM; 2752 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2753 goto out; 2754 2755 result = smb_proc_getattr_trans2(server, dir, req, 2756 SMB_QUERY_FILE_ALL_INFO); 2757 if (result < 0) 2758 goto out_free; 2759 2760 attr->f_ctime = smb_ntutc2unixutc(LVAL(req->rq_data, 0)); 2761 attr->f_atime = smb_ntutc2unixutc(LVAL(req->rq_data, 8)); 2762 attr->f_mtime = smb_ntutc2unixutc(LVAL(req->rq_data, 16)); 2763 /* change (24) */ 2764 attr->attr = WVAL(req->rq_data, 32); 2765 /* pad? (34) */ 2766 /* allocated size (40) */ 2767 attr->f_size = LVAL(req->rq_data, 48); 2768 2769out_free: 2770 smb_rput(req); 2771out: 2772 return result; 2773} 2774 2775static int 2776smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir, 2777 struct smb_fattr *attr) 2778{ 2779 struct smb_request *req; 2780 int result; 2781 2782 result = -ENOMEM; 2783 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2784 goto out; 2785 2786 result = smb_proc_getattr_trans2(server, dir, req, 2787 SMB_QUERY_FILE_UNIX_BASIC); 2788 if (result < 0) 2789 goto out_free; 2790 2791 smb_decode_unix_basic(attr, server, req->rq_data); 2792 2793out_free: 2794 smb_rput(req); 2795out: 2796 return result; 2797} 2798 2799static int 2800smb_proc_getattr_95(struct smb_sb_info *server, struct dentry *dir, 2801 struct smb_fattr *attr) 2802{ 2803 struct inode *inode = dir->d_inode; 2804 int result; 2805 2806 /* FIXME: why not use the "all" version? */ 2807 result = smb_proc_getattr_trans2_std(server, dir, attr); 2808 if (result < 0) 2809 goto out; 2810 2811 /* 2812 * None of the getattr versions here can make win9x return the right 2813 * filesize if there are changes made to an open file. 2814 * A seek-to-end does return the right size, but we only need to do 2815 * that on files we have written. 2816 */ 2817 if (inode && SMB_I(inode)->flags & SMB_F_LOCALWRITE && 2818 smb_is_open(inode)) 2819 { 2820 __u16 fileid = SMB_I(inode)->fileid; 2821 attr->f_size = smb_proc_seek(server, fileid, 2, 0); 2822 } 2823 2824out: 2825 return result; 2826} 2827 2828static int 2829smb_proc_ops_wait(struct smb_sb_info *server) 2830{ 2831 int result; 2832 2833 result = wait_event_interruptible_timeout(server->conn_wq, 2834 server->conn_complete, 30*HZ); 2835 2836 if (!result || signal_pending(current)) 2837 return -EIO; 2838 2839 return 0; 2840} 2841 2842static int 2843smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir, 2844 struct smb_fattr *fattr) 2845{ 2846 int result; 2847 2848 if (smb_proc_ops_wait(server) < 0) 2849 return -EIO; 2850 2851 smb_init_dirent(server, fattr); 2852 result = server->ops->getattr(server, dir, fattr); 2853 smb_finish_dirent(server, fattr); 2854 2855 return result; 2856} 2857 2858static int 2859smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir, 2860 struct smb_cache_control *ctl) 2861{ 2862 struct smb_sb_info *server = server_from_dentry(filp->f_path.dentry); 2863 2864 if (smb_proc_ops_wait(server) < 0) 2865 return -EIO; 2866 2867 return server->ops->readdir(filp, dirent, filldir, ctl); 2868} 2869 2870int 2871smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) 2872{ 2873 struct smb_sb_info *server = server_from_dentry(dir); 2874 int result; 2875 2876 smb_init_dirent(server, fattr); 2877 result = server->ops->getattr(server, dir, fattr); 2878 smb_finish_dirent(server, fattr); 2879 2880 return result; 2881} 2882 2883 2884/* 2885 * Because of bugs in the core protocol, we use this only to set 2886 * attributes. See smb_proc_settime() below for timestamp handling. 2887 * 2888 * Bugs Noted: 2889 * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail 2890 * with an undocumented error (ERRDOS code 50). Setting 2891 * mtime to 0 allows the attributes to be set. 2892 * (2) The extra parameters following the name string aren't 2893 * in the CIFS docs, but seem to be necessary for operation. 2894 */ 2895static int 2896smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, 2897 __u16 attr) 2898{ 2899 char *p; 2900 int result; 2901 struct smb_request *req; 2902 2903 result = -ENOMEM; 2904 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 2905 goto out; 2906 2907 p = smb_setup_header(req, SMBsetatr, 8, 0); 2908 WSET(req->rq_header, smb_vwv0, attr); 2909 DSET(req->rq_header, smb_vwv1, 0); /* mtime */ 2910 WSET(req->rq_header, smb_vwv3, 0); /* reserved values */ 2911 WSET(req->rq_header, smb_vwv4, 0); 2912 WSET(req->rq_header, smb_vwv5, 0); 2913 WSET(req->rq_header, smb_vwv6, 0); 2914 WSET(req->rq_header, smb_vwv7, 0); 2915 result = smb_simple_encode_path(req, &p, dentry, NULL); 2916 if (result < 0) 2917 goto out_free; 2918 if (p + 2 > (char *)req->rq_buffer + req->rq_bufsize) { 2919 result = -ENAMETOOLONG; 2920 goto out_free; 2921 } 2922 *p++ = 4; 2923 *p++ = 0; 2924 smb_setup_bcc(req, p); 2925 2926 result = smb_request_ok(req, SMBsetatr, 0, 0); 2927 if (result < 0) 2928 goto out_free; 2929 result = 0; 2930 2931out_free: 2932 smb_rput(req); 2933out: 2934 return result; 2935} 2936 2937/* 2938 * Because of bugs in the trans2 setattr messages, we must set 2939 * attributes and timestamps separately. The core SMBsetatr 2940 * message seems to be the only reliable way to set attributes. 2941 */ 2942int 2943smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr) 2944{ 2945 struct smb_sb_info *server = server_from_dentry(dir); 2946 int result; 2947 2948 VERBOSE("setting %s/%s, open=%d\n", 2949 DENTRY_PATH(dir), smb_is_open(dir->d_inode)); 2950 result = smb_proc_setattr_core(server, dir, fattr->attr); 2951 return result; 2952} 2953 2954/* 2955 * Sets the timestamps for an file open with write permissions. 2956 */ 2957static int 2958smb_proc_setattr_ext(struct smb_sb_info *server, 2959 struct inode *inode, struct smb_fattr *fattr) 2960{ 2961 __u16 date, time; 2962 int result; 2963 struct smb_request *req; 2964 2965 result = -ENOMEM; 2966 if (! (req = smb_alloc_request(server, 0))) 2967 goto out; 2968 2969 smb_setup_header(req, SMBsetattrE, 7, 0); 2970 WSET(req->rq_header, smb_vwv0, SMB_I(inode)->fileid); 2971 /* We don't change the creation time */ 2972 WSET(req->rq_header, smb_vwv1, 0); 2973 WSET(req->rq_header, smb_vwv2, 0); 2974 date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time); 2975 WSET(req->rq_header, smb_vwv3, date); 2976 WSET(req->rq_header, smb_vwv4, time); 2977 date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time); 2978 WSET(req->rq_header, smb_vwv5, date); 2979 WSET(req->rq_header, smb_vwv6, time); 2980#ifdef SMBFS_DEBUG_TIMESTAMP 2981 printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", 2982 date, time, fattr->f_mtime); 2983#endif 2984 2985 req->rq_flags |= SMB_REQ_NORETRY; 2986 result = smb_request_ok(req, SMBsetattrE, 0, 0); 2987 if (result < 0) 2988 goto out_free; 2989 result = 0; 2990out_free: 2991 smb_rput(req); 2992out: 2993 return result; 2994} 2995 2996/* 2997 * Bugs Noted: 2998 * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't 2999 * set the file's attribute flags. 3000 */ 3001static int 3002smb_proc_setattr_trans2(struct smb_sb_info *server, 3003 struct dentry *dir, struct smb_fattr *fattr) 3004{ 3005 __u16 date, time; 3006 char *p, *param; 3007 int result; 3008 char data[26]; 3009 struct smb_request *req; 3010 3011 result = -ENOMEM; 3012 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 3013 goto out; 3014 param = req->rq_buffer; 3015 3016 WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ 3017 DSET(param, 2, 0); 3018 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL); 3019 if (result < 0) 3020 goto out_free; 3021 p = param + 6 + result; 3022 3023 WSET(data, 0, 0); /* creation time */ 3024 WSET(data, 2, 0); 3025 date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time); 3026 WSET(data, 4, date); 3027 WSET(data, 6, time); 3028 date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time); 3029 WSET(data, 8, date); 3030 WSET(data, 10, time); 3031#ifdef SMBFS_DEBUG_TIMESTAMP 3032 printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 3033 DENTRY_PATH(dir), date, time, fattr->f_mtime); 3034#endif 3035 DSET(data, 12, 0); /* size */ 3036 DSET(data, 16, 0); /* blksize */ 3037 WSET(data, 20, 0); /* attr */ 3038 DSET(data, 22, 0); /* ULONG EA size */ 3039 3040 req->rq_trans2_command = TRANSACT2_SETPATHINFO; 3041 req->rq_ldata = 26; 3042 req->rq_data = data; 3043 req->rq_lparm = p - param; 3044 req->rq_parm = param; 3045 req->rq_flags = 0; 3046 result = smb_add_request(req); 3047 if (result < 0) 3048 goto out_free; 3049 result = 0; 3050 if (req->rq_rcls != 0) 3051 result = smb_errno(req); 3052 3053out_free: 3054 smb_rput(req); 3055out: 3056 return result; 3057} 3058 3059/* 3060 * ATTR_MODE 0x001 3061 * ATTR_UID 0x002 3062 * ATTR_GID 0x004 3063 * ATTR_SIZE 0x008 3064 * ATTR_ATIME 0x010 3065 * ATTR_MTIME 0x020 3066 * ATTR_CTIME 0x040 3067 * ATTR_ATIME_SET 0x080 3068 * ATTR_MTIME_SET 0x100 3069 * ATTR_FORCE 0x200 3070 * ATTR_ATTR_FLAG 0x400 3071 * 3072 * major/minor should only be set by mknod. 3073 */ 3074int 3075smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, 3076 unsigned int major, unsigned int minor) 3077{ 3078 struct smb_sb_info *server = server_from_dentry(d); 3079 u64 nttime; 3080 char *p, *param; 3081 int result; 3082 char data[100]; 3083 struct smb_request *req; 3084 3085 result = -ENOMEM; 3086 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 3087 goto out; 3088 param = req->rq_buffer; 3089 3090 DEBUG1("valid flags = 0x%04x\n", attr->ia_valid); 3091 3092 WSET(param, 0, SMB_SET_FILE_UNIX_BASIC); 3093 DSET(param, 2, 0); 3094 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL); 3095 if (result < 0) 3096 goto out_free; 3097 p = param + 6 + result; 3098 3099 /* 0 L file size in bytes */ 3100 /* 8 L file size on disk in bytes (block count) */ 3101 /* 40 L uid */ 3102 /* 48 L gid */ 3103 /* 56 W file type enum */ 3104 /* 60 L devmajor */ 3105 /* 68 L devminor */ 3106 /* 76 L unique ID (inode) */ 3107 /* 84 L permissions */ 3108 /* 92 L link count */ 3109 LSET(data, 0, SMB_SIZE_NO_CHANGE); 3110 LSET(data, 8, SMB_SIZE_NO_CHANGE); 3111 LSET(data, 16, SMB_TIME_NO_CHANGE); 3112 LSET(data, 24, SMB_TIME_NO_CHANGE); 3113 LSET(data, 32, SMB_TIME_NO_CHANGE); 3114 LSET(data, 40, SMB_UID_NO_CHANGE); 3115 LSET(data, 48, SMB_GID_NO_CHANGE); 3116 DSET(data, 56, smb_filetype_from_mode(attr->ia_mode)); 3117 LSET(data, 60, major); 3118 LSET(data, 68, minor); 3119 LSET(data, 76, 0); 3120 LSET(data, 84, SMB_MODE_NO_CHANGE); 3121 LSET(data, 92, 0); 3122 3123 if (attr->ia_valid & ATTR_SIZE) { 3124 LSET(data, 0, attr->ia_size); 3125 LSET(data, 8, 0); /* can't set anyway */ 3126 } 3127 3128 /* 3129 * FIXME: check the conversion function it the correct one 3130 * 3131 * we can't set ctime but we might as well pass this to the server 3132 * and let it ignore it. 3133 */ 3134 if (attr->ia_valid & ATTR_CTIME) { 3135 nttime = smb_unixutc2ntutc(attr->ia_ctime); 3136 LSET(data, 16, nttime); 3137 } 3138 if (attr->ia_valid & ATTR_ATIME) { 3139 nttime = smb_unixutc2ntutc(attr->ia_atime); 3140 LSET(data, 24, nttime); 3141 } 3142 if (attr->ia_valid & ATTR_MTIME) { 3143 nttime = smb_unixutc2ntutc(attr->ia_mtime); 3144 LSET(data, 32, nttime); 3145 } 3146 3147 if (attr->ia_valid & ATTR_UID) { 3148 LSET(data, 40, attr->ia_uid); 3149 } 3150 if (attr->ia_valid & ATTR_GID) { 3151 LSET(data, 48, attr->ia_gid); 3152 } 3153 3154 if (attr->ia_valid & ATTR_MODE) { 3155 LSET(data, 84, attr->ia_mode); 3156 } 3157 3158 req->rq_trans2_command = TRANSACT2_SETPATHINFO; 3159 req->rq_ldata = 100; 3160 req->rq_data = data; 3161 req->rq_lparm = p - param; 3162 req->rq_parm = param; 3163 req->rq_flags = 0; 3164 result = smb_add_request(req); 3165 3166out_free: 3167 smb_rput(req); 3168out: 3169 return result; 3170} 3171 3172 3173/* 3174 * Set the modify and access timestamps for a file. 3175 * 3176 * Incredibly enough, in all of SMB there is no message to allow 3177 * setting both attributes and timestamps at once. 3178 * 3179 * Bugs Noted: 3180 * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message 3181 * with info level 1 (INFO_STANDARD). 3182 * (2) Win 95 seems not to support setting directory timestamps. 3183 * (3) Under the core protocol apparently the only way to set the 3184 * timestamp is to open and close the file. 3185 */ 3186int 3187smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) 3188{ 3189 struct smb_sb_info *server = server_from_dentry(dentry); 3190 struct inode *inode = dentry->d_inode; 3191 int result; 3192 3193 VERBOSE("setting %s/%s, open=%d\n", 3194 DENTRY_PATH(dentry), smb_is_open(inode)); 3195 3196 /* setting the time on a Win95 server fails (tridge) */ 3197 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && 3198 !(server->mnt->flags & SMB_MOUNT_WIN95)) { 3199 if (smb_is_open(inode) && SMB_I(inode)->access != SMB_O_RDONLY) 3200 result = smb_proc_setattr_ext(server, inode, fattr); 3201 else 3202 result = smb_proc_setattr_trans2(server, dentry, fattr); 3203 } else { 3204 /* 3205 * Fail silently on directories ... timestamp can't be set? 3206 */ 3207 result = 0; 3208 if (S_ISREG(inode->i_mode)) { 3209 /* 3210 * Set the mtime by opening and closing the file. 3211 * Note that the file is opened read-only, but this 3212 * still allows us to set the date (tridge) 3213 */ 3214 result = -EACCES; 3215 if (!smb_is_open(inode)) 3216 smb_proc_open(server, dentry, SMB_O_RDONLY); 3217 if (smb_is_open(inode)) { 3218 inode->i_mtime = fattr->f_mtime; 3219 result = smb_proc_close_inode(server, inode); 3220 } 3221 } 3222 } 3223 3224 return result; 3225} 3226 3227int 3228smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr) 3229{ 3230 struct smb_sb_info *server = SMB_SB(dentry->d_sb); 3231 int result; 3232 char *p; 3233 long unit; 3234 struct smb_request *req; 3235 3236 result = -ENOMEM; 3237 if (! (req = smb_alloc_request(server, 0))) 3238 goto out; 3239 3240 smb_setup_header(req, SMBdskattr, 0, 0); 3241 if ((result = smb_request_ok(req, SMBdskattr, 5, 0)) < 0) 3242 goto out_free; 3243 p = SMB_VWV(req->rq_header); 3244 unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT; 3245 attr->f_blocks = WVAL(p, 0) * unit; 3246 attr->f_bsize = SMB_ST_BLKSIZE; 3247 attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit; 3248 result = 0; 3249 3250out_free: 3251 smb_rput(req); 3252out: 3253 return result; 3254} 3255 3256int 3257smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, 3258 char *buffer, int len) 3259{ 3260 char *p, *param; 3261 int result; 3262 struct smb_request *req; 3263 3264 DEBUG1("readlink of %s/%s\n", DENTRY_PATH(d)); 3265 3266 result = -ENOMEM; 3267 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 3268 goto out; 3269 param = req->rq_buffer; 3270 3271 WSET(param, 0, SMB_QUERY_FILE_UNIX_LINK); 3272 DSET(param, 2, 0); 3273 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL); 3274 if (result < 0) 3275 goto out_free; 3276 p = param + 6 + result; 3277 3278 req->rq_trans2_command = TRANSACT2_QPATHINFO; 3279 req->rq_ldata = 0; 3280 req->rq_data = NULL; 3281 req->rq_lparm = p - param; 3282 req->rq_parm = param; 3283 req->rq_flags = 0; 3284 result = smb_add_request(req); 3285 if (result < 0) 3286 goto out_free; 3287 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", 3288 &param[6], result, req->rq_rcls, req->rq_err); 3289 3290 /* copy data up to the \0 or buffer length */ 3291 result = len; 3292 if (req->rq_ldata < len) 3293 result = req->rq_ldata; 3294 strncpy(buffer, req->rq_data, result); 3295 3296out_free: 3297 smb_rput(req); 3298out: 3299 return result; 3300} 3301 3302 3303/* 3304 * Create a symlink object called dentry which points to oldpath. 3305 * Samba does not permit dangling links but returns a suitable error message. 3306 */ 3307int 3308smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, 3309 const char *oldpath) 3310{ 3311 char *p, *param; 3312 int result; 3313 struct smb_request *req; 3314 3315 result = -ENOMEM; 3316 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 3317 goto out; 3318 param = req->rq_buffer; 3319 3320 WSET(param, 0, SMB_SET_FILE_UNIX_LINK); 3321 DSET(param, 2, 0); 3322 result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, d, NULL); 3323 if (result < 0) 3324 goto out_free; 3325 p = param + 6 + result; 3326 3327 req->rq_trans2_command = TRANSACT2_SETPATHINFO; 3328 req->rq_ldata = strlen(oldpath) + 1; 3329 req->rq_data = (char *) oldpath; 3330 req->rq_lparm = p - param; 3331 req->rq_parm = param; 3332 req->rq_flags = 0; 3333 result = smb_add_request(req); 3334 if (result < 0) 3335 goto out_free; 3336 3337 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", 3338 &param[6], result, req->rq_rcls, req->rq_err); 3339 result = 0; 3340 3341out_free: 3342 smb_rput(req); 3343out: 3344 return result; 3345} 3346 3347/* 3348 * Create a hard link object called new_dentry which points to dentry. 3349 */ 3350int 3351smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, 3352 struct dentry *new_dentry) 3353{ 3354 char *p, *param; 3355 int result; 3356 struct smb_request *req; 3357 3358 result = -ENOMEM; 3359 if (! (req = smb_alloc_request(server, PAGE_SIZE))) 3360 goto out; 3361 param = req->rq_buffer; 3362 3363 WSET(param, 0, SMB_SET_FILE_UNIX_HLINK); 3364 DSET(param, 2, 0); 3365 result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, 3366 new_dentry, NULL); 3367 if (result < 0) 3368 goto out_free; 3369 p = param + 6 + result; 3370 3371 /* Grr, pointless separation of parameters and data ... */ 3372 req->rq_data = p; 3373 req->rq_ldata = smb_encode_path(server, p, SMB_MAXPATHLEN+1, 3374 dentry, NULL); 3375 3376 req->rq_trans2_command = TRANSACT2_SETPATHINFO; 3377 req->rq_lparm = p - param; 3378 req->rq_parm = param; 3379 req->rq_flags = 0; 3380 result = smb_add_request(req); 3381 if (result < 0) 3382 goto out_free; 3383 3384 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", 3385 &param[6], result, req->rq_rcls, req->rq_err); 3386 result = 0; 3387 3388out_free: 3389 smb_rput(req); 3390out: 3391 return result; 3392} 3393 3394static int 3395smb_proc_query_cifsunix(struct smb_sb_info *server) 3396{ 3397 int result; 3398 int major, minor; 3399 u64 caps; 3400 char param[2]; 3401 struct smb_request *req; 3402 3403 result = -ENOMEM; 3404 if (! (req = smb_alloc_request(server, 100))) 3405 goto out; 3406 3407 WSET(param, 0, SMB_QUERY_CIFS_UNIX_INFO); 3408 3409 req->rq_trans2_command = TRANSACT2_QFSINFO; 3410 req->rq_ldata = 0; 3411 req->rq_data = NULL; 3412 req->rq_lparm = 2; 3413 req->rq_parm = param; 3414 req->rq_flags = 0; 3415 result = smb_add_request(req); 3416 if (result < 0) 3417 goto out_free; 3418 3419 if (req->rq_ldata < 12) { 3420 PARANOIA("Not enough data\n"); 3421 goto out_free; 3422 } 3423 major = WVAL(req->rq_data, 0); 3424 minor = WVAL(req->rq_data, 2); 3425 3426 DEBUG1("Server implements CIFS Extensions for UNIX systems v%d.%d\n", 3427 major, minor); 3428 /* FIXME: verify that we are ok with this major/minor? */ 3429 3430 caps = LVAL(req->rq_data, 4); 3431 DEBUG1("Server capabilities 0x%016llx\n", caps); 3432 3433out_free: 3434 smb_rput(req); 3435out: 3436 return result; 3437} 3438 3439 3440static void 3441install_ops(struct smb_ops *dst, struct smb_ops *src) 3442{ 3443 memcpy(dst, src, sizeof(void *) * SMB_OPS_NUM_STATIC); 3444} 3445 3446/* < LANMAN2 */ 3447static struct smb_ops smb_ops_core = 3448{ 3449 .read = smb_proc_read, 3450 .write = smb_proc_write, 3451 .readdir = smb_proc_readdir_short, 3452 .getattr = smb_proc_getattr_core, 3453 .truncate = smb_proc_trunc32, 3454}; 3455 3456/* LANMAN2, OS/2, others? */ 3457static struct smb_ops smb_ops_os2 = 3458{ 3459 .read = smb_proc_read, 3460 .write = smb_proc_write, 3461 .readdir = smb_proc_readdir_long, 3462 .getattr = smb_proc_getattr_trans2_std, 3463 .truncate = smb_proc_trunc32, 3464}; 3465 3466/* Win95, and possibly some NetApp versions too */ 3467static struct smb_ops smb_ops_win95 = 3468{ 3469 .read = smb_proc_read, /* does not support 12word readX */ 3470 .write = smb_proc_write, 3471 .readdir = smb_proc_readdir_long, 3472 .getattr = smb_proc_getattr_95, 3473 .truncate = smb_proc_trunc95, 3474}; 3475 3476/* Samba, NT4 and NT5 */ 3477static struct smb_ops smb_ops_winNT = 3478{ 3479 .read = smb_proc_readX, 3480 .write = smb_proc_writeX, 3481 .readdir = smb_proc_readdir_long, 3482 .getattr = smb_proc_getattr_trans2_all, 3483 .truncate = smb_proc_trunc64, 3484}; 3485 3486/* Samba w/ unix extensions. Others? */ 3487static struct smb_ops smb_ops_unix = 3488{ 3489 .read = smb_proc_readX, 3490 .write = smb_proc_writeX, 3491 .readdir = smb_proc_readdir_long, 3492 .getattr = smb_proc_getattr_unix, 3493 /* FIXME: core/ext/time setattr needs to be cleaned up! */ 3494 /* .setattr = smb_proc_setattr_unix, */ 3495 .truncate = smb_proc_trunc64, 3496}; 3497 3498/* Place holder until real ops are in place */ 3499static struct smb_ops smb_ops_null = 3500{ 3501 .readdir = smb_proc_readdir_null, 3502 .getattr = smb_proc_getattr_null, 3503}; 3504 3505void smb_install_null_ops(struct smb_ops *ops) 3506{ 3507 install_ops(ops, &smb_ops_null); 3508}