Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[linux-2.6] / fs / cifs / cifs_debug.c
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
34 void
35 cifs_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
61 void 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
70 void 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                 if (mid_entry) {
83                         cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
84                                 mid_entry->midState,
85                                 (int)mid_entry->command,
86                                 mid_entry->pid,
87                                 mid_entry->tsk,
88                                 mid_entry->mid));
89 #ifdef CONFIG_CIFS_STATS2
90                         cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
91                                 mid_entry->largeBuf,
92                                 mid_entry->resp_buf,
93                                 mid_entry->when_received,
94                                 jiffies));
95 #endif /* STATS2 */
96                         cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
97                                   mid_entry->multiEnd));
98                         if (mid_entry->resp_buf) {
99                                 cifs_dump_detail(mid_entry->resp_buf);
100                                 cifs_dump_mem("existing buf: ",
101                                         mid_entry->resp_buf,
102                                         62 /* fixme */);
103                         }
104                 }
105         }
106         spin_unlock(&GlobalMid_Lock);
107 }
108 #endif /* CONFIG_CIFS_DEBUG2 */
109
110 #ifdef CONFIG_PROC_FS
111 static int
112 cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
113                      int count, int *eof, void *data)
114 {
115         struct list_head *tmp;
116         struct list_head *tmp1;
117         struct mid_q_entry * mid_entry;
118         struct cifsSesInfo *ses;
119         struct cifsTconInfo *tcon;
120         int i;
121         int length = 0;
122         char * original_buf = buf;
123
124         *beginBuffer = buf + offset;
125
126         length =
127             sprintf(buf,
128                     "Display Internal CIFS Data Structures for Debugging\n"
129                     "---------------------------------------------------\n");
130         buf += length;
131         length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION);
132         buf += length;
133         length = sprintf(buf,
134                 "Active VFS Requests: %d\n", GlobalTotalActiveXid);
135         buf += length;
136         length = sprintf(buf, "Servers:");
137         buf += length;
138
139         i = 0;
140         read_lock(&GlobalSMBSeslock);
141         list_for_each(tmp, &GlobalSMBSessionList) {
142                 i++;
143                 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
144                 if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
145                    (ses->serverNOS == NULL)) {
146                         buf += sprintf(buf, "\nentry for %s not fully "
147                                         "displayed\n\t", ses->serverName);
148                         
149                 } else {
150                         length =
151                             sprintf(buf,
152                                     "\n%d) Name: %s  Domain: %s Mounts: %d OS:"
153                                     " %s  \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
154                                     " session status: %d\t",
155                                 i, ses->serverName, ses->serverDomain,
156                                 atomic_read(&ses->inUse),
157                                 ses->serverOS, ses->serverNOS,
158                                 ses->capabilities, ses->status);
159                         buf += length;
160                 }
161                 if (ses->server) {
162                         buf += sprintf(buf, "TCP status: %d\n\tLocal Users To "
163                                     "Server: %d SecMode: 0x%x Req On Wire: %d",
164                                 ses->server->tcpStatus,
165                                 atomic_read(&ses->server->socketUseCount),
166                                 ses->server->secMode,
167                                 atomic_read(&ses->server->inFlight));
168
169 #ifdef CONFIG_CIFS_STATS2
170                         buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
171                                 atomic_read(&ses->server->inSend),
172                                 atomic_read(&ses->server->num_waiters));
173 #endif
174
175                         length = sprintf(buf, "\nMIDs:\n");
176                         buf += length;
177
178                         spin_lock(&GlobalMid_Lock);
179                         list_for_each(tmp1, &ses->server->pending_mid_q) {
180                                 mid_entry = list_entry(tmp1, struct
181                                         mid_q_entry,
182                                         qhead);
183                                 if (mid_entry) {
184                                         length = sprintf(buf,
185                                                         "State: %d com: %d pid:"
186                                                         " %d tsk: %p mid %d\n",
187                                                         mid_entry->midState,
188                                                         (int)mid_entry->command,
189                                                         mid_entry->pid,
190                                                         mid_entry->tsk,
191                                                         mid_entry->mid);
192                                         buf += length;
193                                 }
194                         }
195                         spin_unlock(&GlobalMid_Lock);
196                 }
197
198         }
199         read_unlock(&GlobalSMBSeslock);
200         sprintf(buf, "\n");
201         buf++;
202
203         length = sprintf(buf, "Shares:");
204         buf += length;
205
206         i = 0;
207         read_lock(&GlobalSMBSeslock);
208         list_for_each(tmp, &GlobalTreeConnectionList) {
209                 __u32 dev_type;
210                 i++;
211                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
212                 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
213                 length =
214                     sprintf(buf,
215                             "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x "
216                             "Attributes: 0x%x\nPathComponentMax: %d Status: %d",
217                             i, tcon->treeName,
218                             atomic_read(&tcon->useCount),
219                             tcon->nativeFileSystem,
220                             le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
221                             le32_to_cpu(tcon->fsAttrInfo.Attributes),
222                             le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
223                             tcon->tidStatus);
224                 buf += length;
225                 if (dev_type == FILE_DEVICE_DISK)
226                         length = sprintf(buf, " type: DISK ");
227                 else if (dev_type == FILE_DEVICE_CD_ROM)
228                         length = sprintf(buf, " type: CDROM ");
229                 else
230                         length =
231                             sprintf(buf, " type: %d ", dev_type);
232                 buf += length;
233                 if (tcon->tidStatus == CifsNeedReconnect) {
234                         buf += sprintf(buf, "\tDISCONNECTED ");
235                         length += 14;
236                 }
237         }
238         read_unlock(&GlobalSMBSeslock);
239
240         length = sprintf(buf, "\n");
241         buf += length;
242
243         /* BB add code to dump additional info such as TCP session info now */
244         /* Now calculate total size of returned data */
245         length = buf - original_buf;
246
247         if (offset + count >= length)
248                 *eof = 1;
249         if (length < offset) {
250                 *eof = 1;
251                 return 0;
252         } else {
253                 length = length - offset;
254         }
255         if (length > count)
256                 length = count;
257
258         return length;
259 }
260
261 #ifdef CONFIG_CIFS_STATS
262
263 static int
264 cifs_stats_write(struct file *file, const char __user *buffer,
265                  unsigned long count, void *data)
266 {
267         char c;
268         int rc;
269         struct list_head *tmp;
270         struct cifsTconInfo *tcon;
271
272         rc = get_user(c, buffer);
273         if (rc)
274                 return rc;
275
276         if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
277                 read_lock(&GlobalSMBSeslock);
278 #ifdef CONFIG_CIFS_STATS2
279                 atomic_set(&totBufAllocCount, 0);
280                 atomic_set(&totSmBufAllocCount, 0);
281 #endif /* CONFIG_CIFS_STATS2 */
282                 list_for_each(tmp, &GlobalTreeConnectionList) {
283                         tcon = list_entry(tmp, struct cifsTconInfo,
284                                         cifsConnectionList);
285                         atomic_set(&tcon->num_smbs_sent, 0);
286                         atomic_set(&tcon->num_writes, 0);
287                         atomic_set(&tcon->num_reads, 0);
288                         atomic_set(&tcon->num_oplock_brks, 0);
289                         atomic_set(&tcon->num_opens, 0);
290                         atomic_set(&tcon->num_closes, 0);
291                         atomic_set(&tcon->num_deletes, 0);
292                         atomic_set(&tcon->num_mkdirs, 0);
293                         atomic_set(&tcon->num_rmdirs, 0);
294                         atomic_set(&tcon->num_renames, 0);
295                         atomic_set(&tcon->num_t2renames, 0);
296                         atomic_set(&tcon->num_ffirst, 0);
297                         atomic_set(&tcon->num_fnext, 0);
298                         atomic_set(&tcon->num_fclose, 0);
299                         atomic_set(&tcon->num_hardlinks, 0);
300                         atomic_set(&tcon->num_symlinks, 0);
301                         atomic_set(&tcon->num_locks, 0);
302                 }
303                 read_unlock(&GlobalSMBSeslock);
304         }
305
306         return count;
307 }
308
309 static int
310 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
311                   int count, int *eof, void *data)
312 {
313         int item_length, i, length;
314         struct list_head *tmp;
315         struct cifsTconInfo *tcon;
316
317         *beginBuffer = buf + offset;
318
319         length = sprintf(buf,
320                         "Resources in use\nCIFS Session: %d\n",
321                         sesInfoAllocCount.counter);
322         buf += length;
323         item_length =
324                 sprintf(buf, "Share (unique mount targets): %d\n",
325                         tconInfoAllocCount.counter);
326         length += item_length;
327         buf += item_length;
328         item_length =
329                 sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n",
330                         bufAllocCount.counter,
331                         cifs_min_rcv + tcpSesAllocCount.counter);
332         length += item_length;
333         buf += item_length;
334         item_length =
335                 sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
336                         smBufAllocCount.counter, cifs_min_small);
337         length += item_length;
338         buf += item_length;
339 #ifdef CONFIG_CIFS_STATS2
340         item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
341                                 atomic_read(&totBufAllocCount),
342                                 atomic_read(&totSmBufAllocCount));
343         length += item_length;
344         buf += item_length;
345 #endif /* CONFIG_CIFS_STATS2 */
346
347         item_length =
348                 sprintf(buf, "Operations (MIDs): %d\n",
349                         midCount.counter);
350         length += item_length;
351         buf += item_length;
352         item_length = sprintf(buf,
353                 "\n%d session %d share reconnects\n",
354                 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
355         length += item_length;
356         buf += item_length;
357
358         item_length = sprintf(buf,
359                 "Total vfs operations: %d maximum at one time: %d\n",
360                 GlobalCurrentXid, GlobalMaxActiveXid);
361         length += item_length;
362         buf += item_length;
363
364         i = 0;
365         read_lock(&GlobalSMBSeslock);
366         list_for_each(tmp, &GlobalTreeConnectionList) {
367                 i++;
368                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
369                 item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName);
370                 buf += item_length;
371                 length += item_length;
372                 if (tcon->tidStatus == CifsNeedReconnect) {
373                         buf += sprintf(buf, "\tDISCONNECTED ");
374                         length += 14;
375                 }
376                 item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d",
377                         atomic_read(&tcon->num_smbs_sent),
378                         atomic_read(&tcon->num_oplock_brks));
379                 buf += item_length;
380                 length += item_length;
381                 item_length = sprintf(buf, "\nReads:  %d Bytes: %lld",
382                         atomic_read(&tcon->num_reads),
383                         (long long)(tcon->bytes_read));
384                 buf += item_length;
385                 length += item_length;
386                 item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
387                         atomic_read(&tcon->num_writes),
388                         (long long)(tcon->bytes_written));
389                 buf += item_length;
390                 length += item_length;
391                 item_length = sprintf(buf,
392                         "\nLocks: %d HardLinks: %d Symlinks: %d",
393                         atomic_read(&tcon->num_locks),
394                         atomic_read(&tcon->num_hardlinks),
395                         atomic_read(&tcon->num_symlinks));
396                 buf += item_length;
397                 length += item_length;
398
399                 item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
400                         atomic_read(&tcon->num_opens),
401                         atomic_read(&tcon->num_closes),
402                         atomic_read(&tcon->num_deletes));
403                 buf += item_length;
404                 length += item_length;
405                 item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d",
406                         atomic_read(&tcon->num_mkdirs),
407                         atomic_read(&tcon->num_rmdirs));
408                 buf += item_length;
409                 length += item_length;
410                 item_length = sprintf(buf, "\nRenames: %d T2 Renames %d",
411                         atomic_read(&tcon->num_renames),
412                         atomic_read(&tcon->num_t2renames));
413                 buf += item_length;
414                 length += item_length;
415                 item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d",
416                         atomic_read(&tcon->num_ffirst),
417                         atomic_read(&tcon->num_fnext),
418                         atomic_read(&tcon->num_fclose));
419                 buf += item_length;
420                 length += item_length;
421         }
422         read_unlock(&GlobalSMBSeslock);
423
424         buf += sprintf(buf, "\n");
425         length++;
426
427         if (offset + count >= length)
428                 *eof = 1;
429         if (length < offset) {
430                 *eof = 1;
431                 return 0;
432         } else {
433                 length = length - offset;
434         }
435         if (length > count)
436                 length = count;
437
438         return length;
439 }
440 #endif
441
442 static struct proc_dir_entry *proc_fs_cifs;
443 read_proc_t cifs_txanchor_read;
444 static read_proc_t cifsFYI_read;
445 static write_proc_t cifsFYI_write;
446 static read_proc_t oplockEnabled_read;
447 static write_proc_t oplockEnabled_write;
448 static read_proc_t lookupFlag_read;
449 static write_proc_t lookupFlag_write;
450 static read_proc_t traceSMB_read;
451 static write_proc_t traceSMB_write;
452 static read_proc_t multiuser_mount_read;
453 static write_proc_t multiuser_mount_write;
454 static read_proc_t security_flags_read;
455 static write_proc_t security_flags_write;
456 /* static read_proc_t ntlmv2_enabled_read;
457 static write_proc_t ntlmv2_enabled_write;
458 static read_proc_t packet_signing_enabled_read;
459 static write_proc_t packet_signing_enabled_write;*/
460 static read_proc_t experimEnabled_read;
461 static write_proc_t experimEnabled_write;
462 static read_proc_t linuxExtensionsEnabled_read;
463 static write_proc_t linuxExtensionsEnabled_write;
464
465 void
466 cifs_proc_init(void)
467 {
468         struct proc_dir_entry *pde;
469
470         proc_fs_cifs = proc_mkdir("cifs", proc_root_fs);
471         if (proc_fs_cifs == NULL)
472                 return;
473
474         proc_fs_cifs->owner = THIS_MODULE;
475         create_proc_read_entry("DebugData", 0, proc_fs_cifs,
476                                 cifs_debug_data_read, NULL);
477
478 #ifdef CONFIG_CIFS_STATS
479         pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
480                                 cifs_stats_read, NULL);
481         if (pde)
482                 pde->write_proc = cifs_stats_write;
483 #endif
484         pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
485                                 cifsFYI_read, NULL);
486         if (pde)
487                 pde->write_proc = cifsFYI_write;
488
489         pde =
490             create_proc_read_entry("traceSMB", 0, proc_fs_cifs,
491                                 traceSMB_read, NULL);
492         if (pde)
493                 pde->write_proc = traceSMB_write;
494
495         pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs,
496                                 oplockEnabled_read, NULL);
497         if (pde)
498                 pde->write_proc = oplockEnabled_write;
499
500         pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
501                                 experimEnabled_read, NULL);
502         if (pde)
503                 pde->write_proc = experimEnabled_write;
504
505         pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
506                                 linuxExtensionsEnabled_read, NULL);
507         if (pde)
508                 pde->write_proc = linuxExtensionsEnabled_write;
509
510         pde =
511             create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
512                                 multiuser_mount_read, NULL);
513         if (pde)
514                 pde->write_proc = multiuser_mount_write;
515
516         pde =
517             create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs,
518                                 security_flags_read, NULL);
519         if (pde)
520                 pde->write_proc = security_flags_write;
521
522         pde =
523         create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
524                                 lookupFlag_read, NULL);
525         if (pde)
526                 pde->write_proc = lookupFlag_write;
527
528 /*      pde =
529             create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
530                                 ntlmv2_enabled_read, NULL);
531         if (pde)
532                 pde->write_proc = ntlmv2_enabled_write;
533
534         pde =
535             create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
536                                 packet_signing_enabled_read, NULL);
537         if (pde)
538                 pde->write_proc = packet_signing_enabled_write;*/
539 }
540
541 void
542 cifs_proc_clean(void)
543 {
544         if (proc_fs_cifs == NULL)
545                 return;
546
547         remove_proc_entry("DebugData", proc_fs_cifs);
548         remove_proc_entry("cifsFYI", proc_fs_cifs);
549         remove_proc_entry("traceSMB", proc_fs_cifs);
550 #ifdef CONFIG_CIFS_STATS
551         remove_proc_entry("Stats", proc_fs_cifs);
552 #endif
553         remove_proc_entry("MultiuserMount", proc_fs_cifs);
554         remove_proc_entry("OplockEnabled", proc_fs_cifs);
555 /*      remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */
556         remove_proc_entry("SecurityFlags", proc_fs_cifs);
557 /*      remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */
558         remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
559         remove_proc_entry("Experimental", proc_fs_cifs);
560         remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
561         remove_proc_entry("cifs", proc_root_fs);
562 }
563
564 static int
565 cifsFYI_read(char *page, char **start, off_t off, int count,
566              int *eof, void *data)
567 {
568         int len;
569
570         len = sprintf(page, "%d\n", cifsFYI);
571
572         len -= off;
573         *start = page + off;
574
575         if (len > count)
576                 len = count;
577         else
578                 *eof = 1;
579
580         if (len < 0)
581                 len = 0;
582
583         return len;
584 }
585 static int
586 cifsFYI_write(struct file *file, const char __user *buffer,
587               unsigned long count, void *data)
588 {
589         char c;
590         int rc;
591
592         rc = get_user(c, buffer);
593         if (rc)
594                 return rc;
595         if (c == '0' || c == 'n' || c == 'N')
596                 cifsFYI = 0;
597         else if (c == '1' || c == 'y' || c == 'Y')
598                 cifsFYI = 1;
599         else if ((c > '1') && (c <= '9'))
600                 cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
601
602         return count;
603 }
604
605 static int
606 oplockEnabled_read(char *page, char **start, off_t off,
607                    int count, int *eof, void *data)
608 {
609         int len;
610
611         len = sprintf(page, "%d\n", oplockEnabled);
612
613         len -= off;
614         *start = page + off;
615
616         if (len > count)
617                 len = count;
618         else
619                 *eof = 1;
620
621         if (len < 0)
622                 len = 0;
623
624         return len;
625 }
626 static int
627 oplockEnabled_write(struct file *file, const char __user *buffer,
628                     unsigned long count, void *data)
629 {
630         char c;
631         int rc;
632
633         rc = get_user(c, buffer);
634         if (rc)
635                 return rc;
636         if (c == '0' || c == 'n' || c == 'N')
637                 oplockEnabled = 0;
638         else if (c == '1' || c == 'y' || c == 'Y')
639                 oplockEnabled = 1;
640
641         return count;
642 }
643
644 static int
645 experimEnabled_read(char *page, char **start, off_t off,
646                     int count, int *eof, void *data)
647 {
648         int len;
649
650         len = sprintf(page, "%d\n", experimEnabled);
651
652         len -= off;
653         *start = page + off;
654
655         if (len > count)
656                 len = count;
657         else
658                 *eof = 1;
659
660         if (len < 0)
661                 len = 0;
662
663         return len;
664 }
665 static int
666 experimEnabled_write(struct file *file, const char __user *buffer,
667                      unsigned long count, void *data)
668 {
669         char c;
670         int rc;
671
672         rc = get_user(c, buffer);
673         if (rc)
674                 return rc;
675         if (c == '0' || c == 'n' || c == 'N')
676                 experimEnabled = 0;
677         else if (c == '1' || c == 'y' || c == 'Y')
678                 experimEnabled = 1;
679         else if (c == '2')
680                 experimEnabled = 2;
681
682         return count;
683 }
684
685 static int
686 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
687                             int count, int *eof, void *data)
688 {
689         int len;
690
691         len = sprintf(page, "%d\n", linuxExtEnabled);
692         len -= off;
693         *start = page + off;
694
695         if (len > count)
696                 len = count;
697         else
698                 *eof = 1;
699
700         if (len < 0)
701                 len = 0;
702
703         return len;
704 }
705 static int
706 linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
707                              unsigned long count, void *data)
708 {
709         char c;
710         int rc;
711
712         rc = get_user(c, buffer);
713         if (rc)
714                 return rc;
715         if (c == '0' || c == 'n' || c == 'N')
716                 linuxExtEnabled = 0;
717         else if (c == '1' || c == 'y' || c == 'Y')
718                 linuxExtEnabled = 1;
719
720         return count;
721 }
722
723
724 static int
725 lookupFlag_read(char *page, char **start, off_t off,
726                 int count, int *eof, void *data)
727 {
728         int len;
729
730         len = sprintf(page, "%d\n", lookupCacheEnabled);
731
732         len -= off;
733         *start = page + off;
734
735         if (len > count)
736                 len = count;
737         else
738                 *eof = 1;
739
740         if (len < 0)
741                 len = 0;
742
743         return len;
744 }
745 static int
746 lookupFlag_write(struct file *file, const char __user *buffer,
747                     unsigned long count, void *data)
748 {
749         char c;
750         int rc;
751
752         rc = get_user(c, buffer);
753         if (rc)
754                 return rc;
755         if (c == '0' || c == 'n' || c == 'N')
756                 lookupCacheEnabled = 0;
757         else if (c == '1' || c == 'y' || c == 'Y')
758                 lookupCacheEnabled = 1;
759
760         return count;
761 }
762 static int
763 traceSMB_read(char *page, char **start, off_t off, int count,
764               int *eof, void *data)
765 {
766         int len;
767
768         len = sprintf(page, "%d\n", traceSMB);
769
770         len -= off;
771         *start = page + off;
772
773         if (len > count)
774                 len = count;
775         else
776                 *eof = 1;
777
778         if (len < 0)
779                 len = 0;
780
781         return len;
782 }
783 static int
784 traceSMB_write(struct file *file, const char __user *buffer,
785                unsigned long count, void *data)
786 {
787         char c;
788         int rc;
789
790         rc = get_user(c, buffer);
791         if (rc)
792                 return rc;
793         if (c == '0' || c == 'n' || c == 'N')
794                 traceSMB = 0;
795         else if (c == '1' || c == 'y' || c == 'Y')
796                 traceSMB = 1;
797
798         return count;
799 }
800
801 static int
802 multiuser_mount_read(char *page, char **start, off_t off,
803                      int count, int *eof, void *data)
804 {
805         int len;
806
807         len = sprintf(page, "%d\n", multiuser_mount);
808
809         len -= off;
810         *start = page + off;
811
812         if (len > count)
813                 len = count;
814         else
815                 *eof = 1;
816
817         if (len < 0)
818                 len = 0;
819
820         return len;
821 }
822 static int
823 multiuser_mount_write(struct file *file, const char __user *buffer,
824                       unsigned long count, void *data)
825 {
826         char c;
827         int rc;
828
829         rc = get_user(c, buffer);
830         if (rc)
831                 return rc;
832         if (c == '0' || c == 'n' || c == 'N')
833                 multiuser_mount = 0;
834         else if (c == '1' || c == 'y' || c == 'Y')
835                 multiuser_mount = 1;
836
837         return count;
838 }
839
840 static int
841 security_flags_read(char *page, char **start, off_t off,
842                        int count, int *eof, void *data)
843 {
844         int len;
845
846         len = sprintf(page, "0x%x\n", extended_security);
847
848         len -= off;
849         *start = page + off;
850
851         if (len > count)
852                 len = count;
853         else
854                 *eof = 1;
855
856         if (len < 0)
857                 len = 0;
858
859         return len;
860 }
861 static int
862 security_flags_write(struct file *file, const char __user *buffer,
863                         unsigned long count, void *data)
864 {
865         unsigned int flags;
866         char flags_string[12];
867         char c;
868
869         if ((count < 1) || (count > 11))
870                 return -EINVAL;
871
872         memset(flags_string, 0, 12);
873
874         if (copy_from_user(flags_string, buffer, count))
875                 return -EFAULT;
876
877         if (count < 3) {
878                 /* single char or single char followed by null */
879                 c = flags_string[0];
880                 if (c == '0' || c == 'n' || c == 'N')
881                         extended_security = CIFSSEC_DEF; /* default */
882                 else if (c == '1' || c == 'y' || c == 'Y')
883                         extended_security = CIFSSEC_MAX;
884                 return count;
885         }
886         /* else we have a number */
887
888         flags = simple_strtoul(flags_string, NULL, 0);
889
890         cFYI(1, ("sec flags 0x%x", flags));
891
892         if (flags <= 0)  {
893                 cERROR(1, ("invalid security flags %s", flags_string));
894                 return -EINVAL;
895         }
896
897         if (flags & ~CIFSSEC_MASK) {
898                 cERROR(1, ("attempt to set unsupported security flags 0x%x",
899                         flags & ~CIFSSEC_MASK));
900                 return -EINVAL;
901         }
902         /* flags look ok - update the global security flags for cifs module */
903         extended_security = flags;
904         return count;
905 }
906
907 /* static int
908 ntlmv2_enabled_read(char *page, char **start, off_t off,
909                        int count, int *eof, void *data)
910 {
911         int len;
912
913         len = sprintf(page, "%d\n", ntlmv2_support);
914
915         len -= off;
916         *start = page + off;
917
918         if (len > count)
919                 len = count;
920         else
921                 *eof = 1;
922
923         if (len < 0)
924                 len = 0;
925
926         return len;
927 }
928 static int
929 ntlmv2_enabled_write(struct file *file, const char __user *buffer,
930                         unsigned long count, void *data)
931 {
932         char c;
933         int rc;
934
935         rc = get_user(c, buffer);
936         if (rc)
937                 return rc;
938         if (c == '0' || c == 'n' || c == 'N')
939                 ntlmv2_support = 0;
940         else if (c == '1' || c == 'y' || c == 'Y')
941                 ntlmv2_support = 1;
942         else if (c == '2')
943                 ntlmv2_support = 2;
944
945         return count;
946 }
947
948 static int
949 packet_signing_enabled_read(char *page, char **start, off_t off,
950                        int count, int *eof, void *data)
951 {
952         int len;
953
954         len = sprintf(page, "%d\n", sign_CIFS_PDUs);
955
956         len -= off;
957         *start = page + off;
958
959         if (len > count)
960                 len = count;
961         else
962                 *eof = 1;
963
964         if (len < 0)
965                 len = 0;
966
967         return len;
968 }
969 static int
970 packet_signing_enabled_write(struct file *file, const char __user *buffer,
971                         unsigned long count, void *data)
972 {
973         char c;
974         int rc;
975
976         rc = get_user(c, buffer);
977         if (rc)
978                 return rc;
979         if (c == '0' || c == 'n' || c == 'N')
980                 sign_CIFS_PDUs = 0;
981         else if (c == '1' || c == 'y' || c == 'Y')
982                 sign_CIFS_PDUs = 1;
983         else if (c == '2')
984                 sign_CIFS_PDUs = 2;
985
986         return count;
987 } */
988
989
990 #endif