Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * linux/fs/nfs/write.c
4 : : *
5 : : * Write file data over NFS.
6 : : *
7 : : * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
8 : : */
9 : :
10 : : #include <linux/types.h>
11 : : #include <linux/slab.h>
12 : : #include <linux/mm.h>
13 : : #include <linux/pagemap.h>
14 : : #include <linux/file.h>
15 : : #include <linux/writeback.h>
16 : : #include <linux/swap.h>
17 : : #include <linux/migrate.h>
18 : :
19 : : #include <linux/sunrpc/clnt.h>
20 : : #include <linux/nfs_fs.h>
21 : : #include <linux/nfs_mount.h>
22 : : #include <linux/nfs_page.h>
23 : : #include <linux/backing-dev.h>
24 : : #include <linux/export.h>
25 : : #include <linux/freezer.h>
26 : : #include <linux/wait.h>
27 : : #include <linux/iversion.h>
28 : :
29 : : #include <linux/uaccess.h>
30 : : #include <linux/sched/mm.h>
31 : :
32 : : #include "delegation.h"
33 : : #include "internal.h"
34 : : #include "iostat.h"
35 : : #include "nfs4_fs.h"
36 : : #include "fscache.h"
37 : : #include "pnfs.h"
38 : :
39 : : #include "nfstrace.h"
40 : :
41 : : #define NFSDBG_FACILITY NFSDBG_PAGECACHE
42 : :
43 : : #define MIN_POOL_WRITE (32)
44 : : #define MIN_POOL_COMMIT (4)
45 : :
46 : : struct nfs_io_completion {
47 : : void (*complete)(void *data);
48 : : void *data;
49 : : struct kref refcount;
50 : : };
51 : :
52 : : /*
53 : : * Local function declarations
54 : : */
55 : : static void nfs_redirty_request(struct nfs_page *req);
56 : : static const struct rpc_call_ops nfs_commit_ops;
57 : : static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
58 : : static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
59 : : static const struct nfs_rw_ops nfs_rw_write_ops;
60 : : static void nfs_inode_remove_request(struct nfs_page *req);
61 : : static void nfs_clear_request_commit(struct nfs_page *req);
62 : : static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
63 : : struct inode *inode);
64 : : static struct nfs_page *
65 : : nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi,
66 : : struct page *page);
67 : :
68 : : static struct kmem_cache *nfs_wdata_cachep;
69 : : static mempool_t *nfs_wdata_mempool;
70 : : static struct kmem_cache *nfs_cdata_cachep;
71 : : static mempool_t *nfs_commit_mempool;
72 : :
73 : 0 : struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail)
74 : : {
75 : : struct nfs_commit_data *p;
76 : :
77 [ # # ]: 0 : if (never_fail)
78 : 0 : p = mempool_alloc(nfs_commit_mempool, GFP_NOIO);
79 : : else {
80 : : /* It is OK to do some reclaim, not no safe to wait
81 : : * for anything to be returned to the pool.
82 : : * mempool_alloc() cannot handle that particular combination,
83 : : * so we need two separate attempts.
84 : : */
85 : 0 : p = mempool_alloc(nfs_commit_mempool, GFP_NOWAIT);
86 [ # # ]: 0 : if (!p)
87 : 0 : p = kmem_cache_alloc(nfs_cdata_cachep, GFP_NOIO |
88 : : __GFP_NOWARN | __GFP_NORETRY);
89 [ # # ]: 0 : if (!p)
90 : : return NULL;
91 : : }
92 : :
93 : 0 : memset(p, 0, sizeof(*p));
94 : 0 : INIT_LIST_HEAD(&p->pages);
95 : 0 : return p;
96 : : }
97 : : EXPORT_SYMBOL_GPL(nfs_commitdata_alloc);
98 : :
99 : 0 : void nfs_commit_free(struct nfs_commit_data *p)
100 : : {
101 : 0 : mempool_free(p, nfs_commit_mempool);
102 : 0 : }
103 : : EXPORT_SYMBOL_GPL(nfs_commit_free);
104 : :
105 : 0 : static struct nfs_pgio_header *nfs_writehdr_alloc(void)
106 : : {
107 : 0 : struct nfs_pgio_header *p = mempool_alloc(nfs_wdata_mempool, GFP_KERNEL);
108 : :
109 : 0 : memset(p, 0, sizeof(*p));
110 : 0 : p->rw_mode = FMODE_WRITE;
111 : 0 : return p;
112 : : }
113 : :
114 : 0 : static void nfs_writehdr_free(struct nfs_pgio_header *hdr)
115 : : {
116 : 0 : mempool_free(hdr, nfs_wdata_mempool);
117 : 0 : }
118 : :
119 : : static struct nfs_io_completion *nfs_io_completion_alloc(gfp_t gfp_flags)
120 : : {
121 : : return kmalloc(sizeof(struct nfs_io_completion), gfp_flags);
122 : : }
123 : :
124 : : static void nfs_io_completion_init(struct nfs_io_completion *ioc,
125 : : void (*complete)(void *), void *data)
126 : : {
127 : 0 : ioc->complete = complete;
128 : 0 : ioc->data = data;
129 : : kref_init(&ioc->refcount);
130 : : }
131 : :
132 : 0 : static void nfs_io_completion_release(struct kref *kref)
133 : : {
134 : 0 : struct nfs_io_completion *ioc = container_of(kref,
135 : : struct nfs_io_completion, refcount);
136 : 0 : ioc->complete(ioc->data);
137 : 0 : kfree(ioc);
138 : 0 : }
139 : :
140 : : static void nfs_io_completion_get(struct nfs_io_completion *ioc)
141 : : {
142 [ # # ]: 0 : if (ioc != NULL)
143 : : kref_get(&ioc->refcount);
144 : : }
145 : :
146 : : static void nfs_io_completion_put(struct nfs_io_completion *ioc)
147 : : {
148 [ # # # # ]: 0 : if (ioc != NULL)
149 : 0 : kref_put(&ioc->refcount, nfs_io_completion_release);
150 : : }
151 : :
152 : : static struct nfs_page *
153 : : nfs_page_private_request(struct page *page)
154 : : {
155 [ # # # # ]: 0 : if (!PagePrivate(page))
156 : : return NULL;
157 : 0 : return (struct nfs_page *)page_private(page);
158 : : }
159 : :
160 : : /*
161 : : * nfs_page_find_head_request_locked - find head request associated with @page
162 : : *
163 : : * must be called while holding the inode lock.
164 : : *
165 : : * returns matching head request with reference held, or NULL if not found.
166 : : */
167 : : static struct nfs_page *
168 : 0 : nfs_page_find_private_request(struct page *page)
169 : : {
170 : 0 : struct address_space *mapping = page_file_mapping(page);
171 : : struct nfs_page *req;
172 : :
173 [ # # ]: 0 : if (!PagePrivate(page))
174 : : return NULL;
175 : : spin_lock(&mapping->private_lock);
176 : : req = nfs_page_private_request(page);
177 [ # # ]: 0 : if (req) {
178 [ # # # # ]: 0 : WARN_ON_ONCE(req->wb_head != req);
179 : : kref_get(&req->wb_kref);
180 : : }
181 : : spin_unlock(&mapping->private_lock);
182 : 0 : return req;
183 : : }
184 : :
185 : : static struct nfs_page *
186 : 0 : nfs_page_find_swap_request(struct page *page)
187 : : {
188 : 0 : struct inode *inode = page_file_mapping(page)->host;
189 : : struct nfs_inode *nfsi = NFS_I(inode);
190 : : struct nfs_page *req = NULL;
191 [ # # ]: 0 : if (!PageSwapCache(page))
192 : : return NULL;
193 : 0 : mutex_lock(&nfsi->commit_mutex);
194 [ # # ]: 0 : if (PageSwapCache(page)) {
195 : 0 : req = nfs_page_search_commits_for_head_request_locked(nfsi,
196 : : page);
197 [ # # ]: 0 : if (req) {
198 [ # # # # ]: 0 : WARN_ON_ONCE(req->wb_head != req);
199 : : kref_get(&req->wb_kref);
200 : : }
201 : : }
202 : 0 : mutex_unlock(&nfsi->commit_mutex);
203 : 0 : return req;
204 : : }
205 : :
206 : : /*
207 : : * nfs_page_find_head_request - find head request associated with @page
208 : : *
209 : : * returns matching head request with reference held, or NULL if not found.
210 : : */
211 : 0 : static struct nfs_page *nfs_page_find_head_request(struct page *page)
212 : : {
213 : : struct nfs_page *req;
214 : :
215 : 0 : req = nfs_page_find_private_request(page);
216 [ # # ]: 0 : if (!req)
217 : 0 : req = nfs_page_find_swap_request(page);
218 : 0 : return req;
219 : : }
220 : :
221 : : /* Adjust the file length if we're writing beyond the end */
222 : 0 : static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count)
223 : : {
224 : 0 : struct inode *inode = page_file_mapping(page)->host;
225 : : loff_t end, i_size;
226 : : pgoff_t end_index;
227 : :
228 : : spin_lock(&inode->i_lock);
229 : : i_size = i_size_read(inode);
230 : 0 : end_index = (i_size - 1) >> PAGE_SHIFT;
231 [ # # # # ]: 0 : if (i_size > 0 && page_index(page) < end_index)
232 : : goto out;
233 : 0 : end = page_file_offset(page) + ((loff_t)offset+count);
234 [ # # ]: 0 : if (i_size >= end)
235 : : goto out;
236 : : i_size_write(inode, end);
237 : 0 : NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
238 : 0 : nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
239 : : out:
240 : : spin_unlock(&inode->i_lock);
241 : 0 : }
242 : :
243 : : /* A writeback failed: mark the page as bad, and invalidate the page cache */
244 : 0 : static void nfs_set_pageerror(struct address_space *mapping)
245 : : {
246 : 0 : struct inode *inode = mapping->host;
247 : :
248 : 0 : nfs_zap_mapping(mapping->host, mapping);
249 : : /* Force file size revalidation */
250 : : spin_lock(&inode->i_lock);
251 : 0 : NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED |
252 : : NFS_INO_REVAL_PAGECACHE |
253 : : NFS_INO_INVALID_SIZE;
254 : : spin_unlock(&inode->i_lock);
255 : 0 : }
256 : :
257 : 0 : static void nfs_mapping_set_error(struct page *page, int error)
258 : : {
259 : : SetPageError(page);
260 : 0 : mapping_set_error(page_file_mapping(page), error);
261 : 0 : }
262 : :
263 : : /*
264 : : * nfs_page_group_search_locked
265 : : * @head - head request of page group
266 : : * @page_offset - offset into page
267 : : *
268 : : * Search page group with head @head to find a request that contains the
269 : : * page offset @page_offset.
270 : : *
271 : : * Returns a pointer to the first matching nfs request, or NULL if no
272 : : * match is found.
273 : : *
274 : : * Must be called with the page group lock held
275 : : */
276 : : static struct nfs_page *
277 : : nfs_page_group_search_locked(struct nfs_page *head, unsigned int page_offset)
278 : : {
279 : : struct nfs_page *req;
280 : :
281 : : req = head;
282 : : do {
283 [ # # # # ]: 0 : if (page_offset >= req->wb_pgbase &&
284 : 0 : page_offset < (req->wb_pgbase + req->wb_bytes))
285 : 0 : return req;
286 : :
287 : 0 : req = req->wb_this_page;
288 [ # # ]: 0 : } while (req != head);
289 : :
290 : : return NULL;
291 : : }
292 : :
293 : : /*
294 : : * nfs_page_group_covers_page
295 : : * @head - head request of page group
296 : : *
297 : : * Return true if the page group with head @head covers the whole page,
298 : : * returns false otherwise
299 : : */
300 : 0 : static bool nfs_page_group_covers_page(struct nfs_page *req)
301 : : {
302 : : struct nfs_page *tmp;
303 : : unsigned int pos = 0;
304 : 0 : unsigned int len = nfs_page_length(req->wb_page);
305 : :
306 : 0 : nfs_page_group_lock(req);
307 : :
308 : : for (;;) {
309 : 0 : tmp = nfs_page_group_search_locked(req->wb_head, pos);
310 [ # # ]: 0 : if (!tmp)
311 : : break;
312 : 0 : pos = tmp->wb_pgbase + tmp->wb_bytes;
313 : 0 : }
314 : :
315 : 0 : nfs_page_group_unlock(req);
316 : 0 : return pos >= len;
317 : : }
318 : :
319 : : /* We can set the PG_uptodate flag if we see that a write request
320 : : * covers the full page.
321 : : */
322 : 0 : static void nfs_mark_uptodate(struct nfs_page *req)
323 : : {
324 [ # # ]: 0 : if (PageUptodate(req->wb_page))
325 : : return;
326 [ # # ]: 0 : if (!nfs_page_group_covers_page(req))
327 : : return;
328 : 0 : SetPageUptodate(req->wb_page);
329 : : }
330 : :
331 : : static int wb_priority(struct writeback_control *wbc)
332 : : {
333 : : int ret = 0;
334 : :
335 [ # # ]: 0 : if (wbc->sync_mode == WB_SYNC_ALL)
336 : : ret = FLUSH_COND_STABLE;
337 : : return ret;
338 : : }
339 : :
340 : : /*
341 : : * NFS congestion control
342 : : */
343 : :
344 : : int nfs_congestion_kb;
345 : :
346 : : #define NFS_CONGESTION_ON_THRESH (nfs_congestion_kb >> (PAGE_SHIFT-10))
347 : : #define NFS_CONGESTION_OFF_THRESH \
348 : : (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
349 : :
350 : 0 : static void nfs_set_page_writeback(struct page *page)
351 : : {
352 : 0 : struct inode *inode = page_file_mapping(page)->host;
353 : : struct nfs_server *nfss = NFS_SERVER(inode);
354 : 0 : int ret = test_set_page_writeback(page);
355 : :
356 [ # # # # ]: 0 : WARN_ON_ONCE(ret != 0);
357 : :
358 [ # # ]: 0 : if (atomic_long_inc_return(&nfss->writeback) >
359 : 0 : NFS_CONGESTION_ON_THRESH)
360 : 0 : set_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
361 : 0 : }
362 : :
363 : 0 : static void nfs_end_page_writeback(struct nfs_page *req)
364 : : {
365 : 0 : struct inode *inode = page_file_mapping(req->wb_page)->host;
366 : : struct nfs_server *nfss = NFS_SERVER(inode);
367 : : bool is_done;
368 : :
369 : 0 : is_done = nfs_page_group_sync_on_bit(req, PG_WB_END);
370 : 0 : nfs_unlock_request(req);
371 [ # # ]: 0 : if (!is_done)
372 : 0 : return;
373 : :
374 : 0 : end_page_writeback(req->wb_page);
375 [ # # ]: 0 : if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
376 : 0 : clear_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
377 : : }
378 : :
379 : : /*
380 : : * nfs_unroll_locks_and_wait - unlock all newly locked reqs and wait on @req
381 : : *
382 : : * this is a helper function for nfs_lock_and_join_requests
383 : : *
384 : : * @inode - inode associated with request page group, must be holding inode lock
385 : : * @head - head request of page group, must be holding head lock
386 : : * @req - request that couldn't lock and needs to wait on the req bit lock
387 : : *
388 : : * NOTE: this must be called holding page_group bit lock
389 : : * which will be released before returning.
390 : : *
391 : : * returns 0 on success, < 0 on error.
392 : : */
393 : : static void
394 : : nfs_unroll_locks(struct inode *inode, struct nfs_page *head,
395 : : struct nfs_page *req)
396 : : {
397 : : struct nfs_page *tmp;
398 : :
399 : : /* relinquish all the locks successfully grabbed this run */
400 [ # # # # ]: 0 : for (tmp = head->wb_this_page ; tmp != req; tmp = tmp->wb_this_page) {
401 [ # # # # ]: 0 : if (!kref_read(&tmp->wb_kref))
402 : 0 : continue;
403 : 0 : nfs_unlock_and_release_request(tmp);
404 : : }
405 : : }
406 : :
407 : : /*
408 : : * nfs_destroy_unlinked_subrequests - destroy recently unlinked subrequests
409 : : *
410 : : * @destroy_list - request list (using wb_this_page) terminated by @old_head
411 : : * @old_head - the old head of the list
412 : : *
413 : : * All subrequests must be locked and removed from all lists, so at this point
414 : : * they are only "active" in this function, and possibly in nfs_wait_on_request
415 : : * with a reference held by some other context.
416 : : */
417 : : static void
418 : 0 : nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list,
419 : : struct nfs_page *old_head,
420 : : struct inode *inode)
421 : : {
422 [ # # ]: 0 : while (destroy_list) {
423 : : struct nfs_page *subreq = destroy_list;
424 : :
425 : 0 : destroy_list = (subreq->wb_this_page == old_head) ?
426 [ # # ]: 0 : NULL : subreq->wb_this_page;
427 : :
428 [ # # # # ]: 0 : WARN_ON_ONCE(old_head != subreq->wb_head);
429 : :
430 : : /* make sure old group is not used */
431 : 0 : subreq->wb_this_page = subreq;
432 : :
433 : 0 : clear_bit(PG_REMOVE, &subreq->wb_flags);
434 : :
435 : : /* Note: races with nfs_page_group_destroy() */
436 [ # # ]: 0 : if (!kref_read(&subreq->wb_kref)) {
437 : : /* Check if we raced with nfs_page_group_destroy() */
438 [ # # ]: 0 : if (test_and_clear_bit(PG_TEARDOWN, &subreq->wb_flags))
439 : 0 : nfs_free_request(subreq);
440 : 0 : continue;
441 : : }
442 : :
443 : 0 : subreq->wb_head = subreq;
444 : 0 : nfs_release_request(old_head);
445 : :
446 [ # # ]: 0 : if (test_and_clear_bit(PG_INODE_REF, &subreq->wb_flags)) {
447 : 0 : nfs_release_request(subreq);
448 : 0 : atomic_long_dec(&NFS_I(inode)->nrequests);
449 : : }
450 : :
451 : : /* subreq is now totally disconnected from page group or any
452 : : * write / commit lists. last chance to wake any waiters */
453 : 0 : nfs_unlock_and_release_request(subreq);
454 : : }
455 : 0 : }
456 : :
457 : : /*
458 : : * nfs_lock_and_join_requests - join all subreqs to the head req and return
459 : : * a locked reference, cancelling any pending
460 : : * operations for this page.
461 : : *
462 : : * @page - the page used to lookup the "page group" of nfs_page structures
463 : : *
464 : : * This function joins all sub requests to the head request by first
465 : : * locking all requests in the group, cancelling any pending operations
466 : : * and finally updating the head request to cover the whole range covered by
467 : : * the (former) group. All subrequests are removed from any write or commit
468 : : * lists, unlinked from the group and destroyed.
469 : : *
470 : : * Returns a locked, referenced pointer to the head request - which after
471 : : * this call is guaranteed to be the only request associated with the page.
472 : : * Returns NULL if no requests are found for @page, or a ERR_PTR if an
473 : : * error was encountered.
474 : : */
475 : : static struct nfs_page *
476 : 0 : nfs_lock_and_join_requests(struct page *page)
477 : : {
478 : 0 : struct inode *inode = page_file_mapping(page)->host;
479 : : struct nfs_page *head, *subreq;
480 : : struct nfs_page *destroy_list = NULL;
481 : : unsigned int total_bytes;
482 : : int ret;
483 : :
484 : : try_again:
485 : : /*
486 : : * A reference is taken only on the head request which acts as a
487 : : * reference to the whole page group - the group will not be destroyed
488 : : * until the head reference is released.
489 : : */
490 : 0 : head = nfs_page_find_head_request(page);
491 [ # # ]: 0 : if (!head)
492 : : return NULL;
493 : :
494 : : /* lock the page head first in order to avoid an ABBA inefficiency */
495 [ # # ]: 0 : if (!nfs_lock_request(head)) {
496 : 0 : ret = nfs_wait_on_request(head);
497 : 0 : nfs_release_request(head);
498 [ # # ]: 0 : if (ret < 0)
499 : 0 : return ERR_PTR(ret);
500 : : goto try_again;
501 : : }
502 : :
503 : : /* Ensure that nobody removed the request before we locked it */
504 [ # # # # ]: 0 : if (head != nfs_page_private_request(page) && !PageSwapCache(page)) {
505 : 0 : nfs_unlock_and_release_request(head);
506 : 0 : goto try_again;
507 : : }
508 : :
509 : 0 : ret = nfs_page_group_lock(head);
510 [ # # ]: 0 : if (ret < 0)
511 : : goto release_request;
512 : :
513 : : /* lock each request in the page group */
514 : 0 : total_bytes = head->wb_bytes;
515 [ # # ]: 0 : for (subreq = head->wb_this_page; subreq != head;
516 : 0 : subreq = subreq->wb_this_page) {
517 : :
518 [ # # ]: 0 : if (!kref_get_unless_zero(&subreq->wb_kref)) {
519 [ # # ]: 0 : if (subreq->wb_offset == head->wb_offset + total_bytes)
520 : 0 : total_bytes += subreq->wb_bytes;
521 : 0 : continue;
522 : : }
523 : :
524 [ # # ]: 0 : while (!nfs_lock_request(subreq)) {
525 : : /*
526 : : * Unlock page to allow nfs_page_group_sync_on_bit()
527 : : * to succeed
528 : : */
529 : 0 : nfs_page_group_unlock(head);
530 : 0 : ret = nfs_wait_on_request(subreq);
531 [ # # ]: 0 : if (!ret)
532 : 0 : ret = nfs_page_group_lock(head);
533 [ # # ]: 0 : if (ret < 0) {
534 : : nfs_unroll_locks(inode, head, subreq);
535 : 0 : nfs_release_request(subreq);
536 : 0 : goto release_request;
537 : : }
538 : : }
539 : : /*
540 : : * Subrequests are always contiguous, non overlapping
541 : : * and in order - but may be repeated (mirrored writes).
542 : : */
543 [ # # ]: 0 : if (subreq->wb_offset == (head->wb_offset + total_bytes)) {
544 : : /* keep track of how many bytes this group covers */
545 : 0 : total_bytes += subreq->wb_bytes;
546 [ # # # # : 0 : } else if (WARN_ON_ONCE(subreq->wb_offset < head->wb_offset ||
# # # # #
# ]
547 : : ((subreq->wb_offset + subreq->wb_bytes) >
548 : : (head->wb_offset + total_bytes)))) {
549 : 0 : nfs_page_group_unlock(head);
550 : : nfs_unroll_locks(inode, head, subreq);
551 : 0 : nfs_unlock_and_release_request(subreq);
552 : : ret = -EIO;
553 : 0 : goto release_request;
554 : : }
555 : : }
556 : :
557 : : /* Now that all requests are locked, make sure they aren't on any list.
558 : : * Commit list removal accounting is done after locks are dropped */
559 : 0 : subreq = head;
560 : : do {
561 : 0 : nfs_clear_request_commit(subreq);
562 : 0 : subreq = subreq->wb_this_page;
563 [ # # ]: 0 : } while (subreq != head);
564 : :
565 : : /* unlink subrequests from head, destroy them later */
566 [ # # ]: 0 : if (head->wb_this_page != head) {
567 : : /* destroy list will be terminated by head */
568 : : destroy_list = head->wb_this_page;
569 : 0 : head->wb_this_page = head;
570 : :
571 : : /* change head request to cover whole range that
572 : : * the former page group covered */
573 : 0 : head->wb_bytes = total_bytes;
574 : : }
575 : :
576 : : /* Postpone destruction of this request */
577 [ # # ]: 0 : if (test_and_clear_bit(PG_REMOVE, &head->wb_flags)) {
578 : 0 : set_bit(PG_INODE_REF, &head->wb_flags);
579 : : kref_get(&head->wb_kref);
580 : 0 : atomic_long_inc(&NFS_I(inode)->nrequests);
581 : : }
582 : :
583 : 0 : nfs_page_group_unlock(head);
584 : :
585 : 0 : nfs_destroy_unlinked_subrequests(destroy_list, head, inode);
586 : :
587 : : /* Did we lose a race with nfs_inode_remove_request()? */
588 [ # # # # ]: 0 : if (!(PagePrivate(page) || PageSwapCache(page))) {
589 : 0 : nfs_unlock_and_release_request(head);
590 : 0 : return NULL;
591 : : }
592 : :
593 : : /* still holds ref on head from nfs_page_find_head_request
594 : : * and still has lock on head from lock loop */
595 : 0 : return head;
596 : :
597 : : release_request:
598 : 0 : nfs_unlock_and_release_request(head);
599 : 0 : return ERR_PTR(ret);
600 : : }
601 : :
602 : 0 : static void nfs_write_error(struct nfs_page *req, int error)
603 : : {
604 : 0 : nfs_set_pageerror(page_file_mapping(req->wb_page));
605 : 0 : nfs_mapping_set_error(req->wb_page, error);
606 : 0 : nfs_inode_remove_request(req);
607 : 0 : nfs_end_page_writeback(req);
608 : 0 : nfs_release_request(req);
609 : 0 : }
610 : :
611 : : /*
612 : : * Find an associated nfs write request, and prepare to flush it out
613 : : * May return an error if the user signalled nfs_wait_on_request().
614 : : */
615 : 0 : static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
616 : : struct page *page)
617 : : {
618 : : struct nfs_page *req;
619 : : int ret = 0;
620 : :
621 : 0 : req = nfs_lock_and_join_requests(page);
622 [ # # ]: 0 : if (!req)
623 : : goto out;
624 : : ret = PTR_ERR(req);
625 [ # # ]: 0 : if (IS_ERR(req))
626 : : goto out;
627 : :
628 : 0 : nfs_set_page_writeback(page);
629 [ # # # # ]: 0 : WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
630 : :
631 : : /* If there is a fatal error that covers this write, just exit */
632 : 0 : ret = pgio->pg_error;
633 [ # # ]: 0 : if (nfs_error_is_fatal_on_server(ret))
634 : : goto out_launder;
635 : :
636 : : ret = 0;
637 [ # # ]: 0 : if (!nfs_pageio_add_request(pgio, req)) {
638 : 0 : ret = pgio->pg_error;
639 : : /*
640 : : * Remove the problematic req upon fatal errors on the server
641 : : */
642 [ # # ]: 0 : if (nfs_error_is_fatal(ret)) {
643 [ # # ]: 0 : if (nfs_error_is_fatal_on_server(ret))
644 : : goto out_launder;
645 : : } else
646 : : ret = -EAGAIN;
647 : 0 : nfs_redirty_request(req);
648 : 0 : pgio->pg_error = 0;
649 : : } else
650 : 0 : nfs_add_stats(page_file_mapping(page)->host,
651 : : NFSIOS_WRITEPAGES, 1);
652 : : out:
653 : 0 : return ret;
654 : : out_launder:
655 : 0 : nfs_write_error(req, ret);
656 : 0 : return 0;
657 : : }
658 : :
659 : 0 : static int nfs_do_writepage(struct page *page, struct writeback_control *wbc,
660 : : struct nfs_pageio_descriptor *pgio)
661 : : {
662 : : int ret;
663 : :
664 : 0 : nfs_pageio_cond_complete(pgio, page_index(page));
665 : 0 : ret = nfs_page_async_flush(pgio, page);
666 [ # # ]: 0 : if (ret == -EAGAIN) {
667 : 0 : redirty_page_for_writepage(wbc, page);
668 : : ret = AOP_WRITEPAGE_ACTIVATE;
669 : : }
670 : 0 : return ret;
671 : : }
672 : :
673 : : /*
674 : : * Write an mmapped page to the server.
675 : : */
676 : 0 : static int nfs_writepage_locked(struct page *page,
677 : : struct writeback_control *wbc)
678 : : {
679 : : struct nfs_pageio_descriptor pgio;
680 : 0 : struct inode *inode = page_file_mapping(page)->host;
681 : : int err;
682 : :
683 : 0 : nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
684 : 0 : nfs_pageio_init_write(&pgio, inode, 0,
685 : : false, &nfs_async_write_completion_ops);
686 : 0 : err = nfs_do_writepage(page, wbc, &pgio);
687 : 0 : pgio.pg_error = 0;
688 : 0 : nfs_pageio_complete(&pgio);
689 [ # # ]: 0 : if (err < 0)
690 : : return err;
691 [ # # ]: 0 : if (nfs_error_is_fatal(pgio.pg_error))
692 : 0 : return pgio.pg_error;
693 : : return 0;
694 : : }
695 : :
696 : 0 : int nfs_writepage(struct page *page, struct writeback_control *wbc)
697 : : {
698 : : int ret;
699 : :
700 : 0 : ret = nfs_writepage_locked(page, wbc);
701 [ # # ]: 0 : if (ret != AOP_WRITEPAGE_ACTIVATE)
702 : 0 : unlock_page(page);
703 : 0 : return ret;
704 : : }
705 : :
706 : 0 : static int nfs_writepages_callback(struct page *page, struct writeback_control *wbc, void *data)
707 : : {
708 : : int ret;
709 : :
710 : 0 : ret = nfs_do_writepage(page, wbc, data);
711 [ # # ]: 0 : if (ret != AOP_WRITEPAGE_ACTIVATE)
712 : 0 : unlock_page(page);
713 : 0 : return ret;
714 : : }
715 : :
716 : 0 : static void nfs_io_completion_commit(void *inode)
717 : : {
718 : : nfs_commit_inode(inode, 0);
719 : 0 : }
720 : :
721 : 0 : int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
722 : : {
723 : 0 : struct inode *inode = mapping->host;
724 : : struct nfs_pageio_descriptor pgio;
725 : : struct nfs_io_completion *ioc;
726 : : int err;
727 : :
728 : 0 : nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
729 : :
730 : : ioc = nfs_io_completion_alloc(GFP_KERNEL);
731 [ # # ]: 0 : if (ioc)
732 : : nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
733 : :
734 : 0 : nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false,
735 : : &nfs_async_write_completion_ops);
736 : 0 : pgio.pg_io_completion = ioc;
737 : 0 : err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
738 : 0 : pgio.pg_error = 0;
739 : 0 : nfs_pageio_complete(&pgio);
740 : : nfs_io_completion_put(ioc);
741 : :
742 [ # # ]: 0 : if (err < 0)
743 : : goto out_err;
744 : 0 : err = pgio.pg_error;
745 [ # # ]: 0 : if (nfs_error_is_fatal(err))
746 : : goto out_err;
747 : : return 0;
748 : : out_err:
749 : 0 : return err;
750 : : }
751 : :
752 : : /*
753 : : * Insert a write request into an inode
754 : : */
755 : 0 : static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
756 : : {
757 : 0 : struct address_space *mapping = page_file_mapping(req->wb_page);
758 : : struct nfs_inode *nfsi = NFS_I(inode);
759 : :
760 [ # # # # ]: 0 : WARN_ON_ONCE(req->wb_this_page != req);
761 : :
762 : : /* Lock the request! */
763 : : nfs_lock_request(req);
764 : :
765 : : /*
766 : : * Swap-space should not get truncated. Hence no need to plug the race
767 : : * with invalidate/truncate.
768 : : */
769 : : spin_lock(&mapping->private_lock);
770 [ # # # # ]: 0 : if (!nfs_have_writebacks(inode) &&
771 : 0 : NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
772 : : inode_inc_iversion_raw(inode);
773 [ # # ]: 0 : if (likely(!PageSwapCache(req->wb_page))) {
774 : 0 : set_bit(PG_MAPPED, &req->wb_flags);
775 : 0 : SetPagePrivate(req->wb_page);
776 : 0 : set_page_private(req->wb_page, (unsigned long)req);
777 : : }
778 : : spin_unlock(&mapping->private_lock);
779 : 0 : atomic_long_inc(&nfsi->nrequests);
780 : : /* this a head request for a page group - mark it as having an
781 : : * extra reference so sub groups can follow suit.
782 : : * This flag also informs pgio layer when to bump nrequests when
783 : : * adding subrequests. */
784 [ # # ]: 0 : WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags));
785 : : kref_get(&req->wb_kref);
786 : 0 : }
787 : :
788 : : /*
789 : : * Remove a write request from an inode
790 : : */
791 : 0 : static void nfs_inode_remove_request(struct nfs_page *req)
792 : : {
793 : 0 : struct address_space *mapping = page_file_mapping(req->wb_page);
794 : 0 : struct inode *inode = mapping->host;
795 : : struct nfs_inode *nfsi = NFS_I(inode);
796 : : struct nfs_page *head;
797 : :
798 [ # # ]: 0 : if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) {
799 : 0 : head = req->wb_head;
800 : :
801 : : spin_lock(&mapping->private_lock);
802 [ # # # # ]: 0 : if (likely(head->wb_page && !PageSwapCache(head->wb_page))) {
803 : 0 : set_page_private(head->wb_page, 0);
804 : 0 : ClearPagePrivate(head->wb_page);
805 : 0 : clear_bit(PG_MAPPED, &head->wb_flags);
806 : : }
807 : : spin_unlock(&mapping->private_lock);
808 : : }
809 : :
810 [ # # ]: 0 : if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) {
811 : 0 : nfs_release_request(req);
812 : 0 : atomic_long_dec(&nfsi->nrequests);
813 : : }
814 : 0 : }
815 : :
816 : : static void
817 : : nfs_mark_request_dirty(struct nfs_page *req)
818 : : {
819 [ # # # # : 0 : if (req->wb_page)
# # # # ]
820 : 0 : __set_page_dirty_nobuffers(req->wb_page);
821 : : }
822 : :
823 : : /*
824 : : * nfs_page_search_commits_for_head_request_locked
825 : : *
826 : : * Search through commit lists on @inode for the head request for @page.
827 : : * Must be called while holding the inode (which is cinfo) lock.
828 : : *
829 : : * Returns the head request if found, or NULL if not found.
830 : : */
831 : : static struct nfs_page *
832 : 0 : nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi,
833 : : struct page *page)
834 : : {
835 : : struct nfs_page *freq, *t;
836 : : struct nfs_commit_info cinfo;
837 : 0 : struct inode *inode = &nfsi->vfs_inode;
838 : :
839 : 0 : nfs_init_cinfo_from_inode(&cinfo, inode);
840 : :
841 : : /* search through pnfs commit lists */
842 : : freq = pnfs_search_commit_reqs(inode, &cinfo, page);
843 [ # # ]: 0 : if (freq)
844 : 0 : return freq->wb_head;
845 : :
846 : : /* Linearly search the commit list for the correct request */
847 [ # # ]: 0 : list_for_each_entry_safe(freq, t, &cinfo.mds->list, wb_list) {
848 [ # # ]: 0 : if (freq->wb_page == page)
849 : 0 : return freq->wb_head;
850 : : }
851 : :
852 : : return NULL;
853 : : }
854 : :
855 : : /**
856 : : * nfs_request_add_commit_list_locked - add request to a commit list
857 : : * @req: pointer to a struct nfs_page
858 : : * @dst: commit list head
859 : : * @cinfo: holds list lock and accounting info
860 : : *
861 : : * This sets the PG_CLEAN bit, updates the cinfo count of
862 : : * number of outstanding requests requiring a commit as well as
863 : : * the MM page stats.
864 : : *
865 : : * The caller must hold NFS_I(cinfo->inode)->commit_mutex, and the
866 : : * nfs_page lock.
867 : : */
868 : : void
869 : 0 : nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst,
870 : : struct nfs_commit_info *cinfo)
871 : : {
872 : 0 : set_bit(PG_CLEAN, &req->wb_flags);
873 : : nfs_list_add_request(req, dst);
874 : 0 : atomic_long_inc(&cinfo->mds->ncommit);
875 : 0 : }
876 : : EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked);
877 : :
878 : : /**
879 : : * nfs_request_add_commit_list - add request to a commit list
880 : : * @req: pointer to a struct nfs_page
881 : : * @cinfo: holds list lock and accounting info
882 : : *
883 : : * This sets the PG_CLEAN bit, updates the cinfo count of
884 : : * number of outstanding requests requiring a commit as well as
885 : : * the MM page stats.
886 : : *
887 : : * The caller must _not_ hold the cinfo->lock, but must be
888 : : * holding the nfs_page lock.
889 : : */
890 : : void
891 : 0 : nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo)
892 : : {
893 : 0 : mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
894 : 0 : nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo);
895 : 0 : mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
896 [ # # ]: 0 : if (req->wb_page)
897 : 0 : nfs_mark_page_unstable(req->wb_page, cinfo);
898 : 0 : }
899 : : EXPORT_SYMBOL_GPL(nfs_request_add_commit_list);
900 : :
901 : : /**
902 : : * nfs_request_remove_commit_list - Remove request from a commit list
903 : : * @req: pointer to a nfs_page
904 : : * @cinfo: holds list lock and accounting info
905 : : *
906 : : * This clears the PG_CLEAN bit, and updates the cinfo's count of
907 : : * number of outstanding requests requiring a commit
908 : : * It does not update the MM page stats.
909 : : *
910 : : * The caller _must_ hold the cinfo->lock and the nfs_page lock.
911 : : */
912 : : void
913 : 0 : nfs_request_remove_commit_list(struct nfs_page *req,
914 : : struct nfs_commit_info *cinfo)
915 : : {
916 [ # # ]: 0 : if (!test_and_clear_bit(PG_CLEAN, &(req)->wb_flags))
917 : 0 : return;
918 : : nfs_list_remove_request(req);
919 : 0 : atomic_long_dec(&cinfo->mds->ncommit);
920 : : }
921 : : EXPORT_SYMBOL_GPL(nfs_request_remove_commit_list);
922 : :
923 : 0 : static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
924 : : struct inode *inode)
925 : : {
926 : 0 : cinfo->inode = inode;
927 : 0 : cinfo->mds = &NFS_I(inode)->commit_info;
928 : 0 : cinfo->ds = pnfs_get_ds_info(inode);
929 : 0 : cinfo->dreq = NULL;
930 : 0 : cinfo->completion_ops = &nfs_commit_completion_ops;
931 : 0 : }
932 : :
933 : 0 : void nfs_init_cinfo(struct nfs_commit_info *cinfo,
934 : : struct inode *inode,
935 : : struct nfs_direct_req *dreq)
936 : : {
937 [ # # ]: 0 : if (dreq)
938 : 0 : nfs_init_cinfo_from_dreq(cinfo, dreq);
939 : : else
940 : 0 : nfs_init_cinfo_from_inode(cinfo, inode);
941 : 0 : }
942 : : EXPORT_SYMBOL_GPL(nfs_init_cinfo);
943 : :
944 : : /*
945 : : * Add a request to the inode's commit list.
946 : : */
947 : : void
948 : 0 : nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
949 : : struct nfs_commit_info *cinfo, u32 ds_commit_idx)
950 : : {
951 [ # # ]: 0 : if (pnfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx))
952 : 0 : return;
953 : 0 : nfs_request_add_commit_list(req, cinfo);
954 : : }
955 : :
956 : : static void
957 : 0 : nfs_clear_page_commit(struct page *page)
958 : : {
959 : 0 : dec_node_page_state(page, NR_UNSTABLE_NFS);
960 : 0 : dec_wb_stat(&inode_to_bdi(page_file_mapping(page)->host)->wb,
961 : : WB_RECLAIMABLE);
962 : 0 : }
963 : :
964 : : /* Called holding the request lock on @req */
965 : : static void
966 : 0 : nfs_clear_request_commit(struct nfs_page *req)
967 : : {
968 [ # # ]: 0 : if (test_bit(PG_CLEAN, &req->wb_flags)) {
969 : : struct nfs_open_context *ctx = nfs_req_openctx(req);
970 : 0 : struct inode *inode = d_inode(ctx->dentry);
971 : : struct nfs_commit_info cinfo;
972 : :
973 : 0 : nfs_init_cinfo_from_inode(&cinfo, inode);
974 : 0 : mutex_lock(&NFS_I(inode)->commit_mutex);
975 [ # # ]: 0 : if (!pnfs_clear_request_commit(req, &cinfo)) {
976 : 0 : nfs_request_remove_commit_list(req, &cinfo);
977 : : }
978 : 0 : mutex_unlock(&NFS_I(inode)->commit_mutex);
979 : 0 : nfs_clear_page_commit(req->wb_page);
980 : : }
981 : 0 : }
982 : :
983 : 0 : int nfs_write_need_commit(struct nfs_pgio_header *hdr)
984 : : {
985 [ # # # # ]: 0 : if (hdr->verf.committed == NFS_DATA_SYNC)
986 : 0 : return hdr->lseg == NULL;
987 : 0 : return hdr->verf.committed != NFS_FILE_SYNC;
988 : : }
989 : :
990 : 0 : static void nfs_async_write_init(struct nfs_pgio_header *hdr)
991 : : {
992 : 0 : nfs_io_completion_get(hdr->io_completion);
993 : 0 : }
994 : :
995 : 0 : static void nfs_write_completion(struct nfs_pgio_header *hdr)
996 : : {
997 : : struct nfs_commit_info cinfo;
998 : : unsigned long bytes = 0;
999 : :
1000 [ # # ]: 0 : if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
1001 : : goto out;
1002 : 0 : nfs_init_cinfo_from_inode(&cinfo, hdr->inode);
1003 [ # # ]: 0 : while (!list_empty(&hdr->pages)) {
1004 : 0 : struct nfs_page *req = nfs_list_entry(hdr->pages.next);
1005 : :
1006 : 0 : bytes += req->wb_bytes;
1007 : : nfs_list_remove_request(req);
1008 [ # # # # ]: 0 : if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
1009 : 0 : (hdr->good_bytes < bytes)) {
1010 : 0 : nfs_set_pageerror(page_file_mapping(req->wb_page));
1011 : 0 : nfs_mapping_set_error(req->wb_page, hdr->error);
1012 : 0 : goto remove_req;
1013 : : }
1014 [ # # ]: 0 : if (nfs_write_need_commit(hdr)) {
1015 : : /* Reset wb_nio, since the write was successful. */
1016 : 0 : req->wb_nio = 0;
1017 : 0 : memcpy(&req->wb_verf, &hdr->verf.verifier, sizeof(req->wb_verf));
1018 : 0 : nfs_mark_request_commit(req, hdr->lseg, &cinfo,
1019 : 0 : hdr->pgio_mirror_idx);
1020 : 0 : goto next;
1021 : : }
1022 : : remove_req:
1023 : 0 : nfs_inode_remove_request(req);
1024 : : next:
1025 : 0 : nfs_end_page_writeback(req);
1026 : 0 : nfs_release_request(req);
1027 : : }
1028 : : out:
1029 : 0 : nfs_io_completion_put(hdr->io_completion);
1030 : 0 : hdr->release(hdr);
1031 : 0 : }
1032 : :
1033 : : unsigned long
1034 : 0 : nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
1035 : : {
1036 : 0 : return atomic_long_read(&cinfo->mds->ncommit);
1037 : : }
1038 : :
1039 : : /* NFS_I(cinfo->inode)->commit_mutex held by caller */
1040 : : int
1041 : 0 : nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
1042 : : struct nfs_commit_info *cinfo, int max)
1043 : : {
1044 : : struct nfs_page *req, *tmp;
1045 : : int ret = 0;
1046 : :
1047 : : restart:
1048 [ # # ]: 0 : list_for_each_entry_safe(req, tmp, src, wb_list) {
1049 : : kref_get(&req->wb_kref);
1050 [ # # ]: 0 : if (!nfs_lock_request(req)) {
1051 : : int status;
1052 : :
1053 : : /* Prevent deadlock with nfs_lock_and_join_requests */
1054 [ # # ]: 0 : if (!list_empty(dst)) {
1055 : 0 : nfs_release_request(req);
1056 : 0 : continue;
1057 : : }
1058 : : /* Ensure we make progress to prevent livelock */
1059 : 0 : mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
1060 : 0 : status = nfs_wait_on_request(req);
1061 : 0 : nfs_release_request(req);
1062 : 0 : mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
1063 [ # # ]: 0 : if (status < 0)
1064 : : break;
1065 : : goto restart;
1066 : : }
1067 : 0 : nfs_request_remove_commit_list(req, cinfo);
1068 : 0 : clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
1069 : : nfs_list_add_request(req, dst);
1070 : 0 : ret++;
1071 [ # # # # ]: 0 : if ((ret == max) && !cinfo->dreq)
1072 : : break;
1073 : 0 : cond_resched();
1074 : : }
1075 : 0 : return ret;
1076 : : }
1077 : : EXPORT_SYMBOL_GPL(nfs_scan_commit_list);
1078 : :
1079 : : /*
1080 : : * nfs_scan_commit - Scan an inode for commit requests
1081 : : * @inode: NFS inode to scan
1082 : : * @dst: mds destination list
1083 : : * @cinfo: mds and ds lists of reqs ready to commit
1084 : : *
1085 : : * Moves requests from the inode's 'commit' request list.
1086 : : * The requests are *not* checked to ensure that they form a contiguous set.
1087 : : */
1088 : : int
1089 : 0 : nfs_scan_commit(struct inode *inode, struct list_head *dst,
1090 : : struct nfs_commit_info *cinfo)
1091 : : {
1092 : : int ret = 0;
1093 : :
1094 [ # # ]: 0 : if (!atomic_long_read(&cinfo->mds->ncommit))
1095 : : return 0;
1096 : 0 : mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
1097 [ # # ]: 0 : if (atomic_long_read(&cinfo->mds->ncommit) > 0) {
1098 : : const int max = INT_MAX;
1099 : :
1100 : 0 : ret = nfs_scan_commit_list(&cinfo->mds->list, dst,
1101 : : cinfo, max);
1102 : 0 : ret += pnfs_scan_commit_lists(inode, cinfo, max - ret);
1103 : : }
1104 : 0 : mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
1105 : 0 : return ret;
1106 : : }
1107 : :
1108 : : /*
1109 : : * Search for an existing write request, and attempt to update
1110 : : * it to reflect a new dirty region on a given page.
1111 : : *
1112 : : * If the attempt fails, then the existing request is flushed out
1113 : : * to disk.
1114 : : */
1115 : 0 : static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
1116 : : struct page *page,
1117 : : unsigned int offset,
1118 : : unsigned int bytes)
1119 : : {
1120 : : struct nfs_page *req;
1121 : : unsigned int rqend;
1122 : : unsigned int end;
1123 : : int error;
1124 : :
1125 : 0 : end = offset + bytes;
1126 : :
1127 : 0 : req = nfs_lock_and_join_requests(page);
1128 [ # # ]: 0 : if (IS_ERR_OR_NULL(req))
1129 : : return req;
1130 : :
1131 : 0 : rqend = req->wb_offset + req->wb_bytes;
1132 : : /*
1133 : : * Tell the caller to flush out the request if
1134 : : * the offsets are non-contiguous.
1135 : : * Note: nfs_flush_incompatible() will already
1136 : : * have flushed out requests having wrong owners.
1137 : : */
1138 [ # # # # ]: 0 : if (offset > rqend || end < req->wb_offset)
1139 : : goto out_flushme;
1140 : :
1141 : : /* Okay, the request matches. Update the region */
1142 [ # # ]: 0 : if (offset < req->wb_offset) {
1143 : 0 : req->wb_offset = offset;
1144 : 0 : req->wb_pgbase = offset;
1145 : : }
1146 [ # # ]: 0 : if (end > rqend)
1147 : 0 : req->wb_bytes = end - req->wb_offset;
1148 : : else
1149 : 0 : req->wb_bytes = rqend - req->wb_offset;
1150 : 0 : req->wb_nio = 0;
1151 : 0 : return req;
1152 : : out_flushme:
1153 : : /*
1154 : : * Note: we mark the request dirty here because
1155 : : * nfs_lock_and_join_requests() cannot preserve
1156 : : * commit flags, so we have to replay the write.
1157 : : */
1158 : : nfs_mark_request_dirty(req);
1159 : 0 : nfs_unlock_and_release_request(req);
1160 : 0 : error = nfs_wb_page(inode, page);
1161 [ # # ]: 0 : return (error < 0) ? ERR_PTR(error) : NULL;
1162 : : }
1163 : :
1164 : : /*
1165 : : * Try to update an existing write request, or create one if there is none.
1166 : : *
1167 : : * Note: Should always be called with the Page Lock held to prevent races
1168 : : * if we have to add a new request. Also assumes that the caller has
1169 : : * already called nfs_flush_incompatible() if necessary.
1170 : : */
1171 : 0 : static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx,
1172 : : struct page *page, unsigned int offset, unsigned int bytes)
1173 : : {
1174 : 0 : struct inode *inode = page_file_mapping(page)->host;
1175 : : struct nfs_page *req;
1176 : :
1177 : 0 : req = nfs_try_to_update_request(inode, page, offset, bytes);
1178 [ # # ]: 0 : if (req != NULL)
1179 : : goto out;
1180 : 0 : req = nfs_create_request(ctx, page, offset, bytes);
1181 [ # # ]: 0 : if (IS_ERR(req))
1182 : : goto out;
1183 : 0 : nfs_inode_add_request(inode, req);
1184 : : out:
1185 : 0 : return req;
1186 : : }
1187 : :
1188 : 0 : static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
1189 : : unsigned int offset, unsigned int count)
1190 : : {
1191 : : struct nfs_page *req;
1192 : :
1193 : 0 : req = nfs_setup_write_request(ctx, page, offset, count);
1194 [ # # ]: 0 : if (IS_ERR(req))
1195 : 0 : return PTR_ERR(req);
1196 : : /* Update file length */
1197 : 0 : nfs_grow_file(page, offset, count);
1198 : 0 : nfs_mark_uptodate(req);
1199 : : nfs_mark_request_dirty(req);
1200 : 0 : nfs_unlock_and_release_request(req);
1201 : 0 : return 0;
1202 : : }
1203 : :
1204 : 0 : int nfs_flush_incompatible(struct file *file, struct page *page)
1205 : : {
1206 : : struct nfs_open_context *ctx = nfs_file_open_context(file);
1207 : : struct nfs_lock_context *l_ctx;
1208 : 0 : struct file_lock_context *flctx = file_inode(file)->i_flctx;
1209 : : struct nfs_page *req;
1210 : : int do_flush, status;
1211 : : /*
1212 : : * Look for a request corresponding to this page. If there
1213 : : * is one, and it belongs to another file, we flush it out
1214 : : * before we try to copy anything into the page. Do this
1215 : : * due to the lack of an ACCESS-type call in NFSv2.
1216 : : * Also do the same if we find a request from an existing
1217 : : * dropped page.
1218 : : */
1219 : : do {
1220 : 0 : req = nfs_page_find_head_request(page);
1221 [ # # ]: 0 : if (req == NULL)
1222 : : return 0;
1223 : 0 : l_ctx = req->wb_lock_context;
1224 [ # # # # ]: 0 : do_flush = req->wb_page != page ||
1225 : 0 : !nfs_match_open_context(nfs_req_openctx(req), ctx);
1226 [ # # # # ]: 0 : if (l_ctx && flctx &&
1227 [ # # ]: 0 : !(list_empty_careful(&flctx->flc_posix) &&
1228 : 0 : list_empty_careful(&flctx->flc_flock))) {
1229 : 0 : do_flush |= l_ctx->lockowner != current->files;
1230 : : }
1231 : 0 : nfs_release_request(req);
1232 [ # # ]: 0 : if (!do_flush)
1233 : : return 0;
1234 : 0 : status = nfs_wb_page(page_file_mapping(page)->host, page);
1235 [ # # ]: 0 : } while (status == 0);
1236 : 0 : return status;
1237 : : }
1238 : :
1239 : : /*
1240 : : * Avoid buffered writes when a open context credential's key would
1241 : : * expire soon.
1242 : : *
1243 : : * Returns -EACCES if the key will expire within RPC_KEY_EXPIRE_FAIL.
1244 : : *
1245 : : * Return 0 and set a credential flag which triggers the inode to flush
1246 : : * and performs NFS_FILE_SYNC writes if the key will expired within
1247 : : * RPC_KEY_EXPIRE_TIMEO.
1248 : : */
1249 : : int
1250 : 0 : nfs_key_timeout_notify(struct file *filp, struct inode *inode)
1251 : : {
1252 : : struct nfs_open_context *ctx = nfs_file_open_context(filp);
1253 : :
1254 [ # # # # ]: 0 : if (nfs_ctx_key_to_expire(ctx, inode) &&
1255 : 0 : !ctx->ll_cred)
1256 : : /* Already expired! */
1257 : : return -EACCES;
1258 : 0 : return 0;
1259 : : }
1260 : :
1261 : : /*
1262 : : * Test if the open context credential key is marked to expire soon.
1263 : : */
1264 : 0 : bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
1265 : : {
1266 : 0 : struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
1267 : 0 : struct rpc_cred *cred = ctx->ll_cred;
1268 : 0 : struct auth_cred acred = {
1269 : 0 : .cred = ctx->cred,
1270 : : };
1271 : :
1272 [ # # # # ]: 0 : if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
1273 : 0 : put_rpccred(cred);
1274 : 0 : ctx->ll_cred = NULL;
1275 : : cred = NULL;
1276 : : }
1277 [ # # ]: 0 : if (!cred)
1278 : 0 : cred = auth->au_ops->lookup_cred(auth, &acred, 0);
1279 [ # # # # ]: 0 : if (!cred || IS_ERR(cred))
1280 : : return true;
1281 : 0 : ctx->ll_cred = cred;
1282 [ # # # # ]: 0 : return !!(cred->cr_ops->crkey_timeout &&
1283 : 0 : cred->cr_ops->crkey_timeout(cred));
1284 : : }
1285 : :
1286 : : /*
1287 : : * If the page cache is marked as unsafe or invalid, then we can't rely on
1288 : : * the PageUptodate() flag. In this case, we will need to turn off
1289 : : * write optimisations that depend on the page contents being correct.
1290 : : */
1291 : 0 : static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
1292 : : {
1293 : : struct nfs_inode *nfsi = NFS_I(inode);
1294 : :
1295 [ # # ]: 0 : if (nfs_have_delegated_attributes(inode))
1296 : : goto out;
1297 [ # # ]: 0 : if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
1298 : : return false;
1299 : 0 : smp_rmb();
1300 [ # # ]: 0 : if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags))
1301 : : return false;
1302 : : out:
1303 [ # # ]: 0 : if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
1304 : : return false;
1305 : 0 : return PageUptodate(page) != 0;
1306 : : }
1307 : :
1308 : : static bool
1309 : : is_whole_file_wrlock(struct file_lock *fl)
1310 : : {
1311 [ # # # # : 0 : return fl->fl_start == 0 && fl->fl_end == OFFSET_MAX &&
# # ]
1312 : 0 : fl->fl_type == F_WRLCK;
1313 : : }
1314 : :
1315 : : /* If we know the page is up to date, and we're not using byte range locks (or
1316 : : * if we have the whole file locked for writing), it may be more efficient to
1317 : : * extend the write to cover the entire page in order to avoid fragmentation
1318 : : * inefficiencies.
1319 : : *
1320 : : * If the file is opened for synchronous writes then we can just skip the rest
1321 : : * of the checks.
1322 : : */
1323 : 0 : static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
1324 : : {
1325 : : int ret;
1326 : 0 : struct file_lock_context *flctx = inode->i_flctx;
1327 : : struct file_lock *fl;
1328 : :
1329 [ # # ]: 0 : if (file->f_flags & O_DSYNC)
1330 : : return 0;
1331 [ # # ]: 0 : if (!nfs_write_pageuptodate(page, inode))
1332 : : return 0;
1333 [ # # ]: 0 : if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
1334 : : return 1;
1335 [ # # # # : 0 : if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
# # ]
1336 : 0 : list_empty_careful(&flctx->flc_posix)))
1337 : : return 1;
1338 : :
1339 : : /* Check to see if there are whole file write locks */
1340 : : ret = 0;
1341 : : spin_lock(&flctx->flc_lock);
1342 [ # # ]: 0 : if (!list_empty(&flctx->flc_posix)) {
1343 : 0 : fl = list_first_entry(&flctx->flc_posix, struct file_lock,
1344 : : fl_list);
1345 [ # # ]: 0 : if (is_whole_file_wrlock(fl))
1346 : : ret = 1;
1347 [ # # ]: 0 : } else if (!list_empty(&flctx->flc_flock)) {
1348 : 0 : fl = list_first_entry(&flctx->flc_flock, struct file_lock,
1349 : : fl_list);
1350 [ # # ]: 0 : if (fl->fl_type == F_WRLCK)
1351 : : ret = 1;
1352 : : }
1353 : : spin_unlock(&flctx->flc_lock);
1354 : 0 : return ret;
1355 : : }
1356 : :
1357 : : /*
1358 : : * Update and possibly write a cached page of an NFS file.
1359 : : *
1360 : : * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
1361 : : * things with a page scheduled for an RPC call (e.g. invalidate it).
1362 : : */
1363 : 0 : int nfs_updatepage(struct file *file, struct page *page,
1364 : : unsigned int offset, unsigned int count)
1365 : : {
1366 : : struct nfs_open_context *ctx = nfs_file_open_context(file);
1367 : 0 : struct address_space *mapping = page_file_mapping(page);
1368 : 0 : struct inode *inode = mapping->host;
1369 : : int status = 0;
1370 : :
1371 : 0 : nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
1372 : :
1373 : : dprintk("NFS: nfs_updatepage(%pD2 %d@%lld)\n",
1374 : : file, count, (long long)(page_file_offset(page) + offset));
1375 : :
1376 [ # # ]: 0 : if (!count)
1377 : : goto out;
1378 : :
1379 [ # # ]: 0 : if (nfs_can_extend_write(file, page, inode)) {
1380 : 0 : count = max(count + offset, nfs_page_length(page));
1381 : : offset = 0;
1382 : : }
1383 : :
1384 : 0 : status = nfs_writepage_setup(ctx, page, offset, count);
1385 [ # # ]: 0 : if (status < 0)
1386 : 0 : nfs_set_pageerror(mapping);
1387 : : else
1388 : 0 : __set_page_dirty_nobuffers(page);
1389 : : out:
1390 : : dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
1391 : : status, (long long)i_size_read(inode));
1392 : 0 : return status;
1393 : : }
1394 : :
1395 : : static int flush_task_priority(int how)
1396 : : {
1397 [ # # # # : 0 : switch (how & (FLUSH_HIGHPRI|FLUSH_LOWPRI)) {
# # ]
1398 : : case FLUSH_HIGHPRI:
1399 : : return RPC_PRIORITY_HIGH;
1400 : : case FLUSH_LOWPRI:
1401 : : return RPC_PRIORITY_LOW;
1402 : : }
1403 : : return RPC_PRIORITY_NORMAL;
1404 : : }
1405 : :
1406 : 0 : static void nfs_initiate_write(struct nfs_pgio_header *hdr,
1407 : : struct rpc_message *msg,
1408 : : const struct nfs_rpc_ops *rpc_ops,
1409 : : struct rpc_task_setup *task_setup_data, int how)
1410 : : {
1411 : : int priority = flush_task_priority(how);
1412 : :
1413 : 0 : task_setup_data->priority = priority;
1414 : 0 : rpc_ops->write_setup(hdr, msg, &task_setup_data->rpc_client);
1415 : 0 : trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes,
1416 : : hdr->args.stable);
1417 : 0 : }
1418 : :
1419 : : /* If a nfs_flush_* function fails, it should remove reqs from @head and
1420 : : * call this on each, which will prepare them to be retried on next
1421 : : * writeback using standard nfs.
1422 : : */
1423 : 0 : static void nfs_redirty_request(struct nfs_page *req)
1424 : : {
1425 : : /* Bump the transmission count */
1426 : 0 : req->wb_nio++;
1427 : : nfs_mark_request_dirty(req);
1428 : 0 : set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
1429 : 0 : nfs_end_page_writeback(req);
1430 : 0 : nfs_release_request(req);
1431 : 0 : }
1432 : :
1433 : 0 : static void nfs_async_write_error(struct list_head *head, int error)
1434 : : {
1435 : : struct nfs_page *req;
1436 : :
1437 [ # # ]: 0 : while (!list_empty(head)) {
1438 : 0 : req = nfs_list_entry(head->next);
1439 : : nfs_list_remove_request(req);
1440 [ # # ]: 0 : if (nfs_error_is_fatal(error))
1441 : 0 : nfs_write_error(req, error);
1442 : : else
1443 : 0 : nfs_redirty_request(req);
1444 : : }
1445 : 0 : }
1446 : :
1447 : 0 : static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
1448 : : {
1449 : 0 : nfs_async_write_error(&hdr->pages, 0);
1450 : 0 : filemap_fdatawrite_range(hdr->inode->i_mapping, hdr->args.offset,
1451 : 0 : hdr->args.offset + hdr->args.count - 1);
1452 : 0 : }
1453 : :
1454 : : static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
1455 : : .init_hdr = nfs_async_write_init,
1456 : : .error_cleanup = nfs_async_write_error,
1457 : : .completion = nfs_write_completion,
1458 : : .reschedule_io = nfs_async_write_reschedule_io,
1459 : : };
1460 : :
1461 : 0 : void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
1462 : : struct inode *inode, int ioflags, bool force_mds,
1463 : : const struct nfs_pgio_completion_ops *compl_ops)
1464 : : {
1465 : : struct nfs_server *server = NFS_SERVER(inode);
1466 : : const struct nfs_pageio_ops *pg_ops = &nfs_pgio_rw_ops;
1467 : :
1468 : : #ifdef CONFIG_NFS_V4_1
1469 [ # # # # ]: 0 : if (server->pnfs_curr_ld && !force_mds)
1470 : 0 : pg_ops = server->pnfs_curr_ld->pg_write_ops;
1471 : : #endif
1472 : 0 : nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_write_ops,
1473 : : server->wsize, ioflags);
1474 : 0 : }
1475 : : EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
1476 : :
1477 : 0 : void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
1478 : : {
1479 : : struct nfs_pgio_mirror *mirror;
1480 : :
1481 [ # # # # ]: 0 : if (pgio->pg_ops && pgio->pg_ops->pg_cleanup)
1482 : 0 : pgio->pg_ops->pg_cleanup(pgio);
1483 : :
1484 : 0 : pgio->pg_ops = &nfs_pgio_rw_ops;
1485 : :
1486 : 0 : nfs_pageio_stop_mirroring(pgio);
1487 : :
1488 : 0 : mirror = &pgio->pg_mirrors[0];
1489 : 0 : mirror->pg_bsize = NFS_SERVER(pgio->pg_inode)->wsize;
1490 : 0 : }
1491 : : EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds);
1492 : :
1493 : :
1494 : 0 : void nfs_commit_prepare(struct rpc_task *task, void *calldata)
1495 : : {
1496 : : struct nfs_commit_data *data = calldata;
1497 : :
1498 : 0 : NFS_PROTO(data->inode)->commit_rpc_prepare(task, data);
1499 : 0 : }
1500 : :
1501 : : /*
1502 : : * Special version of should_remove_suid() that ignores capabilities.
1503 : : */
1504 : : static int nfs_should_remove_suid(const struct inode *inode)
1505 : : {
1506 : 0 : umode_t mode = inode->i_mode;
1507 : : int kill = 0;
1508 : :
1509 : : /* suid always must be killed */
1510 [ # # ]: 0 : if (unlikely(mode & S_ISUID))
1511 : : kill = ATTR_KILL_SUID;
1512 : :
1513 : : /*
1514 : : * sgid without any exec bits is just a mandatory locking mark; leave
1515 : : * it alone. If some exec bits are set, it's a real sgid; kill it.
1516 : : */
1517 [ # # ]: 0 : if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
1518 : 0 : kill |= ATTR_KILL_SGID;
1519 : :
1520 [ # # # # ]: 0 : if (unlikely(kill && S_ISREG(mode)))
1521 : : return kill;
1522 : :
1523 : : return 0;
1524 : : }
1525 : :
1526 : 0 : static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr,
1527 : : struct nfs_fattr *fattr)
1528 : : {
1529 : : struct nfs_pgio_args *argp = &hdr->args;
1530 : : struct nfs_pgio_res *resp = &hdr->res;
1531 : 0 : u64 size = argp->offset + resp->count;
1532 : :
1533 [ # # ]: 0 : if (!(fattr->valid & NFS_ATTR_FATTR_SIZE))
1534 : 0 : fattr->size = size;
1535 [ # # ]: 0 : if (nfs_size_to_loff_t(fattr->size) < i_size_read(hdr->inode)) {
1536 : 0 : fattr->valid &= ~NFS_ATTR_FATTR_SIZE;
1537 : 0 : return;
1538 : : }
1539 [ # # ]: 0 : if (size != fattr->size)
1540 : : return;
1541 : : /* Set attribute barrier */
1542 : 0 : nfs_fattr_set_barrier(fattr);
1543 : : /* ...and update size */
1544 : 0 : fattr->valid |= NFS_ATTR_FATTR_SIZE;
1545 : : }
1546 : :
1547 : 0 : void nfs_writeback_update_inode(struct nfs_pgio_header *hdr)
1548 : : {
1549 : 0 : struct nfs_fattr *fattr = &hdr->fattr;
1550 : 0 : struct inode *inode = hdr->inode;
1551 : :
1552 : : spin_lock(&inode->i_lock);
1553 : 0 : nfs_writeback_check_extend(hdr, fattr);
1554 : 0 : nfs_post_op_update_inode_force_wcc_locked(inode, fattr);
1555 : : spin_unlock(&inode->i_lock);
1556 : 0 : }
1557 : : EXPORT_SYMBOL_GPL(nfs_writeback_update_inode);
1558 : :
1559 : : /*
1560 : : * This function is called when the WRITE call is complete.
1561 : : */
1562 : 0 : static int nfs_writeback_done(struct rpc_task *task,
1563 : : struct nfs_pgio_header *hdr,
1564 : : struct inode *inode)
1565 : : {
1566 : : int status;
1567 : :
1568 : : /*
1569 : : * ->write_done will attempt to use post-op attributes to detect
1570 : : * conflicting writes by other clients. A strict interpretation
1571 : : * of close-to-open would allow us to continue caching even if
1572 : : * another writer had changed the file, but some applications
1573 : : * depend on tighter cache coherency when writing.
1574 : : */
1575 : 0 : status = NFS_PROTO(inode)->write_done(task, hdr);
1576 [ # # ]: 0 : if (status != 0)
1577 : : return status;
1578 : :
1579 : 0 : nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count);
1580 : 0 : trace_nfs_writeback_done(inode, task->tk_status,
1581 : 0 : hdr->args.offset, hdr->res.verf);
1582 : :
1583 [ # # # # ]: 0 : if (hdr->res.verf->committed < hdr->args.stable &&
1584 : 0 : task->tk_status >= 0) {
1585 : : /* We tried a write call, but the server did not
1586 : : * commit data to stable storage even though we
1587 : : * requested it.
1588 : : * Note: There is a known bug in Tru64 < 5.0 in which
1589 : : * the server reports NFS_DATA_SYNC, but performs
1590 : : * NFS_FILE_SYNC. We therefore implement this checking
1591 : : * as a dprintk() in order to avoid filling syslog.
1592 : : */
1593 : : static unsigned long complain;
1594 : :
1595 : : /* Note this will print the MDS for a DS write */
1596 [ # # ]: 0 : if (time_before(complain, jiffies)) {
1597 : : dprintk("NFS: faulty NFS server %s:"
1598 : : " (committed = %d) != (stable = %d)\n",
1599 : : NFS_SERVER(inode)->nfs_client->cl_hostname,
1600 : : hdr->res.verf->committed, hdr->args.stable);
1601 : 0 : complain = jiffies + 300 * HZ;
1602 : : }
1603 : : }
1604 : :
1605 : : /* Deal with the suid/sgid bit corner case */
1606 [ # # ]: 0 : if (nfs_should_remove_suid(inode)) {
1607 : : spin_lock(&inode->i_lock);
1608 : 0 : NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
1609 : : spin_unlock(&inode->i_lock);
1610 : : }
1611 : : return 0;
1612 : : }
1613 : :
1614 : : /*
1615 : : * This function is called when the WRITE call is complete.
1616 : : */
1617 : 0 : static void nfs_writeback_result(struct rpc_task *task,
1618 : : struct nfs_pgio_header *hdr)
1619 : : {
1620 : : struct nfs_pgio_args *argp = &hdr->args;
1621 : : struct nfs_pgio_res *resp = &hdr->res;
1622 : :
1623 [ # # ]: 0 : if (resp->count < argp->count) {
1624 : : static unsigned long complain;
1625 : :
1626 : : /* This a short write! */
1627 : 0 : nfs_inc_stats(hdr->inode, NFSIOS_SHORTWRITE);
1628 : :
1629 : : /* Has the server at least made some progress? */
1630 [ # # ]: 0 : if (resp->count == 0) {
1631 [ # # ]: 0 : if (time_before(complain, jiffies)) {
1632 : 0 : printk(KERN_WARNING
1633 : : "NFS: Server wrote zero bytes, expected %u.\n",
1634 : : argp->count);
1635 : 0 : complain = jiffies + 300 * HZ;
1636 : : }
1637 : 0 : nfs_set_pgio_error(hdr, -EIO, argp->offset);
1638 : 0 : task->tk_status = -EIO;
1639 : 0 : return;
1640 : : }
1641 : :
1642 : : /* For non rpc-based layout drivers, retry-through-MDS */
1643 [ # # ]: 0 : if (!task->tk_ops) {
1644 : 0 : hdr->pnfs_error = -EAGAIN;
1645 : 0 : return;
1646 : : }
1647 : :
1648 : : /* Was this an NFSv2 write or an NFSv3 stable write? */
1649 [ # # ]: 0 : if (resp->verf->committed != NFS_UNSTABLE) {
1650 : : /* Resend from where the server left off */
1651 : 0 : hdr->mds_offset += resp->count;
1652 : 0 : argp->offset += resp->count;
1653 : 0 : argp->pgbase += resp->count;
1654 : 0 : argp->count -= resp->count;
1655 : : } else {
1656 : : /* Resend as a stable write in order to avoid
1657 : : * headaches in the case of a server crash.
1658 : : */
1659 : 0 : argp->stable = NFS_FILE_SYNC;
1660 : : }
1661 : 0 : rpc_restart_call_prepare(task);
1662 : : }
1663 : : }
1664 : :
1665 : 0 : static int wait_on_commit(struct nfs_mds_commit_info *cinfo)
1666 : : {
1667 [ # # # # : 0 : return wait_var_event_killable(&cinfo->rpcs_out,
# # ]
1668 : : !atomic_read(&cinfo->rpcs_out));
1669 : : }
1670 : :
1671 : : static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
1672 : : {
1673 : 0 : atomic_inc(&cinfo->rpcs_out);
1674 : : }
1675 : :
1676 : 0 : static void nfs_commit_end(struct nfs_mds_commit_info *cinfo)
1677 : : {
1678 [ # # ]: 0 : if (atomic_dec_and_test(&cinfo->rpcs_out))
1679 : 0 : wake_up_var(&cinfo->rpcs_out);
1680 : 0 : }
1681 : :
1682 : 0 : void nfs_commitdata_release(struct nfs_commit_data *data)
1683 : : {
1684 : 0 : put_nfs_open_context(data->context);
1685 : : nfs_commit_free(data);
1686 : 0 : }
1687 : : EXPORT_SYMBOL_GPL(nfs_commitdata_release);
1688 : :
1689 : 0 : int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
1690 : : const struct nfs_rpc_ops *nfs_ops,
1691 : : const struct rpc_call_ops *call_ops,
1692 : : int how, int flags)
1693 : : {
1694 : : struct rpc_task *task;
1695 : : int priority = flush_task_priority(how);
1696 : 0 : struct rpc_message msg = {
1697 : 0 : .rpc_argp = &data->args,
1698 : 0 : .rpc_resp = &data->res,
1699 : 0 : .rpc_cred = data->cred,
1700 : : };
1701 : 0 : struct rpc_task_setup task_setup_data = {
1702 : 0 : .task = &data->task,
1703 : : .rpc_client = clnt,
1704 : : .rpc_message = &msg,
1705 : : .callback_ops = call_ops,
1706 : : .callback_data = data,
1707 : : .workqueue = nfsiod_workqueue,
1708 : : .flags = RPC_TASK_ASYNC | flags,
1709 : : .priority = priority,
1710 : : };
1711 : : /* Set up the initial task struct. */
1712 : 0 : nfs_ops->commit_setup(data, &msg, &task_setup_data.rpc_client);
1713 : 0 : trace_nfs_initiate_commit(data);
1714 : :
1715 : : dprintk("NFS: initiated commit call\n");
1716 : :
1717 : 0 : task = rpc_run_task(&task_setup_data);
1718 [ # # ]: 0 : if (IS_ERR(task))
1719 : 0 : return PTR_ERR(task);
1720 [ # # ]: 0 : if (how & FLUSH_SYNC)
1721 : : rpc_wait_for_completion_task(task);
1722 : 0 : rpc_put_task(task);
1723 : 0 : return 0;
1724 : : }
1725 : : EXPORT_SYMBOL_GPL(nfs_initiate_commit);
1726 : :
1727 : : static loff_t nfs_get_lwb(struct list_head *head)
1728 : : {
1729 : : loff_t lwb = 0;
1730 : : struct nfs_page *req;
1731 : :
1732 [ # # ]: 0 : list_for_each_entry(req, head, wb_list)
1733 [ # # ]: 0 : if (lwb < (req_offset(req) + req->wb_bytes))
1734 : : lwb = req_offset(req) + req->wb_bytes;
1735 : :
1736 : 0 : return lwb;
1737 : : }
1738 : :
1739 : : /*
1740 : : * Set up the argument/result storage required for the RPC call.
1741 : : */
1742 : 0 : void nfs_init_commit(struct nfs_commit_data *data,
1743 : : struct list_head *head,
1744 : : struct pnfs_layout_segment *lseg,
1745 : : struct nfs_commit_info *cinfo)
1746 : : {
1747 : 0 : struct nfs_page *first = nfs_list_entry(head->next);
1748 : : struct nfs_open_context *ctx = nfs_req_openctx(first);
1749 : 0 : struct inode *inode = d_inode(ctx->dentry);
1750 : :
1751 : : /* Set up the RPC argument and reply structs
1752 : : * NB: take care not to mess about with data->commit et al. */
1753 : :
1754 : 0 : list_splice_init(head, &data->pages);
1755 : :
1756 : 0 : data->inode = inode;
1757 : 0 : data->cred = ctx->cred;
1758 : 0 : data->lseg = lseg; /* reference transferred */
1759 : : /* only set lwb for pnfs commit */
1760 [ # # ]: 0 : if (lseg)
1761 : 0 : data->lwb = nfs_get_lwb(&data->pages);
1762 : 0 : data->mds_ops = &nfs_commit_ops;
1763 : 0 : data->completion_ops = cinfo->completion_ops;
1764 : 0 : data->dreq = cinfo->dreq;
1765 : :
1766 : 0 : data->args.fh = NFS_FH(data->inode);
1767 : : /* Note: we always request a commit of the entire inode */
1768 : 0 : data->args.offset = 0;
1769 : 0 : data->args.count = 0;
1770 : 0 : data->context = get_nfs_open_context(ctx);
1771 : 0 : data->res.fattr = &data->fattr;
1772 : 0 : data->res.verf = &data->verf;
1773 : 0 : nfs_fattr_init(&data->fattr);
1774 : 0 : }
1775 : : EXPORT_SYMBOL_GPL(nfs_init_commit);
1776 : :
1777 : 0 : void nfs_retry_commit(struct list_head *page_list,
1778 : : struct pnfs_layout_segment *lseg,
1779 : : struct nfs_commit_info *cinfo,
1780 : : u32 ds_commit_idx)
1781 : : {
1782 : : struct nfs_page *req;
1783 : :
1784 [ # # ]: 0 : while (!list_empty(page_list)) {
1785 : 0 : req = nfs_list_entry(page_list->next);
1786 : : nfs_list_remove_request(req);
1787 : 0 : nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx);
1788 [ # # ]: 0 : if (!cinfo->dreq)
1789 : 0 : nfs_clear_page_commit(req->wb_page);
1790 : 0 : nfs_unlock_and_release_request(req);
1791 : : }
1792 : 0 : }
1793 : : EXPORT_SYMBOL_GPL(nfs_retry_commit);
1794 : :
1795 : : static void
1796 : 0 : nfs_commit_resched_write(struct nfs_commit_info *cinfo,
1797 : : struct nfs_page *req)
1798 : : {
1799 : 0 : __set_page_dirty_nobuffers(req->wb_page);
1800 : 0 : }
1801 : :
1802 : : /*
1803 : : * Commit dirty pages
1804 : : */
1805 : : static int
1806 : 0 : nfs_commit_list(struct inode *inode, struct list_head *head, int how,
1807 : : struct nfs_commit_info *cinfo)
1808 : : {
1809 : : struct nfs_commit_data *data;
1810 : :
1811 : : /* another commit raced with us */
1812 [ # # ]: 0 : if (list_empty(head))
1813 : : return 0;
1814 : :
1815 : 0 : data = nfs_commitdata_alloc(true);
1816 : :
1817 : : /* Set up the argument struct */
1818 : 0 : nfs_init_commit(data, head, NULL, cinfo);
1819 : 0 : atomic_inc(&cinfo->mds->rpcs_out);
1820 : 0 : return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
1821 : : data->mds_ops, how, 0);
1822 : : }
1823 : :
1824 : : /*
1825 : : * COMMIT call returned
1826 : : */
1827 : 0 : static void nfs_commit_done(struct rpc_task *task, void *calldata)
1828 : : {
1829 : : struct nfs_commit_data *data = calldata;
1830 : :
1831 : : dprintk("NFS: %5u nfs_commit_done (status %d)\n",
1832 : : task->tk_pid, task->tk_status);
1833 : :
1834 : : /* Call the NFS version-specific code */
1835 : 0 : NFS_PROTO(data->inode)->commit_done(task, data);
1836 : 0 : trace_nfs_commit_done(data);
1837 : 0 : }
1838 : :
1839 : 0 : static void nfs_commit_release_pages(struct nfs_commit_data *data)
1840 : : {
1841 : 0 : const struct nfs_writeverf *verf = data->res.verf;
1842 : : struct nfs_page *req;
1843 : 0 : int status = data->task.tk_status;
1844 : : struct nfs_commit_info cinfo;
1845 : : struct nfs_server *nfss;
1846 : :
1847 [ # # ]: 0 : while (!list_empty(&data->pages)) {
1848 : 0 : req = nfs_list_entry(data->pages.next);
1849 : : nfs_list_remove_request(req);
1850 [ # # ]: 0 : if (req->wb_page)
1851 : 0 : nfs_clear_page_commit(req->wb_page);
1852 : :
1853 : : dprintk("NFS: commit (%s/%llu %d@%lld)",
1854 : : nfs_req_openctx(req)->dentry->d_sb->s_id,
1855 : : (unsigned long long)NFS_FILEID(d_inode(nfs_req_openctx(req)->dentry)),
1856 : : req->wb_bytes,
1857 : : (long long)req_offset(req));
1858 [ # # ]: 0 : if (status < 0) {
1859 [ # # ]: 0 : if (req->wb_page) {
1860 : 0 : nfs_mapping_set_error(req->wb_page, status);
1861 : 0 : nfs_inode_remove_request(req);
1862 : : }
1863 : : dprintk_cont(", error = %d\n", status);
1864 : : goto next;
1865 : : }
1866 : :
1867 : : /* Okay, COMMIT succeeded, apparently. Check the verifier
1868 : : * returned by the server against all stored verfs. */
1869 [ # # # # ]: 0 : if (verf->committed > NFS_UNSTABLE &&
1870 : : !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier)) {
1871 : : /* We have a match */
1872 [ # # ]: 0 : if (req->wb_page)
1873 : 0 : nfs_inode_remove_request(req);
1874 : : dprintk_cont(" OK\n");
1875 : : goto next;
1876 : : }
1877 : : /* We have a mismatch. Write the page again */
1878 : : dprintk_cont(" mismatch\n");
1879 : : nfs_mark_request_dirty(req);
1880 : 0 : set_bit(NFS_CONTEXT_RESEND_WRITES, &nfs_req_openctx(req)->flags);
1881 : : next:
1882 : 0 : nfs_unlock_and_release_request(req);
1883 : : /* Latency breaker */
1884 : 0 : cond_resched();
1885 : : }
1886 : 0 : nfss = NFS_SERVER(data->inode);
1887 [ # # ]: 0 : if (atomic_long_read(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
1888 : 0 : clear_bdi_congested(inode_to_bdi(data->inode), BLK_RW_ASYNC);
1889 : :
1890 : 0 : nfs_init_cinfo(&cinfo, data->inode, data->dreq);
1891 : 0 : nfs_commit_end(cinfo.mds);
1892 : 0 : }
1893 : :
1894 : 0 : static void nfs_commit_release(void *calldata)
1895 : : {
1896 : : struct nfs_commit_data *data = calldata;
1897 : :
1898 : 0 : data->completion_ops->completion(data);
1899 : 0 : nfs_commitdata_release(calldata);
1900 : 0 : }
1901 : :
1902 : : static const struct rpc_call_ops nfs_commit_ops = {
1903 : : .rpc_call_prepare = nfs_commit_prepare,
1904 : : .rpc_call_done = nfs_commit_done,
1905 : : .rpc_release = nfs_commit_release,
1906 : : };
1907 : :
1908 : : static const struct nfs_commit_completion_ops nfs_commit_completion_ops = {
1909 : : .completion = nfs_commit_release_pages,
1910 : : .resched_write = nfs_commit_resched_write,
1911 : : };
1912 : :
1913 : 0 : int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
1914 : : int how, struct nfs_commit_info *cinfo)
1915 : : {
1916 : : int status;
1917 : :
1918 : : status = pnfs_commit_list(inode, head, how, cinfo);
1919 [ # # ]: 0 : if (status == PNFS_NOT_ATTEMPTED)
1920 : 0 : status = nfs_commit_list(inode, head, how, cinfo);
1921 : 0 : return status;
1922 : : }
1923 : :
1924 : 0 : static int __nfs_commit_inode(struct inode *inode, int how,
1925 : : struct writeback_control *wbc)
1926 : : {
1927 : 0 : LIST_HEAD(head);
1928 : : struct nfs_commit_info cinfo;
1929 : 0 : int may_wait = how & FLUSH_SYNC;
1930 : : int ret, nscan;
1931 : :
1932 : 0 : nfs_init_cinfo_from_inode(&cinfo, inode);
1933 : 0 : nfs_commit_begin(cinfo.mds);
1934 : : for (;;) {
1935 : 0 : ret = nscan = nfs_scan_commit(inode, &head, &cinfo);
1936 [ # # ]: 0 : if (ret <= 0)
1937 : : break;
1938 : 0 : ret = nfs_generic_commit_list(inode, &head, how, &cinfo);
1939 [ # # ]: 0 : if (ret < 0)
1940 : : break;
1941 : : ret = 0;
1942 [ # # # # ]: 0 : if (wbc && wbc->sync_mode == WB_SYNC_NONE) {
1943 [ # # ]: 0 : if (nscan < wbc->nr_to_write)
1944 : 0 : wbc->nr_to_write -= nscan;
1945 : : else
1946 : 0 : wbc->nr_to_write = 0;
1947 : : }
1948 [ # # ]: 0 : if (nscan < INT_MAX)
1949 : : break;
1950 : 0 : cond_resched();
1951 : 0 : }
1952 : 0 : nfs_commit_end(cinfo.mds);
1953 [ # # ]: 0 : if (ret || !may_wait)
1954 : : return ret;
1955 : 0 : return wait_on_commit(cinfo.mds);
1956 : : }
1957 : :
1958 : 0 : int nfs_commit_inode(struct inode *inode, int how)
1959 : : {
1960 : 0 : return __nfs_commit_inode(inode, how, NULL);
1961 : : }
1962 : : EXPORT_SYMBOL_GPL(nfs_commit_inode);
1963 : :
1964 : 0 : int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
1965 : : {
1966 : : struct nfs_inode *nfsi = NFS_I(inode);
1967 : : int flags = FLUSH_SYNC;
1968 : : int ret = 0;
1969 : :
1970 [ # # ]: 0 : if (wbc->sync_mode == WB_SYNC_NONE) {
1971 : : /* no commits means nothing needs to be done */
1972 [ # # ]: 0 : if (!atomic_long_read(&nfsi->commit_info.ncommit))
1973 : : goto check_requests_outstanding;
1974 : :
1975 : : /* Don't commit yet if this is a non-blocking flush and there
1976 : : * are a lot of outstanding writes for this mapping.
1977 : : */
1978 [ # # ]: 0 : if (mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK))
1979 : : goto out_mark_dirty;
1980 : :
1981 : : /* don't wait for the COMMIT response */
1982 : : flags = 0;
1983 : : }
1984 : :
1985 : 0 : ret = __nfs_commit_inode(inode, flags, wbc);
1986 [ # # ]: 0 : if (!ret) {
1987 [ # # ]: 0 : if (flags & FLUSH_SYNC)
1988 : : return 0;
1989 [ # # ]: 0 : } else if (atomic_long_read(&nfsi->commit_info.ncommit))
1990 : : goto out_mark_dirty;
1991 : :
1992 : : check_requests_outstanding:
1993 [ # # ]: 0 : if (!atomic_read(&nfsi->commit_info.rpcs_out))
1994 : : return ret;
1995 : : out_mark_dirty:
1996 : 0 : __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1997 : 0 : return ret;
1998 : : }
1999 : : EXPORT_SYMBOL_GPL(nfs_write_inode);
2000 : :
2001 : : /*
2002 : : * Wrapper for filemap_write_and_wait_range()
2003 : : *
2004 : : * Needed for pNFS in order to ensure data becomes visible to the
2005 : : * client.
2006 : : */
2007 : 0 : int nfs_filemap_write_and_wait_range(struct address_space *mapping,
2008 : : loff_t lstart, loff_t lend)
2009 : : {
2010 : : int ret;
2011 : :
2012 : 0 : ret = filemap_write_and_wait_range(mapping, lstart, lend);
2013 [ # # ]: 0 : if (ret == 0)
2014 : 0 : ret = pnfs_sync_inode(mapping->host, true);
2015 : 0 : return ret;
2016 : : }
2017 : : EXPORT_SYMBOL_GPL(nfs_filemap_write_and_wait_range);
2018 : :
2019 : : /*
2020 : : * flush the inode to disk.
2021 : : */
2022 : 0 : int nfs_wb_all(struct inode *inode)
2023 : : {
2024 : : int ret;
2025 : :
2026 : 0 : trace_nfs_writeback_inode_enter(inode);
2027 : :
2028 : 0 : ret = filemap_write_and_wait(inode->i_mapping);
2029 [ # # ]: 0 : if (ret)
2030 : : goto out;
2031 : : ret = nfs_commit_inode(inode, FLUSH_SYNC);
2032 [ # # ]: 0 : if (ret < 0)
2033 : : goto out;
2034 : : pnfs_sync_inode(inode, true);
2035 : : ret = 0;
2036 : :
2037 : : out:
2038 : 0 : trace_nfs_writeback_inode_exit(inode, ret);
2039 : 0 : return ret;
2040 : : }
2041 : : EXPORT_SYMBOL_GPL(nfs_wb_all);
2042 : :
2043 : 0 : int nfs_wb_page_cancel(struct inode *inode, struct page *page)
2044 : : {
2045 : : struct nfs_page *req;
2046 : : int ret = 0;
2047 : :
2048 : 0 : wait_on_page_writeback(page);
2049 : :
2050 : : /* blocking call to cancel all requests and join to a single (head)
2051 : : * request */
2052 : 0 : req = nfs_lock_and_join_requests(page);
2053 : :
2054 [ # # ]: 0 : if (IS_ERR(req)) {
2055 : : ret = PTR_ERR(req);
2056 [ # # ]: 0 : } else if (req) {
2057 : : /* all requests from this page have been cancelled by
2058 : : * nfs_lock_and_join_requests, so just remove the head
2059 : : * request from the inode / page_private pointer and
2060 : : * release it */
2061 : 0 : nfs_inode_remove_request(req);
2062 : 0 : nfs_unlock_and_release_request(req);
2063 : : }
2064 : :
2065 : 0 : return ret;
2066 : : }
2067 : :
2068 : : /*
2069 : : * Write back all requests on one page - we do this before reading it.
2070 : : */
2071 : 0 : int nfs_wb_page(struct inode *inode, struct page *page)
2072 : : {
2073 : : loff_t range_start = page_file_offset(page);
2074 : 0 : loff_t range_end = range_start + (loff_t)(PAGE_SIZE - 1);
2075 : 0 : struct writeback_control wbc = {
2076 : : .sync_mode = WB_SYNC_ALL,
2077 : : .nr_to_write = 0,
2078 : : .range_start = range_start,
2079 : : .range_end = range_end,
2080 : : };
2081 : : int ret;
2082 : :
2083 : 0 : trace_nfs_writeback_page_enter(inode);
2084 : :
2085 : : for (;;) {
2086 : 0 : wait_on_page_writeback(page);
2087 [ # # ]: 0 : if (clear_page_dirty_for_io(page)) {
2088 : 0 : ret = nfs_writepage_locked(page, &wbc);
2089 [ # # ]: 0 : if (ret < 0)
2090 : : goto out_error;
2091 : 0 : continue;
2092 : : }
2093 : : ret = 0;
2094 [ # # ]: 0 : if (!PagePrivate(page))
2095 : : break;
2096 : : ret = nfs_commit_inode(inode, FLUSH_SYNC);
2097 [ # # ]: 0 : if (ret < 0)
2098 : : goto out_error;
2099 : : }
2100 : : out_error:
2101 : 0 : trace_nfs_writeback_page_exit(inode, ret);
2102 : 0 : return ret;
2103 : : }
2104 : :
2105 : : #ifdef CONFIG_MIGRATION
2106 : 0 : int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
2107 : : struct page *page, enum migrate_mode mode)
2108 : : {
2109 : : /*
2110 : : * If PagePrivate is set, then the page is currently associated with
2111 : : * an in-progress read or write request. Don't try to migrate it.
2112 : : *
2113 : : * FIXME: we could do this in principle, but we'll need a way to ensure
2114 : : * that we can safely release the inode reference while holding
2115 : : * the page lock.
2116 : : */
2117 [ # # ]: 0 : if (PagePrivate(page))
2118 : : return -EBUSY;
2119 : :
2120 [ # # ]: 0 : if (!nfs_fscache_release_page(page, GFP_KERNEL))
2121 : : return -EBUSY;
2122 : :
2123 : 0 : return migrate_page(mapping, newpage, page, mode);
2124 : : }
2125 : : #endif
2126 : :
2127 : 404 : int __init nfs_init_writepagecache(void)
2128 : : {
2129 : 404 : nfs_wdata_cachep = kmem_cache_create("nfs_write_data",
2130 : : sizeof(struct nfs_pgio_header),
2131 : : 0, SLAB_HWCACHE_ALIGN,
2132 : : NULL);
2133 [ + - ]: 404 : if (nfs_wdata_cachep == NULL)
2134 : : return -ENOMEM;
2135 : :
2136 : 404 : nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
2137 : : nfs_wdata_cachep);
2138 [ + - ]: 404 : if (nfs_wdata_mempool == NULL)
2139 : : goto out_destroy_write_cache;
2140 : :
2141 : 404 : nfs_cdata_cachep = kmem_cache_create("nfs_commit_data",
2142 : : sizeof(struct nfs_commit_data),
2143 : : 0, SLAB_HWCACHE_ALIGN,
2144 : : NULL);
2145 [ + - ]: 404 : if (nfs_cdata_cachep == NULL)
2146 : : goto out_destroy_write_mempool;
2147 : :
2148 : 404 : nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
2149 : : nfs_cdata_cachep);
2150 [ + - ]: 404 : if (nfs_commit_mempool == NULL)
2151 : : goto out_destroy_commit_cache;
2152 : :
2153 : : /*
2154 : : * NFS congestion size, scale with available memory.
2155 : : *
2156 : : * 64MB: 8192k
2157 : : * 128MB: 11585k
2158 : : * 256MB: 16384k
2159 : : * 512MB: 23170k
2160 : : * 1GB: 32768k
2161 : : * 2GB: 46340k
2162 : : * 4GB: 65536k
2163 : : * 8GB: 92681k
2164 : : * 16GB: 131072k
2165 : : *
2166 : : * This allows larger machines to have larger/more transfers.
2167 : : * Limit the default to 256M
2168 : : */
2169 : 404 : nfs_congestion_kb = (16*int_sqrt(totalram_pages())) << (PAGE_SHIFT-10);
2170 [ - + ]: 404 : if (nfs_congestion_kb > 256*1024)
2171 : 0 : nfs_congestion_kb = 256*1024;
2172 : :
2173 : : return 0;
2174 : :
2175 : : out_destroy_commit_cache:
2176 : 0 : kmem_cache_destroy(nfs_cdata_cachep);
2177 : : out_destroy_write_mempool:
2178 : 0 : mempool_destroy(nfs_wdata_mempool);
2179 : : out_destroy_write_cache:
2180 : 0 : kmem_cache_destroy(nfs_wdata_cachep);
2181 : 0 : return -ENOMEM;
2182 : : }
2183 : :
2184 : 0 : void nfs_destroy_writepagecache(void)
2185 : : {
2186 : 0 : mempool_destroy(nfs_commit_mempool);
2187 : 0 : kmem_cache_destroy(nfs_cdata_cachep);
2188 : 0 : mempool_destroy(nfs_wdata_mempool);
2189 : 0 : kmem_cache_destroy(nfs_wdata_cachep);
2190 : 0 : }
2191 : :
2192 : : static const struct nfs_rw_ops nfs_rw_write_ops = {
2193 : : .rw_alloc_header = nfs_writehdr_alloc,
2194 : : .rw_free_header = nfs_writehdr_free,
2195 : : .rw_done = nfs_writeback_done,
2196 : : .rw_result = nfs_writeback_result,
2197 : : .rw_initiate = nfs_initiate_write,
2198 : : };
|