blob: bff2ec6e054adbc83c37c4befe9c22d8d68cc919 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * fs/cifs_debug.c
3 *
Steve Frenchb8643e12005-04-28 22:41:07 -07004 * Copyright (C) International Business Machines Corp., 2000,2005
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
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"
Steve French6c91d362005-04-28 22:41:06 -070032#include "cifsfs.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34void
35cifs_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
61static int
62cifs_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;
Steve French6c91d362005-04-28 22:41:06 -070082 length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
83 buf += length;
84 length = sprintf(buf, "Servers:");
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 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",
Steve Frenchb8643e12005-04-28 22:41:07 -070095 i, ses->serverName, ses->serverDomain,
96 atomic_read(&ses->inUse),
97 ses->serverOS, ses->serverNOS,
98 ses->capabilities,ses->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 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
Steve French6c91d362005-04-28 22:41:06 -0700107 length = sprintf(buf, "\nMIDs:\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 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) {
Steve French848f3fc2005-04-28 22:41:07 -0700116 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 buf += length;
123 }
124 }
125 spin_unlock(&GlobalMid_Lock);
126 }
127
128 }
129 read_unlock(&GlobalSMBSeslock);
130 sprintf(buf, "\n");
131 buf++;
132
Steve French6c91d362005-04-28 22:41:06 -0700133 length = sprintf(buf, "Shares:");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 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
191static int
192cifs_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",
Steve Frenchb8643e12005-04-28 22:41:07 -0700212 bufAllocCount.counter,
213 cifs_min_rcv + tcpSesAllocCount.counter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 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
300static struct proc_dir_entry *proc_fs_cifs;
301read_proc_t cifs_txanchor_read;
302static read_proc_t cifsFYI_read;
303static write_proc_t cifsFYI_write;
304static read_proc_t oplockEnabled_read;
305static write_proc_t oplockEnabled_write;
306static read_proc_t lookupFlag_read;
307static write_proc_t lookupFlag_write;
308static read_proc_t traceSMB_read;
309static write_proc_t traceSMB_write;
310static read_proc_t multiuser_mount_read;
311static write_proc_t multiuser_mount_write;
312static read_proc_t extended_security_read;
313static write_proc_t extended_security_write;
314static read_proc_t ntlmv2_enabled_read;
315static write_proc_t ntlmv2_enabled_write;
316static read_proc_t packet_signing_enabled_read;
317static write_proc_t packet_signing_enabled_write;
318static read_proc_t quotaEnabled_read;
319static write_proc_t quotaEnabled_write;
320static read_proc_t linuxExtensionsEnabled_read;
321static write_proc_t linuxExtensionsEnabled_write;
322
323void
324cifs_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
397void
398cifs_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
420static int
421cifsFYI_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}
441static int
442cifsFYI_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
459static int
460oplockEnabled_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}
480static int
481oplockEnabled_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
498static int
499quotaEnabled_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}
520static int
521quotaEnabled_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
538static int
539linuxExtensionsEnabled_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}
560static int
561linuxExtensionsEnabled_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
579static int
580lookupFlag_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}
600static int
601lookupFlag_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}
617static int
618traceSMB_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}
638static int
639traceSMB_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
656static int
657multiuser_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}
677static int
678multiuser_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
695static int
696extended_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}
716static int
717extended_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
734static int
735ntlmv2_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}
755static int
756ntlmv2_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
773static int
774packet_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}
794static int
795packet_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