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