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