at v4.6 673 lines 18 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 pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data); 38 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, 39 data, length, true); 40} 41 42#ifdef CONFIG_CIFS_DEBUG 43void cifs_vfs_err(const char *fmt, ...) 44{ 45 struct va_format vaf; 46 va_list args; 47 48 va_start(args, fmt); 49 50 vaf.fmt = fmt; 51 vaf.va = &args; 52 53 pr_err_ratelimited("CIFS VFS: %pV", &vaf); 54 55 va_end(args); 56} 57#endif 58 59void cifs_dump_detail(void *buf) 60{ 61#ifdef CONFIG_CIFS_DEBUG2 62 struct smb_hdr *smb = (struct smb_hdr *)buf; 63 64 cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n", 65 smb->Command, smb->Status.CifsError, 66 smb->Flags, smb->Flags2, smb->Mid, smb->Pid); 67 cifs_dbg(VFS, "smb buf %p len %u\n", smb, smbCalcSize(smb)); 68#endif /* CONFIG_CIFS_DEBUG2 */ 69} 70 71void cifs_dump_mids(struct TCP_Server_Info *server) 72{ 73#ifdef CONFIG_CIFS_DEBUG2 74 struct list_head *tmp; 75 struct mid_q_entry *mid_entry; 76 77 if (server == NULL) 78 return; 79 80 cifs_dbg(VFS, "Dump pending requests:\n"); 81 spin_lock(&GlobalMid_Lock); 82 list_for_each(tmp, &server->pending_mid_q) { 83 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 84 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n", 85 mid_entry->mid_state, 86 le16_to_cpu(mid_entry->command), 87 mid_entry->pid, 88 mid_entry->callback_data, 89 mid_entry->mid); 90#ifdef CONFIG_CIFS_STATS2 91 cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n", 92 mid_entry->large_buf, 93 mid_entry->resp_buf, 94 mid_entry->when_received, 95 jiffies); 96#endif /* STATS2 */ 97 cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n", 98 mid_entry->multiRsp, mid_entry->multiEnd); 99 if (mid_entry->resp_buf) { 100 cifs_dump_detail(mid_entry->resp_buf); 101 cifs_dump_mem("existing buf: ", 102 mid_entry->resp_buf, 62); 103 } 104 } 105 spin_unlock(&GlobalMid_Lock); 106#endif /* CONFIG_CIFS_DEBUG2 */ 107} 108 109#ifdef CONFIG_PROC_FS 110static int cifs_debug_data_proc_show(struct seq_file *m, void *v) 111{ 112 struct list_head *tmp1, *tmp2, *tmp3; 113 struct mid_q_entry *mid_entry; 114 struct TCP_Server_Info *server; 115 struct cifs_ses *ses; 116 struct cifs_tcon *tcon; 117 int i, j; 118 __u32 dev_type; 119 120 seq_puts(m, 121 "Display Internal CIFS Data Structures for Debugging\n" 122 "---------------------------------------------------\n"); 123 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); 124 seq_printf(m, "Features:"); 125#ifdef CONFIG_CIFS_DFS_UPCALL 126 seq_printf(m, " dfs"); 127#endif 128#ifdef CONFIG_CIFS_FSCACHE 129 seq_printf(m, " fscache"); 130#endif 131#ifdef CONFIG_CIFS_WEAK_PW_HASH 132 seq_printf(m, " lanman"); 133#endif 134#ifdef CONFIG_CIFS_POSIX 135 seq_printf(m, " posix"); 136#endif 137#ifdef CONFIG_CIFS_UPCALL 138 seq_printf(m, " spnego"); 139#endif 140#ifdef CONFIG_CIFS_XATTR 141 seq_printf(m, " xattr"); 142#endif 143#ifdef CONFIG_CIFS_ACL 144 seq_printf(m, " acl"); 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 spin_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 cifs_ses, 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->sec_mode, in_flight(server)); 177 178#ifdef CONFIG_CIFS_STATS2 179 seq_printf(m, " In Send: %d In MaxReq Wait: %d", 180 atomic_read(&server->in_send), 181 atomic_read(&server->num_waiters)); 182#endif 183 184 seq_puts(m, "\n\tShares:"); 185 j = 0; 186 list_for_each(tmp3, &ses->tcon_list) { 187 tcon = list_entry(tmp3, struct cifs_tcon, 188 tcon_list); 189 ++j; 190 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 191 seq_printf(m, "\n\t%d) %s Mounts: %d ", j, 192 tcon->treeName, tcon->tc_count); 193 if (tcon->nativeFileSystem) { 194 seq_printf(m, "Type: %s ", 195 tcon->nativeFileSystem); 196 } 197 seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x" 198 "\n\tPathComponentMax: %d Status: %d", 199 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), 200 le32_to_cpu(tcon->fsAttrInfo.Attributes), 201 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), 202 tcon->tidStatus); 203 if (dev_type == FILE_DEVICE_DISK) 204 seq_puts(m, " type: DISK "); 205 else if (dev_type == FILE_DEVICE_CD_ROM) 206 seq_puts(m, " type: CDROM "); 207 else 208 seq_printf(m, " type: %d ", dev_type); 209 if (server->ops->dump_share_caps) 210 server->ops->dump_share_caps(m, tcon); 211 212 if (tcon->need_reconnect) 213 seq_puts(m, "\tDISCONNECTED "); 214 seq_putc(m, '\n'); 215 } 216 217 seq_puts(m, "\n\tMIDs:\n"); 218 219 spin_lock(&GlobalMid_Lock); 220 list_for_each(tmp3, &server->pending_mid_q) { 221 mid_entry = list_entry(tmp3, struct mid_q_entry, 222 qhead); 223 seq_printf(m, "\tState: %d com: %d pid:" 224 " %d cbdata: %p mid %llu\n", 225 mid_entry->mid_state, 226 le16_to_cpu(mid_entry->command), 227 mid_entry->pid, 228 mid_entry->callback_data, 229 mid_entry->mid); 230 } 231 spin_unlock(&GlobalMid_Lock); 232 } 233 } 234 spin_unlock(&cifs_tcp_ses_lock); 235 seq_putc(m, '\n'); 236 237 /* BB add code to dump additional info such as TCP session info now */ 238 return 0; 239} 240 241static int cifs_debug_data_proc_open(struct inode *inode, struct file *file) 242{ 243 return single_open(file, cifs_debug_data_proc_show, NULL); 244} 245 246static const struct file_operations cifs_debug_data_proc_fops = { 247 .owner = THIS_MODULE, 248 .open = cifs_debug_data_proc_open, 249 .read = seq_read, 250 .llseek = seq_lseek, 251 .release = single_release, 252}; 253 254#ifdef CONFIG_CIFS_STATS 255static ssize_t cifs_stats_proc_write(struct file *file, 256 const char __user *buffer, size_t count, loff_t *ppos) 257{ 258 bool bv; 259 int rc; 260 struct list_head *tmp1, *tmp2, *tmp3; 261 struct TCP_Server_Info *server; 262 struct cifs_ses *ses; 263 struct cifs_tcon *tcon; 264 265 rc = kstrtobool_from_user(buffer, count, &bv); 266 if (rc == 0) { 267#ifdef CONFIG_CIFS_STATS2 268 atomic_set(&totBufAllocCount, 0); 269 atomic_set(&totSmBufAllocCount, 0); 270#endif /* CONFIG_CIFS_STATS2 */ 271 spin_lock(&cifs_tcp_ses_lock); 272 list_for_each(tmp1, &cifs_tcp_ses_list) { 273 server = list_entry(tmp1, struct TCP_Server_Info, 274 tcp_ses_list); 275 list_for_each(tmp2, &server->smb_ses_list) { 276 ses = list_entry(tmp2, struct cifs_ses, 277 smb_ses_list); 278 list_for_each(tmp3, &ses->tcon_list) { 279 tcon = list_entry(tmp3, 280 struct cifs_tcon, 281 tcon_list); 282 atomic_set(&tcon->num_smbs_sent, 0); 283 if (server->ops->clear_stats) 284 server->ops->clear_stats(tcon); 285 } 286 } 287 } 288 spin_unlock(&cifs_tcp_ses_lock); 289 } else { 290 return rc; 291 } 292 293 return count; 294} 295 296static int cifs_stats_proc_show(struct seq_file *m, void *v) 297{ 298 int i; 299 struct list_head *tmp1, *tmp2, *tmp3; 300 struct TCP_Server_Info *server; 301 struct cifs_ses *ses; 302 struct cifs_tcon *tcon; 303 304 seq_printf(m, 305 "Resources in use\nCIFS Session: %d\n", 306 sesInfoAllocCount.counter); 307 seq_printf(m, "Share (unique mount targets): %d\n", 308 tconInfoAllocCount.counter); 309 seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n", 310 bufAllocCount.counter, 311 cifs_min_rcv + tcpSesAllocCount.counter); 312 seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", 313 smBufAllocCount.counter, cifs_min_small); 314#ifdef CONFIG_CIFS_STATS2 315 seq_printf(m, "Total Large %d Small %d Allocations\n", 316 atomic_read(&totBufAllocCount), 317 atomic_read(&totSmBufAllocCount)); 318#endif /* CONFIG_CIFS_STATS2 */ 319 320 seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount)); 321 seq_printf(m, 322 "\n%d session %d share reconnects\n", 323 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); 324 325 seq_printf(m, 326 "Total vfs operations: %d maximum at one time: %d\n", 327 GlobalCurrentXid, GlobalMaxActiveXid); 328 329 i = 0; 330 spin_lock(&cifs_tcp_ses_lock); 331 list_for_each(tmp1, &cifs_tcp_ses_list) { 332 server = list_entry(tmp1, struct TCP_Server_Info, 333 tcp_ses_list); 334 list_for_each(tmp2, &server->smb_ses_list) { 335 ses = list_entry(tmp2, struct cifs_ses, 336 smb_ses_list); 337 list_for_each(tmp3, &ses->tcon_list) { 338 tcon = list_entry(tmp3, 339 struct cifs_tcon, 340 tcon_list); 341 i++; 342 seq_printf(m, "\n%d) %s", i, tcon->treeName); 343 if (tcon->need_reconnect) 344 seq_puts(m, "\tDISCONNECTED "); 345 seq_printf(m, "\nSMBs: %d", 346 atomic_read(&tcon->num_smbs_sent)); 347 if (server->ops->print_stats) 348 server->ops->print_stats(m, tcon); 349 } 350 } 351 } 352 spin_unlock(&cifs_tcp_ses_lock); 353 354 seq_putc(m, '\n'); 355 return 0; 356} 357 358static int cifs_stats_proc_open(struct inode *inode, struct file *file) 359{ 360 return single_open(file, cifs_stats_proc_show, NULL); 361} 362 363static const struct file_operations cifs_stats_proc_fops = { 364 .owner = THIS_MODULE, 365 .open = cifs_stats_proc_open, 366 .read = seq_read, 367 .llseek = seq_lseek, 368 .release = single_release, 369 .write = cifs_stats_proc_write, 370}; 371#endif /* STATS */ 372 373static struct proc_dir_entry *proc_fs_cifs; 374static const struct file_operations cifsFYI_proc_fops; 375static const struct file_operations cifs_lookup_cache_proc_fops; 376static const struct file_operations traceSMB_proc_fops; 377static const struct file_operations cifs_security_flags_proc_fops; 378static const struct file_operations cifs_linux_ext_proc_fops; 379 380void 381cifs_proc_init(void) 382{ 383 proc_fs_cifs = proc_mkdir("fs/cifs", NULL); 384 if (proc_fs_cifs == NULL) 385 return; 386 387 proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops); 388 389#ifdef CONFIG_CIFS_STATS 390 proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops); 391#endif /* STATS */ 392 proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); 393 proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); 394 proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, 395 &cifs_linux_ext_proc_fops); 396 proc_create("SecurityFlags", 0, proc_fs_cifs, 397 &cifs_security_flags_proc_fops); 398 proc_create("LookupCacheEnabled", 0, proc_fs_cifs, 399 &cifs_lookup_cache_proc_fops); 400} 401 402void 403cifs_proc_clean(void) 404{ 405 if (proc_fs_cifs == NULL) 406 return; 407 408 remove_proc_entry("DebugData", proc_fs_cifs); 409 remove_proc_entry("cifsFYI", proc_fs_cifs); 410 remove_proc_entry("traceSMB", proc_fs_cifs); 411#ifdef CONFIG_CIFS_STATS 412 remove_proc_entry("Stats", proc_fs_cifs); 413#endif 414 remove_proc_entry("SecurityFlags", proc_fs_cifs); 415 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 416 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); 417 remove_proc_entry("fs/cifs", NULL); 418} 419 420static int cifsFYI_proc_show(struct seq_file *m, void *v) 421{ 422 seq_printf(m, "%d\n", cifsFYI); 423 return 0; 424} 425 426static int cifsFYI_proc_open(struct inode *inode, struct file *file) 427{ 428 return single_open(file, cifsFYI_proc_show, NULL); 429} 430 431static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, 432 size_t count, loff_t *ppos) 433{ 434 char c[2] = { '\0' }; 435 bool bv; 436 int rc; 437 438 rc = get_user(c[0], buffer); 439 if (rc) 440 return rc; 441 if (strtobool(c, &bv) == 0) 442 cifsFYI = bv; 443 else if ((c[0] > '1') && (c[0] <= '9')) 444 cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */ 445 446 return count; 447} 448 449static const struct file_operations cifsFYI_proc_fops = { 450 .owner = THIS_MODULE, 451 .open = cifsFYI_proc_open, 452 .read = seq_read, 453 .llseek = seq_lseek, 454 .release = single_release, 455 .write = cifsFYI_proc_write, 456}; 457 458static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) 459{ 460 seq_printf(m, "%d\n", linuxExtEnabled); 461 return 0; 462} 463 464static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file) 465{ 466 return single_open(file, cifs_linux_ext_proc_show, NULL); 467} 468 469static ssize_t cifs_linux_ext_proc_write(struct file *file, 470 const char __user *buffer, size_t count, loff_t *ppos) 471{ 472 int rc; 473 474 rc = kstrtobool_from_user(buffer, count, &linuxExtEnabled); 475 if (rc) 476 return rc; 477 478 return count; 479} 480 481static const struct file_operations cifs_linux_ext_proc_fops = { 482 .owner = THIS_MODULE, 483 .open = cifs_linux_ext_proc_open, 484 .read = seq_read, 485 .llseek = seq_lseek, 486 .release = single_release, 487 .write = cifs_linux_ext_proc_write, 488}; 489 490static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v) 491{ 492 seq_printf(m, "%d\n", lookupCacheEnabled); 493 return 0; 494} 495 496static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file) 497{ 498 return single_open(file, cifs_lookup_cache_proc_show, NULL); 499} 500 501static ssize_t cifs_lookup_cache_proc_write(struct file *file, 502 const char __user *buffer, size_t count, loff_t *ppos) 503{ 504 int rc; 505 506 rc = kstrtobool_from_user(buffer, count, &lookupCacheEnabled); 507 if (rc) 508 return rc; 509 510 return count; 511} 512 513static const struct file_operations cifs_lookup_cache_proc_fops = { 514 .owner = THIS_MODULE, 515 .open = cifs_lookup_cache_proc_open, 516 .read = seq_read, 517 .llseek = seq_lseek, 518 .release = single_release, 519 .write = cifs_lookup_cache_proc_write, 520}; 521 522static int traceSMB_proc_show(struct seq_file *m, void *v) 523{ 524 seq_printf(m, "%d\n", traceSMB); 525 return 0; 526} 527 528static int traceSMB_proc_open(struct inode *inode, struct file *file) 529{ 530 return single_open(file, traceSMB_proc_show, NULL); 531} 532 533static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, 534 size_t count, loff_t *ppos) 535{ 536 int rc; 537 538 rc = kstrtobool_from_user(buffer, count, &traceSMB); 539 if (rc) 540 return rc; 541 542 return count; 543} 544 545static const struct file_operations traceSMB_proc_fops = { 546 .owner = THIS_MODULE, 547 .open = traceSMB_proc_open, 548 .read = seq_read, 549 .llseek = seq_lseek, 550 .release = single_release, 551 .write = traceSMB_proc_write, 552}; 553 554static int cifs_security_flags_proc_show(struct seq_file *m, void *v) 555{ 556 seq_printf(m, "0x%x\n", global_secflags); 557 return 0; 558} 559 560static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) 561{ 562 return single_open(file, cifs_security_flags_proc_show, NULL); 563} 564 565/* 566 * Ensure that if someone sets a MUST flag, that we disable all other MAY 567 * flags except for the ones corresponding to the given MUST flag. If there are 568 * multiple MUST flags, then try to prefer more secure ones. 569 */ 570static void 571cifs_security_flags_handle_must_flags(unsigned int *flags) 572{ 573 unsigned int signflags = *flags & CIFSSEC_MUST_SIGN; 574 575 if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 576 *flags = CIFSSEC_MUST_KRB5; 577 else if ((*flags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP) 578 *flags = CIFSSEC_MUST_NTLMSSP; 579 else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) 580 *flags = CIFSSEC_MUST_NTLMV2; 581 else if ((*flags & CIFSSEC_MUST_NTLM) == CIFSSEC_MUST_NTLM) 582 *flags = CIFSSEC_MUST_NTLM; 583 else if (CIFSSEC_MUST_LANMAN && 584 (*flags & CIFSSEC_MUST_LANMAN) == CIFSSEC_MUST_LANMAN) 585 *flags = CIFSSEC_MUST_LANMAN; 586 else if (CIFSSEC_MUST_PLNTXT && 587 (*flags & CIFSSEC_MUST_PLNTXT) == CIFSSEC_MUST_PLNTXT) 588 *flags = CIFSSEC_MUST_PLNTXT; 589 590 *flags |= signflags; 591} 592 593static ssize_t cifs_security_flags_proc_write(struct file *file, 594 const char __user *buffer, size_t count, loff_t *ppos) 595{ 596 int rc; 597 unsigned int flags; 598 char flags_string[12]; 599 bool bv; 600 601 if ((count < 1) || (count > 11)) 602 return -EINVAL; 603 604 memset(flags_string, 0, 12); 605 606 if (copy_from_user(flags_string, buffer, count)) 607 return -EFAULT; 608 609 if (count < 3) { 610 /* single char or single char followed by null */ 611 if (strtobool(flags_string, &bv) == 0) { 612 global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF; 613 return count; 614 } else if (!isdigit(flags_string[0])) { 615 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", 616 flags_string); 617 return -EINVAL; 618 } 619 } 620 621 /* else we have a number */ 622 rc = kstrtouint(flags_string, 0, &flags); 623 if (rc) { 624 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", 625 flags_string); 626 return rc; 627 } 628 629 cifs_dbg(FYI, "sec flags 0x%x\n", flags); 630 631 if (flags == 0) { 632 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", flags_string); 633 return -EINVAL; 634 } 635 636 if (flags & ~CIFSSEC_MASK) { 637 cifs_dbg(VFS, "Unsupported security flags: 0x%x\n", 638 flags & ~CIFSSEC_MASK); 639 return -EINVAL; 640 } 641 642 cifs_security_flags_handle_must_flags(&flags); 643 644 /* flags look ok - update the global security flags for cifs module */ 645 global_secflags = flags; 646 if (global_secflags & CIFSSEC_MUST_SIGN) { 647 /* requiring signing implies signing is allowed */ 648 global_secflags |= CIFSSEC_MAY_SIGN; 649 cifs_dbg(FYI, "packet signing now required\n"); 650 } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) { 651 cifs_dbg(FYI, "packet signing disabled\n"); 652 } 653 /* BB should we turn on MAY flags for other MUST options? */ 654 return count; 655} 656 657static const struct file_operations cifs_security_flags_proc_fops = { 658 .owner = THIS_MODULE, 659 .open = cifs_security_flags_proc_open, 660 .read = seq_read, 661 .llseek = seq_lseek, 662 .release = single_release, 663 .write = cifs_security_flags_proc_write, 664}; 665#else 666inline void cifs_proc_init(void) 667{ 668} 669 670inline void cifs_proc_clean(void) 671{ 672} 673#endif /* PROC_FS */