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