vserver 1.9.5.x5
[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 list_head *tmp1;
66         struct mid_q_entry * mid_entry;
67         struct cifsSesInfo *ses;
68         struct cifsTconInfo *tcon;
69         int i;
70         int length = 0;
71         char * original_buf = buf;
72
73         *beginBuffer = buf + offset;
74
75         
76         length =
77             sprintf(buf,
78                     "Display Internal CIFS Data Structures for Debugging\n"
79                     "---------------------------------------------------\n");
80         buf += length;
81
82         length = sprintf(buf, "Servers:\n");
83         buf += length;
84
85         i = 0;
86         read_lock(&GlobalSMBSeslock);
87         list_for_each(tmp, &GlobalSMBSessionList) {
88                 i++;
89                 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
90                 length =
91                     sprintf(buf,
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);
95                 buf += length;
96                 if(ses->server) {
97                         buf += sprintf(buf, "\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
98                                 atomic_read(&ses->server->socketUseCount),
99                                 ses->server->secMode,
100                                 atomic_read(&ses->server->inFlight));
101                         
102                         length = sprintf(buf, "\nMIDs: \n");
103                         buf += length;
104
105                         spin_lock(&GlobalMid_Lock);
106                         list_for_each(tmp1, &ses->server->pending_mid_q) {
107                                 mid_entry = list_entry(tmp1, struct
108                                         mid_q_entry,
109                                         qhead);
110                                 if(mid_entry) {
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);
112                                         buf += length;
113                                 }
114                         }
115                         spin_unlock(&GlobalMid_Lock); 
116                 }
117
118         }
119         read_unlock(&GlobalSMBSeslock);
120         sprintf(buf, "\n");
121         buf++;
122
123         length = sprintf(buf, "\nShares:\n");
124         buf += length;
125
126         i = 0;
127         read_lock(&GlobalSMBSeslock);
128         list_for_each(tmp, &GlobalTreeConnectionList) {
129                 __u32 dev_type;
130                 i++;
131                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
132                 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
133                 length =
134                     sprintf(buf,
135                             "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
136                             i, tcon->treeName,
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),
142                             tcon->tidStatus);
143                 buf += length;        
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 ");
148                 else
149                         length =
150                             sprintf(buf, " type: %d ", dev_type);
151                 buf += length;
152                 if(tcon->tidStatus == CifsNeedReconnect) {
153                         buf += sprintf(buf, "\tDISCONNECTED ");
154                         length += 14;
155                 }
156         }
157         read_unlock(&GlobalSMBSeslock);
158
159         length = sprintf(buf, "\n");
160         buf += length;
161
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;
165
166         if(offset + count >= length)
167                 *eof = 1;
168         if(length < offset) {
169                 *eof = 1;
170                 return 0;
171         } else {
172                 length = length - offset;
173         }
174         if (length > count)
175                 length = count;
176
177         return length;
178 }
179
180 #ifdef CONFIG_CIFS_STATS
181 int
182 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
183                   int count, int *eof, void *data)
184 {
185         int item_length,i,length;
186         struct list_head *tmp;
187         struct cifsTconInfo *tcon;
188
189         *beginBuffer = buf + offset;
190
191         length = sprintf(buf,
192                         "Resources in use\nCIFS Session: %d\n",
193                         sesInfoAllocCount.counter);
194         buf += length;
195         item_length = 
196                 sprintf(buf,"Share (unique mount targets): %d\n",
197                         tconInfoAllocCount.counter);
198         length += item_length;
199         buf += item_length;      
200         item_length = 
201                 sprintf(buf,"SMB Request/Response Buffer: %d\n",
202                         bufAllocCount.counter);
203         length += item_length;
204         buf += item_length;
205         item_length = 
206                 sprintf(buf,"SMB Small Req/Resp Buffer: %d\n",
207                         smBufAllocCount.counter);
208         length += item_length;
209         buf += item_length;
210         item_length = 
211                 sprintf(buf,"Operations (MIDs): %d\n",
212                         midCount.counter);
213         length += item_length;
214         buf += item_length;
215         item_length = sprintf(buf,
216                 "\n%d session %d share reconnects\n",
217                 tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
218         length += item_length;
219         buf += item_length;
220
221         item_length = sprintf(buf,
222                 "Total vfs operations: %d maximum at one time: %d\n",
223                 GlobalCurrentXid,GlobalMaxActiveXid);
224         length += item_length;
225         buf += item_length;
226
227         i = 0;
228         read_lock(&GlobalSMBSeslock);
229         list_for_each(tmp, &GlobalTreeConnectionList) {
230                 i++;
231                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
232                 item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName);
233                 buf += item_length;
234                 length += item_length;
235                 if(tcon->tidStatus == CifsNeedReconnect) {
236                         buf += sprintf(buf, "\tDISCONNECTED ");
237                         length += 14;
238                 }
239                 item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
240                         atomic_read(&tcon->num_smbs_sent),
241                         atomic_read(&tcon->num_oplock_brks));
242                 buf += item_length;
243                 length += item_length;
244                 item_length = sprintf(buf,"\nReads: %d Bytes %lld",
245                         atomic_read(&tcon->num_reads),
246                         (long long)(tcon->bytes_read));
247                 buf += item_length;
248                 length += item_length;
249                 item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
250                         atomic_read(&tcon->num_writes),
251                         (long long)(tcon->bytes_written));
252                 buf += item_length;
253                 length += item_length;
254                 item_length = sprintf(buf,
255                         "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
256                         atomic_read(&tcon->num_opens),
257                         atomic_read(&tcon->num_deletes),
258                         atomic_read(&tcon->num_mkdirs),
259                         atomic_read(&tcon->num_rmdirs));
260                 buf += item_length;
261                 length += item_length;
262                 item_length = sprintf(buf,
263                         "\nRenames: %d T2 Renames %d",
264                         atomic_read(&tcon->num_renames),
265                         atomic_read(&tcon->num_t2renames));
266                 buf += item_length;
267                 length += item_length;
268         }
269         read_unlock(&GlobalSMBSeslock);
270
271         buf += sprintf(buf,"\n");
272         length++;
273
274         if(offset + count >= length)
275                 *eof = 1;
276         if(length < offset) {
277                 *eof = 1;
278                 return 0;
279         } else {
280                 length = length - offset;
281         }
282         if (length > count)
283                 length = count;
284                 
285         return length;
286 }
287 #endif
288
289 struct proc_dir_entry *proc_fs_cifs;
290 read_proc_t cifs_txanchor_read;
291 static read_proc_t cifsFYI_read;
292 static write_proc_t cifsFYI_write;
293 static read_proc_t oplockEnabled_read;
294 static write_proc_t oplockEnabled_write;
295 static read_proc_t lookupFlag_read;
296 static write_proc_t lookupFlag_write;
297 static read_proc_t traceSMB_read;
298 static write_proc_t traceSMB_write;
299 static read_proc_t multiuser_mount_read;
300 static write_proc_t multiuser_mount_write;
301 static read_proc_t extended_security_read;
302 static write_proc_t extended_security_write;
303 static read_proc_t ntlmv2_enabled_read;
304 static write_proc_t ntlmv2_enabled_write;
305 static read_proc_t packet_signing_enabled_read;
306 static write_proc_t packet_signing_enabled_write;
307 static read_proc_t quotaEnabled_read;
308 static write_proc_t quotaEnabled_write;
309 static read_proc_t linuxExtensionsEnabled_read;
310 static write_proc_t linuxExtensionsEnabled_write;
311
312 void
313 cifs_proc_init(void)
314 {
315         struct proc_dir_entry *pde;
316
317         proc_fs_cifs = proc_mkdir("cifs", proc_root_fs);
318         if (proc_fs_cifs == NULL)
319                 return;
320
321         proc_fs_cifs->owner = THIS_MODULE;
322         create_proc_read_entry("DebugData", 0, proc_fs_cifs,
323                                 cifs_debug_data_read, NULL);
324
325 #ifdef CONFIG_CIFS_STATS
326         create_proc_read_entry("Stats", 0, proc_fs_cifs,
327                                 cifs_stats_read, NULL);
328 #endif
329         pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
330                                 cifsFYI_read, NULL);
331         if (pde)
332                 pde->write_proc = cifsFYI_write;
333
334         pde =
335             create_proc_read_entry("traceSMB", 0, proc_fs_cifs,
336                                 traceSMB_read, NULL);
337         if (pde)
338                 pde->write_proc = traceSMB_write;
339
340         pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs,
341                                 oplockEnabled_read, NULL);
342         if (pde)
343                 pde->write_proc = oplockEnabled_write;
344
345         pde = create_proc_read_entry("ReenableOldCifsReaddirCode", 0, proc_fs_cifs,
346                                 quotaEnabled_read, NULL);
347         if (pde)
348                 pde->write_proc = quotaEnabled_write;
349
350         pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
351                                 linuxExtensionsEnabled_read, NULL);
352         if (pde)
353                 pde->write_proc = linuxExtensionsEnabled_write;
354
355         pde =
356             create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
357                                 multiuser_mount_read, NULL);
358         if (pde)
359                 pde->write_proc = multiuser_mount_write;
360
361         pde =
362             create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs,
363                                 extended_security_read, NULL);
364         if (pde)
365                 pde->write_proc = extended_security_write;
366
367         pde =
368         create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
369                                 lookupFlag_read, NULL);
370         if (pde)
371                 pde->write_proc = lookupFlag_write;
372
373         pde =
374             create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
375                                 ntlmv2_enabled_read, NULL);
376         if (pde)
377                 pde->write_proc = ntlmv2_enabled_write;
378
379         pde =
380             create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
381                                 packet_signing_enabled_read, NULL);
382         if (pde)
383                 pde->write_proc = packet_signing_enabled_write;
384 }
385
386 void
387 cifs_proc_clean(void)
388 {
389         if (proc_fs_cifs == NULL)
390                 return;
391
392         remove_proc_entry("DebugData", proc_fs_cifs);
393         remove_proc_entry("cifsFYI", proc_fs_cifs);
394         remove_proc_entry("traceSMB", proc_fs_cifs);
395 #ifdef CONFIG_CIFS_STATS
396         remove_proc_entry("Stats", proc_fs_cifs);
397 #endif
398         remove_proc_entry("MultiuserMount", proc_fs_cifs);
399         remove_proc_entry("OplockEnabled", proc_fs_cifs);
400         remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
401         remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
402         remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
403         remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
404         remove_proc_entry("ReenableOldCifsReaddirCode",proc_fs_cifs);
405         remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
406         remove_proc_entry("cifs", proc_root_fs);
407 }
408
409 static int
410 cifsFYI_read(char *page, char **start, off_t off, int count,
411              int *eof, void *data)
412 {
413         int len;
414
415         len = sprintf(page, "%d\n", cifsFYI);
416
417         len -= off;
418         *start = page + off;
419
420         if (len > count)
421                 len = count;
422         else
423                 *eof = 1;
424
425         if (len < 0)
426                 len = 0;
427
428         return len;
429 }
430 static int
431 cifsFYI_write(struct file *file, const char __user *buffer,
432               unsigned long count, void *data)
433 {
434         char c;
435         int rc;
436
437         rc = get_user(c, buffer);
438         if (rc)
439                 return rc;
440         if (c == '0' || c == 'n' || c == 'N')
441                 cifsFYI = 0;
442         else if (c == '1' || c == 'y' || c == 'Y')
443                 cifsFYI = 1;
444
445         return count;
446 }
447
448 static int
449 oplockEnabled_read(char *page, char **start, off_t off,
450                    int count, int *eof, void *data)
451 {
452         int len;
453
454         len = sprintf(page, "%d\n", oplockEnabled);
455
456         len -= off;
457         *start = page + off;
458
459         if (len > count)
460                 len = count;
461         else
462                 *eof = 1;
463
464         if (len < 0)
465                 len = 0;
466
467         return len;
468 }
469 static int
470 oplockEnabled_write(struct file *file, const char __user *buffer,
471                     unsigned long count, void *data)
472 {
473         char c;
474         int rc;
475
476         rc = get_user(c, buffer);
477         if (rc)
478                 return rc;
479         if (c == '0' || c == 'n' || c == 'N')
480                 oplockEnabled = 0;
481         else if (c == '1' || c == 'y' || c == 'Y')
482                 oplockEnabled = 1;
483
484         return count;
485 }
486
487 static int
488 quotaEnabled_read(char *page, char **start, off_t off,
489                    int count, int *eof, void *data)
490 {
491         int len;
492
493         len = sprintf(page, "%d\n", experimEnabled);
494 /* could also check if quotas are enabled in kernel
495         as a whole first */
496         len -= off;
497         *start = page + off;
498
499         if (len > count)
500                 len = count;
501         else
502                 *eof = 1;
503
504         if (len < 0)
505                 len = 0;
506
507         return len;
508 }
509 static int
510 quotaEnabled_write(struct file *file, const char __user *buffer,
511                     unsigned long count, void *data)
512 {
513         char c;
514         int rc;
515
516         rc = get_user(c, buffer);
517         if (rc)
518                 return rc;
519         if (c == '0' || c == 'n' || c == 'N')
520                 experimEnabled = 0;
521         else if (c == '1' || c == 'y' || c == 'Y')
522                 experimEnabled = 1;
523
524         return count;
525 }
526
527 static int
528 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
529                    int count, int *eof, void *data)
530 {
531         int len;
532
533         len = sprintf(page, "%d\n", linuxExtEnabled);
534 /* could also check if quotas are enabled in kernel
535         as a whole first */
536         len -= off;
537         *start = page + off;
538
539         if (len > count)
540                 len = count;
541         else
542                 *eof = 1;
543
544         if (len < 0)
545                 len = 0;
546
547         return len;
548 }
549 static int
550 linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
551                     unsigned long count, void *data)
552 {
553         char c;
554         int rc;
555
556         rc = get_user(c, buffer);
557         if (rc)
558                 return rc;
559         if (c == '0' || c == 'n' || c == 'N')
560                 linuxExtEnabled = 0;
561         else if (c == '1' || c == 'y' || c == 'Y')
562                 linuxExtEnabled = 1;
563
564         return count;
565 }
566
567
568 static int
569 lookupFlag_read(char *page, char **start, off_t off,
570                    int count, int *eof, void *data)
571 {
572         int len;
573
574         len = sprintf(page, "%d\n", lookupCacheEnabled);
575
576         len -= off;
577         *start = page + off;
578
579         if (len > count)
580                 len = count;
581         else
582                 *eof = 1;
583
584         if (len < 0)
585                 len = 0;
586
587         return len;
588 }
589 static int
590 lookupFlag_write(struct file *file, const char __user *buffer,
591                     unsigned long count, void *data)
592 {
593         char c;
594         int rc;
595
596         rc = get_user(c, buffer);
597         if (rc)
598                 return rc;
599         if (c == '0' || c == 'n' || c == 'N')
600                 lookupCacheEnabled = 0;
601         else if (c == '1' || c == 'y' || c == 'Y')
602                 lookupCacheEnabled = 1;
603
604         return count;
605 }
606 static int
607 traceSMB_read(char *page, char **start, off_t off, int count,
608               int *eof, void *data)
609 {
610         int len;
611
612         len = sprintf(page, "%d\n", traceSMB);
613
614         len -= off;
615         *start = page + off;
616
617         if (len > count)
618                 len = count;
619         else
620                 *eof = 1;
621
622         if (len < 0)
623                 len = 0;
624
625         return len;
626 }
627 static int
628 traceSMB_write(struct file *file, const char __user *buffer,
629                unsigned long count, void *data)
630 {
631         char c;
632         int rc;
633
634         rc = get_user(c, buffer);
635         if (rc)
636                 return rc;
637         if (c == '0' || c == 'n' || c == 'N')
638                 traceSMB = 0;
639         else if (c == '1' || c == 'y' || c == 'Y')
640                 traceSMB = 1;
641
642         return count;
643 }
644
645 static int
646 multiuser_mount_read(char *page, char **start, off_t off,
647                      int count, int *eof, void *data)
648 {
649         int len;
650
651         len = sprintf(page, "%d\n", multiuser_mount);
652
653         len -= off;
654         *start = page + off;
655
656         if (len > count)
657                 len = count;
658         else
659                 *eof = 1;
660
661         if (len < 0)
662                 len = 0;
663
664         return len;
665 }
666 static int
667 multiuser_mount_write(struct file *file, const char __user *buffer,
668                       unsigned long count, void *data)
669 {
670         char c;
671         int rc;
672
673         rc = get_user(c, buffer);
674         if (rc)
675                 return rc;
676         if (c == '0' || c == 'n' || c == 'N')
677                 multiuser_mount = 0;
678         else if (c == '1' || c == 'y' || c == 'Y')
679                 multiuser_mount = 1;
680
681         return count;
682 }
683
684 static int
685 extended_security_read(char *page, char **start, off_t off,
686                        int count, int *eof, void *data)
687 {
688         int len;
689
690         len = sprintf(page, "%d\n", extended_security);
691
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 extended_security_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                 extended_security = 0;
717         else if (c == '1' || c == 'y' || c == 'Y')
718                 extended_security = 1;
719
720         return count;
721 }
722
723 static int
724 ntlmv2_enabled_read(char *page, char **start, off_t off,
725                        int count, int *eof, void *data)
726 {
727         int len;
728
729         len = sprintf(page, "%d\n", ntlmv2_support);
730
731         len -= off;
732         *start = page + off;
733
734         if (len > count)
735                 len = count;
736         else
737                 *eof = 1;
738
739         if (len < 0)
740                 len = 0;
741
742         return len;
743 }
744 static int
745 ntlmv2_enabled_write(struct file *file, const char __user *buffer,
746                         unsigned long count, void *data)
747 {
748         char c;
749         int rc;
750
751         rc = get_user(c, buffer);
752         if (rc)
753                 return rc;
754         if (c == '0' || c == 'n' || c == 'N')
755                 ntlmv2_support = 0;
756         else if (c == '1' || c == 'y' || c == 'Y')
757                 ntlmv2_support = 1;
758
759         return count;
760 }
761
762 static int
763 packet_signing_enabled_read(char *page, char **start, off_t off,
764                        int count, int *eof, void *data)
765 {
766         int len;
767
768         len = sprintf(page, "%d\n", sign_CIFS_PDUs);
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 packet_signing_enabled_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                 sign_CIFS_PDUs = 0;
795         else if (c == '1' || c == 'y' || c == 'Y')
796                 sign_CIFS_PDUs = 1;
797         else if (c == '2')
798                 sign_CIFS_PDUs = 2;
799
800         return count;
801 }
802
803
804 #endif