Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * linux/fs/nfs/direct.c
4 : : *
5 : : * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
6 : : *
7 : : * High-performance uncached I/O for the Linux NFS client
8 : : *
9 : : * There are important applications whose performance or correctness
10 : : * depends on uncached access to file data. Database clusters
11 : : * (multiple copies of the same instance running on separate hosts)
12 : : * implement their own cache coherency protocol that subsumes file
13 : : * system cache protocols. Applications that process datasets
14 : : * considerably larger than the client's memory do not always benefit
15 : : * from a local cache. A streaming video server, for instance, has no
16 : : * need to cache the contents of a file.
17 : : *
18 : : * When an application requests uncached I/O, all read and write requests
19 : : * are made directly to the server; data stored or fetched via these
20 : : * requests is not cached in the Linux page cache. The client does not
21 : : * correct unaligned requests from applications. All requested bytes are
22 : : * held on permanent storage before a direct write system call returns to
23 : : * an application.
24 : : *
25 : : * Solaris implements an uncached I/O facility called directio() that
26 : : * is used for backups and sequential I/O to very large files. Solaris
27 : : * also supports uncaching whole NFS partitions with "-o forcedirectio,"
28 : : * an undocumented mount option.
29 : : *
30 : : * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust, with
31 : : * help from Andrew Morton.
32 : : *
33 : : * 18 Dec 2001 Initial implementation for 2.4 --cel
34 : : * 08 Jul 2002 Version for 2.4.19, with bug fixes --trondmy
35 : : * 08 Jun 2003 Port to 2.5 APIs --cel
36 : : * 31 Mar 2004 Handle direct I/O without VFS support --cel
37 : : * 15 Sep 2004 Parallel async reads --cel
38 : : * 04 May 2005 support O_DIRECT with aio --cel
39 : : *
40 : : */
41 : :
42 : : #include <linux/errno.h>
43 : : #include <linux/sched.h>
44 : : #include <linux/kernel.h>
45 : : #include <linux/file.h>
46 : : #include <linux/pagemap.h>
47 : : #include <linux/kref.h>
48 : : #include <linux/slab.h>
49 : : #include <linux/task_io_accounting_ops.h>
50 : : #include <linux/module.h>
51 : :
52 : : #include <linux/nfs_fs.h>
53 : : #include <linux/nfs_page.h>
54 : : #include <linux/sunrpc/clnt.h>
55 : :
56 : : #include <linux/uaccess.h>
57 : : #include <linux/atomic.h>
58 : :
59 : : #include "internal.h"
60 : : #include "iostat.h"
61 : : #include "pnfs.h"
62 : :
63 : : #define NFSDBG_FACILITY NFSDBG_VFS
64 : :
65 : : static struct kmem_cache *nfs_direct_cachep;
66 : :
67 : : struct nfs_direct_req {
68 : : struct kref kref; /* release manager */
69 : :
70 : : /* I/O parameters */
71 : : struct nfs_open_context *ctx; /* file open context info */
72 : : struct nfs_lock_context *l_ctx; /* Lock context info */
73 : : struct kiocb * iocb; /* controlling i/o request */
74 : : struct inode * inode; /* target file of i/o */
75 : :
76 : : /* completion state */
77 : : atomic_t io_count; /* i/os we're waiting for */
78 : : spinlock_t lock; /* protect completion state */
79 : :
80 : : loff_t io_start; /* Start offset for I/O */
81 : : ssize_t count, /* bytes actually processed */
82 : : max_count, /* max expected count */
83 : : bytes_left, /* bytes left to be sent */
84 : : error; /* any reported error */
85 : : struct completion completion; /* wait for i/o completion */
86 : :
87 : : /* commit state */
88 : : struct nfs_mds_commit_info mds_cinfo; /* Storage for cinfo */
89 : : struct pnfs_ds_commit_info ds_cinfo; /* Storage for cinfo */
90 : : struct work_struct work;
91 : : int flags;
92 : : /* for write */
93 : : #define NFS_ODIRECT_DO_COMMIT (1) /* an unstable reply was received */
94 : : #define NFS_ODIRECT_RESCHED_WRITES (2) /* write verification failed */
95 : : /* for read */
96 : : #define NFS_ODIRECT_SHOULD_DIRTY (3) /* dirty user-space page after read */
97 : : struct nfs_writeverf verf; /* unstable write verifier */
98 : : };
99 : :
100 : : static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops;
101 : : static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops;
102 : : static void nfs_direct_write_complete(struct nfs_direct_req *dreq);
103 : : static void nfs_direct_write_schedule_work(struct work_struct *work);
104 : :
105 : 0 : static inline void get_dreq(struct nfs_direct_req *dreq)
106 : : {
107 : 0 : atomic_inc(&dreq->io_count);
108 : : }
109 : :
110 : 0 : static inline int put_dreq(struct nfs_direct_req *dreq)
111 : : {
112 : 0 : return atomic_dec_and_test(&dreq->io_count);
113 : : }
114 : :
115 : : static void
116 : 0 : nfs_direct_handle_truncated(struct nfs_direct_req *dreq,
117 : : const struct nfs_pgio_header *hdr,
118 : : ssize_t dreq_len)
119 : : {
120 [ # # # # ]: 0 : if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) ||
121 : : test_bit(NFS_IOHDR_EOF, &hdr->flags)))
122 : : return;
123 [ # # ]: 0 : if (dreq->max_count >= dreq_len) {
124 : 0 : dreq->max_count = dreq_len;
125 [ # # ]: 0 : if (dreq->count > dreq_len)
126 : 0 : dreq->count = dreq_len;
127 : :
128 [ # # ]: 0 : if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
129 : 0 : dreq->error = hdr->error;
130 : : else /* Clear outstanding error if this is EOF */
131 : 0 : dreq->error = 0;
132 : : }
133 : : }
134 : :
135 : : static void
136 : 0 : nfs_direct_count_bytes(struct nfs_direct_req *dreq,
137 : : const struct nfs_pgio_header *hdr)
138 : : {
139 : 0 : loff_t hdr_end = hdr->io_start + hdr->good_bytes;
140 : 0 : ssize_t dreq_len = 0;
141 : :
142 [ # # ]: 0 : if (hdr_end > dreq->io_start)
143 : 0 : dreq_len = hdr_end - dreq->io_start;
144 : :
145 : 0 : nfs_direct_handle_truncated(dreq, hdr, dreq_len);
146 : :
147 : 0 : if (dreq_len > dreq->max_count)
148 : : dreq_len = dreq->max_count;
149 : :
150 [ # # ]: 0 : if (dreq->count < dreq_len)
151 : 0 : dreq->count = dreq_len;
152 : 0 : }
153 : :
154 : : /*
155 : : * nfs_direct_select_verf - select the right verifier
156 : : * @dreq - direct request possibly spanning multiple servers
157 : : * @ds_clp - nfs_client of data server or NULL if MDS / non-pnfs
158 : : * @commit_idx - commit bucket index for the DS
159 : : *
160 : : * returns the correct verifier to use given the role of the server
161 : : */
162 : : static struct nfs_writeverf *
163 : 0 : nfs_direct_select_verf(struct nfs_direct_req *dreq,
164 : : struct nfs_client *ds_clp,
165 : : int commit_idx)
166 : : {
167 : 0 : struct nfs_writeverf *verfp = &dreq->verf;
168 : :
169 : : #ifdef CONFIG_NFS_V4_1
170 : : /*
171 : : * pNFS is in use, use the DS verf except commit_through_mds is set
172 : : * for layout segment where nbuckets is zero.
173 : : */
174 : : if (ds_clp && dreq->ds_cinfo.nbuckets > 0) {
175 : : if (commit_idx >= 0 && commit_idx < dreq->ds_cinfo.nbuckets)
176 : : verfp = &dreq->ds_cinfo.buckets[commit_idx].direct_verf;
177 : : else
178 : : WARN_ON_ONCE(1);
179 : : }
180 : : #endif
181 : 0 : return verfp;
182 : : }
183 : :
184 : :
185 : : /*
186 : : * nfs_direct_set_hdr_verf - set the write/commit verifier
187 : : * @dreq - direct request possibly spanning multiple servers
188 : : * @hdr - pageio header to validate against previously seen verfs
189 : : *
190 : : * Set the server's (MDS or DS) "seen" verifier
191 : : */
192 : 0 : static void nfs_direct_set_hdr_verf(struct nfs_direct_req *dreq,
193 : : struct nfs_pgio_header *hdr)
194 : : {
195 : 0 : struct nfs_writeverf *verfp;
196 : :
197 : 0 : verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx);
198 [ # # ]: 0 : WARN_ON_ONCE(verfp->committed >= 0);
199 : 0 : memcpy(verfp, &hdr->verf, sizeof(struct nfs_writeverf));
200 [ # # ]: 0 : WARN_ON_ONCE(verfp->committed < 0);
201 : 0 : }
202 : :
203 : 0 : static int nfs_direct_cmp_verf(const struct nfs_writeverf *v1,
204 : : const struct nfs_writeverf *v2)
205 : : {
206 : 0 : return nfs_write_verifier_cmp(&v1->verifier, &v2->verifier);
207 : : }
208 : :
209 : : /*
210 : : * nfs_direct_cmp_hdr_verf - compare verifier for pgio header
211 : : * @dreq - direct request possibly spanning multiple servers
212 : : * @hdr - pageio header to validate against previously seen verf
213 : : *
214 : : * set the server's "seen" verf if not initialized.
215 : : * returns result of comparison between @hdr->verf and the "seen"
216 : : * verf of the server used by @hdr (DS or MDS)
217 : : */
218 : 0 : static int nfs_direct_set_or_cmp_hdr_verf(struct nfs_direct_req *dreq,
219 : : struct nfs_pgio_header *hdr)
220 : : {
221 : 0 : struct nfs_writeverf *verfp;
222 : :
223 : 0 : verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx);
224 [ # # ]: 0 : if (verfp->committed < 0) {
225 : 0 : nfs_direct_set_hdr_verf(dreq, hdr);
226 : 0 : return 0;
227 : : }
228 : 0 : return nfs_direct_cmp_verf(verfp, &hdr->verf);
229 : : }
230 : :
231 : : /*
232 : : * nfs_direct_cmp_commit_data_verf - compare verifier for commit data
233 : : * @dreq - direct request possibly spanning multiple servers
234 : : * @data - commit data to validate against previously seen verf
235 : : *
236 : : * returns result of comparison between @data->verf and the verf of
237 : : * the server used by @data (DS or MDS)
238 : : */
239 : 0 : static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq,
240 : : struct nfs_commit_data *data)
241 : : {
242 : 0 : struct nfs_writeverf *verfp;
243 : :
244 : 0 : verfp = nfs_direct_select_verf(dreq, data->ds_clp,
245 : : data->ds_commit_index);
246 : :
247 : : /* verifier not set so always fail */
248 [ # # # # ]: 0 : if (verfp->committed < 0 || data->res.verf->committed <= NFS_UNSTABLE)
249 : : return 1;
250 : :
251 [ # # ]: 0 : return nfs_direct_cmp_verf(verfp, data->res.verf);
252 : : }
253 : :
254 : : /**
255 : : * nfs_direct_IO - NFS address space operation for direct I/O
256 : : * @iocb: target I/O control block
257 : : * @iter: I/O buffer
258 : : *
259 : : * The presence of this routine in the address space ops vector means
260 : : * the NFS client supports direct I/O. However, for most direct IO, we
261 : : * shunt off direct read and write requests before the VFS gets them,
262 : : * so this method is only ever called for swap.
263 : : */
264 : 0 : ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
265 : : {
266 : 0 : struct inode *inode = iocb->ki_filp->f_mapping->host;
267 : :
268 : : /* we only support swap file calling nfs_direct_IO */
269 [ # # ]: 0 : if (!IS_SWAPFILE(inode))
270 : : return 0;
271 : :
272 : 0 : VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
273 : :
274 [ # # ]: 0 : if (iov_iter_rw(iter) == READ)
275 : 0 : return nfs_file_direct_read(iocb, iter);
276 : 0 : return nfs_file_direct_write(iocb, iter);
277 : : }
278 : :
279 : 0 : static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
280 : : {
281 : 0 : unsigned int i;
282 [ # # # # ]: 0 : for (i = 0; i < npages; i++)
283 : 0 : put_page(pages[i]);
284 : : }
285 : :
286 : 0 : void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
287 : : struct nfs_direct_req *dreq)
288 : : {
289 : 0 : cinfo->inode = dreq->inode;
290 : 0 : cinfo->mds = &dreq->mds_cinfo;
291 : 0 : cinfo->ds = &dreq->ds_cinfo;
292 : 0 : cinfo->dreq = dreq;
293 : 0 : cinfo->completion_ops = &nfs_direct_commit_completion_ops;
294 : 0 : }
295 : :
296 : 0 : static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
297 : : {
298 : 0 : struct nfs_direct_req *dreq;
299 : :
300 : 0 : dreq = kmem_cache_zalloc(nfs_direct_cachep, GFP_KERNEL);
301 [ # # ]: 0 : if (!dreq)
302 : : return NULL;
303 : :
304 : 0 : kref_init(&dreq->kref);
305 : 0 : kref_get(&dreq->kref);
306 : 0 : init_completion(&dreq->completion);
307 : 0 : INIT_LIST_HEAD(&dreq->mds_cinfo.list);
308 : 0 : dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */
309 : 0 : INIT_WORK(&dreq->work, nfs_direct_write_schedule_work);
310 : 0 : spin_lock_init(&dreq->lock);
311 : :
312 : 0 : return dreq;
313 : : }
314 : :
315 : 0 : static void nfs_direct_req_free(struct kref *kref)
316 : : {
317 : 0 : struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
318 : :
319 [ # # ]: 0 : nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo);
320 [ # # ]: 0 : if (dreq->l_ctx != NULL)
321 : 0 : nfs_put_lock_context(dreq->l_ctx);
322 [ # # ]: 0 : if (dreq->ctx != NULL)
323 : 0 : put_nfs_open_context(dreq->ctx);
324 : 0 : kmem_cache_free(nfs_direct_cachep, dreq);
325 : 0 : }
326 : :
327 : 0 : static void nfs_direct_req_release(struct nfs_direct_req *dreq)
328 : : {
329 : 0 : kref_put(&dreq->kref, nfs_direct_req_free);
330 : 0 : }
331 : :
332 : 0 : ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq)
333 : : {
334 : 0 : return dreq->bytes_left;
335 : : }
336 : : EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left);
337 : :
338 : : /*
339 : : * Collects and returns the final error value/byte-count.
340 : : */
341 : 0 : static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
342 : : {
343 : 0 : ssize_t result = -EIOCBQUEUED;
344 : :
345 : : /* Async requests don't wait here */
346 [ # # ]: 0 : if (dreq->iocb)
347 : 0 : goto out;
348 : :
349 : 0 : result = wait_for_completion_killable(&dreq->completion);
350 : :
351 [ # # ]: 0 : if (!result) {
352 : 0 : result = dreq->count;
353 [ # # ]: 0 : WARN_ON_ONCE(dreq->count < 0);
354 : : }
355 [ # # ]: 0 : if (!result)
356 : 0 : result = dreq->error;
357 : :
358 : 0 : out:
359 : 0 : return (ssize_t) result;
360 : : }
361 : :
362 : : /*
363 : : * Synchronous I/O uses a stack-allocated iocb. Thus we can't trust
364 : : * the iocb is still valid here if this is a synchronous request.
365 : : */
366 : 0 : static void nfs_direct_complete(struct nfs_direct_req *dreq)
367 : : {
368 : 0 : struct inode *inode = dreq->inode;
369 : :
370 : 0 : inode_dio_end(inode);
371 : :
372 [ # # ]: 0 : if (dreq->iocb) {
373 : 0 : long res = (long) dreq->error;
374 [ # # ]: 0 : if (dreq->count != 0) {
375 : 0 : res = (long) dreq->count;
376 [ # # ]: 0 : WARN_ON_ONCE(dreq->count < 0);
377 : : }
378 : 0 : dreq->iocb->ki_complete(dreq->iocb, res, 0);
379 : : }
380 : :
381 : 0 : complete(&dreq->completion);
382 : :
383 : 0 : nfs_direct_req_release(dreq);
384 : 0 : }
385 : :
386 : 0 : static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
387 : : {
388 : 0 : unsigned long bytes = 0;
389 : 0 : struct nfs_direct_req *dreq = hdr->dreq;
390 : :
391 : 0 : spin_lock(&dreq->lock);
392 [ # # ]: 0 : if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
393 : 0 : spin_unlock(&dreq->lock);
394 : 0 : goto out_put;
395 : : }
396 : :
397 : 0 : nfs_direct_count_bytes(dreq, hdr);
398 : 0 : spin_unlock(&dreq->lock);
399 : :
400 [ # # ]: 0 : while (!list_empty(&hdr->pages)) {
401 : 0 : struct nfs_page *req = nfs_list_entry(hdr->pages.next);
402 : 0 : struct page *page = req->wb_page;
403 : :
404 [ # # # # ]: 0 : if (!PageCompound(page) && bytes < hdr->good_bytes &&
405 [ # # ]: 0 : (dreq->flags == NFS_ODIRECT_SHOULD_DIRTY))
406 : 0 : set_page_dirty(page);
407 : 0 : bytes += req->wb_bytes;
408 [ # # ]: 0 : nfs_list_remove_request(req);
409 : 0 : nfs_release_request(req);
410 : : }
411 : 0 : out_put:
412 [ # # ]: 0 : if (put_dreq(dreq))
413 : 0 : nfs_direct_complete(dreq);
414 : 0 : hdr->release(hdr);
415 : 0 : }
416 : :
417 : 0 : static void nfs_read_sync_pgio_error(struct list_head *head, int error)
418 : : {
419 : 0 : struct nfs_page *req;
420 : :
421 [ # # ]: 0 : while (!list_empty(head)) {
422 [ # # ]: 0 : req = nfs_list_entry(head->next);
423 [ # # ]: 0 : nfs_list_remove_request(req);
424 : 0 : nfs_release_request(req);
425 : : }
426 : 0 : }
427 : :
428 : 0 : static void nfs_direct_pgio_init(struct nfs_pgio_header *hdr)
429 : : {
430 : 0 : get_dreq(hdr->dreq);
431 : 0 : }
432 : :
433 : : static const struct nfs_pgio_completion_ops nfs_direct_read_completion_ops = {
434 : : .error_cleanup = nfs_read_sync_pgio_error,
435 : : .init_hdr = nfs_direct_pgio_init,
436 : : .completion = nfs_direct_read_completion,
437 : : };
438 : :
439 : : /*
440 : : * For each rsize'd chunk of the user's buffer, dispatch an NFS READ
441 : : * operation. If nfs_readdata_alloc() or get_user_pages() fails,
442 : : * bail and stop sending more reads. Read length accounting is
443 : : * handled automatically by nfs_direct_read_result(). Otherwise, if
444 : : * no requests have been sent, just return an error.
445 : : */
446 : :
447 : 0 : static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
448 : : struct iov_iter *iter,
449 : : loff_t pos)
450 : : {
451 : 0 : struct nfs_pageio_descriptor desc;
452 : 0 : struct inode *inode = dreq->inode;
453 : 0 : ssize_t result = -EINVAL;
454 : 0 : size_t requested_bytes = 0;
455 : 0 : size_t rsize = max_t(size_t, NFS_SERVER(inode)->rsize, PAGE_SIZE);
456 : :
457 : 0 : nfs_pageio_init_read(&desc, dreq->inode, false,
458 : : &nfs_direct_read_completion_ops);
459 : 0 : get_dreq(dreq);
460 : 0 : desc.pg_dreq = dreq;
461 : 0 : inode_dio_begin(inode);
462 : :
463 [ # # ]: 0 : while (iov_iter_count(iter)) {
464 : 0 : struct page **pagevec;
465 : 0 : size_t bytes;
466 : 0 : size_t pgbase;
467 : 0 : unsigned npages, i;
468 : :
469 : 0 : result = iov_iter_get_pages_alloc(iter, &pagevec,
470 : : rsize, &pgbase);
471 [ # # ]: 0 : if (result < 0)
472 : : break;
473 : :
474 : 0 : bytes = result;
475 : 0 : iov_iter_advance(iter, bytes);
476 : 0 : npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
477 [ # # ]: 0 : for (i = 0; i < npages; i++) {
478 : 0 : struct nfs_page *req;
479 : 0 : unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
480 : : /* XXX do we need to do the eof zeroing found in async_filler? */
481 : 0 : req = nfs_create_request(dreq->ctx, pagevec[i],
482 : : pgbase, req_len);
483 [ # # ]: 0 : if (IS_ERR(req)) {
484 : 0 : result = PTR_ERR(req);
485 : 0 : break;
486 : : }
487 : 0 : req->wb_index = pos >> PAGE_SHIFT;
488 : 0 : req->wb_offset = pos & ~PAGE_MASK;
489 [ # # ]: 0 : if (!nfs_pageio_add_request(&desc, req)) {
490 : 0 : result = desc.pg_error;
491 : 0 : nfs_release_request(req);
492 : 0 : break;
493 : : }
494 : 0 : pgbase = 0;
495 : 0 : bytes -= req_len;
496 : 0 : requested_bytes += req_len;
497 : 0 : pos += req_len;
498 : 0 : dreq->bytes_left -= req_len;
499 : : }
500 : 0 : nfs_direct_release_pages(pagevec, npages);
501 : 0 : kvfree(pagevec);
502 [ # # ]: 0 : if (result < 0)
503 : : break;
504 : : }
505 : :
506 : 0 : nfs_pageio_complete(&desc);
507 : :
508 : : /*
509 : : * If no bytes were started, return the error, and let the
510 : : * generic layer handle the completion.
511 : : */
512 [ # # ]: 0 : if (requested_bytes == 0) {
513 : 0 : inode_dio_end(inode);
514 : 0 : nfs_direct_req_release(dreq);
515 [ # # ]: 0 : return result < 0 ? result : -EIO;
516 : : }
517 : :
518 [ # # ]: 0 : if (put_dreq(dreq))
519 : 0 : nfs_direct_complete(dreq);
520 : 0 : return requested_bytes;
521 : : }
522 : :
523 : : /**
524 : : * nfs_file_direct_read - file direct read operation for NFS files
525 : : * @iocb: target I/O control block
526 : : * @iter: vector of user buffers into which to read data
527 : : *
528 : : * We use this function for direct reads instead of calling
529 : : * generic_file_aio_read() in order to avoid gfar's check to see if
530 : : * the request starts before the end of the file. For that check
531 : : * to work, we must generate a GETATTR before each direct read, and
532 : : * even then there is a window between the GETATTR and the subsequent
533 : : * READ where the file size could change. Our preference is simply
534 : : * to do all reads the application wants, and the server will take
535 : : * care of managing the end of file boundary.
536 : : *
537 : : * This function also eliminates unnecessarily updating the file's
538 : : * atime locally, as the NFS server sets the file's atime, and this
539 : : * client must read the updated atime from the server back into its
540 : : * cache.
541 : : */
542 : 0 : ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
543 : : {
544 : 0 : struct file *file = iocb->ki_filp;
545 : 0 : struct address_space *mapping = file->f_mapping;
546 : 0 : struct inode *inode = mapping->host;
547 : 0 : struct nfs_direct_req *dreq;
548 : 0 : struct nfs_lock_context *l_ctx;
549 : 0 : ssize_t result = -EINVAL, requested;
550 [ # # ]: 0 : size_t count = iov_iter_count(iter);
551 [ # # ]: 0 : nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
552 : :
553 : 0 : dfprintk(FILE, "NFS: direct read(%pD2, %zd@%Ld)\n",
554 : : file, count, (long long) iocb->ki_pos);
555 : :
556 : 0 : result = 0;
557 [ # # ]: 0 : if (!count)
558 : 0 : goto out;
559 : :
560 : 0 : task_io_account_read(count);
561 : :
562 : 0 : result = -ENOMEM;
563 : 0 : dreq = nfs_direct_req_alloc();
564 [ # # ]: 0 : if (dreq == NULL)
565 : 0 : goto out;
566 : :
567 : 0 : dreq->inode = inode;
568 : 0 : dreq->bytes_left = dreq->max_count = count;
569 : 0 : dreq->io_start = iocb->ki_pos;
570 : 0 : dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
571 : 0 : l_ctx = nfs_get_lock_context(dreq->ctx);
572 [ # # ]: 0 : if (IS_ERR(l_ctx)) {
573 : 0 : result = PTR_ERR(l_ctx);
574 : 0 : goto out_release;
575 : : }
576 : 0 : dreq->l_ctx = l_ctx;
577 [ # # ]: 0 : if (!is_sync_kiocb(iocb))
578 : 0 : dreq->iocb = iocb;
579 : :
580 [ # # ]: 0 : if (iter_is_iovec(iter))
581 : 0 : dreq->flags = NFS_ODIRECT_SHOULD_DIRTY;
582 : :
583 : 0 : nfs_start_io_direct(inode);
584 : :
585 : 0 : NFS_I(inode)->read_io += count;
586 : 0 : requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);
587 : :
588 : 0 : nfs_end_io_direct(inode);
589 : :
590 [ # # ]: 0 : if (requested > 0) {
591 : 0 : result = nfs_direct_wait(dreq);
592 [ # # ]: 0 : if (result > 0) {
593 : 0 : requested -= result;
594 : 0 : iocb->ki_pos += result;
595 : : }
596 : 0 : iov_iter_revert(iter, requested);
597 : : } else {
598 : : result = requested;
599 : : }
600 : :
601 : 0 : out_release:
602 : 0 : nfs_direct_req_release(dreq);
603 : 0 : out:
604 : 0 : return result;
605 : : }
606 : :
607 : : static void
608 : : nfs_direct_write_scan_commit_list(struct inode *inode,
609 : : struct list_head *list,
610 : : struct nfs_commit_info *cinfo)
611 : : {
612 : : mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
613 : : #ifdef CONFIG_NFS_V4_1
614 : : if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
615 : : NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
616 : : #endif
617 : : nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
618 : : mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
619 : : }
620 : :
621 : 0 : static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
622 : : {
623 : 0 : struct nfs_pageio_descriptor desc;
624 : 0 : struct nfs_page *req, *tmp;
625 : 0 : LIST_HEAD(reqs);
626 : 0 : struct nfs_commit_info cinfo;
627 : 0 : LIST_HEAD(failed);
628 : :
629 : 0 : nfs_init_cinfo_from_dreq(&cinfo, dreq);
630 : 0 : nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
631 : :
632 : 0 : dreq->count = 0;
633 : 0 : dreq->max_count = 0;
634 [ # # ]: 0 : list_for_each_entry(req, &reqs, wb_list)
635 : 0 : dreq->max_count += req->wb_bytes;
636 : 0 : dreq->verf.committed = NFS_INVALID_STABLE_HOW;
637 : 0 : nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo);
638 : 0 : get_dreq(dreq);
639 : :
640 : 0 : nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false,
641 : : &nfs_direct_write_completion_ops);
642 : 0 : desc.pg_dreq = dreq;
643 : :
644 [ # # ]: 0 : list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
645 : : /* Bump the transmission count */
646 : 0 : req->wb_nio++;
647 [ # # ]: 0 : if (!nfs_pageio_add_request(&desc, req)) {
648 : 0 : nfs_list_move_request(req, &failed);
649 : 0 : spin_lock(&cinfo.inode->i_lock);
650 : 0 : dreq->flags = 0;
651 [ # # ]: 0 : if (desc.pg_error < 0)
652 : 0 : dreq->error = desc.pg_error;
653 : : else
654 : 0 : dreq->error = -EIO;
655 : 0 : spin_unlock(&cinfo.inode->i_lock);
656 : : }
657 : 0 : nfs_release_request(req);
658 : : }
659 : 0 : nfs_pageio_complete(&desc);
660 : :
661 [ # # ]: 0 : while (!list_empty(&failed)) {
662 [ # # ]: 0 : req = nfs_list_entry(failed.next);
663 [ # # ]: 0 : nfs_list_remove_request(req);
664 : 0 : nfs_unlock_and_release_request(req);
665 : : }
666 : :
667 [ # # ]: 0 : if (put_dreq(dreq))
668 : 0 : nfs_direct_write_complete(dreq);
669 : 0 : }
670 : :
671 : 0 : static void nfs_direct_commit_complete(struct nfs_commit_data *data)
672 : : {
673 : 0 : struct nfs_direct_req *dreq = data->dreq;
674 : 0 : struct nfs_commit_info cinfo;
675 : 0 : struct nfs_page *req;
676 : 0 : int status = data->task.tk_status;
677 : :
678 : 0 : nfs_init_cinfo_from_dreq(&cinfo, dreq);
679 [ # # # # ]: 0 : if (status < 0 || nfs_direct_cmp_commit_data_verf(dreq, data))
680 : 0 : dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
681 : :
682 [ # # ]: 0 : while (!list_empty(&data->pages)) {
683 [ # # ]: 0 : req = nfs_list_entry(data->pages.next);
684 [ # # ]: 0 : nfs_list_remove_request(req);
685 [ # # ]: 0 : if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
686 : : /*
687 : : * Despite the reboot, the write was successful,
688 : : * so reset wb_nio.
689 : : */
690 : 0 : req->wb_nio = 0;
691 : : /* Note the rewrite will go through mds */
692 : 0 : nfs_mark_request_commit(req, NULL, &cinfo, 0);
693 : : } else
694 : 0 : nfs_release_request(req);
695 : 0 : nfs_unlock_and_release_request(req);
696 : : }
697 : :
698 [ # # ]: 0 : if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
699 : 0 : nfs_direct_write_complete(dreq);
700 : 0 : }
701 : :
702 : 0 : static void nfs_direct_resched_write(struct nfs_commit_info *cinfo,
703 : : struct nfs_page *req)
704 : : {
705 : 0 : struct nfs_direct_req *dreq = cinfo->dreq;
706 : :
707 : 0 : spin_lock(&dreq->lock);
708 : 0 : dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
709 : 0 : spin_unlock(&dreq->lock);
710 : 0 : nfs_mark_request_commit(req, NULL, cinfo, 0);
711 : 0 : }
712 : :
713 : : static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = {
714 : : .completion = nfs_direct_commit_complete,
715 : : .resched_write = nfs_direct_resched_write,
716 : : };
717 : :
718 : 0 : static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
719 : : {
720 : 0 : int res;
721 : 0 : struct nfs_commit_info cinfo;
722 : 0 : LIST_HEAD(mds_list);
723 : :
724 : 0 : nfs_init_cinfo_from_dreq(&cinfo, dreq);
725 : 0 : nfs_scan_commit(dreq->inode, &mds_list, &cinfo);
726 : 0 : res = nfs_generic_commit_list(dreq->inode, &mds_list, 0, &cinfo);
727 [ # # ]: 0 : if (res < 0) /* res == -ENOMEM */
728 : 0 : nfs_direct_write_reschedule(dreq);
729 : 0 : }
730 : :
731 : 0 : static void nfs_direct_write_schedule_work(struct work_struct *work)
732 : : {
733 : 0 : struct nfs_direct_req *dreq = container_of(work, struct nfs_direct_req, work);
734 : 0 : int flags = dreq->flags;
735 : :
736 : 0 : dreq->flags = 0;
737 [ # # # ]: 0 : switch (flags) {
738 : 0 : case NFS_ODIRECT_DO_COMMIT:
739 : 0 : nfs_direct_commit_schedule(dreq);
740 : 0 : break;
741 : 0 : case NFS_ODIRECT_RESCHED_WRITES:
742 : 0 : nfs_direct_write_reschedule(dreq);
743 : 0 : break;
744 : 0 : default:
745 : 0 : nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping);
746 : 0 : nfs_direct_complete(dreq);
747 : : }
748 : 0 : }
749 : :
750 : 0 : static void nfs_direct_write_complete(struct nfs_direct_req *dreq)
751 : : {
752 : 0 : queue_work(nfsiod_workqueue, &dreq->work); /* Calls nfs_direct_write_schedule_work */
753 : 0 : }
754 : :
755 : 0 : static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
756 : : {
757 : 0 : struct nfs_direct_req *dreq = hdr->dreq;
758 : 0 : struct nfs_commit_info cinfo;
759 : 0 : bool request_commit = false;
760 : 0 : struct nfs_page *req = nfs_list_entry(hdr->pages.next);
761 : :
762 : 0 : nfs_init_cinfo_from_dreq(&cinfo, dreq);
763 : :
764 : 0 : spin_lock(&dreq->lock);
765 [ # # ]: 0 : if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
766 : 0 : spin_unlock(&dreq->lock);
767 : 0 : goto out_put;
768 : : }
769 : :
770 : 0 : nfs_direct_count_bytes(dreq, hdr);
771 [ # # ]: 0 : if (hdr->good_bytes != 0) {
772 [ # # ]: 0 : if (nfs_write_need_commit(hdr)) {
773 [ # # ]: 0 : if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
774 : : request_commit = true;
775 [ # # ]: 0 : else if (dreq->flags == 0) {
776 : 0 : nfs_direct_set_hdr_verf(dreq, hdr);
777 : 0 : request_commit = true;
778 : 0 : dreq->flags = NFS_ODIRECT_DO_COMMIT;
779 [ # # ]: 0 : } else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) {
780 : 0 : request_commit = true;
781 [ # # ]: 0 : if (nfs_direct_set_or_cmp_hdr_verf(dreq, hdr))
782 : 0 : dreq->flags =
783 : : NFS_ODIRECT_RESCHED_WRITES;
784 : : }
785 : : }
786 : : }
787 : 0 : spin_unlock(&dreq->lock);
788 : :
789 [ # # ]: 0 : while (!list_empty(&hdr->pages)) {
790 : :
791 [ # # ]: 0 : req = nfs_list_entry(hdr->pages.next);
792 [ # # ]: 0 : nfs_list_remove_request(req);
793 [ # # ]: 0 : if (request_commit) {
794 : 0 : kref_get(&req->wb_kref);
795 : 0 : nfs_mark_request_commit(req, hdr->lseg, &cinfo,
796 : 0 : hdr->ds_commit_idx);
797 : : }
798 : 0 : nfs_unlock_and_release_request(req);
799 : : }
800 : :
801 : 0 : out_put:
802 [ # # ]: 0 : if (put_dreq(dreq))
803 : 0 : nfs_direct_write_complete(dreq);
804 : 0 : hdr->release(hdr);
805 : 0 : }
806 : :
807 : 0 : static void nfs_write_sync_pgio_error(struct list_head *head, int error)
808 : : {
809 : 0 : struct nfs_page *req;
810 : :
811 [ # # ]: 0 : while (!list_empty(head)) {
812 [ # # ]: 0 : req = nfs_list_entry(head->next);
813 [ # # ]: 0 : nfs_list_remove_request(req);
814 : 0 : nfs_unlock_and_release_request(req);
815 : : }
816 : 0 : }
817 : :
818 : 0 : static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
819 : : {
820 : 0 : struct nfs_direct_req *dreq = hdr->dreq;
821 : :
822 : 0 : spin_lock(&dreq->lock);
823 [ # # ]: 0 : if (dreq->error == 0) {
824 : 0 : dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
825 : : /* fake unstable write to let common nfs resend pages */
826 : 0 : hdr->verf.committed = NFS_UNSTABLE;
827 : 0 : hdr->good_bytes = hdr->args.offset + hdr->args.count -
828 : 0 : hdr->io_start;
829 : : }
830 : 0 : spin_unlock(&dreq->lock);
831 : 0 : }
832 : :
833 : : static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
834 : : .error_cleanup = nfs_write_sync_pgio_error,
835 : : .init_hdr = nfs_direct_pgio_init,
836 : : .completion = nfs_direct_write_completion,
837 : : .reschedule_io = nfs_direct_write_reschedule_io,
838 : : };
839 : :
840 : :
841 : : /*
842 : : * NB: Return the value of the first error return code. Subsequent
843 : : * errors after the first one are ignored.
844 : : */
845 : : /*
846 : : * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE
847 : : * operation. If nfs_writedata_alloc() or get_user_pages() fails,
848 : : * bail and stop sending more writes. Write length accounting is
849 : : * handled automatically by nfs_direct_write_result(). Otherwise, if
850 : : * no requests have been sent, just return an error.
851 : : */
852 : 0 : static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
853 : : struct iov_iter *iter,
854 : : loff_t pos)
855 : : {
856 : 0 : struct nfs_pageio_descriptor desc;
857 : 0 : struct inode *inode = dreq->inode;
858 : 0 : ssize_t result = 0;
859 : 0 : size_t requested_bytes = 0;
860 : 0 : size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE);
861 : :
862 : 0 : nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE, false,
863 : : &nfs_direct_write_completion_ops);
864 : 0 : desc.pg_dreq = dreq;
865 : 0 : get_dreq(dreq);
866 : 0 : inode_dio_begin(inode);
867 : :
868 : 0 : NFS_I(inode)->write_io += iov_iter_count(iter);
869 [ # # ]: 0 : while (iov_iter_count(iter)) {
870 : 0 : struct page **pagevec;
871 : 0 : size_t bytes;
872 : 0 : size_t pgbase;
873 : 0 : unsigned npages, i;
874 : :
875 : 0 : result = iov_iter_get_pages_alloc(iter, &pagevec,
876 : : wsize, &pgbase);
877 [ # # ]: 0 : if (result < 0)
878 : : break;
879 : :
880 : 0 : bytes = result;
881 : 0 : iov_iter_advance(iter, bytes);
882 : 0 : npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
883 [ # # ]: 0 : for (i = 0; i < npages; i++) {
884 : 0 : struct nfs_page *req;
885 : 0 : unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
886 : :
887 : 0 : req = nfs_create_request(dreq->ctx, pagevec[i],
888 : : pgbase, req_len);
889 [ # # ]: 0 : if (IS_ERR(req)) {
890 : 0 : result = PTR_ERR(req);
891 : 0 : break;
892 : : }
893 : :
894 [ # # ]: 0 : if (desc.pg_error < 0) {
895 : 0 : nfs_free_request(req);
896 : 0 : result = desc.pg_error;
897 : 0 : break;
898 : : }
899 : :
900 : 0 : nfs_lock_request(req);
901 : 0 : req->wb_index = pos >> PAGE_SHIFT;
902 : 0 : req->wb_offset = pos & ~PAGE_MASK;
903 [ # # ]: 0 : if (!nfs_pageio_add_request(&desc, req)) {
904 : 0 : result = desc.pg_error;
905 : 0 : nfs_unlock_and_release_request(req);
906 : 0 : break;
907 : : }
908 : 0 : pgbase = 0;
909 : 0 : bytes -= req_len;
910 : 0 : requested_bytes += req_len;
911 : 0 : pos += req_len;
912 : 0 : dreq->bytes_left -= req_len;
913 : : }
914 : 0 : nfs_direct_release_pages(pagevec, npages);
915 : 0 : kvfree(pagevec);
916 [ # # ]: 0 : if (result < 0)
917 : : break;
918 : : }
919 : 0 : nfs_pageio_complete(&desc);
920 : :
921 : : /*
922 : : * If no bytes were started, return the error, and let the
923 : : * generic layer handle the completion.
924 : : */
925 [ # # ]: 0 : if (requested_bytes == 0) {
926 : 0 : inode_dio_end(inode);
927 : 0 : nfs_direct_req_release(dreq);
928 [ # # ]: 0 : return result < 0 ? result : -EIO;
929 : : }
930 : :
931 [ # # ]: 0 : if (put_dreq(dreq))
932 : 0 : nfs_direct_write_complete(dreq);
933 : 0 : return requested_bytes;
934 : : }
935 : :
936 : : /**
937 : : * nfs_file_direct_write - file direct write operation for NFS files
938 : : * @iocb: target I/O control block
939 : : * @iter: vector of user buffers from which to write data
940 : : *
941 : : * We use this function for direct writes instead of calling
942 : : * generic_file_aio_write() in order to avoid taking the inode
943 : : * semaphore and updating the i_size. The NFS server will set
944 : : * the new i_size and this client must read the updated size
945 : : * back into its cache. We let the server do generic write
946 : : * parameter checking and report problems.
947 : : *
948 : : * We eliminate local atime updates, see direct read above.
949 : : *
950 : : * We avoid unnecessary page cache invalidations for normal cached
951 : : * readers of this file.
952 : : *
953 : : * Note that O_APPEND is not supported for NFS direct writes, as there
954 : : * is no atomic O_APPEND write facility in the NFS protocol.
955 : : */
956 : 0 : ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
957 : : {
958 : 0 : ssize_t result = -EINVAL, requested;
959 : 0 : size_t count;
960 : 0 : struct file *file = iocb->ki_filp;
961 : 0 : struct address_space *mapping = file->f_mapping;
962 : 0 : struct inode *inode = mapping->host;
963 : 0 : struct nfs_direct_req *dreq;
964 : 0 : struct nfs_lock_context *l_ctx;
965 : 0 : loff_t pos, end;
966 : :
967 : 0 : dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
968 : : file, iov_iter_count(iter), (long long) iocb->ki_pos);
969 : :
970 : 0 : result = generic_write_checks(iocb, iter);
971 [ # # ]: 0 : if (result <= 0)
972 : : return result;
973 : 0 : count = result;
974 [ # # ]: 0 : nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
975 : :
976 : 0 : pos = iocb->ki_pos;
977 : 0 : end = (pos + iov_iter_count(iter) - 1) >> PAGE_SHIFT;
978 : :
979 : 0 : task_io_account_write(count);
980 : :
981 : 0 : result = -ENOMEM;
982 : 0 : dreq = nfs_direct_req_alloc();
983 [ # # ]: 0 : if (!dreq)
984 : 0 : goto out;
985 : :
986 : 0 : dreq->inode = inode;
987 : 0 : dreq->bytes_left = dreq->max_count = count;
988 : 0 : dreq->io_start = pos;
989 : 0 : dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
990 : 0 : l_ctx = nfs_get_lock_context(dreq->ctx);
991 [ # # ]: 0 : if (IS_ERR(l_ctx)) {
992 : 0 : result = PTR_ERR(l_ctx);
993 : 0 : goto out_release;
994 : : }
995 : 0 : dreq->l_ctx = l_ctx;
996 [ # # ]: 0 : if (!is_sync_kiocb(iocb))
997 : 0 : dreq->iocb = iocb;
998 : :
999 : 0 : nfs_start_io_direct(inode);
1000 : :
1001 : 0 : requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
1002 : :
1003 [ # # ]: 0 : if (mapping->nrpages) {
1004 : 0 : invalidate_inode_pages2_range(mapping,
1005 : 0 : pos >> PAGE_SHIFT, end);
1006 : : }
1007 : :
1008 : 0 : nfs_end_io_direct(inode);
1009 : :
1010 [ # # ]: 0 : if (requested > 0) {
1011 : 0 : result = nfs_direct_wait(dreq);
1012 [ # # ]: 0 : if (result > 0) {
1013 : 0 : requested -= result;
1014 : 0 : iocb->ki_pos = pos + result;
1015 : : /* XXX: should check the generic_write_sync retval */
1016 : 0 : generic_write_sync(iocb, result);
1017 : : }
1018 : 0 : iov_iter_revert(iter, requested);
1019 : : } else {
1020 : : result = requested;
1021 : : }
1022 : 0 : out_release:
1023 : 0 : nfs_direct_req_release(dreq);
1024 : : out:
1025 : : return result;
1026 : : }
1027 : :
1028 : : /**
1029 : : * nfs_init_directcache - create a slab cache for nfs_direct_req structures
1030 : : *
1031 : : */
1032 : 13 : int __init nfs_init_directcache(void)
1033 : : {
1034 : 13 : nfs_direct_cachep = kmem_cache_create("nfs_direct_cache",
1035 : : sizeof(struct nfs_direct_req),
1036 : : 0, (SLAB_RECLAIM_ACCOUNT|
1037 : : SLAB_MEM_SPREAD),
1038 : : NULL);
1039 [ - + ]: 13 : if (nfs_direct_cachep == NULL)
1040 : 0 : return -ENOMEM;
1041 : :
1042 : : return 0;
1043 : : }
1044 : :
1045 : : /**
1046 : : * nfs_destroy_directcache - destroy the slab cache for nfs_direct_req structures
1047 : : *
1048 : : */
1049 : 0 : void nfs_destroy_directcache(void)
1050 : : {
1051 : 0 : kmem_cache_destroy(nfs_direct_cachep);
1052 : 0 : }
|