This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / fs / cifs / cifs_debug.c
1 /*
2  *   fs/cifs_debug.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2000,2003
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
33 void
34 cifs_dump_mem(char *label, void *data, int length)
35 {
36         int i, j;
37         int *intptr = data;
38         char *charptr = data;
39         char buf[10], line[80];
40
41         printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n\n", 
42                 label, length, data);
43         for (i = 0; i < length; i += 16) {
44                 line[0] = 0;
45                 for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
46                         sprintf(buf, " %08x", intptr[i / 4 + j]);
47                         strcat(line, buf);
48                 }
49                 buf[0] = ' ';
50                 buf[2] = 0;
51                 for (j = 0; (j < 16) && (i + j < length); j++) {
52                         buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
53                         strcat(line, buf);
54                 }
55                 printk(KERN_DEBUG "%s\n", line);
56         }
57 }
58
59 #ifdef CONFIG_PROC_FS
60 int
61 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
62                      int count, int *eof, void *data)
63 {
64         struct list_head *tmp;
65         struct cifsSesInfo *ses;
66         struct cifsTconInfo *tcon;
67         int i;
68         int length = 0;
69         char *buf_start = buf;
70
71         length =
72             sprintf(buf,
73                     "Display Internal CIFS Data Structures for Debugging\n"
74                     "---------------------------------------------------\n");
75         buf += length;
76
77         length = sprintf(buf, "Servers:\n");
78         buf += length;
79
80         i = 0;
81         read_lock(&GlobalSMBSeslock);
82         list_for_each(tmp, &GlobalSMBSessionList) {
83                 i++;
84                 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
85                 length =
86                     sprintf(buf,
87                             "\n%d) Name: %s  Domain: %s Mounts: %d ServerOS: %s  \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\tTCP status: %d",
88                                 i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
89                                 ses->serverOS, ses->serverNOS, ses->capabilities,ses->status,ses->server->tcpStatus);
90                 buf += length;
91                 if(ses->server) {
92                         buf += sprintf(buf, "\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
93                                 atomic_read(&ses->server->socketUseCount),
94                                 ses->server->secMode,
95                                 atomic_read(&ses->server->inFlight));
96                         
97                         /* length = sprintf(buf, "\nMIDs: \n");
98                         buf += length;
99
100                         spin_lock(&GlobalMid_Lock);
101                         list_for_each(tmp1, &ses->server->pending_mid_q) {
102                                 mid_entry = list_entry(tmp1, struct
103                                         mid_q_entry,
104                                         qhead);
105                                 if(mid_entry) {
106                                         length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p\n",mid_entry->midState,mid_entry->command,mid_entry->pid,mid_entry->tsk);
107                                         buf += length;
108                                 }
109                         }
110                         spin_unlock(&GlobalMid_Lock); */
111                 }
112
113         }
114         read_unlock(&GlobalSMBSeslock);
115         sprintf(buf, "\n");
116         buf++;
117
118         length = sprintf(buf, "\nShares:\n");
119         buf += length;
120
121         i = 0;
122         read_lock(&GlobalSMBSeslock);
123         list_for_each(tmp, &GlobalTreeConnectionList) {
124                 i++;
125                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
126                 length =
127                     sprintf(buf,
128                             "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
129                             i, tcon->treeName,
130                             atomic_read(&tcon->useCount),
131                             tcon->nativeFileSystem,
132                             tcon->fsDevInfo.DeviceCharacteristics,
133                             tcon->fsAttrInfo.Attributes,
134                             tcon->fsAttrInfo.MaxPathNameComponentLength,tcon->tidStatus);
135                 buf += length;        
136                 if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_DISK)
137                         length = sprintf(buf, " type: DISK ");
138                 else if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_CD_ROM)
139                         length = sprintf(buf, " type: CDROM ");
140                 else
141                         length =
142                             sprintf(buf, " type: %d ",
143                                     tcon->fsDevInfo.DeviceType);
144                 buf += length;
145                 if(tcon->tidStatus == CifsNeedReconnect)
146                         buf += sprintf(buf, "\tDISCONNECTED ");
147 #ifdef CONFIG_CIFS_STATS
148                 length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
149                         atomic_read(&tcon->num_smbs_sent),
150                         atomic_read(&tcon->num_oplock_brks));
151                 buf += length;
152                 length = sprintf(buf,"\nReads: %d Bytes %lld",
153                         atomic_read(&tcon->num_reads),
154                         (long long)(tcon->bytes_read));
155                 buf += length;
156                 length = sprintf(buf,"\nWrites: %d Bytes: %lld",
157                         atomic_read(&tcon->num_writes),
158                         (long long)(tcon->bytes_written));
159                 buf += length;
160                 length = sprintf(buf,
161                         "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
162                         atomic_read(&tcon->num_opens),
163                         atomic_read(&tcon->num_deletes),
164                         atomic_read(&tcon->num_mkdirs),
165                         atomic_read(&tcon->num_rmdirs));
166                 buf += length;
167 #endif
168
169         }
170         read_unlock(&GlobalSMBSeslock);
171
172         length = sprintf(buf, "\n");
173         buf += length;
174
175         *eof = 1;
176         /* BB add code to dump additional info such as TCP session info now */
177         /*
178            if (offset >= (buf - buf_start)) 
179            {
180            *beginBuffer = buf;
181            return 0;
182            }
183            *beginBuffer = buf + offset;
184            if ((buf - buf_start - offset) > count)
185            return count;
186    else */
187         return (buf - buf_start - offset);
188 }
189
190 int
191 cifs_total_xid_read(char *buf, char **beginBuffer, off_t offset,
192                     int length, int *eof, void *data)
193 {
194
195         length =
196             sprintf(buf,
197                     "Total vfs operations: %d and maximum simultaneous serviced by this filesystem: %d\n",
198                     GlobalCurrentXid,GlobalMaxActiveXid);
199
200         return length;
201 }
202
203 int
204 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
205                   int length, int *eof, void *data)
206 {
207         int item_length;
208         length =
209             sprintf(buf,
210                     "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter);
211         buf += length;
212         item_length = 
213                 sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
214         length += item_length;
215         buf += item_length;      
216         item_length = 
217                         sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
218         length += item_length;
219         buf += item_length;      
220         item_length = 
221                 sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
222         length += item_length;
223         buf += item_length;
224         item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
225         length += item_length;
226
227         return length;
228 }
229
230 struct proc_dir_entry *proc_fs_cifs;
231 read_proc_t cifs_txanchor_read;
232 static read_proc_t cifsFYI_read;
233 static write_proc_t cifsFYI_write;
234 static read_proc_t oplockEnabled_read;
235 static write_proc_t oplockEnabled_write;
236 static read_proc_t lookupFlag_read;
237 static write_proc_t lookupFlag_write;
238 static read_proc_t traceSMB_read;
239 static write_proc_t traceSMB_write;
240 static read_proc_t multiuser_mount_read;
241 static write_proc_t multiuser_mount_write;
242 static read_proc_t extended_security_read;
243 static write_proc_t extended_security_write;
244 static read_proc_t ntlmv2_enabled_read;
245 static write_proc_t ntlmv2_enabled_write;
246 static read_proc_t packet_signing_enabled_read;
247 static write_proc_t packet_signing_enabled_write;
248 static read_proc_t quotaEnabled_read;
249 static write_proc_t quotaEnabled_write;
250 static read_proc_t linuxExtensionsEnabled_read;
251 static write_proc_t linuxExtensionsEnabled_write;
252
253 void
254 cifs_proc_init(void)
255 {
256         struct proc_dir_entry *pde;
257
258         proc_fs_cifs = proc_mkdir("cifs", proc_root_fs);
259         if (proc_fs_cifs == NULL)
260                 return;
261
262         proc_fs_cifs->owner = THIS_MODULE;
263         create_proc_read_entry("DebugData", 0, proc_fs_cifs,
264                                 cifs_debug_data_read, 0);
265
266         create_proc_read_entry("SimultaneousOps", 0, proc_fs_cifs,
267                                 cifs_total_xid_read, 0);
268
269         create_proc_read_entry("Stats", 0, proc_fs_cifs,
270                                 cifs_stats_read, 0);
271
272         pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
273                                 cifsFYI_read, 0);
274         if (pde)
275                 pde->write_proc = cifsFYI_write;
276
277         pde =
278             create_proc_read_entry("traceSMB", 0, proc_fs_cifs,
279                                 traceSMB_read, 0);
280         if (pde)
281                 pde->write_proc = traceSMB_write;
282
283         pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs,
284                                 oplockEnabled_read, 0);
285         if (pde)
286                 pde->write_proc = oplockEnabled_write;
287
288         pde = create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs,
289                                 quotaEnabled_read, 0);
290         if (pde)
291                 pde->write_proc = quotaEnabled_write;
292
293         pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
294                                 linuxExtensionsEnabled_read, 0);
295         if (pde)
296                 pde->write_proc = linuxExtensionsEnabled_write;
297
298         pde =
299             create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
300                                 multiuser_mount_read, 0);
301         if (pde)
302                 pde->write_proc = multiuser_mount_write;
303
304         pde =
305             create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs,
306                                 extended_security_read, 0);
307         if (pde)
308                 pde->write_proc = extended_security_write;
309
310         pde =
311         create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
312                                 lookupFlag_read, 0);
313         if (pde)
314                 pde->write_proc = lookupFlag_write;
315
316         pde =
317             create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
318                                 ntlmv2_enabled_read, 0);
319         if (pde)
320                 pde->write_proc = ntlmv2_enabled_write;
321
322         pde =
323             create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
324                                 packet_signing_enabled_read, 0);
325         if (pde)
326                 pde->write_proc = packet_signing_enabled_write;
327 }
328
329 void
330 cifs_proc_clean(void)
331 {
332         if (proc_fs_cifs == NULL)
333                 return;
334
335         remove_proc_entry("DebugData", proc_fs_cifs);
336         remove_proc_entry("cifsFYI", proc_fs_cifs);
337         remove_proc_entry("traceSMB", proc_fs_cifs);
338         remove_proc_entry("SimultaneousOps", proc_fs_cifs);
339         remove_proc_entry("Stats", proc_fs_cifs);
340         remove_proc_entry("MultiuserMount", proc_fs_cifs);
341         remove_proc_entry("OplockEnabled", proc_fs_cifs);
342         remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
343         remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
344         remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
345         remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
346         remove_proc_entry("QuotaEnabled",proc_fs_cifs);
347         remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
348         remove_proc_entry("cifs", proc_root_fs);
349 }
350
351 static int
352 cifsFYI_read(char *page, char **start, off_t off, int count,
353              int *eof, void *data)
354 {
355         int len;
356
357         len = sprintf(page, "%d\n", cifsFYI);
358
359         len -= off;
360         *start = page + off;
361
362         if (len > count)
363                 len = count;
364         else
365                 *eof = 1;
366
367         if (len < 0)
368                 len = 0;
369
370         return len;
371 }
372 static int
373 cifsFYI_write(struct file *file, const char *buffer,
374               unsigned long count, void *data)
375 {
376         char c;
377         int rc;
378
379         rc = get_user(c, buffer);
380         if (rc)
381                 return rc;
382         if (c == '0' || c == 'n' || c == 'N')
383                 cifsFYI = 0;
384         else if (c == '1' || c == 'y' || c == 'Y')
385                 cifsFYI = 1;
386
387         return count;
388 }
389
390 static int
391 oplockEnabled_read(char *page, char **start, off_t off,
392                    int count, int *eof, void *data)
393 {
394         int len;
395
396         len = sprintf(page, "%d\n", oplockEnabled);
397
398         len -= off;
399         *start = page + off;
400
401         if (len > count)
402                 len = count;
403         else
404                 *eof = 1;
405
406         if (len < 0)
407                 len = 0;
408
409         return len;
410 }
411 static int
412 oplockEnabled_write(struct file *file, const char *buffer,
413                     unsigned long count, void *data)
414 {
415         char c;
416         int rc;
417
418         rc = get_user(c, buffer);
419         if (rc)
420                 return rc;
421         if (c == '0' || c == 'n' || c == 'N')
422                 oplockEnabled = 0;
423         else if (c == '1' || c == 'y' || c == 'Y')
424                 oplockEnabled = 1;
425
426         return count;
427 }
428
429 static int
430 quotaEnabled_read(char *page, char **start, off_t off,
431                    int count, int *eof, void *data)
432 {
433         int len;
434
435         len = sprintf(page, "%d\n", quotaEnabled);
436 /* could also check if quotas are enabled in kernel
437         as a whole first */
438         len -= off;
439         *start = page + off;
440
441         if (len > count)
442                 len = count;
443         else
444                 *eof = 1;
445
446         if (len < 0)
447                 len = 0;
448
449         return len;
450 }
451 static int
452 quotaEnabled_write(struct file *file, const char *buffer,
453                     unsigned long count, void *data)
454 {
455         char c;
456         int rc;
457
458         rc = get_user(c, buffer);
459         if (rc)
460                 return rc;
461         if (c == '0' || c == 'n' || c == 'N')
462                 quotaEnabled = 0;
463         else if (c == '1' || c == 'y' || c == 'Y')
464                 quotaEnabled = 1;
465
466         return count;
467 }
468
469 static int
470 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
471                    int count, int *eof, void *data)
472 {
473         int len;
474
475         len = sprintf(page, "%d\n", linuxExtEnabled);
476 /* could also check if quotas are enabled in kernel
477         as a whole first */
478         len -= off;
479         *start = page + off;
480
481         if (len > count)
482                 len = count;
483         else
484                 *eof = 1;
485
486         if (len < 0)
487                 len = 0;
488
489         return len;
490 }
491 static int
492 linuxExtensionsEnabled_write(struct file *file, const char *buffer,
493                     unsigned long count, void *data)
494 {
495         char c;
496         int rc;
497
498         rc = get_user(c, buffer);
499         if (rc)
500                 return rc;
501         if (c == '0' || c == 'n' || c == 'N')
502                 linuxExtEnabled = 0;
503         else if (c == '1' || c == 'y' || c == 'Y')
504                 linuxExtEnabled = 1;
505
506         return count;
507 }
508
509
510 static int
511 lookupFlag_read(char *page, char **start, off_t off,
512                    int count, int *eof, void *data)
513 {
514         int len;
515
516         len = sprintf(page, "%d\n", lookupCacheEnabled);
517
518         len -= off;
519         *start = page + off;
520
521         if (len > count)
522                 len = count;
523         else
524                 *eof = 1;
525
526         if (len < 0)
527                 len = 0;
528
529         return len;
530 }
531 static int
532 lookupFlag_write(struct file *file, const char *buffer,
533                     unsigned long count, void *data)
534 {
535         char c;
536         int rc;
537
538         rc = get_user(c, buffer);
539         if (rc)
540                 return rc;
541         if (c == '0' || c == 'n' || c == 'N')
542                 lookupCacheEnabled = 0;
543         else if (c == '1' || c == 'y' || c == 'Y')
544                 lookupCacheEnabled = 1;
545
546         return count;
547 }
548 static int
549 traceSMB_read(char *page, char **start, off_t off, int count,
550               int *eof, void *data)
551 {
552         int len;
553
554         len = sprintf(page, "%d\n", traceSMB);
555
556         len -= off;
557         *start = page + off;
558
559         if (len > count)
560                 len = count;
561         else
562                 *eof = 1;
563
564         if (len < 0)
565                 len = 0;
566
567         return len;
568 }
569 static int
570 traceSMB_write(struct file *file, const char *buffer,
571                unsigned long count, void *data)
572 {
573         char c;
574         int rc;
575
576         rc = get_user(c, buffer);
577         if (rc)
578                 return rc;
579         if (c == '0' || c == 'n' || c == 'N')
580                 traceSMB = 0;
581         else if (c == '1' || c == 'y' || c == 'Y')
582                 traceSMB = 1;
583
584         return count;
585 }
586
587 static int
588 multiuser_mount_read(char *page, char **start, off_t off,
589                      int count, int *eof, void *data)
590 {
591         int len;
592
593         len = sprintf(page, "%d\n", multiuser_mount);
594
595         len -= off;
596         *start = page + off;
597
598         if (len > count)
599                 len = count;
600         else
601                 *eof = 1;
602
603         if (len < 0)
604                 len = 0;
605
606         return len;
607 }
608 static int
609 multiuser_mount_write(struct file *file, const char *buffer,
610                       unsigned long count, void *data)
611 {
612         char c;
613         int rc;
614
615         rc = get_user(c, buffer);
616         if (rc)
617                 return rc;
618         if (c == '0' || c == 'n' || c == 'N')
619                 multiuser_mount = 0;
620         else if (c == '1' || c == 'y' || c == 'Y')
621                 multiuser_mount = 1;
622
623         return count;
624 }
625
626 static int
627 extended_security_read(char *page, char **start, off_t off,
628                        int count, int *eof, void *data)
629 {
630         int len;
631
632         len = sprintf(page, "%d\n", extended_security);
633
634         len -= off;
635         *start = page + off;
636
637         if (len > count)
638                 len = count;
639         else
640                 *eof = 1;
641
642         if (len < 0)
643                 len = 0;
644
645         return len;
646 }
647 static int
648 extended_security_write(struct file *file, const char *buffer,
649                         unsigned long count, void *data)
650 {
651         char c;
652         int rc;
653
654         rc = get_user(c, buffer);
655         if (rc)
656                 return rc;
657         if (c == '0' || c == 'n' || c == 'N')
658                 extended_security = 0;
659         else if (c == '1' || c == 'y' || c == 'Y')
660                 extended_security = 1;
661
662         return count;
663 }
664
665 static int
666 ntlmv2_enabled_read(char *page, char **start, off_t off,
667                        int count, int *eof, void *data)
668 {
669         int len;
670
671         len = sprintf(page, "%d\n", ntlmv2_support);
672
673         len -= off;
674         *start = page + off;
675
676         if (len > count)
677                 len = count;
678         else
679                 *eof = 1;
680
681         if (len < 0)
682                 len = 0;
683
684         return len;
685 }
686 static int
687 ntlmv2_enabled_write(struct file *file, const char *buffer,
688                         unsigned long count, void *data)
689 {
690         char c;
691         int rc;
692
693         rc = get_user(c, buffer);
694         if (rc)
695                 return rc;
696         if (c == '0' || c == 'n' || c == 'N')
697                 ntlmv2_support = 0;
698         else if (c == '1' || c == 'y' || c == 'Y')
699                 ntlmv2_support = 1;
700
701         return count;
702 }
703
704 static int
705 packet_signing_enabled_read(char *page, char **start, off_t off,
706                        int count, int *eof, void *data)
707 {
708         int len;
709
710         len = sprintf(page, "%d\n", sign_CIFS_PDUs);
711
712         len -= off;
713         *start = page + off;
714
715         if (len > count)
716                 len = count;
717         else
718                 *eof = 1;
719
720         if (len < 0)
721                 len = 0;
722
723         return len;
724 }
725 static int
726 packet_signing_enabled_write(struct file *file, const char *buffer,
727                         unsigned long count, void *data)
728 {
729         char c;
730         int rc;
731
732         rc = get_user(c, buffer);
733         if (rc)
734                 return rc;
735         if (c == '0' || c == 'n' || c == 'N')
736                 sign_CIFS_PDUs = 0;
737         else if (c == '1' || c == 'y' || c == 'Y')
738                 sign_CIFS_PDUs = 1;
739         else if (c == '2')
740                 sign_CIFS_PDUs = 2;
741
742         return count;
743 }
744
745
746 #endif