4 * Copyright (C) International Business Machines Corp., 2000,2003
6 * Modified by Steve French (sfrench@us.ibm.com)
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.
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.
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
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>
30 #include "cifsproto.h"
31 #include "cifs_debug.h"
34 cifs_dump_mem(char *label, void *data, int length)
39 char buf[10], line[80];
41 printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n\n",
43 for (i = 0; i < length; i += 16) {
45 for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
46 sprintf(buf, " %08x", intptr[i / 4 + j]);
51 for (j = 0; (j < 16) && (i + j < length); j++) {
52 buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
55 printk(KERN_DEBUG "%s\n", line);
61 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
62 int count, int *eof, void *data)
64 struct list_head *tmp;
65 struct cifsSesInfo *ses;
66 struct cifsTconInfo *tcon;
69 char *buf_start = buf;
73 "Display Internal CIFS Data Structures for Debugging\n"
74 "---------------------------------------------------\n");
77 length = sprintf(buf, "Servers: \n");
81 read_lock(&GlobalSMBSeslock);
82 list_for_each(tmp, &GlobalSMBSessionList) {
84 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
87 "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\tTCP session status: %d",
88 i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
89 ses->serverOS, ses->serverNOS, ses->capabilities,ses->status,ses->server->tcpStatus);
92 buf += sprintf(buf, "\n\tLocal Users To Same Server: %d SecMode: 0x%x",
93 atomic_read(&ses->server->socketUseCount),ses->server->secMode);
95 /* length = sprintf(buf, "\nMIDs: \n");
98 spin_lock(&GlobalMid_Lock);
99 list_for_each(tmp1, &ses->server->pending_mid_q) {
100 mid_entry = list_entry(tmp1, struct
104 length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p\n",mid_entry->midState,mid_entry->command,mid_entry->pid,mid_entry->tsk);
108 spin_unlock(&GlobalMid_Lock); */
112 read_unlock(&GlobalSMBSeslock);
116 length = sprintf(buf, "\nShares: \n");
120 read_lock(&GlobalSMBSeslock);
121 list_for_each(tmp, &GlobalTreeConnectionList) {
123 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
126 "\n%d) %s Uses: %d on FS: %s with characteristics: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
128 atomic_read(&tcon->useCount),
129 tcon->nativeFileSystem,
130 tcon->fsDevInfo.DeviceCharacteristics,
131 tcon->fsAttrInfo.Attributes,
132 tcon->fsAttrInfo.MaxPathNameComponentLength,tcon->tidStatus);
134 if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_DISK)
135 length = sprintf(buf, " type: DISK ");
136 else if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_CD_ROM)
137 length = sprintf(buf, " type: CDROM ");
140 sprintf(buf, " type: %d ",
141 tcon->fsDevInfo.DeviceType);
143 if(tcon->tidStatus == CifsNeedReconnect)
144 buf += sprintf(buf, "\tDISCONNECTED ");
146 read_unlock(&GlobalSMBSeslock);
148 length = sprintf(buf, "\n");
152 /* BB add code to dump additional info such as TCP session info now */
154 if (offset >= (buf - buf_start))
159 *beginBuffer = buf + offset;
160 if ((buf - buf_start - offset) > count)
163 return (buf - buf_start - offset);
167 cifs_total_xid_read(char *buf, char **beginBuffer, off_t offset,
168 int length, int *eof, void *data)
173 "Total vfs operations: %d and maximum simultaneous serviced by this filesystem: %d\n",
174 GlobalCurrentXid,GlobalMaxActiveXid);
180 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
181 int length, int *eof, void *data)
186 "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter);
189 sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
190 length += item_length;
193 sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
194 length += item_length;
197 sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
198 length += item_length;
200 item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
201 length += item_length;
206 struct proc_dir_entry *proc_fs_cifs;
207 read_proc_t cifs_txanchor_read;
208 static read_proc_t cifsFYI_read;
209 static write_proc_t cifsFYI_write;
210 static read_proc_t oplockEnabled_read;
211 static write_proc_t oplockEnabled_write;
212 static read_proc_t lookupFlag_read;
213 static write_proc_t lookupFlag_write;
214 static read_proc_t traceSMB_read;
215 static write_proc_t traceSMB_write;
216 static read_proc_t multiuser_mount_read;
217 static write_proc_t multiuser_mount_write;
218 static read_proc_t extended_security_read;
219 static write_proc_t extended_security_write;
220 static read_proc_t ntlmv2_enabled_read;
221 static write_proc_t ntlmv2_enabled_write;
222 static read_proc_t packet_signing_enabled_read;
223 static write_proc_t packet_signing_enabled_write;
224 static read_proc_t quotaEnabled_read;
225 static write_proc_t quotaEnabled_write;
226 static read_proc_t linuxExtensionsEnabled_read;
227 static write_proc_t linuxExtensionsEnabled_write;
232 struct proc_dir_entry *pde;
234 proc_fs_cifs = proc_mkdir("cifs", proc_root_fs);
235 if (proc_fs_cifs == NULL)
238 proc_fs_cifs->owner = THIS_MODULE;
239 create_proc_read_entry("DebugData", 0, proc_fs_cifs,
240 cifs_debug_data_read, 0);
242 create_proc_read_entry("SimultaneousOps", 0, proc_fs_cifs,
243 cifs_total_xid_read, 0);
245 create_proc_read_entry("Stats", 0, proc_fs_cifs,
248 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
251 pde->write_proc = cifsFYI_write;
254 create_proc_read_entry("traceSMB", 0, proc_fs_cifs,
257 pde->write_proc = traceSMB_write;
259 pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs,
260 oplockEnabled_read, 0);
262 pde->write_proc = oplockEnabled_write;
264 pde = create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs,
265 quotaEnabled_read, 0);
267 pde->write_proc = quotaEnabled_write;
269 pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
270 linuxExtensionsEnabled_read, 0);
272 pde->write_proc = linuxExtensionsEnabled_write;
275 create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
276 multiuser_mount_read, 0);
278 pde->write_proc = multiuser_mount_write;
281 create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs,
282 extended_security_read, 0);
284 pde->write_proc = extended_security_write;
287 create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
290 pde->write_proc = lookupFlag_write;
293 create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
294 ntlmv2_enabled_read, 0);
296 pde->write_proc = ntlmv2_enabled_write;
299 create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
300 packet_signing_enabled_read, 0);
302 pde->write_proc = packet_signing_enabled_write;
306 cifs_proc_clean(void)
308 if (proc_fs_cifs == NULL)
311 remove_proc_entry("DebugData", proc_fs_cifs);
312 remove_proc_entry("cifsFYI", proc_fs_cifs);
313 remove_proc_entry("traceSMB", proc_fs_cifs);
314 remove_proc_entry("SimultaneousOps", proc_fs_cifs);
315 remove_proc_entry("Stats", proc_fs_cifs);
316 remove_proc_entry("MultiuserMount", proc_fs_cifs);
317 remove_proc_entry("OplockEnabled", proc_fs_cifs);
318 remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
319 remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
320 remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
321 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
322 remove_proc_entry("QuotaEnabled",proc_fs_cifs);
323 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
324 remove_proc_entry("cifs", proc_root_fs);
328 cifsFYI_read(char *page, char **start, off_t off, int count,
329 int *eof, void *data)
333 len = sprintf(page, "%d\n", cifsFYI);
349 cifsFYI_write(struct file *file, const char *buffer,
350 unsigned long count, void *data)
355 rc = get_user(c, buffer);
358 if (c == '0' || c == 'n' || c == 'N')
360 else if (c == '1' || c == 'y' || c == 'Y')
367 oplockEnabled_read(char *page, char **start, off_t off,
368 int count, int *eof, void *data)
372 len = sprintf(page, "%d\n", oplockEnabled);
388 oplockEnabled_write(struct file *file, const char *buffer,
389 unsigned long count, void *data)
394 rc = get_user(c, buffer);
397 if (c == '0' || c == 'n' || c == 'N')
399 else if (c == '1' || c == 'y' || c == 'Y')
406 quotaEnabled_read(char *page, char **start, off_t off,
407 int count, int *eof, void *data)
411 len = sprintf(page, "%d\n", quotaEnabled);
412 /* could also check if quotas are enabled in kernel
428 quotaEnabled_write(struct file *file, const char *buffer,
429 unsigned long count, void *data)
434 rc = get_user(c, buffer);
437 if (c == '0' || c == 'n' || c == 'N')
439 else if (c == '1' || c == 'y' || c == 'Y')
446 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
447 int count, int *eof, void *data)
451 len = sprintf(page, "%d\n", linuxExtEnabled);
452 /* could also check if quotas are enabled in kernel
468 linuxExtensionsEnabled_write(struct file *file, const char *buffer,
469 unsigned long count, void *data)
474 rc = get_user(c, buffer);
477 if (c == '0' || c == 'n' || c == 'N')
479 else if (c == '1' || c == 'y' || c == 'Y')
487 lookupFlag_read(char *page, char **start, off_t off,
488 int count, int *eof, void *data)
492 len = sprintf(page, "%d\n", lookupCacheEnabled);
508 lookupFlag_write(struct file *file, const char *buffer,
509 unsigned long count, void *data)
514 rc = get_user(c, buffer);
517 if (c == '0' || c == 'n' || c == 'N')
518 lookupCacheEnabled = 0;
519 else if (c == '1' || c == 'y' || c == 'Y')
520 lookupCacheEnabled = 1;
525 traceSMB_read(char *page, char **start, off_t off, int count,
526 int *eof, void *data)
530 len = sprintf(page, "%d\n", traceSMB);
546 traceSMB_write(struct file *file, const char *buffer,
547 unsigned long count, void *data)
552 rc = get_user(c, buffer);
555 if (c == '0' || c == 'n' || c == 'N')
557 else if (c == '1' || c == 'y' || c == 'Y')
564 multiuser_mount_read(char *page, char **start, off_t off,
565 int count, int *eof, void *data)
569 len = sprintf(page, "%d\n", multiuser_mount);
585 multiuser_mount_write(struct file *file, const char *buffer,
586 unsigned long count, void *data)
591 rc = get_user(c, buffer);
594 if (c == '0' || c == 'n' || c == 'N')
596 else if (c == '1' || c == 'y' || c == 'Y')
603 extended_security_read(char *page, char **start, off_t off,
604 int count, int *eof, void *data)
608 len = sprintf(page, "%d\n", extended_security);
624 extended_security_write(struct file *file, const char *buffer,
625 unsigned long count, void *data)
630 rc = get_user(c, buffer);
633 if (c == '0' || c == 'n' || c == 'N')
634 extended_security = 0;
635 else if (c == '1' || c == 'y' || c == 'Y')
636 extended_security = 1;
642 ntlmv2_enabled_read(char *page, char **start, off_t off,
643 int count, int *eof, void *data)
647 len = sprintf(page, "%d\n", ntlmv2_support);
663 ntlmv2_enabled_write(struct file *file, const char *buffer,
664 unsigned long count, void *data)
669 rc = get_user(c, buffer);
672 if (c == '0' || c == 'n' || c == 'N')
674 else if (c == '1' || c == 'y' || c == 'Y')
681 packet_signing_enabled_read(char *page, char **start, off_t off,
682 int count, int *eof, void *data)
686 len = sprintf(page, "%d\n", sign_CIFS_PDUs);
702 packet_signing_enabled_write(struct file *file, const char *buffer,
703 unsigned long count, void *data)
708 rc = get_user(c, buffer);
711 if (c == '0' || c == 'n' || c == 'N')
713 else if (c == '1' || c == 'y' || c == 'Y')