xref: /linux/fs/nfsd/debugfs.c (revision 75a9b40f3b14d1cc3771c463d32b71cf4e558246)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/debugfs.h>
4 
5 #include "nfsd.h"
6 
7 static struct dentry *nfsd_top_dir __read_mostly;
8 
9 /*
10  * /sys/kernel/debug/nfsd/disable-splice-read
11  *
12  * Contents:
13  *   %0: NFS READ is allowed to use page splicing
14  *   %1: NFS READ uses only iov iter read
15  *
16  * The default value of this setting is zero (page splicing is
17  * allowed). This setting takes immediate effect for all NFS
18  * versions, all exports, and in all NFSD net namespaces.
19  */
20 
21 static int nfsd_dsr_get(void *data, u64 *val)
22 {
23 	*val = nfsd_disable_splice_read ? 1 : 0;
24 	return 0;
25 }
26 
27 static int nfsd_dsr_set(void *data, u64 val)
28 {
29 	nfsd_disable_splice_read = (val > 0);
30 	if (!nfsd_disable_splice_read) {
31 		/*
32 		 * Must use buffered I/O if splice_read is enabled.
33 		 */
34 		nfsd_io_cache_read = NFSD_IO_BUFFERED;
35 	}
36 	return 0;
37 }
38 
39 DEFINE_DEBUGFS_ATTRIBUTE(nfsd_dsr_fops, nfsd_dsr_get, nfsd_dsr_set, "%llu\n");
40 
41 /*
42  * /sys/kernel/debug/nfsd/io_cache_read
43  *
44  * Contents:
45  *   %0: NFS READ will use buffered IO
46  *   %1: NFS READ will use dontcache (buffered IO w/ dropbehind)
47  *   %2: NFS READ will use direct IO
48  *
49  * This setting takes immediate effect for all NFS versions,
50  * all exports, and in all NFSD net namespaces.
51  */
52 
53 static int nfsd_io_cache_read_get(void *data, u64 *val)
54 {
55 	*val = nfsd_io_cache_read;
56 	return 0;
57 }
58 
59 static int nfsd_io_cache_read_set(void *data, u64 val)
60 {
61 	int ret = 0;
62 
63 	switch (val) {
64 	case NFSD_IO_BUFFERED:
65 		nfsd_io_cache_read = NFSD_IO_BUFFERED;
66 		break;
67 	case NFSD_IO_DONTCACHE:
68 	case NFSD_IO_DIRECT:
69 		/*
70 		 * Must disable splice_read when enabling
71 		 * NFSD_IO_DONTCACHE.
72 		 */
73 		nfsd_disable_splice_read = true;
74 		nfsd_io_cache_read = val;
75 		break;
76 	default:
77 		ret = -EINVAL;
78 		break;
79 	}
80 
81 	return ret;
82 }
83 
84 DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_read_fops, nfsd_io_cache_read_get,
85 			 nfsd_io_cache_read_set, "%llu\n");
86 
87 /*
88  * /sys/kernel/debug/nfsd/io_cache_write
89  *
90  * Contents:
91  *   %0: NFS WRITE will use buffered IO
92  *   %1: NFS WRITE will use dontcache (buffered IO w/ dropbehind)
93  *
94  * This setting takes immediate effect for all NFS versions,
95  * all exports, and in all NFSD net namespaces.
96  */
97 
98 static int nfsd_io_cache_write_get(void *data, u64 *val)
99 {
100 	*val = nfsd_io_cache_write;
101 	return 0;
102 }
103 
104 static int nfsd_io_cache_write_set(void *data, u64 val)
105 {
106 	int ret = 0;
107 
108 	switch (val) {
109 	case NFSD_IO_BUFFERED:
110 	case NFSD_IO_DONTCACHE:
111 		nfsd_io_cache_write = val;
112 		break;
113 	default:
114 		ret = -EINVAL;
115 		break;
116 	}
117 
118 	return ret;
119 }
120 
121 DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_write_fops, nfsd_io_cache_write_get,
122 			 nfsd_io_cache_write_set, "%llu\n");
123 
124 void nfsd_debugfs_exit(void)
125 {
126 	debugfs_remove_recursive(nfsd_top_dir);
127 	nfsd_top_dir = NULL;
128 }
129 
130 void nfsd_debugfs_init(void)
131 {
132 	nfsd_top_dir = debugfs_create_dir("nfsd", NULL);
133 
134 	debugfs_create_file("disable-splice-read", S_IWUSR | S_IRUGO,
135 			    nfsd_top_dir, NULL, &nfsd_dsr_fops);
136 
137 	debugfs_create_file("io_cache_read", 0644, nfsd_top_dir, NULL,
138 			    &nfsd_io_cache_read_fops);
139 
140 	debugfs_create_file("io_cache_write", 0644, nfsd_top_dir, NULL,
141 			    &nfsd_io_cache_write_fops);
142 }
143