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 list_head
*tmp1
;
66 struct mid_q_entry
* mid_entry
;
67 struct cifsSesInfo
*ses
;
68 struct cifsTconInfo
*tcon
;
71 char * original_buf
= buf
;
73 *beginBuffer
= buf
+ offset
;
78 "Display Internal CIFS Data Structures for Debugging\n"
79 "---------------------------------------------------\n");
82 length
= sprintf(buf
, "Servers:\n");
86 read_lock(&GlobalSMBSeslock
);
87 list_for_each(tmp
, &GlobalSMBSessionList
) {
89 ses
= list_entry(tmp
, struct cifsSesInfo
, cifsSessionList
);
92 "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\tTCP status: %d",
93 i
, ses
->serverName
, ses
->serverDomain
, atomic_read(&ses
->inUse
),
94 ses
->serverOS
, ses
->serverNOS
, ses
->capabilities
,ses
->status
,ses
->server
->tcpStatus
);
97 buf
+= sprintf(buf
, "\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
98 atomic_read(&ses
->server
->socketUseCount
),
100 atomic_read(&ses
->server
->inFlight
));
102 length
= sprintf(buf
, "\nMIDs: \n");
105 spin_lock(&GlobalMid_Lock
);
106 list_for_each(tmp1
, &ses
->server
->pending_mid_q
) {
107 mid_entry
= list_entry(tmp1
, struct
111 length
= sprintf(buf
,"State: %d com: %d pid: %d tsk: %p mid %d\n",mid_entry
->midState
,mid_entry
->command
,mid_entry
->pid
,mid_entry
->tsk
,mid_entry
->mid
);
115 spin_unlock(&GlobalMid_Lock
);
119 read_unlock(&GlobalSMBSeslock
);
123 length
= sprintf(buf
, "\nShares:\n");
127 read_lock(&GlobalSMBSeslock
);
128 list_for_each(tmp
, &GlobalTreeConnectionList
) {
131 tcon
= list_entry(tmp
, struct cifsTconInfo
, cifsConnectionList
);
132 dev_type
= le32_to_cpu(tcon
->fsDevInfo
.DeviceType
);
135 "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
137 atomic_read(&tcon
->useCount
),
138 tcon
->nativeFileSystem
,
139 le32_to_cpu(tcon
->fsDevInfo
.DeviceCharacteristics
),
140 le32_to_cpu(tcon
->fsAttrInfo
.Attributes
),
141 le32_to_cpu(tcon
->fsAttrInfo
.MaxPathNameComponentLength
),
144 if (dev_type
== FILE_DEVICE_DISK
)
145 length
= sprintf(buf
, " type: DISK ");
146 else if (dev_type
== FILE_DEVICE_CD_ROM
)
147 length
= sprintf(buf
, " type: CDROM ");
150 sprintf(buf
, " type: %d ", dev_type
);
152 if(tcon
->tidStatus
== CifsNeedReconnect
) {
153 buf
+= sprintf(buf
, "\tDISCONNECTED ");
157 read_unlock(&GlobalSMBSeslock
);
159 length
= sprintf(buf
, "\n");
162 /* BB add code to dump additional info such as TCP session info now */
163 /* Now calculate total size of returned data */
164 length
= buf
- original_buf
;
166 if(offset
+ count
>= length
)
168 if(length
< offset
) {
172 length
= length
- offset
;
180 #ifdef CONFIG_CIFS_STATS
182 cifs_stats_read(char *buf
, char **beginBuffer
, off_t offset
,
183 int count
, int *eof
, void *data
)
185 int item_length
,i
,length
;
186 struct list_head
*tmp
;
187 struct cifsTconInfo
*tcon
;
189 *beginBuffer
= buf
+ offset
;
191 length
= sprintf(buf
,
192 "Resources in use\nCIFS Session: %d\n",
193 sesInfoAllocCount
.counter
);
196 sprintf(buf
,"Share (unique mount targets): %d\n",
197 tconInfoAllocCount
.counter
);
198 length
+= item_length
;
201 sprintf(buf
,"SMB Request/Response Buffer: %d\n",
202 bufAllocCount
.counter
);
203 length
+= item_length
;
206 sprintf(buf
,"Operations (MIDs): %d\n",
208 length
+= item_length
;
210 item_length
= sprintf(buf
,
211 "\n%d session %d share reconnects\n",
212 tcpSesReconnectCount
.counter
,tconInfoReconnectCount
.counter
);
213 length
+= item_length
;
216 item_length
= sprintf(buf
,
217 "Total vfs operations: %d maximum at one time: %d\n",
218 GlobalCurrentXid
,GlobalMaxActiveXid
);
219 length
+= item_length
;
223 read_lock(&GlobalSMBSeslock
);
224 list_for_each(tmp
, &GlobalTreeConnectionList
) {
226 tcon
= list_entry(tmp
, struct cifsTconInfo
, cifsConnectionList
);
227 item_length
= sprintf(buf
,"\n%d) %s",i
, tcon
->treeName
);
229 length
+= item_length
;
230 if(tcon
->tidStatus
== CifsNeedReconnect
) {
231 buf
+= sprintf(buf
, "\tDISCONNECTED ");
234 item_length
= sprintf(buf
,"\nSMBs: %d Oplock Breaks: %d",
235 atomic_read(&tcon
->num_smbs_sent
),
236 atomic_read(&tcon
->num_oplock_brks
));
238 length
+= item_length
;
239 item_length
= sprintf(buf
,"\nReads: %d Bytes %lld",
240 atomic_read(&tcon
->num_reads
),
241 (long long)(tcon
->bytes_read
));
243 length
+= item_length
;
244 item_length
= sprintf(buf
,"\nWrites: %d Bytes: %lld",
245 atomic_read(&tcon
->num_writes
),
246 (long long)(tcon
->bytes_written
));
248 length
+= item_length
;
249 item_length
= sprintf(buf
,
250 "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
251 atomic_read(&tcon
->num_opens
),
252 atomic_read(&tcon
->num_deletes
),
253 atomic_read(&tcon
->num_mkdirs
),
254 atomic_read(&tcon
->num_rmdirs
));
256 length
+= item_length
;
257 item_length
= sprintf(buf
,
258 "\nRenames: %d T2 Renames %d",
259 atomic_read(&tcon
->num_renames
),
260 atomic_read(&tcon
->num_t2renames
));
262 length
+= item_length
;
264 read_unlock(&GlobalSMBSeslock
);
266 buf
+= sprintf(buf
,"\n");
269 if(offset
+ count
>= length
)
271 if(length
< offset
) {
275 length
= length
- offset
;
284 struct proc_dir_entry
*proc_fs_cifs
;
285 read_proc_t cifs_txanchor_read
;
286 static read_proc_t cifsFYI_read
;
287 static write_proc_t cifsFYI_write
;
288 static read_proc_t oplockEnabled_read
;
289 static write_proc_t oplockEnabled_write
;
290 static read_proc_t lookupFlag_read
;
291 static write_proc_t lookupFlag_write
;
292 static read_proc_t traceSMB_read
;
293 static write_proc_t traceSMB_write
;
294 static read_proc_t multiuser_mount_read
;
295 static write_proc_t multiuser_mount_write
;
296 static read_proc_t extended_security_read
;
297 static write_proc_t extended_security_write
;
298 static read_proc_t ntlmv2_enabled_read
;
299 static write_proc_t ntlmv2_enabled_write
;
300 static read_proc_t packet_signing_enabled_read
;
301 static write_proc_t packet_signing_enabled_write
;
302 static read_proc_t quotaEnabled_read
;
303 static write_proc_t quotaEnabled_write
;
304 static read_proc_t linuxExtensionsEnabled_read
;
305 static write_proc_t linuxExtensionsEnabled_write
;
310 struct proc_dir_entry
*pde
;
312 proc_fs_cifs
= proc_mkdir("cifs", proc_root_fs
);
313 if (proc_fs_cifs
== NULL
)
316 proc_fs_cifs
->owner
= THIS_MODULE
;
317 create_proc_read_entry("DebugData", 0, proc_fs_cifs
,
318 cifs_debug_data_read
, NULL
);
320 #ifdef CONFIG_CIFS_STATS
321 create_proc_read_entry("Stats", 0, proc_fs_cifs
,
322 cifs_stats_read
, NULL
);
324 pde
= create_proc_read_entry("cifsFYI", 0, proc_fs_cifs
,
327 pde
->write_proc
= cifsFYI_write
;
330 create_proc_read_entry("traceSMB", 0, proc_fs_cifs
,
331 traceSMB_read
, NULL
);
333 pde
->write_proc
= traceSMB_write
;
335 pde
= create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs
,
336 oplockEnabled_read
, NULL
);
338 pde
->write_proc
= oplockEnabled_write
;
340 pde
= create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs
,
341 quotaEnabled_read
, NULL
);
343 pde
->write_proc
= quotaEnabled_write
;
345 pde
= create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs
,
346 linuxExtensionsEnabled_read
, NULL
);
348 pde
->write_proc
= linuxExtensionsEnabled_write
;
351 create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs
,
352 multiuser_mount_read
, NULL
);
354 pde
->write_proc
= multiuser_mount_write
;
357 create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs
,
358 extended_security_read
, NULL
);
360 pde
->write_proc
= extended_security_write
;
363 create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs
,
364 lookupFlag_read
, NULL
);
366 pde
->write_proc
= lookupFlag_write
;
369 create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs
,
370 ntlmv2_enabled_read
, NULL
);
372 pde
->write_proc
= ntlmv2_enabled_write
;
375 create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs
,
376 packet_signing_enabled_read
, NULL
);
378 pde
->write_proc
= packet_signing_enabled_write
;
382 cifs_proc_clean(void)
384 if (proc_fs_cifs
== NULL
)
387 remove_proc_entry("DebugData", proc_fs_cifs
);
388 remove_proc_entry("cifsFYI", proc_fs_cifs
);
389 remove_proc_entry("traceSMB", proc_fs_cifs
);
390 #ifdef CONFIG_CIFS_STATS
391 remove_proc_entry("Stats", proc_fs_cifs
);
393 remove_proc_entry("MultiuserMount", proc_fs_cifs
);
394 remove_proc_entry("OplockEnabled", proc_fs_cifs
);
395 remove_proc_entry("NTLMV2Enabled",proc_fs_cifs
);
396 remove_proc_entry("ExtendedSecurity",proc_fs_cifs
);
397 remove_proc_entry("PacketSigningEnabled",proc_fs_cifs
);
398 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs
);
399 remove_proc_entry("QuotaEnabled",proc_fs_cifs
);
400 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs
);
401 remove_proc_entry("cifs", proc_root_fs
);
405 cifsFYI_read(char *page
, char **start
, off_t off
, int count
,
406 int *eof
, void *data
)
410 len
= sprintf(page
, "%d\n", cifsFYI
);
426 cifsFYI_write(struct file
*file
, const char __user
*buffer
,
427 unsigned long count
, void *data
)
432 rc
= get_user(c
, buffer
);
435 if (c
== '0' || c
== 'n' || c
== 'N')
437 else if (c
== '1' || c
== 'y' || c
== 'Y')
444 oplockEnabled_read(char *page
, char **start
, off_t off
,
445 int count
, int *eof
, void *data
)
449 len
= sprintf(page
, "%d\n", oplockEnabled
);
465 oplockEnabled_write(struct file
*file
, const char __user
*buffer
,
466 unsigned long count
, void *data
)
471 rc
= get_user(c
, buffer
);
474 if (c
== '0' || c
== 'n' || c
== 'N')
476 else if (c
== '1' || c
== 'y' || c
== 'Y')
483 quotaEnabled_read(char *page
, char **start
, off_t off
,
484 int count
, int *eof
, void *data
)
488 len
= sprintf(page
, "%d\n", quotaEnabled
);
489 /* could also check if quotas are enabled in kernel
505 quotaEnabled_write(struct file
*file
, const char __user
*buffer
,
506 unsigned long count
, void *data
)
511 rc
= get_user(c
, buffer
);
514 if (c
== '0' || c
== 'n' || c
== 'N')
516 else if (c
== '1' || c
== 'y' || c
== 'Y')
523 linuxExtensionsEnabled_read(char *page
, char **start
, off_t off
,
524 int count
, int *eof
, void *data
)
528 len
= sprintf(page
, "%d\n", linuxExtEnabled
);
529 /* could also check if quotas are enabled in kernel
545 linuxExtensionsEnabled_write(struct file
*file
, const char __user
*buffer
,
546 unsigned long count
, void *data
)
551 rc
= get_user(c
, buffer
);
554 if (c
== '0' || c
== 'n' || c
== 'N')
556 else if (c
== '1' || c
== 'y' || c
== 'Y')
564 lookupFlag_read(char *page
, char **start
, off_t off
,
565 int count
, int *eof
, void *data
)
569 len
= sprintf(page
, "%d\n", lookupCacheEnabled
);
585 lookupFlag_write(struct file
*file
, const char __user
*buffer
,
586 unsigned long count
, void *data
)
591 rc
= get_user(c
, buffer
);
594 if (c
== '0' || c
== 'n' || c
== 'N')
595 lookupCacheEnabled
= 0;
596 else if (c
== '1' || c
== 'y' || c
== 'Y')
597 lookupCacheEnabled
= 1;
602 traceSMB_read(char *page
, char **start
, off_t off
, int count
,
603 int *eof
, void *data
)
607 len
= sprintf(page
, "%d\n", traceSMB
);
623 traceSMB_write(struct file
*file
, const char __user
*buffer
,
624 unsigned long count
, void *data
)
629 rc
= get_user(c
, buffer
);
632 if (c
== '0' || c
== 'n' || c
== 'N')
634 else if (c
== '1' || c
== 'y' || c
== 'Y')
641 multiuser_mount_read(char *page
, char **start
, off_t off
,
642 int count
, int *eof
, void *data
)
646 len
= sprintf(page
, "%d\n", multiuser_mount
);
662 multiuser_mount_write(struct file
*file
, const char __user
*buffer
,
663 unsigned long count
, void *data
)
668 rc
= get_user(c
, buffer
);
671 if (c
== '0' || c
== 'n' || c
== 'N')
673 else if (c
== '1' || c
== 'y' || c
== 'Y')
680 extended_security_read(char *page
, char **start
, off_t off
,
681 int count
, int *eof
, void *data
)
685 len
= sprintf(page
, "%d\n", extended_security
);
701 extended_security_write(struct file
*file
, const char __user
*buffer
,
702 unsigned long count
, void *data
)
707 rc
= get_user(c
, buffer
);
710 if (c
== '0' || c
== 'n' || c
== 'N')
711 extended_security
= 0;
712 else if (c
== '1' || c
== 'y' || c
== 'Y')
713 extended_security
= 1;
719 ntlmv2_enabled_read(char *page
, char **start
, off_t off
,
720 int count
, int *eof
, void *data
)
724 len
= sprintf(page
, "%d\n", ntlmv2_support
);
740 ntlmv2_enabled_write(struct file
*file
, const char __user
*buffer
,
741 unsigned long count
, void *data
)
746 rc
= get_user(c
, buffer
);
749 if (c
== '0' || c
== 'n' || c
== 'N')
751 else if (c
== '1' || c
== 'y' || c
== 'Y')
758 packet_signing_enabled_read(char *page
, char **start
, off_t off
,
759 int count
, int *eof
, void *data
)
763 len
= sprintf(page
, "%d\n", sign_CIFS_PDUs
);
779 packet_signing_enabled_write(struct file
*file
, const char __user
*buffer
,
780 unsigned long count
, void *data
)
785 rc
= get_user(c
, buffer
);
788 if (c
== '0' || c
== 'n' || c
== 'N')
790 else if (c
== '1' || c
== 'y' || c
== 'Y')