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