1/* 2 * fs/cifs_debug.c 3 * 4 * Copyright (C) International Business Machines Corp., 2000,2005 5 * 6 * Modified by Steve French (sfrench@us.ibm.com) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 * the GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22#include <linux/fs.h> 23#include <linux/string.h> 24#include <linux/ctype.h> 25#include <linux/module.h> 26#include <linux/proc_fs.h> 27#include <asm/uaccess.h> 28#include "cifspdu.h" 29#include "cifsglob.h" 30#include "cifsproto.h" 31#include "cifs_debug.h" 32#include "cifsfs.h" 33 34void 35cifs_dump_mem(char *label, void *data, int length) 36{ 37 int i, j; 38 int *intptr = data; 39 char *charptr = data; 40 char buf[10], line[80]; 41 42 printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", 43 label, length, data); 44 for (i = 0; i < length; i += 16) { 45 line[0] = 0; 46 for (j = 0; (j < 4) && (i + j * 4 < length); j++) { 47 sprintf(buf, " %08x", intptr[i / 4 + j]); 48 strcat(line, buf); 49 } 50 buf[0] = ' '; 51 buf[2] = 0; 52 for (j = 0; (j < 16) && (i + j < length); j++) { 53 buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.'; 54 strcat(line, buf); 55 } 56 printk(KERN_DEBUG "%s\n", line); 57 } 58} 59 60#ifdef CONFIG_CIFS_DEBUG2 61void cifs_dump_detail(struct smb_hdr * smb) 62{ 63 cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", 64 smb->Command, smb->Status.CifsError, 65 smb->Flags, smb->Flags2, smb->Mid, smb->Pid)); 66 cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb))); 67} 68 69 70void cifs_dump_mids(struct TCP_Server_Info * server) 71{ 72 struct list_head *tmp; 73 struct mid_q_entry * mid_entry; 74 75 if (server == NULL) 76 return; 77 78 cERROR(1, ("Dump pending requests:")); 79 spin_lock(&GlobalMid_Lock); 80 list_for_each(tmp, &server->pending_mid_q) { 81 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 82 if (mid_entry) { 83 cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", 84 mid_entry->midState, 85 (int)mid_entry->command, 86 mid_entry->pid, 87 mid_entry->tsk, 88 mid_entry->mid)); 89#ifdef CONFIG_CIFS_STATS2 90 cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld", 91 mid_entry->largeBuf, 92 mid_entry->resp_buf, 93 mid_entry->when_received, 94 jiffies)); 95#endif /* STATS2 */ 96 cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp, 97 mid_entry->multiEnd)); 98 if (mid_entry->resp_buf) { 99 cifs_dump_detail(mid_entry->resp_buf); 100 cifs_dump_mem("existing buf: ", 101 mid_entry->resp_buf, 102 62); 103 } 104 } 105 } 106 spin_unlock(&GlobalMid_Lock); 107} 108#endif /* CONFIG_CIFS_DEBUG2 */ 109 110#ifdef CONFIG_PROC_FS 111static int 112cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, 113 int count, int *eof, void *data) 114{ 115 struct list_head *tmp; 116 struct list_head *tmp1; 117 struct mid_q_entry * mid_entry; 118 struct cifsSesInfo *ses; 119 struct cifsTconInfo *tcon; 120 int i; 121 int length = 0; 122 char * original_buf = buf; 123 124 *beginBuffer = buf + offset; 125 126 length = 127 sprintf(buf, 128 "Display Internal CIFS Data Structures for Debugging\n" 129 "---------------------------------------------------\n"); 130 buf += length; 131 length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION); 132 buf += length; 133 length = sprintf(buf, 134 "Active VFS Requests: %d\n", GlobalTotalActiveXid); 135 buf += length; 136 length = sprintf(buf, "Servers:"); 137 buf += length; 138 139 i = 0; 140 read_lock(&GlobalSMBSeslock); 141 list_for_each(tmp, &GlobalSMBSessionList) { 142 i++; 143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); 144 if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || 145 (ses->serverNOS == NULL)) { 146 buf += sprintf(buf, "\nentry for %s not fully " 147 "displayed\n\t", ses->serverName); 148 149 } else { 150 length = 151 sprintf(buf, 152 "\n%d) Name: %s Domain: %s Mounts: %d OS:" 153 " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB" 154 " session status: %d\t", 155 i, ses->serverName, ses->serverDomain, 156 atomic_read(&ses->inUse), 157 ses->serverOS, ses->serverNOS, 158 ses->capabilities, ses->status); 159 buf += length; 160 } 161 if (ses->server) { 162 buf += sprintf(buf, "TCP status: %d\n\tLocal Users To " 163 "Server: %d SecMode: 0x%x Req On Wire: %d", 164 ses->server->tcpStatus, 165 atomic_read(&ses->server->socketUseCount), 166 ses->server->secMode, 167 atomic_read(&ses->server->inFlight)); 168 169#ifdef CONFIG_CIFS_STATS2 170 buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", 171 atomic_read(&ses->server->inSend), 172 atomic_read(&ses->server->num_waiters)); 173#endif 174 175 length = sprintf(buf, "\nMIDs:\n"); 176 buf += length; 177 178 spin_lock(&GlobalMid_Lock); 179 list_for_each(tmp1, &ses->server->pending_mid_q) { 180 mid_entry = list_entry(tmp1, struct 181 mid_q_entry, 182 qhead); 183 if (mid_entry) { 184 length = sprintf(buf, 185 "State: %d com: %d pid:" 186 " %d tsk: %p mid %d\n", 187 mid_entry->midState, 188 (int)mid_entry->command, 189 mid_entry->pid, 190 mid_entry->tsk, 191 mid_entry->mid); 192 buf += length; 193 } 194 } 195 spin_unlock(&GlobalMid_Lock); 196 } 197 198 } 199 read_unlock(&GlobalSMBSeslock); 200 sprintf(buf, "\n"); 201 buf++; 202 203 length = sprintf(buf, "Shares:"); 204 buf += length; 205 206 i = 0; 207 read_lock(&GlobalSMBSeslock); 208 list_for_each(tmp, &GlobalTreeConnectionList) { 209 __u32 dev_type; 210 i++; 211 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 212 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 213 length = 214 sprintf(buf, 215 "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x " 216 "Attributes: 0x%x\nPathComponentMax: %d Status: %d", 217 i, tcon->treeName, 218 atomic_read(&tcon->useCount), 219 tcon->nativeFileSystem, 220 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), 221 le32_to_cpu(tcon->fsAttrInfo.Attributes), 222 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), 223 tcon->tidStatus); 224 buf += length; 225 if (dev_type == FILE_DEVICE_DISK) 226 length = sprintf(buf, " type: DISK "); 227 else if (dev_type == FILE_DEVICE_CD_ROM) 228 length = sprintf(buf, " type: CDROM "); 229 else 230 length = 231 sprintf(buf, " type: %d ", dev_type); 232 buf += length; 233 if (tcon->tidStatus == CifsNeedReconnect) { 234 buf += sprintf(buf, "\tDISCONNECTED "); 235 length += 14; 236 } 237 } 238 read_unlock(&GlobalSMBSeslock); 239 240 length = sprintf(buf, "\n"); 241 buf += length; 242 243 /* BB add code to dump additional info such as TCP session info now */ 244 /* Now calculate total size of returned data */ 245 length = buf - original_buf; 246 247 if (offset + count >= length) 248 *eof = 1; 249 if (length < offset) { 250 *eof = 1; 251 return 0; 252 } else { 253 length = length - offset; 254 } 255 if (length > count) 256 length = count; 257 258 return length; 259} 260 261#ifdef CONFIG_CIFS_STATS 262 263static int 264cifs_stats_write(struct file *file, const char __user *buffer, 265 unsigned long count, void *data) 266{ 267 char c; 268 int rc; 269 struct list_head *tmp; 270 struct cifsTconInfo *tcon; 271 272 rc = get_user(c, buffer); 273 if (rc) 274 return rc; 275 276 if (c == '1' || c == 'y' || c == 'Y' || c == '0') { 277 read_lock(&GlobalSMBSeslock); 278#ifdef CONFIG_CIFS_STATS2 279 atomic_set(&totBufAllocCount, 0); 280 atomic_set(&totSmBufAllocCount, 0); 281#endif /* CONFIG_CIFS_STATS2 */ 282 list_for_each(tmp, &GlobalTreeConnectionList) { 283 tcon = list_entry(tmp, struct cifsTconInfo, 284 cifsConnectionList); 285 atomic_set(&tcon->num_smbs_sent, 0); 286 atomic_set(&tcon->num_writes, 0); 287 atomic_set(&tcon->num_reads, 0); 288 atomic_set(&tcon->num_oplock_brks, 0); 289 atomic_set(&tcon->num_opens, 0); 290 atomic_set(&tcon->num_closes, 0); 291 atomic_set(&tcon->num_deletes, 0); 292 atomic_set(&tcon->num_mkdirs, 0); 293 atomic_set(&tcon->num_rmdirs, 0); 294 atomic_set(&tcon->num_renames, 0); 295 atomic_set(&tcon->num_t2renames, 0); 296 atomic_set(&tcon->num_ffirst, 0); 297 atomic_set(&tcon->num_fnext, 0); 298 atomic_set(&tcon->num_fclose, 0); 299 atomic_set(&tcon->num_hardlinks, 0); 300 atomic_set(&tcon->num_symlinks, 0); 301 atomic_set(&tcon->num_locks, 0); 302 } 303 read_unlock(&GlobalSMBSeslock); 304 } 305 306 return count; 307} 308 309static int 310cifs_stats_read(char *buf, char **beginBuffer, off_t offset, 311 int count, int *eof, void *data) 312{ 313 int item_length, i, length; 314 struct list_head *tmp; 315 struct cifsTconInfo *tcon; 316 317 *beginBuffer = buf + offset; 318 319 length = sprintf(buf, 320 "Resources in use\nCIFS Session: %d\n", 321 sesInfoAllocCount.counter); 322 buf += length; 323 item_length = 324 sprintf(buf, "Share (unique mount targets): %d\n", 325 tconInfoAllocCount.counter); 326 length += item_length; 327 buf += item_length; 328 item_length = 329 sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n", 330 bufAllocCount.counter, 331 cifs_min_rcv + tcpSesAllocCount.counter); 332 length += item_length; 333 buf += item_length; 334 item_length = 335 sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", 336 smBufAllocCount.counter, cifs_min_small); 337 length += item_length; 338 buf += item_length; 339#ifdef CONFIG_CIFS_STATS2 340 item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", 341 atomic_read(&totBufAllocCount), 342 atomic_read(&totSmBufAllocCount)); 343 length += item_length; 344 buf += item_length; 345#endif /* CONFIG_CIFS_STATS2 */ 346 347 item_length = 348 sprintf(buf, "Operations (MIDs): %d\n", 349 midCount.counter); 350 length += item_length; 351 buf += item_length; 352 item_length = sprintf(buf, 353 "\n%d session %d share reconnects\n", 354 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); 355 length += item_length; 356 buf += item_length; 357 358 item_length = sprintf(buf, 359 "Total vfs operations: %d maximum at one time: %d\n", 360 GlobalCurrentXid, GlobalMaxActiveXid); 361 length += item_length; 362 buf += item_length; 363 364 i = 0; 365 read_lock(&GlobalSMBSeslock); 366 list_for_each(tmp, &GlobalTreeConnectionList) { 367 i++; 368 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 369 item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName); 370 buf += item_length; 371 length += item_length; 372 if (tcon->tidStatus == CifsNeedReconnect) { 373 buf += sprintf(buf, "\tDISCONNECTED "); 374 length += 14; 375 } 376 item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d", 377 atomic_read(&tcon->num_smbs_sent), 378 atomic_read(&tcon->num_oplock_brks)); 379 buf += item_length; 380 length += item_length; 381 item_length = sprintf(buf, "\nReads: %d Bytes: %lld", 382 atomic_read(&tcon->num_reads), 383 (long long)(tcon->bytes_read)); 384 buf += item_length; 385 length += item_length; 386 item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", 387 atomic_read(&tcon->num_writes), 388 (long long)(tcon->bytes_written)); 389 buf += item_length; 390 length += item_length; 391 item_length = sprintf(buf, 392 "\nLocks: %d HardLinks: %d Symlinks: %d", 393 atomic_read(&tcon->num_locks), 394 atomic_read(&tcon->num_hardlinks), 395 atomic_read(&tcon->num_symlinks)); 396 buf += item_length; 397 length += item_length; 398 399 item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", 400 atomic_read(&tcon->num_opens), 401 atomic_read(&tcon->num_closes), 402 atomic_read(&tcon->num_deletes)); 403 buf += item_length; 404 length += item_length; 405 item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d", 406 atomic_read(&tcon->num_mkdirs), 407 atomic_read(&tcon->num_rmdirs)); 408 buf += item_length; 409 length += item_length; 410 item_length = sprintf(buf, "\nRenames: %d T2 Renames %d", 411 atomic_read(&tcon->num_renames), 412 atomic_read(&tcon->num_t2renames)); 413 buf += item_length; 414 length += item_length; 415 item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d", 416 atomic_read(&tcon->num_ffirst), 417 atomic_read(&tcon->num_fnext), 418 atomic_read(&tcon->num_fclose)); 419 buf += item_length; 420 length += item_length; 421 } 422 read_unlock(&GlobalSMBSeslock); 423 424 buf += sprintf(buf, "\n"); 425 length++; 426 427 if (offset + count >= length) 428 *eof = 1; 429 if (length < offset) { 430 *eof = 1; 431 return 0; 432 } else { 433 length = length - offset; 434 } 435 if (length > count) 436 length = count; 437 438 return length; 439} 440#endif 441 442static struct proc_dir_entry *proc_fs_cifs; 443read_proc_t cifs_txanchor_read; 444static read_proc_t cifsFYI_read; 445static write_proc_t cifsFYI_write; 446static read_proc_t oplockEnabled_read; 447static write_proc_t oplockEnabled_write; 448static read_proc_t lookupFlag_read; 449static write_proc_t lookupFlag_write; 450static read_proc_t traceSMB_read; 451static write_proc_t traceSMB_write; 452static read_proc_t multiuser_mount_read; 453static write_proc_t multiuser_mount_write; 454static read_proc_t security_flags_read; 455static write_proc_t security_flags_write; 456/* static read_proc_t ntlmv2_enabled_read; 457static write_proc_t ntlmv2_enabled_write; 458static read_proc_t packet_signing_enabled_read; 459static write_proc_t packet_signing_enabled_write;*/ 460static read_proc_t experimEnabled_read; 461static write_proc_t experimEnabled_write; 462static read_proc_t linuxExtensionsEnabled_read; 463static write_proc_t linuxExtensionsEnabled_write; 464 465void 466cifs_proc_init(void) 467{ 468 struct proc_dir_entry *pde; 469 470 proc_fs_cifs = proc_mkdir("cifs", proc_root_fs); 471 if (proc_fs_cifs == NULL) 472 return; 473 474 proc_fs_cifs->owner = THIS_MODULE; 475 create_proc_read_entry("DebugData", 0, proc_fs_cifs, 476 cifs_debug_data_read, NULL); 477 478#ifdef CONFIG_CIFS_STATS 479 pde = create_proc_read_entry("Stats", 0, proc_fs_cifs, 480 cifs_stats_read, NULL); 481 if (pde) 482 pde->write_proc = cifs_stats_write; 483#endif 484 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, 485 cifsFYI_read, NULL); 486 if (pde) 487 pde->write_proc = cifsFYI_write; 488 489 pde = 490 create_proc_read_entry("traceSMB", 0, proc_fs_cifs, 491 traceSMB_read, NULL); 492 if (pde) 493 pde->write_proc = traceSMB_write; 494 495 pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs, 496 oplockEnabled_read, NULL); 497 if (pde) 498 pde->write_proc = oplockEnabled_write; 499 500 pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, 501 experimEnabled_read, NULL); 502 if (pde) 503 pde->write_proc = experimEnabled_write; 504 505 pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, 506 linuxExtensionsEnabled_read, NULL); 507 if (pde) 508 pde->write_proc = linuxExtensionsEnabled_write; 509 510 pde = 511 create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs, 512 multiuser_mount_read, NULL); 513 if (pde) 514 pde->write_proc = multiuser_mount_write; 515 516 pde = 517 create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs, 518 security_flags_read, NULL); 519 if (pde) 520 pde->write_proc = security_flags_write; 521 522 pde = 523 create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs, 524 lookupFlag_read, NULL); 525 if (pde) 526 pde->write_proc = lookupFlag_write; 527 528/* pde = 529 create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs, 530 ntlmv2_enabled_read, NULL); 531 if (pde) 532 pde->write_proc = ntlmv2_enabled_write; 533 534 pde = 535 create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs, 536 packet_signing_enabled_read, NULL); 537 if (pde) 538 pde->write_proc = packet_signing_enabled_write;*/ 539} 540 541void 542cifs_proc_clean(void) 543{ 544 if (proc_fs_cifs == NULL) 545 return; 546 547 remove_proc_entry("DebugData", proc_fs_cifs); 548 remove_proc_entry("cifsFYI", proc_fs_cifs); 549 remove_proc_entry("traceSMB", proc_fs_cifs); 550#ifdef CONFIG_CIFS_STATS 551 remove_proc_entry("Stats", proc_fs_cifs); 552#endif 553 remove_proc_entry("MultiuserMount", proc_fs_cifs); 554 remove_proc_entry("OplockEnabled", proc_fs_cifs); 555/* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ 556 remove_proc_entry("SecurityFlags", proc_fs_cifs); 557/* remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */ 558 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 559 remove_proc_entry("Experimental", proc_fs_cifs); 560 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); 561 remove_proc_entry("cifs", proc_root_fs); 562} 563 564static int 565cifsFYI_read(char *page, char **start, off_t off, int count, 566 int *eof, void *data) 567{ 568 int len; 569 570 len = sprintf(page, "%d\n", cifsFYI); 571 572 len -= off; 573 *start = page + off; 574 575 if (len > count) 576 len = count; 577 else 578 *eof = 1; 579 580 if (len < 0) 581 len = 0; 582 583 return len; 584} 585static int 586cifsFYI_write(struct file *file, const char __user *buffer, 587 unsigned long count, void *data) 588{ 589 char c; 590 int rc; 591 592 rc = get_user(c, buffer); 593 if (rc) 594 return rc; 595 if (c == '0' || c == 'n' || c == 'N') 596 cifsFYI = 0; 597 else if (c == '1' || c == 'y' || c == 'Y') 598 cifsFYI = 1; 599 else if ((c > '1') && (c <= '9')) 600 cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ 601 602 return count; 603} 604 605static int 606oplockEnabled_read(char *page, char **start, off_t off, 607 int count, int *eof, void *data) 608{ 609 int len; 610 611 len = sprintf(page, "%d\n", oplockEnabled); 612 613 len -= off; 614 *start = page + off; 615 616 if (len > count) 617 len = count; 618 else 619 *eof = 1; 620 621 if (len < 0) 622 len = 0; 623 624 return len; 625} 626static int 627oplockEnabled_write(struct file *file, const char __user *buffer, 628 unsigned long count, void *data) 629{ 630 char c; 631 int rc; 632 633 rc = get_user(c, buffer); 634 if (rc) 635 return rc; 636 if (c == '0' || c == 'n' || c == 'N') 637 oplockEnabled = 0; 638 else if (c == '1' || c == 'y' || c == 'Y') 639 oplockEnabled = 1; 640 641 return count; 642} 643 644static int 645experimEnabled_read(char *page, char **start, off_t off, 646 int count, int *eof, void *data) 647{ 648 int len; 649 650 len = sprintf(page, "%d\n", experimEnabled); 651 652 len -= off; 653 *start = page + off; 654 655 if (len > count) 656 len = count; 657 else 658 *eof = 1; 659 660 if (len < 0) 661 len = 0; 662 663 return len; 664} 665static int 666experimEnabled_write(struct file *file, const char __user *buffer, 667 unsigned long count, void *data) 668{ 669 char c; 670 int rc; 671 672 rc = get_user(c, buffer); 673 if (rc) 674 return rc; 675 if (c == '0' || c == 'n' || c == 'N') 676 experimEnabled = 0; 677 else if (c == '1' || c == 'y' || c == 'Y') 678 experimEnabled = 1; 679 else if (c == '2') 680 experimEnabled = 2; 681 682 return count; 683} 684 685static int 686linuxExtensionsEnabled_read(char *page, char **start, off_t off, 687 int count, int *eof, void *data) 688{ 689 int len; 690 691 len = sprintf(page, "%d\n", linuxExtEnabled); 692 len -= off; 693 *start = page + off; 694 695 if (len > count) 696 len = count; 697 else 698 *eof = 1; 699 700 if (len < 0) 701 len = 0; 702 703 return len; 704} 705static int 706linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, 707 unsigned long count, void *data) 708{ 709 char c; 710 int rc; 711 712 rc = get_user(c, buffer); 713 if (rc) 714 return rc; 715 if (c == '0' || c == 'n' || c == 'N') 716 linuxExtEnabled = 0; 717 else if (c == '1' || c == 'y' || c == 'Y') 718 linuxExtEnabled = 1; 719 720 return count; 721} 722 723 724static int 725lookupFlag_read(char *page, char **start, off_t off, 726 int count, int *eof, void *data) 727{ 728 int len; 729 730 len = sprintf(page, "%d\n", lookupCacheEnabled); 731 732 len -= off; 733 *start = page + off; 734 735 if (len > count) 736 len = count; 737 else 738 *eof = 1; 739 740 if (len < 0) 741 len = 0; 742 743 return len; 744} 745static int 746lookupFlag_write(struct file *file, const char __user *buffer, 747 unsigned long count, void *data) 748{ 749 char c; 750 int rc; 751 752 rc = get_user(c, buffer); 753 if (rc) 754 return rc; 755 if (c == '0' || c == 'n' || c == 'N') 756 lookupCacheEnabled = 0; 757 else if (c == '1' || c == 'y' || c == 'Y') 758 lookupCacheEnabled = 1; 759 760 return count; 761} 762static int 763traceSMB_read(char *page, char **start, off_t off, int count, 764 int *eof, void *data) 765{ 766 int len; 767 768 len = sprintf(page, "%d\n", traceSMB); 769 770 len -= off; 771 *start = page + off; 772 773 if (len > count) 774 len = count; 775 else 776 *eof = 1; 777 778 if (len < 0) 779 len = 0; 780 781 return len; 782} 783static int 784traceSMB_write(struct file *file, const char __user *buffer, 785 unsigned long count, void *data) 786{ 787 char c; 788 int rc; 789 790 rc = get_user(c, buffer); 791 if (rc) 792 return rc; 793 if (c == '0' || c == 'n' || c == 'N') 794 traceSMB = 0; 795 else if (c == '1' || c == 'y' || c == 'Y') 796 traceSMB = 1; 797 798 return count; 799} 800 801static int 802multiuser_mount_read(char *page, char **start, off_t off, 803 int count, int *eof, void *data) 804{ 805 int len; 806 807 len = sprintf(page, "%d\n", multiuser_mount); 808 809 len -= off; 810 *start = page + off; 811 812 if (len > count) 813 len = count; 814 else 815 *eof = 1; 816 817 if (len < 0) 818 len = 0; 819 820 return len; 821} 822static int 823multiuser_mount_write(struct file *file, const char __user *buffer, 824 unsigned long count, void *data) 825{ 826 char c; 827 int rc; 828 829 rc = get_user(c, buffer); 830 if (rc) 831 return rc; 832 if (c == '0' || c == 'n' || c == 'N') 833 multiuser_mount = 0; 834 else if (c == '1' || c == 'y' || c == 'Y') 835 multiuser_mount = 1; 836 837 return count; 838} 839 840static int 841security_flags_read(char *page, char **start, off_t off, 842 int count, int *eof, void *data) 843{ 844 int len; 845 846 len = sprintf(page, "0x%x\n", extended_security); 847 848 len -= off; 849 *start = page + off; 850 851 if (len > count) 852 len = count; 853 else 854 *eof = 1; 855 856 if (len < 0) 857 len = 0; 858 859 return len; 860} 861static int 862security_flags_write(struct file *file, const char __user *buffer, 863 unsigned long count, void *data) 864{ 865 unsigned int flags; 866 char flags_string[12]; 867 char c; 868 869 if ((count < 1) || (count > 11)) 870 return -EINVAL; 871 872 memset(flags_string, 0, 12); 873 874 if (copy_from_user(flags_string, buffer, count)) 875 return -EFAULT; 876 877 if (count < 3) { 878 /* single char or single char followed by null */ 879 c = flags_string[0]; 880 if (c == '0' || c == 'n' || c == 'N') 881 extended_security = CIFSSEC_DEF; /* default */ 882 else if (c == '1' || c == 'y' || c == 'Y') 883 extended_security = CIFSSEC_MAX; 884 return count; 885 } 886 /* else we have a number */ 887 888 flags = simple_strtoul(flags_string, NULL, 0); 889 890 cFYI(1, ("sec flags 0x%x", flags)); 891 892 if (flags <= 0) { 893 cERROR(1, ("invalid security flags %s", flags_string)); 894 return -EINVAL; 895 } 896 897 if (flags & ~CIFSSEC_MASK) { 898 cERROR(1, ("attempt to set unsupported security flags 0x%x", 899 flags & ~CIFSSEC_MASK)); 900 return -EINVAL; 901 } 902 /* flags look ok - update the global security flags for cifs module */ 903 extended_security = flags; 904 return count; 905} 906 907/* static int 908ntlmv2_enabled_read(char *page, char **start, off_t off, 909 int count, int *eof, void *data) 910{ 911 int len; 912 913 len = sprintf(page, "%d\n", ntlmv2_support); 914 915 len -= off; 916 *start = page + off; 917 918 if (len > count) 919 len = count; 920 else 921 *eof = 1; 922 923 if (len < 0) 924 len = 0; 925 926 return len; 927} 928static int 929ntlmv2_enabled_write(struct file *file, const char __user *buffer, 930 unsigned long count, void *data) 931{ 932 char c; 933 int rc; 934 935 rc = get_user(c, buffer); 936 if (rc) 937 return rc; 938 if (c == '0' || c == 'n' || c == 'N') 939 ntlmv2_support = 0; 940 else if (c == '1' || c == 'y' || c == 'Y') 941 ntlmv2_support = 1; 942 else if (c == '2') 943 ntlmv2_support = 2; 944 945 return count; 946} 947 948static int 949packet_signing_enabled_read(char *page, char **start, off_t off, 950 int count, int *eof, void *data) 951{ 952 int len; 953 954 len = sprintf(page, "%d\n", sign_CIFS_PDUs); 955 956 len -= off; 957 *start = page + off; 958 959 if (len > count) 960 len = count; 961 else 962 *eof = 1; 963 964 if (len < 0) 965 len = 0; 966 967 return len; 968} 969static int 970packet_signing_enabled_write(struct file *file, const char __user *buffer, 971 unsigned long count, void *data) 972{ 973 char c; 974 int rc; 975 976 rc = get_user(c, buffer); 977 if (rc) 978 return rc; 979 if (c == '0' || c == 'n' || c == 'N') 980 sign_CIFS_PDUs = 0; 981 else if (c == '1' || c == 'y' || c == 'Y') 982 sign_CIFS_PDUs = 1; 983 else if (c == '2') 984 sign_CIFS_PDUs = 2; 985 986 return count; 987} */ 988 989 990#endif 991