Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.36-rc8 827 lines 23 kB view raw
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 cERROR(1, "State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", 83 mid_entry->midState, 84 (int)mid_entry->command, 85 mid_entry->pid, 86 mid_entry->tsk, 87 mid_entry->mid); 88#ifdef CONFIG_CIFS_STATS2 89 cERROR(1, "IsLarge: %d buf: %p time rcv: %ld now: %ld", 90 mid_entry->largeBuf, 91 mid_entry->resp_buf, 92 mid_entry->when_received, 93 jiffies); 94#endif /* STATS2 */ 95 cERROR(1, "IsMult: %d IsEnd: %d", mid_entry->multiRsp, 96 mid_entry->multiEnd); 97 if (mid_entry->resp_buf) { 98 cifs_dump_detail(mid_entry->resp_buf); 99 cifs_dump_mem("existing buf: ", 100 mid_entry->resp_buf, 62); 101 } 102 } 103 spin_unlock(&GlobalMid_Lock); 104} 105#endif /* CONFIG_CIFS_DEBUG2 */ 106 107#ifdef CONFIG_PROC_FS 108static int cifs_debug_data_proc_show(struct seq_file *m, void *v) 109{ 110 struct list_head *tmp1, *tmp2, *tmp3; 111 struct mid_q_entry *mid_entry; 112 struct TCP_Server_Info *server; 113 struct cifsSesInfo *ses; 114 struct cifsTconInfo *tcon; 115 int i, j; 116 __u32 dev_type; 117 118 seq_puts(m, 119 "Display Internal CIFS Data Structures for Debugging\n" 120 "---------------------------------------------------\n"); 121 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); 122 seq_printf(m, "Features: "); 123#ifdef CONFIG_CIFS_DFS_UPCALL 124 seq_printf(m, "dfs"); 125 seq_putc(m, ' '); 126#endif 127#ifdef CONFIG_CIFS_FSCACHE 128 seq_printf(m, "fscache"); 129 seq_putc(m, ' '); 130#endif 131#ifdef CONFIG_CIFS_WEAK_PW_HASH 132 seq_printf(m, "lanman"); 133 seq_putc(m, ' '); 134#endif 135#ifdef CONFIG_CIFS_POSIX 136 seq_printf(m, "posix"); 137 seq_putc(m, ' '); 138#endif 139#ifdef CONFIG_CIFS_UPCALL 140 seq_printf(m, "spnego"); 141 seq_putc(m, ' '); 142#endif 143#ifdef CONFIG_CIFS_XATTR 144 seq_printf(m, "xattr"); 145#endif 146 seq_putc(m, '\n'); 147 seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); 148 seq_printf(m, "Servers:"); 149 150 i = 0; 151 read_lock(&cifs_tcp_ses_lock); 152 list_for_each(tmp1, &cifs_tcp_ses_list) { 153 server = list_entry(tmp1, struct TCP_Server_Info, 154 tcp_ses_list); 155 i++; 156 list_for_each(tmp2, &server->smb_ses_list) { 157 ses = list_entry(tmp2, struct cifsSesInfo, 158 smb_ses_list); 159 if ((ses->serverDomain == NULL) || 160 (ses->serverOS == NULL) || 161 (ses->serverNOS == NULL)) { 162 seq_printf(m, "\n%d) entry for %s not fully " 163 "displayed\n\t", i, ses->serverName); 164 } else { 165 seq_printf(m, 166 "\n%d) Name: %s Domain: %s Uses: %d OS:" 167 " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB" 168 " session status: %d\t", 169 i, ses->serverName, ses->serverDomain, 170 ses->ses_count, ses->serverOS, ses->serverNOS, 171 ses->capabilities, ses->status); 172 } 173 seq_printf(m, "TCP status: %d\n\tLocal Users To " 174 "Server: %d SecMode: 0x%x Req On Wire: %d", 175 server->tcpStatus, server->srv_count, 176 server->secMode, 177 atomic_read(&server->inFlight)); 178 179#ifdef CONFIG_CIFS_STATS2 180 seq_printf(m, " In Send: %d In MaxReq Wait: %d", 181 atomic_read(&server->inSend), 182 atomic_read(&server->num_waiters)); 183#endif 184 185 seq_puts(m, "\n\tShares:"); 186 j = 0; 187 list_for_each(tmp3, &ses->tcon_list) { 188 tcon = list_entry(tmp3, struct cifsTconInfo, 189 tcon_list); 190 ++j; 191 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 192 seq_printf(m, "\n\t%d) %s Mounts: %d ", j, 193 tcon->treeName, tcon->tc_count); 194 if (tcon->nativeFileSystem) { 195 seq_printf(m, "Type: %s ", 196 tcon->nativeFileSystem); 197 } 198 seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x" 199 "\nPathComponentMax: %d Status: 0x%d", 200 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), 201 le32_to_cpu(tcon->fsAttrInfo.Attributes), 202 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), 203 tcon->tidStatus); 204 if (dev_type == FILE_DEVICE_DISK) 205 seq_puts(m, " type: DISK "); 206 else if (dev_type == FILE_DEVICE_CD_ROM) 207 seq_puts(m, " type: CDROM "); 208 else 209 seq_printf(m, " type: %d ", dev_type); 210 211 if (tcon->need_reconnect) 212 seq_puts(m, "\tDISCONNECTED "); 213 seq_putc(m, '\n'); 214 } 215 216 seq_puts(m, "\n\tMIDs:\n"); 217 218 spin_lock(&GlobalMid_Lock); 219 list_for_each(tmp3, &server->pending_mid_q) { 220 mid_entry = list_entry(tmp3, struct mid_q_entry, 221 qhead); 222 seq_printf(m, "\tState: %d com: %d pid:" 223 " %d tsk: %p mid %d\n", 224 mid_entry->midState, 225 (int)mid_entry->command, 226 mid_entry->pid, 227 mid_entry->tsk, 228 mid_entry->mid); 229 } 230 spin_unlock(&GlobalMid_Lock); 231 } 232 } 233 read_unlock(&cifs_tcp_ses_lock); 234 seq_putc(m, '\n'); 235 236 /* BB add code to dump additional info such as TCP session info now */ 237 return 0; 238} 239 240static int cifs_debug_data_proc_open(struct inode *inode, struct file *file) 241{ 242 return single_open(file, cifs_debug_data_proc_show, NULL); 243} 244 245static const struct file_operations cifs_debug_data_proc_fops = { 246 .owner = THIS_MODULE, 247 .open = cifs_debug_data_proc_open, 248 .read = seq_read, 249 .llseek = seq_lseek, 250 .release = single_release, 251}; 252 253#ifdef CONFIG_CIFS_STATS 254static ssize_t cifs_stats_proc_write(struct file *file, 255 const char __user *buffer, size_t count, loff_t *ppos) 256{ 257 char c; 258 int rc; 259 struct list_head *tmp1, *tmp2, *tmp3; 260 struct TCP_Server_Info *server; 261 struct cifsSesInfo *ses; 262 struct cifsTconInfo *tcon; 263 264 rc = get_user(c, buffer); 265 if (rc) 266 return rc; 267 268 if (c == '1' || c == 'y' || c == 'Y' || c == '0') { 269#ifdef CONFIG_CIFS_STATS2 270 atomic_set(&totBufAllocCount, 0); 271 atomic_set(&totSmBufAllocCount, 0); 272#endif /* CONFIG_CIFS_STATS2 */ 273 read_lock(&cifs_tcp_ses_lock); 274 list_for_each(tmp1, &cifs_tcp_ses_list) { 275 server = list_entry(tmp1, struct TCP_Server_Info, 276 tcp_ses_list); 277 list_for_each(tmp2, &server->smb_ses_list) { 278 ses = list_entry(tmp2, struct cifsSesInfo, 279 smb_ses_list); 280 list_for_each(tmp3, &ses->tcon_list) { 281 tcon = list_entry(tmp3, 282 struct cifsTconInfo, 283 tcon_list); 284 atomic_set(&tcon->num_smbs_sent, 0); 285 atomic_set(&tcon->num_writes, 0); 286 atomic_set(&tcon->num_reads, 0); 287 atomic_set(&tcon->num_oplock_brks, 0); 288 atomic_set(&tcon->num_opens, 0); 289 atomic_set(&tcon->num_posixopens, 0); 290 atomic_set(&tcon->num_posixmkdirs, 0); 291 atomic_set(&tcon->num_closes, 0); 292 atomic_set(&tcon->num_deletes, 0); 293 atomic_set(&tcon->num_mkdirs, 0); 294 atomic_set(&tcon->num_rmdirs, 0); 295 atomic_set(&tcon->num_renames, 0); 296 atomic_set(&tcon->num_t2renames, 0); 297 atomic_set(&tcon->num_ffirst, 0); 298 atomic_set(&tcon->num_fnext, 0); 299 atomic_set(&tcon->num_fclose, 0); 300 atomic_set(&tcon->num_hardlinks, 0); 301 atomic_set(&tcon->num_symlinks, 0); 302 atomic_set(&tcon->num_locks, 0); 303 } 304 } 305 } 306 read_unlock(&cifs_tcp_ses_lock); 307 } 308 309 return count; 310} 311 312static int cifs_stats_proc_show(struct seq_file *m, void *v) 313{ 314 int i; 315 struct list_head *tmp1, *tmp2, *tmp3; 316 struct TCP_Server_Info *server; 317 struct cifsSesInfo *ses; 318 struct cifsTconInfo *tcon; 319 320 seq_printf(m, 321 "Resources in use\nCIFS Session: %d\n", 322 sesInfoAllocCount.counter); 323 seq_printf(m, "Share (unique mount targets): %d\n", 324 tconInfoAllocCount.counter); 325 seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n", 326 bufAllocCount.counter, 327 cifs_min_rcv + tcpSesAllocCount.counter); 328 seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", 329 smBufAllocCount.counter, cifs_min_small); 330#ifdef CONFIG_CIFS_STATS2 331 seq_printf(m, "Total Large %d Small %d Allocations\n", 332 atomic_read(&totBufAllocCount), 333 atomic_read(&totSmBufAllocCount)); 334#endif /* CONFIG_CIFS_STATS2 */ 335 336 seq_printf(m, "Operations (MIDs): %d\n", midCount.counter); 337 seq_printf(m, 338 "\n%d session %d share reconnects\n", 339 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); 340 341 seq_printf(m, 342 "Total vfs operations: %d maximum at one time: %d\n", 343 GlobalCurrentXid, GlobalMaxActiveXid); 344 345 i = 0; 346 read_lock(&cifs_tcp_ses_lock); 347 list_for_each(tmp1, &cifs_tcp_ses_list) { 348 server = list_entry(tmp1, struct TCP_Server_Info, 349 tcp_ses_list); 350 list_for_each(tmp2, &server->smb_ses_list) { 351 ses = list_entry(tmp2, struct cifsSesInfo, 352 smb_ses_list); 353 list_for_each(tmp3, &ses->tcon_list) { 354 tcon = list_entry(tmp3, 355 struct cifsTconInfo, 356 tcon_list); 357 i++; 358 seq_printf(m, "\n%d) %s", i, tcon->treeName); 359 if (tcon->need_reconnect) 360 seq_puts(m, "\tDISCONNECTED "); 361 seq_printf(m, "\nSMBs: %d Oplock Breaks: %d", 362 atomic_read(&tcon->num_smbs_sent), 363 atomic_read(&tcon->num_oplock_brks)); 364 seq_printf(m, "\nReads: %d Bytes: %lld", 365 atomic_read(&tcon->num_reads), 366 (long long)(tcon->bytes_read)); 367 seq_printf(m, "\nWrites: %d Bytes: %lld", 368 atomic_read(&tcon->num_writes), 369 (long long)(tcon->bytes_written)); 370 seq_printf(m, "\nFlushes: %d", 371 atomic_read(&tcon->num_flushes)); 372 seq_printf(m, "\nLocks: %d HardLinks: %d " 373 "Symlinks: %d", 374 atomic_read(&tcon->num_locks), 375 atomic_read(&tcon->num_hardlinks), 376 atomic_read(&tcon->num_symlinks)); 377 seq_printf(m, "\nOpens: %d Closes: %d " 378 "Deletes: %d", 379 atomic_read(&tcon->num_opens), 380 atomic_read(&tcon->num_closes), 381 atomic_read(&tcon->num_deletes)); 382 seq_printf(m, "\nPosix Opens: %d " 383 "Posix Mkdirs: %d", 384 atomic_read(&tcon->num_posixopens), 385 atomic_read(&tcon->num_posixmkdirs)); 386 seq_printf(m, "\nMkdirs: %d Rmdirs: %d", 387 atomic_read(&tcon->num_mkdirs), 388 atomic_read(&tcon->num_rmdirs)); 389 seq_printf(m, "\nRenames: %d T2 Renames %d", 390 atomic_read(&tcon->num_renames), 391 atomic_read(&tcon->num_t2renames)); 392 seq_printf(m, "\nFindFirst: %d FNext %d " 393 "FClose %d", 394 atomic_read(&tcon->num_ffirst), 395 atomic_read(&tcon->num_fnext), 396 atomic_read(&tcon->num_fclose)); 397 } 398 } 399 } 400 read_unlock(&cifs_tcp_ses_lock); 401 402 seq_putc(m, '\n'); 403 return 0; 404} 405 406static int cifs_stats_proc_open(struct inode *inode, struct file *file) 407{ 408 return single_open(file, cifs_stats_proc_show, NULL); 409} 410 411static const struct file_operations cifs_stats_proc_fops = { 412 .owner = THIS_MODULE, 413 .open = cifs_stats_proc_open, 414 .read = seq_read, 415 .llseek = seq_lseek, 416 .release = single_release, 417 .write = cifs_stats_proc_write, 418}; 419#endif /* STATS */ 420 421static struct proc_dir_entry *proc_fs_cifs; 422static const struct file_operations cifsFYI_proc_fops; 423static const struct file_operations cifs_oplock_proc_fops; 424static const struct file_operations cifs_lookup_cache_proc_fops; 425static const struct file_operations traceSMB_proc_fops; 426static const struct file_operations cifs_multiuser_mount_proc_fops; 427static const struct file_operations cifs_security_flags_proc_fops; 428static const struct file_operations cifs_experimental_proc_fops; 429static const struct file_operations cifs_linux_ext_proc_fops; 430 431void 432cifs_proc_init(void) 433{ 434 proc_fs_cifs = proc_mkdir("fs/cifs", NULL); 435 if (proc_fs_cifs == NULL) 436 return; 437 438 proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops); 439 440#ifdef CONFIG_CIFS_STATS 441 proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops); 442#endif /* STATS */ 443 proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); 444 proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); 445 proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops); 446 proc_create("Experimental", 0, proc_fs_cifs, 447 &cifs_experimental_proc_fops); 448 proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, 449 &cifs_linux_ext_proc_fops); 450 proc_create("MultiuserMount", 0, proc_fs_cifs, 451 &cifs_multiuser_mount_proc_fops); 452 proc_create("SecurityFlags", 0, proc_fs_cifs, 453 &cifs_security_flags_proc_fops); 454 proc_create("LookupCacheEnabled", 0, proc_fs_cifs, 455 &cifs_lookup_cache_proc_fops); 456} 457 458void 459cifs_proc_clean(void) 460{ 461 if (proc_fs_cifs == NULL) 462 return; 463 464 remove_proc_entry("DebugData", proc_fs_cifs); 465 remove_proc_entry("cifsFYI", proc_fs_cifs); 466 remove_proc_entry("traceSMB", proc_fs_cifs); 467#ifdef CONFIG_CIFS_STATS 468 remove_proc_entry("Stats", proc_fs_cifs); 469#endif 470 remove_proc_entry("MultiuserMount", proc_fs_cifs); 471 remove_proc_entry("OplockEnabled", proc_fs_cifs); 472 remove_proc_entry("SecurityFlags", proc_fs_cifs); 473 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 474 remove_proc_entry("Experimental", proc_fs_cifs); 475 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); 476 remove_proc_entry("fs/cifs", NULL); 477} 478 479static int cifsFYI_proc_show(struct seq_file *m, void *v) 480{ 481 seq_printf(m, "%d\n", cifsFYI); 482 return 0; 483} 484 485static int cifsFYI_proc_open(struct inode *inode, struct file *file) 486{ 487 return single_open(file, cifsFYI_proc_show, NULL); 488} 489 490static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, 491 size_t count, loff_t *ppos) 492{ 493 char c; 494 int rc; 495 496 rc = get_user(c, buffer); 497 if (rc) 498 return rc; 499 if (c == '0' || c == 'n' || c == 'N') 500 cifsFYI = 0; 501 else if (c == '1' || c == 'y' || c == 'Y') 502 cifsFYI = 1; 503 else if ((c > '1') && (c <= '9')) 504 cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ 505 506 return count; 507} 508 509static const struct file_operations cifsFYI_proc_fops = { 510 .owner = THIS_MODULE, 511 .open = cifsFYI_proc_open, 512 .read = seq_read, 513 .llseek = seq_lseek, 514 .release = single_release, 515 .write = cifsFYI_proc_write, 516}; 517 518static int cifs_oplock_proc_show(struct seq_file *m, void *v) 519{ 520 seq_printf(m, "%d\n", oplockEnabled); 521 return 0; 522} 523 524static int cifs_oplock_proc_open(struct inode *inode, struct file *file) 525{ 526 return single_open(file, cifs_oplock_proc_show, NULL); 527} 528 529static ssize_t cifs_oplock_proc_write(struct file *file, 530 const char __user *buffer, size_t count, loff_t *ppos) 531{ 532 char c; 533 int rc; 534 535 rc = get_user(c, buffer); 536 if (rc) 537 return rc; 538 if (c == '0' || c == 'n' || c == 'N') 539 oplockEnabled = 0; 540 else if (c == '1' || c == 'y' || c == 'Y') 541 oplockEnabled = 1; 542 543 return count; 544} 545 546static const struct file_operations cifs_oplock_proc_fops = { 547 .owner = THIS_MODULE, 548 .open = cifs_oplock_proc_open, 549 .read = seq_read, 550 .llseek = seq_lseek, 551 .release = single_release, 552 .write = cifs_oplock_proc_write, 553}; 554 555static int cifs_experimental_proc_show(struct seq_file *m, void *v) 556{ 557 seq_printf(m, "%d\n", experimEnabled); 558 return 0; 559} 560 561static int cifs_experimental_proc_open(struct inode *inode, struct file *file) 562{ 563 return single_open(file, cifs_experimental_proc_show, NULL); 564} 565 566static ssize_t cifs_experimental_proc_write(struct file *file, 567 const char __user *buffer, size_t count, loff_t *ppos) 568{ 569 char c; 570 int rc; 571 572 rc = get_user(c, buffer); 573 if (rc) 574 return rc; 575 if (c == '0' || c == 'n' || c == 'N') 576 experimEnabled = 0; 577 else if (c == '1' || c == 'y' || c == 'Y') 578 experimEnabled = 1; 579 else if (c == '2') 580 experimEnabled = 2; 581 582 return count; 583} 584 585static const struct file_operations cifs_experimental_proc_fops = { 586 .owner = THIS_MODULE, 587 .open = cifs_experimental_proc_open, 588 .read = seq_read, 589 .llseek = seq_lseek, 590 .release = single_release, 591 .write = cifs_experimental_proc_write, 592}; 593 594static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) 595{ 596 seq_printf(m, "%d\n", linuxExtEnabled); 597 return 0; 598} 599 600static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file) 601{ 602 return single_open(file, cifs_linux_ext_proc_show, NULL); 603} 604 605static ssize_t cifs_linux_ext_proc_write(struct file *file, 606 const char __user *buffer, size_t count, loff_t *ppos) 607{ 608 char c; 609 int rc; 610 611 rc = get_user(c, buffer); 612 if (rc) 613 return rc; 614 if (c == '0' || c == 'n' || c == 'N') 615 linuxExtEnabled = 0; 616 else if (c == '1' || c == 'y' || c == 'Y') 617 linuxExtEnabled = 1; 618 619 return count; 620} 621 622static const struct file_operations cifs_linux_ext_proc_fops = { 623 .owner = THIS_MODULE, 624 .open = cifs_linux_ext_proc_open, 625 .read = seq_read, 626 .llseek = seq_lseek, 627 .release = single_release, 628 .write = cifs_linux_ext_proc_write, 629}; 630 631static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v) 632{ 633 seq_printf(m, "%d\n", lookupCacheEnabled); 634 return 0; 635} 636 637static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file) 638{ 639 return single_open(file, cifs_lookup_cache_proc_show, NULL); 640} 641 642static ssize_t cifs_lookup_cache_proc_write(struct file *file, 643 const char __user *buffer, size_t count, loff_t *ppos) 644{ 645 char c; 646 int rc; 647 648 rc = get_user(c, buffer); 649 if (rc) 650 return rc; 651 if (c == '0' || c == 'n' || c == 'N') 652 lookupCacheEnabled = 0; 653 else if (c == '1' || c == 'y' || c == 'Y') 654 lookupCacheEnabled = 1; 655 656 return count; 657} 658 659static const struct file_operations cifs_lookup_cache_proc_fops = { 660 .owner = THIS_MODULE, 661 .open = cifs_lookup_cache_proc_open, 662 .read = seq_read, 663 .llseek = seq_lseek, 664 .release = single_release, 665 .write = cifs_lookup_cache_proc_write, 666}; 667 668static int traceSMB_proc_show(struct seq_file *m, void *v) 669{ 670 seq_printf(m, "%d\n", traceSMB); 671 return 0; 672} 673 674static int traceSMB_proc_open(struct inode *inode, struct file *file) 675{ 676 return single_open(file, traceSMB_proc_show, NULL); 677} 678 679static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, 680 size_t count, loff_t *ppos) 681{ 682 char c; 683 int rc; 684 685 rc = get_user(c, buffer); 686 if (rc) 687 return rc; 688 if (c == '0' || c == 'n' || c == 'N') 689 traceSMB = 0; 690 else if (c == '1' || c == 'y' || c == 'Y') 691 traceSMB = 1; 692 693 return count; 694} 695 696static const struct file_operations traceSMB_proc_fops = { 697 .owner = THIS_MODULE, 698 .open = traceSMB_proc_open, 699 .read = seq_read, 700 .llseek = seq_lseek, 701 .release = single_release, 702 .write = traceSMB_proc_write, 703}; 704 705static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v) 706{ 707 seq_printf(m, "%d\n", multiuser_mount); 708 return 0; 709} 710 711static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh) 712{ 713 return single_open(fh, cifs_multiuser_mount_proc_show, NULL); 714} 715 716static ssize_t cifs_multiuser_mount_proc_write(struct file *file, 717 const char __user *buffer, size_t count, loff_t *ppos) 718{ 719 char c; 720 int rc; 721 722 rc = get_user(c, buffer); 723 if (rc) 724 return rc; 725 if (c == '0' || c == 'n' || c == 'N') 726 multiuser_mount = 0; 727 else if (c == '1' || c == 'y' || c == 'Y') 728 multiuser_mount = 1; 729 730 return count; 731} 732 733static const struct file_operations cifs_multiuser_mount_proc_fops = { 734 .owner = THIS_MODULE, 735 .open = cifs_multiuser_mount_proc_open, 736 .read = seq_read, 737 .llseek = seq_lseek, 738 .release = single_release, 739 .write = cifs_multiuser_mount_proc_write, 740}; 741 742static int cifs_security_flags_proc_show(struct seq_file *m, void *v) 743{ 744 seq_printf(m, "0x%x\n", global_secflags); 745 return 0; 746} 747 748static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) 749{ 750 return single_open(file, cifs_security_flags_proc_show, NULL); 751} 752 753static ssize_t cifs_security_flags_proc_write(struct file *file, 754 const char __user *buffer, size_t count, loff_t *ppos) 755{ 756 unsigned int flags; 757 char flags_string[12]; 758 char c; 759 760 if ((count < 1) || (count > 11)) 761 return -EINVAL; 762 763 memset(flags_string, 0, 12); 764 765 if (copy_from_user(flags_string, buffer, count)) 766 return -EFAULT; 767 768 if (count < 3) { 769 /* single char or single char followed by null */ 770 c = flags_string[0]; 771 if (c == '0' || c == 'n' || c == 'N') { 772 global_secflags = CIFSSEC_DEF; /* default */ 773 return count; 774 } else if (c == '1' || c == 'y' || c == 'Y') { 775 global_secflags = CIFSSEC_MAX; 776 return count; 777 } else if (!isdigit(c)) { 778 cERROR(1, "invalid flag %c", c); 779 return -EINVAL; 780 } 781 } 782 /* else we have a number */ 783 784 flags = simple_strtoul(flags_string, NULL, 0); 785 786 cFYI(1, "sec flags 0x%x", flags); 787 788 if (flags <= 0) { 789 cERROR(1, "invalid security flags %s", flags_string); 790 return -EINVAL; 791 } 792 793 if (flags & ~CIFSSEC_MASK) { 794 cERROR(1, "attempt to set unsupported security flags 0x%x", 795 flags & ~CIFSSEC_MASK); 796 return -EINVAL; 797 } 798 /* flags look ok - update the global security flags for cifs module */ 799 global_secflags = flags; 800 if (global_secflags & CIFSSEC_MUST_SIGN) { 801 /* requiring signing implies signing is allowed */ 802 global_secflags |= CIFSSEC_MAY_SIGN; 803 cFYI(1, "packet signing now required"); 804 } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) { 805 cFYI(1, "packet signing disabled"); 806 } 807 /* BB should we turn on MAY flags for other MUST options? */ 808 return count; 809} 810 811static const struct file_operations cifs_security_flags_proc_fops = { 812 .owner = THIS_MODULE, 813 .open = cifs_security_flags_proc_open, 814 .read = seq_read, 815 .llseek = seq_lseek, 816 .release = single_release, 817 .write = cifs_security_flags_proc_write, 818}; 819#else 820inline void cifs_proc_init(void) 821{ 822} 823 824inline void cifs_proc_clean(void) 825{ 826} 827#endif /* PROC_FS */