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