aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/trace.h
diff options
context:
space:
mode:
authorJeff Layton <jeff.layton@primarydata.com>2019-08-18 14:18:48 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-08-19 11:00:39 -0400
commit65294c1f2c5e72b15b76e16c8c8cfd9359fc9f6f (patch)
tree9b088b0f2e2fba280862b489910b1aeb0460c8c3 /fs/nfsd/trace.h
parent7239a40ca8bfd88dc5d2f66a14882054fe8e3b92 (diff)
nfsd: add a new struct file caching facility to nfsd
Currently, NFSv2/3 reads and writes have to open a file, do the read or write and then close it again for each RPC. This is highly inefficient, especially when the underlying filesystem has a relatively slow open routine. This patch adds a new open file cache to knfsd. Rather than doing an open for each RPC, the read/write handlers can call into this cache to see if there is one already there for the correct filehandle and NFS_MAY_READ/WRITE flags. If there isn't an entry, then we create a new one and attempt to perform the open. If there is, then we wait until the entry is fully instantiated and return it if it is at the end of the wait. If it's not, then we attempt to take over construction. Since the main goal is to speed up NFSv2/3 I/O, we don't want to close these files on last put of these objects. We need to keep them around for a little while since we never know when the next READ/WRITE will come in. Cache entries have a hardcoded 1s timeout, and we have a recurring workqueue job that walks the cache and purges any entries that have expired. Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> Signed-off-by: Weston Andros Adamson <dros@primarydata.com> Signed-off-by: Richard Sharpe <richard.sharpe@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/trace.h')
-rw-r--r--fs/nfsd/trace.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 80933e4334d8..ffc78a0e28b2 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -126,6 +126,8 @@ DEFINE_NFSD_ERR_EVENT(read_err);
126DEFINE_NFSD_ERR_EVENT(write_err); 126DEFINE_NFSD_ERR_EVENT(write_err);
127 127
128#include "state.h" 128#include "state.h"
129#include "filecache.h"
130#include "vfs.h"
129 131
130DECLARE_EVENT_CLASS(nfsd_stateid_class, 132DECLARE_EVENT_CLASS(nfsd_stateid_class,
131 TP_PROTO(stateid_t *stp), 133 TP_PROTO(stateid_t *stp),
@@ -164,6 +166,144 @@ DEFINE_STATEID_EVENT(layout_recall_done);
164DEFINE_STATEID_EVENT(layout_recall_fail); 166DEFINE_STATEID_EVENT(layout_recall_fail);
165DEFINE_STATEID_EVENT(layout_recall_release); 167DEFINE_STATEID_EVENT(layout_recall_release);
166 168
169#define show_nf_flags(val) \
170 __print_flags(val, "|", \
171 { 1 << NFSD_FILE_HASHED, "HASHED" }, \
172 { 1 << NFSD_FILE_PENDING, "PENDING" }, \
173 { 1 << NFSD_FILE_BREAK_READ, "BREAK_READ" }, \
174 { 1 << NFSD_FILE_BREAK_WRITE, "BREAK_WRITE" }, \
175 { 1 << NFSD_FILE_REFERENCED, "REFERENCED"})
176
177/* FIXME: This should probably be fleshed out in the future. */
178#define show_nf_may(val) \
179 __print_flags(val, "|", \
180 { NFSD_MAY_READ, "READ" }, \
181 { NFSD_MAY_WRITE, "WRITE" }, \
182 { NFSD_MAY_NOT_BREAK_LEASE, "NOT_BREAK_LEASE" })
183
184DECLARE_EVENT_CLASS(nfsd_file_class,
185 TP_PROTO(struct nfsd_file *nf),
186 TP_ARGS(nf),
187 TP_STRUCT__entry(
188 __field(unsigned int, nf_hashval)
189 __field(void *, nf_inode)
190 __field(int, nf_ref)
191 __field(unsigned long, nf_flags)
192 __field(unsigned char, nf_may)
193 __field(struct file *, nf_file)
194 ),
195 TP_fast_assign(
196 __entry->nf_hashval = nf->nf_hashval;
197 __entry->nf_inode = nf->nf_inode;
198 __entry->nf_ref = atomic_read(&nf->nf_ref);
199 __entry->nf_flags = nf->nf_flags;
200 __entry->nf_may = nf->nf_may;
201 __entry->nf_file = nf->nf_file;
202 ),
203 TP_printk("hash=0x%x inode=0x%p ref=%d flags=%s may=%s file=%p",
204 __entry->nf_hashval,
205 __entry->nf_inode,
206 __entry->nf_ref,
207 show_nf_flags(__entry->nf_flags),
208 show_nf_may(__entry->nf_may),
209 __entry->nf_file)
210)
211
212#define DEFINE_NFSD_FILE_EVENT(name) \
213DEFINE_EVENT(nfsd_file_class, name, \
214 TP_PROTO(struct nfsd_file *nf), \
215 TP_ARGS(nf))
216
217DEFINE_NFSD_FILE_EVENT(nfsd_file_alloc);
218DEFINE_NFSD_FILE_EVENT(nfsd_file_put_final);
219DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash);
220DEFINE_NFSD_FILE_EVENT(nfsd_file_put);
221DEFINE_NFSD_FILE_EVENT(nfsd_file_unhash_and_release_locked);
222
223TRACE_EVENT(nfsd_file_acquire,
224 TP_PROTO(struct svc_rqst *rqstp, unsigned int hash,
225 struct inode *inode, unsigned int may_flags,
226 struct nfsd_file *nf, __be32 status),
227
228 TP_ARGS(rqstp, hash, inode, may_flags, nf, status),
229
230 TP_STRUCT__entry(
231 __field(__be32, xid)
232 __field(unsigned int, hash)
233 __field(void *, inode)
234 __field(unsigned int, may_flags)
235 __field(int, nf_ref)
236 __field(unsigned long, nf_flags)
237 __field(unsigned char, nf_may)
238 __field(struct file *, nf_file)
239 __field(__be32, status)
240 ),
241
242 TP_fast_assign(
243 __entry->xid = rqstp->rq_xid;
244 __entry->hash = hash;
245 __entry->inode = inode;
246 __entry->may_flags = may_flags;
247 __entry->nf_ref = nf ? atomic_read(&nf->nf_ref) : 0;
248 __entry->nf_flags = nf ? nf->nf_flags : 0;
249 __entry->nf_may = nf ? nf->nf_may : 0;
250 __entry->nf_file = nf ? nf->nf_file : NULL;
251 __entry->status = status;
252 ),
253
254 TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
255 be32_to_cpu(__entry->xid), __entry->hash, __entry->inode,
256 show_nf_may(__entry->may_flags), __entry->nf_ref,
257 show_nf_flags(__entry->nf_flags),
258 show_nf_may(__entry->nf_may), __entry->nf_file,
259 be32_to_cpu(__entry->status))
260);
261
262DECLARE_EVENT_CLASS(nfsd_file_search_class,
263 TP_PROTO(struct inode *inode, unsigned int hash, int found),
264 TP_ARGS(inode, hash, found),
265 TP_STRUCT__entry(
266 __field(struct inode *, inode)
267 __field(unsigned int, hash)
268 __field(int, found)
269 ),
270 TP_fast_assign(
271 __entry->inode = inode;
272 __entry->hash = hash;
273 __entry->found = found;
274 ),
275 TP_printk("hash=0x%x inode=0x%p found=%d", __entry->hash,
276 __entry->inode, __entry->found)
277);
278
279#define DEFINE_NFSD_FILE_SEARCH_EVENT(name) \
280DEFINE_EVENT(nfsd_file_search_class, name, \
281 TP_PROTO(struct inode *inode, unsigned int hash, int found), \
282 TP_ARGS(inode, hash, found))
283
284DEFINE_NFSD_FILE_SEARCH_EVENT(nfsd_file_close_inode_sync);
285DEFINE_NFSD_FILE_SEARCH_EVENT(nfsd_file_close_inode);
286DEFINE_NFSD_FILE_SEARCH_EVENT(nfsd_file_is_cached);
287
288TRACE_EVENT(nfsd_file_fsnotify_handle_event,
289 TP_PROTO(struct inode *inode, u32 mask),
290 TP_ARGS(inode, mask),
291 TP_STRUCT__entry(
292 __field(struct inode *, inode)
293 __field(unsigned int, nlink)
294 __field(umode_t, mode)
295 __field(u32, mask)
296 ),
297 TP_fast_assign(
298 __entry->inode = inode;
299 __entry->nlink = inode->i_nlink;
300 __entry->mode = inode->i_mode;
301 __entry->mask = mask;
302 ),
303 TP_printk("inode=0x%p nlink=%u mode=0%ho mask=0x%x", __entry->inode,
304 __entry->nlink, __entry->mode, __entry->mask)
305);
306
167#endif /* _NFSD_TRACE_H */ 307#endif /* _NFSD_TRACE_H */
168 308
169#undef TRACE_INCLUDE_PATH 309#undef TRACE_INCLUDE_PATH