Branch data Line data Source code
1 : : /*
2 : : * pNFS functions to call and manage layout drivers.
3 : : *
4 : : * Copyright (c) 2002 [year of first publication]
5 : : * The Regents of the University of Michigan
6 : : * All Rights Reserved
7 : : *
8 : : * Dean Hildebrand <dhildebz@umich.edu>
9 : : *
10 : : * Permission is granted to use, copy, create derivative works, and
11 : : * redistribute this software and such derivative works for any purpose,
12 : : * so long as the name of the University of Michigan is not used in
13 : : * any advertising or publicity pertaining to the use or distribution
14 : : * of this software without specific, written prior authorization. If
15 : : * the above copyright notice or any other identification of the
16 : : * University of Michigan is included in any copy of any portion of
17 : : * this software, then the disclaimer below must also be included.
18 : : *
19 : : * This software is provided as is, without representation or warranty
20 : : * of any kind either express or implied, including without limitation
21 : : * the implied warranties of merchantability, fitness for a particular
22 : : * purpose, or noninfringement. The Regents of the University of
23 : : * Michigan shall not be liable for any damages, including special,
24 : : * indirect, incidental, or consequential damages, with respect to any
25 : : * claim arising out of or in connection with the use of the software,
26 : : * even if it has been or is hereafter advised of the possibility of
27 : : * such damages.
28 : : */
29 : :
30 : : #include <linux/nfs_fs.h>
31 : : #include <linux/nfs_page.h>
32 : : #include <linux/module.h>
33 : : #include <linux/sort.h>
34 : : #include "internal.h"
35 : : #include "pnfs.h"
36 : : #include "iostat.h"
37 : : #include "nfs4trace.h"
38 : : #include "delegation.h"
39 : : #include "nfs42.h"
40 : : #include "nfs4_fs.h"
41 : :
42 : : #define NFSDBG_FACILITY NFSDBG_PNFS
43 : : #define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
44 : :
45 : : /* Locking:
46 : : *
47 : : * pnfs_spinlock:
48 : : * protects pnfs_modules_tbl.
49 : : */
50 : : static DEFINE_SPINLOCK(pnfs_spinlock);
51 : :
52 : : /*
53 : : * pnfs_modules_tbl holds all pnfs modules
54 : : */
55 : : static LIST_HEAD(pnfs_modules_tbl);
56 : :
57 : : static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo);
58 : : static void pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
59 : : struct list_head *free_me,
60 : : const struct pnfs_layout_range *range,
61 : : u32 seq);
62 : : static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
63 : : struct list_head *tmp_list);
64 : :
65 : : /* Return the registered pnfs layout driver module matching given id */
66 : : static struct pnfs_layoutdriver_type *
67 : : find_pnfs_driver_locked(u32 id)
68 : : {
69 : : struct pnfs_layoutdriver_type *local;
70 : :
71 : 3 : list_for_each_entry(local, &pnfs_modules_tbl, pnfs_tblid)
72 : 0 : if (local->id == id)
73 : : goto out;
74 : : local = NULL;
75 : : out:
76 : : dprintk("%s: Searching for id %u, found %p\n", __func__, id, local);
77 : : return local;
78 : : }
79 : :
80 : : static struct pnfs_layoutdriver_type *
81 : 0 : find_pnfs_driver(u32 id)
82 : : {
83 : : struct pnfs_layoutdriver_type *local;
84 : :
85 : : spin_lock(&pnfs_spinlock);
86 : : local = find_pnfs_driver_locked(id);
87 : 0 : if (local != NULL && !try_module_get(local->owner)) {
88 : : dprintk("%s: Could not grab reference on module\n", __func__);
89 : : local = NULL;
90 : : }
91 : : spin_unlock(&pnfs_spinlock);
92 : 0 : return local;
93 : : }
94 : :
95 : : void
96 : 0 : unset_pnfs_layoutdriver(struct nfs_server *nfss)
97 : : {
98 : 0 : if (nfss->pnfs_curr_ld) {
99 : 0 : if (nfss->pnfs_curr_ld->clear_layoutdriver)
100 : 0 : nfss->pnfs_curr_ld->clear_layoutdriver(nfss);
101 : : /* Decrement the MDS count. Purge the deviceid cache if zero */
102 : 0 : if (atomic_dec_and_test(&nfss->nfs_client->cl_mds_count))
103 : 0 : nfs4_deviceid_purge_client(nfss->nfs_client);
104 : 0 : module_put(nfss->pnfs_curr_ld->owner);
105 : : }
106 : 0 : nfss->pnfs_curr_ld = NULL;
107 : 0 : }
108 : :
109 : : /*
110 : : * When the server sends a list of layout types, we choose one in the order
111 : : * given in the list below.
112 : : *
113 : : * FIXME: should this list be configurable in some fashion? module param?
114 : : * mount option? something else?
115 : : */
116 : : static const u32 ld_prefs[] = {
117 : : LAYOUT_SCSI,
118 : : LAYOUT_BLOCK_VOLUME,
119 : : LAYOUT_OSD2_OBJECTS,
120 : : LAYOUT_FLEX_FILES,
121 : : LAYOUT_NFSV4_1_FILES,
122 : : 0
123 : : };
124 : :
125 : : static int
126 : 0 : ld_cmp(const void *e1, const void *e2)
127 : : {
128 : 0 : u32 ld1 = *((u32 *)e1);
129 : 0 : u32 ld2 = *((u32 *)e2);
130 : : int i;
131 : :
132 : 0 : for (i = 0; ld_prefs[i] != 0; i++) {
133 : 0 : if (ld1 == ld_prefs[i])
134 : : return -1;
135 : :
136 : 0 : if (ld2 == ld_prefs[i])
137 : : return 1;
138 : : }
139 : : return 0;
140 : : }
141 : :
142 : : /*
143 : : * Try to set the server's pnfs module to the pnfs layout type specified by id.
144 : : * Currently only one pNFS layout driver per filesystem is supported.
145 : : *
146 : : * @ids array of layout types supported by MDS.
147 : : */
148 : : void
149 : 0 : set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
150 : : struct nfs_fsinfo *fsinfo)
151 : : {
152 : : struct pnfs_layoutdriver_type *ld_type = NULL;
153 : : u32 id;
154 : : int i;
155 : :
156 : 0 : if (fsinfo->nlayouttypes == 0)
157 : : goto out_no_driver;
158 : 0 : if (!(server->nfs_client->cl_exchange_flags &
159 : : (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) {
160 : 0 : printk(KERN_ERR "NFS: %s: cl_exchange_flags 0x%x\n",
161 : : __func__, server->nfs_client->cl_exchange_flags);
162 : 0 : goto out_no_driver;
163 : : }
164 : :
165 : 0 : sort(fsinfo->layouttype, fsinfo->nlayouttypes,
166 : : sizeof(*fsinfo->layouttype), ld_cmp, NULL);
167 : :
168 : 0 : for (i = 0; i < fsinfo->nlayouttypes; i++) {
169 : 0 : id = fsinfo->layouttype[i];
170 : 0 : ld_type = find_pnfs_driver(id);
171 : 0 : if (!ld_type) {
172 : 0 : request_module("%s-%u", LAYOUT_NFSV4_1_MODULE_PREFIX,
173 : : id);
174 : 0 : ld_type = find_pnfs_driver(id);
175 : : }
176 : 0 : if (ld_type)
177 : : break;
178 : : }
179 : :
180 : 0 : if (!ld_type) {
181 : : dprintk("%s: No pNFS module found!\n", __func__);
182 : : goto out_no_driver;
183 : : }
184 : :
185 : 0 : server->pnfs_curr_ld = ld_type;
186 : 0 : if (ld_type->set_layoutdriver
187 : 0 : && ld_type->set_layoutdriver(server, mntfh)) {
188 : 0 : printk(KERN_ERR "NFS: %s: Error initializing pNFS layout "
189 : : "driver %u.\n", __func__, id);
190 : 0 : module_put(ld_type->owner);
191 : 0 : goto out_no_driver;
192 : : }
193 : : /* Bump the MDS count */
194 : 0 : atomic_inc(&server->nfs_client->cl_mds_count);
195 : :
196 : : dprintk("%s: pNFS module for %u set\n", __func__, id);
197 : 0 : return;
198 : :
199 : : out_no_driver:
200 : : dprintk("%s: Using NFSv4 I/O\n", __func__);
201 : 0 : server->pnfs_curr_ld = NULL;
202 : : }
203 : :
204 : : int
205 : 3 : pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
206 : : {
207 : : int status = -EINVAL;
208 : : struct pnfs_layoutdriver_type *tmp;
209 : :
210 : 3 : if (ld_type->id == 0) {
211 : 0 : printk(KERN_ERR "NFS: %s id 0 is reserved\n", __func__);
212 : 0 : return status;
213 : : }
214 : 3 : if (!ld_type->alloc_lseg || !ld_type->free_lseg) {
215 : 0 : printk(KERN_ERR "NFS: %s Layout driver must provide "
216 : : "alloc_lseg and free_lseg.\n", __func__);
217 : 0 : return status;
218 : : }
219 : :
220 : : spin_lock(&pnfs_spinlock);
221 : 3 : tmp = find_pnfs_driver_locked(ld_type->id);
222 : 3 : if (!tmp) {
223 : 3 : list_add(&ld_type->pnfs_tblid, &pnfs_modules_tbl);
224 : : status = 0;
225 : : dprintk("%s Registering id:%u name:%s\n", __func__, ld_type->id,
226 : : ld_type->name);
227 : : } else {
228 : 0 : printk(KERN_ERR "NFS: %s Module with id %d already loaded!\n",
229 : : __func__, ld_type->id);
230 : : }
231 : : spin_unlock(&pnfs_spinlock);
232 : :
233 : 3 : return status;
234 : : }
235 : : EXPORT_SYMBOL_GPL(pnfs_register_layoutdriver);
236 : :
237 : : void
238 : 0 : pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
239 : : {
240 : : dprintk("%s Deregistering id:%u\n", __func__, ld_type->id);
241 : : spin_lock(&pnfs_spinlock);
242 : : list_del(&ld_type->pnfs_tblid);
243 : : spin_unlock(&pnfs_spinlock);
244 : 0 : }
245 : : EXPORT_SYMBOL_GPL(pnfs_unregister_layoutdriver);
246 : :
247 : : /*
248 : : * pNFS client layout cache
249 : : */
250 : :
251 : : /* Need to hold i_lock if caller does not already hold reference */
252 : : void
253 : 0 : pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo)
254 : : {
255 : 0 : refcount_inc(&lo->plh_refcount);
256 : 0 : }
257 : :
258 : : static struct pnfs_layout_hdr *
259 : : pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags)
260 : : {
261 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
262 : 0 : return ld->alloc_layout_hdr(ino, gfp_flags);
263 : : }
264 : :
265 : : static void
266 : 0 : pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
267 : : {
268 : 0 : struct nfs_server *server = NFS_SERVER(lo->plh_inode);
269 : 0 : struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
270 : :
271 : 0 : if (!list_empty(&lo->plh_layouts)) {
272 : 0 : struct nfs_client *clp = server->nfs_client;
273 : :
274 : : spin_lock(&clp->cl_lock);
275 : : list_del_init(&lo->plh_layouts);
276 : : spin_unlock(&clp->cl_lock);
277 : : }
278 : 0 : put_cred(lo->plh_lc_cred);
279 : 0 : return ld->free_layout_hdr(lo);
280 : : }
281 : :
282 : : static void
283 : : pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo)
284 : : {
285 : 0 : struct nfs_inode *nfsi = NFS_I(lo->plh_inode);
286 : : dprintk("%s: freeing layout cache %p\n", __func__, lo);
287 : 0 : nfsi->layout = NULL;
288 : : /* Reset MDS Threshold I/O counters */
289 : 0 : nfsi->write_io = 0;
290 : 0 : nfsi->read_io = 0;
291 : : }
292 : :
293 : : void
294 : 0 : pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
295 : : {
296 : : struct inode *inode;
297 : :
298 : 0 : if (!lo)
299 : 0 : return;
300 : 0 : inode = lo->plh_inode;
301 : 0 : pnfs_layoutreturn_before_put_layout_hdr(lo);
302 : :
303 : 0 : if (refcount_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
304 : 0 : if (!list_empty(&lo->plh_segs))
305 : 0 : WARN_ONCE(1, "NFS: BUG unfreed layout segments.\n");
306 : : pnfs_detach_layout_hdr(lo);
307 : : spin_unlock(&inode->i_lock);
308 : 0 : pnfs_free_layout_hdr(lo);
309 : : }
310 : : }
311 : :
312 : : static void
313 : 0 : pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode,
314 : : u32 seq)
315 : : {
316 : 0 : if (lo->plh_return_iomode != 0 && lo->plh_return_iomode != iomode)
317 : : iomode = IOMODE_ANY;
318 : 0 : lo->plh_return_iomode = iomode;
319 : 0 : set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
320 : 0 : if (seq != 0) {
321 : 0 : WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq);
322 : 0 : lo->plh_return_seq = seq;
323 : : }
324 : 0 : }
325 : :
326 : : static void
327 : 0 : pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo)
328 : : {
329 : : struct pnfs_layout_segment *lseg;
330 : 0 : lo->plh_return_iomode = 0;
331 : 0 : lo->plh_return_seq = 0;
332 : 0 : clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
333 : 0 : list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
334 : 0 : if (!test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags))
335 : 0 : continue;
336 : 0 : pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
337 : : }
338 : 0 : }
339 : :
340 : 0 : static void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
341 : : {
342 : 0 : clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
343 : 0 : clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
344 : 0 : smp_mb__after_atomic();
345 : 0 : wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
346 : 0 : rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
347 : 0 : }
348 : :
349 : : static void
350 : 0 : pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
351 : : struct list_head *free_me)
352 : : {
353 : 0 : clear_bit(NFS_LSEG_ROC, &lseg->pls_flags);
354 : 0 : clear_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
355 : 0 : if (test_and_clear_bit(NFS_LSEG_VALID, &lseg->pls_flags))
356 : 0 : pnfs_lseg_dec_and_remove_zero(lseg, free_me);
357 : 0 : if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
358 : 0 : pnfs_lseg_dec_and_remove_zero(lseg, free_me);
359 : 0 : }
360 : :
361 : : /*
362 : : * Update the seqid of a layout stateid after receiving
363 : : * NFS4ERR_OLD_STATEID
364 : : */
365 : 0 : bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
366 : : struct pnfs_layout_range *dst_range,
367 : : struct inode *inode)
368 : : {
369 : : struct pnfs_layout_hdr *lo;
370 : 0 : struct pnfs_layout_range range = {
371 : : .iomode = IOMODE_ANY,
372 : : .offset = 0,
373 : : .length = NFS4_MAX_UINT64,
374 : : };
375 : : bool ret = false;
376 : 0 : LIST_HEAD(head);
377 : : int err;
378 : :
379 : : spin_lock(&inode->i_lock);
380 : 0 : lo = NFS_I(inode)->layout;
381 : 0 : if (lo && pnfs_layout_is_valid(lo) &&
382 : : nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
383 : : /* Is our call using the most recent seqid? If so, bump it */
384 : 0 : if (!nfs4_stateid_is_newer(&lo->plh_stateid, dst)) {
385 : : nfs4_stateid_seqid_inc(dst);
386 : : ret = true;
387 : 0 : goto out;
388 : : }
389 : : /* Try to update the seqid to the most recent */
390 : 0 : err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
391 : 0 : if (err != -EBUSY) {
392 : 0 : dst->seqid = lo->plh_stateid.seqid;
393 : 0 : *dst_range = range;
394 : : ret = true;
395 : : }
396 : : }
397 : : out:
398 : : spin_unlock(&inode->i_lock);
399 : 0 : pnfs_free_lseg_list(&head);
400 : 0 : return ret;
401 : : }
402 : :
403 : : /*
404 : : * Mark a pnfs_layout_hdr and all associated layout segments as invalid
405 : : *
406 : : * In order to continue using the pnfs_layout_hdr, a full recovery
407 : : * is required.
408 : : * Note that caller must hold inode->i_lock.
409 : : */
410 : : int
411 : 0 : pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
412 : : struct list_head *lseg_list)
413 : : {
414 : 0 : struct pnfs_layout_range range = {
415 : : .iomode = IOMODE_ANY,
416 : : .offset = 0,
417 : : .length = NFS4_MAX_UINT64,
418 : : };
419 : : struct pnfs_layout_segment *lseg, *next;
420 : :
421 : 0 : set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
422 : 0 : list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
423 : 0 : pnfs_clear_lseg_state(lseg, lseg_list);
424 : 0 : pnfs_clear_layoutreturn_info(lo);
425 : 0 : pnfs_free_returned_lsegs(lo, lseg_list, &range, 0);
426 : 0 : if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) &&
427 : 0 : !test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
428 : 0 : pnfs_clear_layoutreturn_waitbit(lo);
429 : 0 : return !list_empty(&lo->plh_segs);
430 : : }
431 : :
432 : : static int
433 : : pnfs_iomode_to_fail_bit(u32 iomode)
434 : : {
435 : 0 : return iomode == IOMODE_RW ?
436 : 0 : NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
437 : : }
438 : :
439 : : static void
440 : 0 : pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
441 : : {
442 : 0 : lo->plh_retry_timestamp = jiffies;
443 : 0 : if (!test_and_set_bit(fail_bit, &lo->plh_flags))
444 : 0 : refcount_inc(&lo->plh_refcount);
445 : 0 : }
446 : :
447 : : static void
448 : 0 : pnfs_layout_clear_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
449 : : {
450 : 0 : if (test_and_clear_bit(fail_bit, &lo->plh_flags))
451 : 0 : refcount_dec(&lo->plh_refcount);
452 : 0 : }
453 : :
454 : : static void
455 : 0 : pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
456 : : {
457 : 0 : struct inode *inode = lo->plh_inode;
458 : 0 : struct pnfs_layout_range range = {
459 : : .iomode = iomode,
460 : : .offset = 0,
461 : : .length = NFS4_MAX_UINT64,
462 : : };
463 : 0 : LIST_HEAD(head);
464 : :
465 : : spin_lock(&inode->i_lock);
466 : 0 : pnfs_layout_set_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
467 : 0 : pnfs_mark_matching_lsegs_invalid(lo, &head, &range, 0);
468 : : spin_unlock(&inode->i_lock);
469 : 0 : pnfs_free_lseg_list(&head);
470 : : dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
471 : : iomode == IOMODE_RW ? "RW" : "READ");
472 : 0 : }
473 : :
474 : : static bool
475 : 0 : pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode)
476 : : {
477 : : unsigned long start, end;
478 : : int fail_bit = pnfs_iomode_to_fail_bit(iomode);
479 : :
480 : 0 : if (test_bit(fail_bit, &lo->plh_flags) == 0)
481 : : return false;
482 : 0 : end = jiffies;
483 : 0 : start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT;
484 : 0 : if (!time_in_range(lo->plh_retry_timestamp, start, end)) {
485 : : /* It is time to retry the failed layoutgets */
486 : 0 : pnfs_layout_clear_fail_bit(lo, fail_bit);
487 : 0 : return false;
488 : : }
489 : : return true;
490 : : }
491 : :
492 : : static void
493 : 0 : pnfs_init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg,
494 : : const struct pnfs_layout_range *range,
495 : : const nfs4_stateid *stateid)
496 : : {
497 : 0 : INIT_LIST_HEAD(&lseg->pls_list);
498 : 0 : INIT_LIST_HEAD(&lseg->pls_lc_list);
499 : : refcount_set(&lseg->pls_refcount, 1);
500 : 0 : set_bit(NFS_LSEG_VALID, &lseg->pls_flags);
501 : 0 : lseg->pls_layout = lo;
502 : 0 : lseg->pls_range = *range;
503 : 0 : lseg->pls_seq = be32_to_cpu(stateid->seqid);
504 : 0 : }
505 : :
506 : : static void pnfs_free_lseg(struct pnfs_layout_segment *lseg)
507 : : {
508 : 0 : if (lseg != NULL) {
509 : 0 : struct inode *inode = lseg->pls_layout->plh_inode;
510 : 0 : NFS_SERVER(inode)->pnfs_curr_ld->free_lseg(lseg);
511 : : }
512 : : }
513 : :
514 : : static void
515 : 0 : pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
516 : : struct pnfs_layout_segment *lseg)
517 : : {
518 : 0 : WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
519 : 0 : list_del_init(&lseg->pls_list);
520 : : /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */
521 : 0 : refcount_dec(&lo->plh_refcount);
522 : 0 : if (test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags))
523 : 0 : return;
524 : 0 : if (list_empty(&lo->plh_segs) &&
525 : 0 : !test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) &&
526 : : !test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
527 : 0 : if (atomic_read(&lo->plh_outstanding) == 0)
528 : 0 : set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
529 : 0 : clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
530 : : }
531 : : }
532 : :
533 : : static bool
534 : 0 : pnfs_cache_lseg_for_layoutreturn(struct pnfs_layout_hdr *lo,
535 : : struct pnfs_layout_segment *lseg)
536 : : {
537 : 0 : if (test_and_clear_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags) &&
538 : : pnfs_layout_is_valid(lo)) {
539 : 0 : pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
540 : 0 : list_move_tail(&lseg->pls_list, &lo->plh_return_segs);
541 : 0 : return true;
542 : : }
543 : : return false;
544 : : }
545 : :
546 : : void
547 : 0 : pnfs_put_lseg(struct pnfs_layout_segment *lseg)
548 : : {
549 : : struct pnfs_layout_hdr *lo;
550 : : struct inode *inode;
551 : :
552 : 0 : if (!lseg)
553 : : return;
554 : :
555 : : dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg,
556 : : refcount_read(&lseg->pls_refcount),
557 : : test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
558 : :
559 : 0 : lo = lseg->pls_layout;
560 : 0 : inode = lo->plh_inode;
561 : :
562 : 0 : if (refcount_dec_and_lock(&lseg->pls_refcount, &inode->i_lock)) {
563 : 0 : if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags)) {
564 : : spin_unlock(&inode->i_lock);
565 : : return;
566 : : }
567 : : pnfs_get_layout_hdr(lo);
568 : 0 : pnfs_layout_remove_lseg(lo, lseg);
569 : 0 : if (pnfs_cache_lseg_for_layoutreturn(lo, lseg))
570 : : lseg = NULL;
571 : : spin_unlock(&inode->i_lock);
572 : : pnfs_free_lseg(lseg);
573 : 0 : pnfs_put_layout_hdr(lo);
574 : : }
575 : : }
576 : : EXPORT_SYMBOL_GPL(pnfs_put_lseg);
577 : :
578 : : /*
579 : : * is l2 fully contained in l1?
580 : : * start1 end1
581 : : * [----------------------------------)
582 : : * start2 end2
583 : : * [----------------)
584 : : */
585 : : static bool
586 : : pnfs_lseg_range_contained(const struct pnfs_layout_range *l1,
587 : : const struct pnfs_layout_range *l2)
588 : : {
589 : 0 : u64 start1 = l1->offset;
590 : 0 : u64 end1 = pnfs_end_offset(start1, l1->length);
591 : : u64 start2 = l2->offset;
592 : : u64 end2 = pnfs_end_offset(start2, l2->length);
593 : :
594 : 0 : return (start1 <= start2) && (end1 >= end2);
595 : : }
596 : :
597 : 0 : static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
598 : : struct list_head *tmp_list)
599 : : {
600 : 0 : if (!refcount_dec_and_test(&lseg->pls_refcount))
601 : : return false;
602 : 0 : pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
603 : 0 : list_add(&lseg->pls_list, tmp_list);
604 : 0 : return true;
605 : : }
606 : :
607 : : /* Returns 1 if lseg is removed from list, 0 otherwise */
608 : 0 : static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
609 : : struct list_head *tmp_list)
610 : : {
611 : : int rv = 0;
612 : :
613 : 0 : if (test_and_clear_bit(NFS_LSEG_VALID, &lseg->pls_flags)) {
614 : : /* Remove the reference keeping the lseg in the
615 : : * list. It will now be removed when all
616 : : * outstanding io is finished.
617 : : */
618 : : dprintk("%s: lseg %p ref %d\n", __func__, lseg,
619 : : refcount_read(&lseg->pls_refcount));
620 : 0 : if (pnfs_lseg_dec_and_remove_zero(lseg, tmp_list))
621 : : rv = 1;
622 : : }
623 : 0 : return rv;
624 : : }
625 : :
626 : : /*
627 : : * Compare 2 layout stateid sequence ids, to see which is newer,
628 : : * taking into account wraparound issues.
629 : : */
630 : : static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
631 : : {
632 : 0 : return (s32)(s1 - s2) > 0;
633 : : }
634 : :
635 : : static bool
636 : 0 : pnfs_should_free_range(const struct pnfs_layout_range *lseg_range,
637 : : const struct pnfs_layout_range *recall_range)
638 : : {
639 : 0 : return (recall_range->iomode == IOMODE_ANY ||
640 : 0 : lseg_range->iomode == recall_range->iomode) &&
641 : 0 : pnfs_lseg_range_intersecting(lseg_range, recall_range);
642 : : }
643 : :
644 : : static bool
645 : 0 : pnfs_match_lseg_recall(const struct pnfs_layout_segment *lseg,
646 : : const struct pnfs_layout_range *recall_range,
647 : : u32 seq)
648 : : {
649 : 0 : if (seq != 0 && pnfs_seqid_is_newer(lseg->pls_seq, seq))
650 : : return false;
651 : 0 : if (recall_range == NULL)
652 : : return true;
653 : 0 : return pnfs_should_free_range(&lseg->pls_range, recall_range);
654 : : }
655 : :
656 : : /**
657 : : * pnfs_mark_matching_lsegs_invalid - tear down lsegs or mark them for later
658 : : * @lo: layout header containing the lsegs
659 : : * @tmp_list: list head where doomed lsegs should go
660 : : * @recall_range: optional recall range argument to match (may be NULL)
661 : : * @seq: only invalidate lsegs obtained prior to this sequence (may be 0)
662 : : *
663 : : * Walk the list of lsegs in the layout header, and tear down any that should
664 : : * be destroyed. If "recall_range" is specified then the segment must match
665 : : * that range. If "seq" is non-zero, then only match segments that were handed
666 : : * out at or before that sequence.
667 : : *
668 : : * Returns number of matching invalid lsegs remaining in list after scanning
669 : : * it and purging them.
670 : : */
671 : : int
672 : 0 : pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
673 : : struct list_head *tmp_list,
674 : : const struct pnfs_layout_range *recall_range,
675 : : u32 seq)
676 : : {
677 : : struct pnfs_layout_segment *lseg, *next;
678 : : int remaining = 0;
679 : :
680 : : dprintk("%s:Begin lo %p\n", __func__, lo);
681 : :
682 : 0 : if (list_empty(&lo->plh_segs))
683 : : return 0;
684 : 0 : list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
685 : 0 : if (pnfs_match_lseg_recall(lseg, recall_range, seq)) {
686 : : dprintk("%s: freeing lseg %p iomode %d seq %u "
687 : : "offset %llu length %llu\n", __func__,
688 : : lseg, lseg->pls_range.iomode, lseg->pls_seq,
689 : : lseg->pls_range.offset, lseg->pls_range.length);
690 : 0 : if (!mark_lseg_invalid(lseg, tmp_list))
691 : 0 : remaining++;
692 : : }
693 : : dprintk("%s:Return %i\n", __func__, remaining);
694 : 0 : return remaining;
695 : : }
696 : :
697 : : static void
698 : 0 : pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
699 : : struct list_head *free_me,
700 : : const struct pnfs_layout_range *range,
701 : : u32 seq)
702 : : {
703 : : struct pnfs_layout_segment *lseg, *next;
704 : :
705 : 0 : list_for_each_entry_safe(lseg, next, &lo->plh_return_segs, pls_list) {
706 : 0 : if (pnfs_match_lseg_recall(lseg, range, seq))
707 : : list_move_tail(&lseg->pls_list, free_me);
708 : : }
709 : 0 : }
710 : :
711 : : /* note free_me must contain lsegs from a single layout_hdr */
712 : : void
713 : 0 : pnfs_free_lseg_list(struct list_head *free_me)
714 : : {
715 : : struct pnfs_layout_segment *lseg, *tmp;
716 : :
717 : 0 : if (list_empty(free_me))
718 : 0 : return;
719 : :
720 : 0 : list_for_each_entry_safe(lseg, tmp, free_me, pls_list) {
721 : : list_del(&lseg->pls_list);
722 : : pnfs_free_lseg(lseg);
723 : : }
724 : : }
725 : :
726 : : void
727 : 0 : pnfs_destroy_layout(struct nfs_inode *nfsi)
728 : : {
729 : : struct pnfs_layout_hdr *lo;
730 : 0 : LIST_HEAD(tmp_list);
731 : :
732 : : spin_lock(&nfsi->vfs_inode.i_lock);
733 : 0 : lo = nfsi->layout;
734 : 0 : if (lo) {
735 : : pnfs_get_layout_hdr(lo);
736 : 0 : pnfs_mark_layout_stateid_invalid(lo, &tmp_list);
737 : 0 : pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
738 : 0 : pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
739 : : spin_unlock(&nfsi->vfs_inode.i_lock);
740 : 0 : pnfs_free_lseg_list(&tmp_list);
741 : 0 : nfs_commit_inode(&nfsi->vfs_inode, 0);
742 : 0 : pnfs_put_layout_hdr(lo);
743 : : } else
744 : : spin_unlock(&nfsi->vfs_inode.i_lock);
745 : 0 : }
746 : : EXPORT_SYMBOL_GPL(pnfs_destroy_layout);
747 : :
748 : : static bool
749 : 0 : pnfs_layout_add_bulk_destroy_list(struct inode *inode,
750 : : struct list_head *layout_list)
751 : : {
752 : : struct pnfs_layout_hdr *lo;
753 : : bool ret = false;
754 : :
755 : : spin_lock(&inode->i_lock);
756 : 0 : lo = NFS_I(inode)->layout;
757 : 0 : if (lo != NULL && list_empty(&lo->plh_bulk_destroy)) {
758 : : pnfs_get_layout_hdr(lo);
759 : : list_add(&lo->plh_bulk_destroy, layout_list);
760 : : ret = true;
761 : : }
762 : : spin_unlock(&inode->i_lock);
763 : 0 : return ret;
764 : : }
765 : :
766 : : /* Caller must hold rcu_read_lock and clp->cl_lock */
767 : : static int
768 : 0 : pnfs_layout_bulk_destroy_byserver_locked(struct nfs_client *clp,
769 : : struct nfs_server *server,
770 : : struct list_head *layout_list)
771 : : __must_hold(&clp->cl_lock)
772 : : __must_hold(RCU)
773 : : {
774 : : struct pnfs_layout_hdr *lo, *next;
775 : : struct inode *inode;
776 : :
777 : 0 : list_for_each_entry_safe(lo, next, &server->layouts, plh_layouts) {
778 : 0 : if (test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags) ||
779 : 0 : test_bit(NFS_LAYOUT_INODE_FREEING, &lo->plh_flags) ||
780 : 0 : !list_empty(&lo->plh_bulk_destroy))
781 : 0 : continue;
782 : : /* If the sb is being destroyed, just bail */
783 : 0 : if (!nfs_sb_active(server->super))
784 : : break;
785 : 0 : inode = igrab(lo->plh_inode);
786 : 0 : if (inode != NULL) {
787 : : list_del_init(&lo->plh_layouts);
788 : 0 : if (pnfs_layout_add_bulk_destroy_list(inode,
789 : : layout_list))
790 : 0 : continue;
791 : : rcu_read_unlock();
792 : : spin_unlock(&clp->cl_lock);
793 : 0 : iput(inode);
794 : : } else {
795 : : rcu_read_unlock();
796 : : spin_unlock(&clp->cl_lock);
797 : 0 : set_bit(NFS_LAYOUT_INODE_FREEING, &lo->plh_flags);
798 : : }
799 : 0 : nfs_sb_deactive(server->super);
800 : : spin_lock(&clp->cl_lock);
801 : : rcu_read_lock();
802 : 0 : return -EAGAIN;
803 : : }
804 : : return 0;
805 : : }
806 : :
807 : : static int
808 : 0 : pnfs_layout_free_bulk_destroy_list(struct list_head *layout_list,
809 : : bool is_bulk_recall)
810 : : {
811 : : struct pnfs_layout_hdr *lo;
812 : : struct inode *inode;
813 : 0 : LIST_HEAD(lseg_list);
814 : : int ret = 0;
815 : :
816 : 0 : while (!list_empty(layout_list)) {
817 : 0 : lo = list_entry(layout_list->next, struct pnfs_layout_hdr,
818 : : plh_bulk_destroy);
819 : : dprintk("%s freeing layout for inode %lu\n", __func__,
820 : : lo->plh_inode->i_ino);
821 : 0 : inode = lo->plh_inode;
822 : :
823 : 0 : pnfs_layoutcommit_inode(inode, false);
824 : :
825 : : spin_lock(&inode->i_lock);
826 : 0 : list_del_init(&lo->plh_bulk_destroy);
827 : 0 : if (pnfs_mark_layout_stateid_invalid(lo, &lseg_list)) {
828 : 0 : if (is_bulk_recall)
829 : 0 : set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
830 : : ret = -EAGAIN;
831 : : }
832 : : spin_unlock(&inode->i_lock);
833 : 0 : pnfs_free_lseg_list(&lseg_list);
834 : : /* Free all lsegs that are attached to commit buckets */
835 : 0 : nfs_commit_inode(inode, 0);
836 : 0 : pnfs_put_layout_hdr(lo);
837 : 0 : nfs_iput_and_deactive(inode);
838 : : }
839 : 0 : return ret;
840 : : }
841 : :
842 : : int
843 : 0 : pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
844 : : struct nfs_fsid *fsid,
845 : : bool is_recall)
846 : : {
847 : : struct nfs_server *server;
848 : 0 : LIST_HEAD(layout_list);
849 : :
850 : : spin_lock(&clp->cl_lock);
851 : : rcu_read_lock();
852 : : restart:
853 : 0 : list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
854 : 0 : if (memcmp(&server->fsid, fsid, sizeof(*fsid)) != 0)
855 : 0 : continue;
856 : 0 : if (pnfs_layout_bulk_destroy_byserver_locked(clp,
857 : : server,
858 : : &layout_list) != 0)
859 : : goto restart;
860 : : }
861 : : rcu_read_unlock();
862 : : spin_unlock(&clp->cl_lock);
863 : :
864 : 0 : if (list_empty(&layout_list))
865 : : return 0;
866 : 0 : return pnfs_layout_free_bulk_destroy_list(&layout_list, is_recall);
867 : : }
868 : :
869 : : int
870 : 0 : pnfs_destroy_layouts_byclid(struct nfs_client *clp,
871 : : bool is_recall)
872 : : {
873 : : struct nfs_server *server;
874 : 0 : LIST_HEAD(layout_list);
875 : :
876 : : spin_lock(&clp->cl_lock);
877 : : rcu_read_lock();
878 : : restart:
879 : 0 : list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
880 : 0 : if (pnfs_layout_bulk_destroy_byserver_locked(clp,
881 : : server,
882 : : &layout_list) != 0)
883 : : goto restart;
884 : : }
885 : : rcu_read_unlock();
886 : : spin_unlock(&clp->cl_lock);
887 : :
888 : 0 : if (list_empty(&layout_list))
889 : : return 0;
890 : 0 : return pnfs_layout_free_bulk_destroy_list(&layout_list, is_recall);
891 : : }
892 : :
893 : : /*
894 : : * Called by the state manger to remove all layouts established under an
895 : : * expired lease.
896 : : */
897 : : void
898 : 0 : pnfs_destroy_all_layouts(struct nfs_client *clp)
899 : : {
900 : 0 : nfs4_deviceid_mark_client_invalid(clp);
901 : 0 : nfs4_deviceid_purge_client(clp);
902 : :
903 : 0 : pnfs_destroy_layouts_byclid(clp, false);
904 : 0 : }
905 : :
906 : : /* update lo->plh_stateid with new if is more recent */
907 : : void
908 : 0 : pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
909 : : bool update_barrier)
910 : : {
911 : : u32 oldseq, newseq, new_barrier = 0;
912 : :
913 : 0 : oldseq = be32_to_cpu(lo->plh_stateid.seqid);
914 : 0 : newseq = be32_to_cpu(new->seqid);
915 : :
916 : 0 : if (!pnfs_layout_is_valid(lo)) {
917 : : nfs4_stateid_copy(&lo->plh_stateid, new);
918 : 0 : lo->plh_barrier = newseq;
919 : 0 : pnfs_clear_layoutreturn_info(lo);
920 : 0 : clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
921 : 0 : return;
922 : : }
923 : 0 : if (pnfs_seqid_is_newer(newseq, oldseq)) {
924 : : nfs4_stateid_copy(&lo->plh_stateid, new);
925 : : /*
926 : : * Because of wraparound, we want to keep the barrier
927 : : * "close" to the current seqids.
928 : : */
929 : 0 : new_barrier = newseq - atomic_read(&lo->plh_outstanding);
930 : : }
931 : 0 : if (update_barrier)
932 : 0 : new_barrier = be32_to_cpu(new->seqid);
933 : 0 : else if (new_barrier == 0)
934 : : return;
935 : 0 : if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
936 : 0 : lo->plh_barrier = new_barrier;
937 : : }
938 : :
939 : : static bool
940 : : pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
941 : : const nfs4_stateid *stateid)
942 : : {
943 : 0 : u32 seqid = be32_to_cpu(stateid->seqid);
944 : :
945 : 0 : return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
946 : : }
947 : :
948 : : /* lget is set to 1 if called from inside send_layoutget call chain */
949 : : static bool
950 : : pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo)
951 : : {
952 : 0 : return lo->plh_block_lgets ||
953 : : test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
954 : : }
955 : :
956 : : static struct nfs_server *
957 : 0 : pnfs_find_server(struct inode *inode, struct nfs_open_context *ctx)
958 : : {
959 : : struct nfs_server *server;
960 : :
961 : 0 : if (inode) {
962 : : server = NFS_SERVER(inode);
963 : : } else {
964 : 0 : struct dentry *parent_dir = dget_parent(ctx->dentry);
965 : 0 : server = NFS_SERVER(parent_dir->d_inode);
966 : 0 : dput(parent_dir);
967 : : }
968 : 0 : return server;
969 : : }
970 : :
971 : 0 : static void nfs4_free_pages(struct page **pages, size_t size)
972 : : {
973 : : int i;
974 : :
975 : 0 : if (!pages)
976 : 0 : return;
977 : :
978 : 0 : for (i = 0; i < size; i++) {
979 : 0 : if (!pages[i])
980 : : break;
981 : 0 : __free_page(pages[i]);
982 : : }
983 : 0 : kfree(pages);
984 : : }
985 : :
986 : 0 : static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
987 : : {
988 : : struct page **pages;
989 : : int i;
990 : :
991 : 0 : pages = kmalloc_array(size, sizeof(struct page *), gfp_flags);
992 : 0 : if (!pages) {
993 : : dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
994 : : return NULL;
995 : : }
996 : :
997 : 0 : for (i = 0; i < size; i++) {
998 : 0 : pages[i] = alloc_page(gfp_flags);
999 : 0 : if (!pages[i]) {
1000 : : dprintk("%s: failed to allocate page\n", __func__);
1001 : 0 : nfs4_free_pages(pages, i);
1002 : 0 : return NULL;
1003 : : }
1004 : : }
1005 : :
1006 : : return pages;
1007 : : }
1008 : :
1009 : : static struct nfs4_layoutget *
1010 : 0 : pnfs_alloc_init_layoutget_args(struct inode *ino,
1011 : : struct nfs_open_context *ctx,
1012 : : const nfs4_stateid *stateid,
1013 : : const struct pnfs_layout_range *range,
1014 : : gfp_t gfp_flags)
1015 : : {
1016 : 0 : struct nfs_server *server = pnfs_find_server(ino, ctx);
1017 : 0 : size_t max_reply_sz = server->pnfs_curr_ld->max_layoutget_response;
1018 : 0 : size_t max_pages = max_response_pages(server);
1019 : : struct nfs4_layoutget *lgp;
1020 : :
1021 : : dprintk("--> %s\n", __func__);
1022 : :
1023 : 0 : lgp = kzalloc(sizeof(*lgp), gfp_flags);
1024 : 0 : if (lgp == NULL)
1025 : : return NULL;
1026 : :
1027 : 0 : if (max_reply_sz) {
1028 : 0 : size_t npages = (max_reply_sz + PAGE_SIZE - 1) >> PAGE_SHIFT;
1029 : 0 : if (npages < max_pages)
1030 : : max_pages = npages;
1031 : : }
1032 : :
1033 : 0 : lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
1034 : 0 : if (!lgp->args.layout.pages) {
1035 : 0 : kfree(lgp);
1036 : 0 : return NULL;
1037 : : }
1038 : 0 : lgp->args.layout.pglen = max_pages * PAGE_SIZE;
1039 : 0 : lgp->res.layoutp = &lgp->args.layout;
1040 : :
1041 : : /* Don't confuse uninitialised result and success */
1042 : 0 : lgp->res.status = -NFS4ERR_DELAY;
1043 : :
1044 : 0 : lgp->args.minlength = PAGE_SIZE;
1045 : 0 : if (lgp->args.minlength > range->length)
1046 : 0 : lgp->args.minlength = range->length;
1047 : 0 : if (ino) {
1048 : : loff_t i_size = i_size_read(ino);
1049 : :
1050 : 0 : if (range->iomode == IOMODE_READ) {
1051 : 0 : if (range->offset >= i_size)
1052 : 0 : lgp->args.minlength = 0;
1053 : 0 : else if (i_size - range->offset < lgp->args.minlength)
1054 : 0 : lgp->args.minlength = i_size - range->offset;
1055 : : }
1056 : : }
1057 : 0 : lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
1058 : 0 : pnfs_copy_range(&lgp->args.range, range);
1059 : 0 : lgp->args.type = server->pnfs_curr_ld->id;
1060 : 0 : lgp->args.inode = ino;
1061 : 0 : lgp->args.ctx = get_nfs_open_context(ctx);
1062 : : nfs4_stateid_copy(&lgp->args.stateid, stateid);
1063 : 0 : lgp->gfp_flags = gfp_flags;
1064 : 0 : lgp->cred = get_cred(ctx->cred);
1065 : 0 : return lgp;
1066 : : }
1067 : :
1068 : 0 : void pnfs_layoutget_free(struct nfs4_layoutget *lgp)
1069 : : {
1070 : 0 : size_t max_pages = lgp->args.layout.pglen / PAGE_SIZE;
1071 : :
1072 : 0 : nfs4_free_pages(lgp->args.layout.pages, max_pages);
1073 : 0 : if (lgp->args.inode)
1074 : 0 : pnfs_put_layout_hdr(NFS_I(lgp->args.inode)->layout);
1075 : 0 : put_cred(lgp->cred);
1076 : 0 : put_nfs_open_context(lgp->args.ctx);
1077 : 0 : kfree(lgp);
1078 : 0 : }
1079 : :
1080 : 0 : static void pnfs_clear_layoutcommit(struct inode *inode,
1081 : : struct list_head *head)
1082 : : {
1083 : : struct nfs_inode *nfsi = NFS_I(inode);
1084 : : struct pnfs_layout_segment *lseg, *tmp;
1085 : :
1086 : 0 : if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
1087 : 0 : return;
1088 : 0 : list_for_each_entry_safe(lseg, tmp, &nfsi->layout->plh_segs, pls_list) {
1089 : 0 : if (!test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
1090 : 0 : continue;
1091 : 0 : pnfs_lseg_dec_and_remove_zero(lseg, head);
1092 : : }
1093 : : }
1094 : :
1095 : 0 : void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
1096 : : const nfs4_stateid *arg_stateid,
1097 : : const struct pnfs_layout_range *range,
1098 : : const nfs4_stateid *stateid)
1099 : : {
1100 : 0 : struct inode *inode = lo->plh_inode;
1101 : 0 : LIST_HEAD(freeme);
1102 : :
1103 : : spin_lock(&inode->i_lock);
1104 : 0 : if (!pnfs_layout_is_valid(lo) || !arg_stateid ||
1105 : : !nfs4_stateid_match_other(&lo->plh_stateid, arg_stateid))
1106 : : goto out_unlock;
1107 : 0 : if (stateid) {
1108 : 0 : u32 seq = be32_to_cpu(arg_stateid->seqid);
1109 : :
1110 : 0 : pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
1111 : 0 : pnfs_free_returned_lsegs(lo, &freeme, range, seq);
1112 : 0 : pnfs_set_layout_stateid(lo, stateid, true);
1113 : : } else
1114 : 0 : pnfs_mark_layout_stateid_invalid(lo, &freeme);
1115 : : out_unlock:
1116 : 0 : pnfs_clear_layoutreturn_waitbit(lo);
1117 : : spin_unlock(&inode->i_lock);
1118 : 0 : pnfs_free_lseg_list(&freeme);
1119 : :
1120 : 0 : }
1121 : :
1122 : : static bool
1123 : 0 : pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
1124 : : nfs4_stateid *stateid,
1125 : : enum pnfs_iomode *iomode)
1126 : : {
1127 : : /* Serialise LAYOUTGET/LAYOUTRETURN */
1128 : 0 : if (atomic_read(&lo->plh_outstanding) != 0)
1129 : : return false;
1130 : 0 : if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
1131 : : return false;
1132 : 0 : set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
1133 : : pnfs_get_layout_hdr(lo);
1134 : 0 : if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
1135 : 0 : if (stateid != NULL) {
1136 : : nfs4_stateid_copy(stateid, &lo->plh_stateid);
1137 : 0 : if (lo->plh_return_seq != 0)
1138 : 0 : stateid->seqid = cpu_to_be32(lo->plh_return_seq);
1139 : : }
1140 : 0 : if (iomode != NULL)
1141 : 0 : *iomode = lo->plh_return_iomode;
1142 : 0 : pnfs_clear_layoutreturn_info(lo);
1143 : 0 : return true;
1144 : : }
1145 : 0 : if (stateid != NULL)
1146 : : nfs4_stateid_copy(stateid, &lo->plh_stateid);
1147 : 0 : if (iomode != NULL)
1148 : 0 : *iomode = IOMODE_ANY;
1149 : : return true;
1150 : : }
1151 : :
1152 : : static void
1153 : 0 : pnfs_init_layoutreturn_args(struct nfs4_layoutreturn_args *args,
1154 : : struct pnfs_layout_hdr *lo,
1155 : : const nfs4_stateid *stateid,
1156 : : enum pnfs_iomode iomode)
1157 : : {
1158 : 0 : struct inode *inode = lo->plh_inode;
1159 : :
1160 : 0 : args->layout_type = NFS_SERVER(inode)->pnfs_curr_ld->id;
1161 : 0 : args->inode = inode;
1162 : 0 : args->range.iomode = iomode;
1163 : 0 : args->range.offset = 0;
1164 : 0 : args->range.length = NFS4_MAX_UINT64;
1165 : 0 : args->layout = lo;
1166 : : nfs4_stateid_copy(&args->stateid, stateid);
1167 : 0 : }
1168 : :
1169 : : static int
1170 : 0 : pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid,
1171 : : enum pnfs_iomode iomode, bool sync)
1172 : : {
1173 : 0 : struct inode *ino = lo->plh_inode;
1174 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
1175 : : struct nfs4_layoutreturn *lrp;
1176 : : int status = 0;
1177 : :
1178 : 0 : lrp = kzalloc(sizeof(*lrp), GFP_NOFS);
1179 : 0 : if (unlikely(lrp == NULL)) {
1180 : : status = -ENOMEM;
1181 : : spin_lock(&ino->i_lock);
1182 : 0 : pnfs_clear_layoutreturn_waitbit(lo);
1183 : : spin_unlock(&ino->i_lock);
1184 : 0 : pnfs_put_layout_hdr(lo);
1185 : 0 : goto out;
1186 : : }
1187 : :
1188 : 0 : pnfs_init_layoutreturn_args(&lrp->args, lo, stateid, iomode);
1189 : 0 : lrp->args.ld_private = &lrp->ld_private;
1190 : 0 : lrp->clp = NFS_SERVER(ino)->nfs_client;
1191 : 0 : lrp->cred = lo->plh_lc_cred;
1192 : 0 : if (ld->prepare_layoutreturn)
1193 : 0 : ld->prepare_layoutreturn(&lrp->args);
1194 : :
1195 : 0 : status = nfs4_proc_layoutreturn(lrp, sync);
1196 : : out:
1197 : : dprintk("<-- %s status: %d\n", __func__, status);
1198 : 0 : return status;
1199 : : }
1200 : :
1201 : : static bool
1202 : 0 : pnfs_layout_segments_returnable(struct pnfs_layout_hdr *lo,
1203 : : enum pnfs_iomode iomode,
1204 : : u32 seq)
1205 : : {
1206 : 0 : struct pnfs_layout_range recall_range = {
1207 : : .length = NFS4_MAX_UINT64,
1208 : : .iomode = iomode,
1209 : : };
1210 : 0 : return pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
1211 : : &recall_range, seq) != -EBUSY;
1212 : : }
1213 : :
1214 : : /* Return true if layoutreturn is needed */
1215 : : static bool
1216 : 0 : pnfs_layout_need_return(struct pnfs_layout_hdr *lo)
1217 : : {
1218 : 0 : if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
1219 : : return false;
1220 : 0 : return pnfs_layout_segments_returnable(lo, lo->plh_return_iomode,
1221 : : lo->plh_return_seq);
1222 : : }
1223 : :
1224 : 0 : static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo)
1225 : : {
1226 : 0 : struct inode *inode= lo->plh_inode;
1227 : :
1228 : 0 : if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
1229 : 0 : return;
1230 : : spin_lock(&inode->i_lock);
1231 : 0 : if (pnfs_layout_need_return(lo)) {
1232 : : nfs4_stateid stateid;
1233 : : enum pnfs_iomode iomode;
1234 : : bool send;
1235 : :
1236 : 0 : send = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
1237 : : spin_unlock(&inode->i_lock);
1238 : 0 : if (send) {
1239 : : /* Send an async layoutreturn so we dont deadlock */
1240 : 0 : pnfs_send_layoutreturn(lo, &stateid, iomode, false);
1241 : : }
1242 : : } else
1243 : : spin_unlock(&inode->i_lock);
1244 : : }
1245 : :
1246 : : /*
1247 : : * Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr
1248 : : * when the layout segment list is empty.
1249 : : *
1250 : : * Note that a pnfs_layout_hdr can exist with an empty layout segment
1251 : : * list when LAYOUTGET has failed, or when LAYOUTGET succeeded, but the
1252 : : * deviceid is marked invalid.
1253 : : */
1254 : : int
1255 : 0 : _pnfs_return_layout(struct inode *ino)
1256 : : {
1257 : : struct pnfs_layout_hdr *lo = NULL;
1258 : : struct nfs_inode *nfsi = NFS_I(ino);
1259 : 0 : LIST_HEAD(tmp_list);
1260 : : nfs4_stateid stateid;
1261 : : int status = 0;
1262 : : bool send, valid_layout;
1263 : :
1264 : : dprintk("NFS: %s for inode %lu\n", __func__, ino->i_ino);
1265 : :
1266 : : spin_lock(&ino->i_lock);
1267 : 0 : lo = nfsi->layout;
1268 : 0 : if (!lo) {
1269 : : spin_unlock(&ino->i_lock);
1270 : : dprintk("NFS: %s no layout to return\n", __func__);
1271 : : goto out;
1272 : : }
1273 : : /* Reference matched in nfs4_layoutreturn_release */
1274 : : pnfs_get_layout_hdr(lo);
1275 : : /* Is there an outstanding layoutreturn ? */
1276 : 0 : if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) {
1277 : : spin_unlock(&ino->i_lock);
1278 : 0 : if (wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN,
1279 : : TASK_UNINTERRUPTIBLE))
1280 : : goto out_put_layout_hdr;
1281 : : spin_lock(&ino->i_lock);
1282 : : }
1283 : : valid_layout = pnfs_layout_is_valid(lo);
1284 : 0 : pnfs_clear_layoutcommit(ino, &tmp_list);
1285 : 0 : pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL, 0);
1286 : :
1287 : 0 : if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
1288 : 0 : struct pnfs_layout_range range = {
1289 : : .iomode = IOMODE_ANY,
1290 : : .offset = 0,
1291 : : .length = NFS4_MAX_UINT64,
1292 : : };
1293 : 0 : NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &range);
1294 : : }
1295 : :
1296 : : /* Don't send a LAYOUTRETURN if list was initially empty */
1297 : 0 : if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) ||
1298 : : !valid_layout) {
1299 : : spin_unlock(&ino->i_lock);
1300 : : dprintk("NFS: %s no layout segments to return\n", __func__);
1301 : : goto out_put_layout_hdr;
1302 : : }
1303 : :
1304 : 0 : send = pnfs_prepare_layoutreturn(lo, &stateid, NULL);
1305 : : spin_unlock(&ino->i_lock);
1306 : 0 : if (send)
1307 : 0 : status = pnfs_send_layoutreturn(lo, &stateid, IOMODE_ANY, true);
1308 : : out_put_layout_hdr:
1309 : 0 : pnfs_free_lseg_list(&tmp_list);
1310 : 0 : pnfs_put_layout_hdr(lo);
1311 : : out:
1312 : : dprintk("<-- %s status: %d\n", __func__, status);
1313 : 0 : return status;
1314 : : }
1315 : :
1316 : : int
1317 : 0 : pnfs_commit_and_return_layout(struct inode *inode)
1318 : : {
1319 : : struct pnfs_layout_hdr *lo;
1320 : : int ret;
1321 : :
1322 : : spin_lock(&inode->i_lock);
1323 : 0 : lo = NFS_I(inode)->layout;
1324 : 0 : if (lo == NULL) {
1325 : : spin_unlock(&inode->i_lock);
1326 : 0 : return 0;
1327 : : }
1328 : : pnfs_get_layout_hdr(lo);
1329 : : /* Block new layoutgets and read/write to ds */
1330 : 0 : lo->plh_block_lgets++;
1331 : : spin_unlock(&inode->i_lock);
1332 : 0 : filemap_fdatawait(inode->i_mapping);
1333 : 0 : ret = pnfs_layoutcommit_inode(inode, true);
1334 : 0 : if (ret == 0)
1335 : 0 : ret = _pnfs_return_layout(inode);
1336 : : spin_lock(&inode->i_lock);
1337 : 0 : lo->plh_block_lgets--;
1338 : : spin_unlock(&inode->i_lock);
1339 : 0 : pnfs_put_layout_hdr(lo);
1340 : 0 : return ret;
1341 : : }
1342 : :
1343 : 0 : bool pnfs_roc(struct inode *ino,
1344 : : struct nfs4_layoutreturn_args *args,
1345 : : struct nfs4_layoutreturn_res *res,
1346 : : const struct cred *cred)
1347 : : {
1348 : : struct nfs_inode *nfsi = NFS_I(ino);
1349 : : struct nfs_open_context *ctx;
1350 : : struct nfs4_state *state;
1351 : : struct pnfs_layout_hdr *lo;
1352 : : struct pnfs_layout_segment *lseg, *next;
1353 : : nfs4_stateid stateid;
1354 : 0 : enum pnfs_iomode iomode = 0;
1355 : : bool layoutreturn = false, roc = false;
1356 : : bool skip_read = false;
1357 : :
1358 : 0 : if (!nfs_have_layout(ino))
1359 : : return false;
1360 : : retry:
1361 : : rcu_read_lock();
1362 : : spin_lock(&ino->i_lock);
1363 : 0 : lo = nfsi->layout;
1364 : 0 : if (!lo || !pnfs_layout_is_valid(lo) ||
1365 : : test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
1366 : : lo = NULL;
1367 : : goto out_noroc;
1368 : : }
1369 : : pnfs_get_layout_hdr(lo);
1370 : 0 : if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) {
1371 : : spin_unlock(&ino->i_lock);
1372 : : rcu_read_unlock();
1373 : 0 : wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN,
1374 : : TASK_UNINTERRUPTIBLE);
1375 : 0 : pnfs_put_layout_hdr(lo);
1376 : 0 : goto retry;
1377 : : }
1378 : :
1379 : : /* no roc if we hold a delegation */
1380 : 0 : if (nfs4_check_delegation(ino, FMODE_READ)) {
1381 : 0 : if (nfs4_check_delegation(ino, FMODE_WRITE))
1382 : : goto out_noroc;
1383 : : skip_read = true;
1384 : : }
1385 : :
1386 : 0 : list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
1387 : 0 : state = ctx->state;
1388 : 0 : if (state == NULL)
1389 : 0 : continue;
1390 : : /* Don't return layout if there is open file state */
1391 : 0 : if (state->state & FMODE_WRITE)
1392 : : goto out_noroc;
1393 : 0 : if (state->state & FMODE_READ)
1394 : : skip_read = true;
1395 : : }
1396 : :
1397 : :
1398 : 0 : list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) {
1399 : 0 : if (skip_read && lseg->pls_range.iomode == IOMODE_READ)
1400 : 0 : continue;
1401 : : /* If we are sending layoutreturn, invalidate all valid lsegs */
1402 : 0 : if (!test_and_clear_bit(NFS_LSEG_ROC, &lseg->pls_flags))
1403 : 0 : continue;
1404 : : /*
1405 : : * Note: mark lseg for return so pnfs_layout_remove_lseg
1406 : : * doesn't invalidate the layout for us.
1407 : : */
1408 : 0 : set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
1409 : 0 : if (!mark_lseg_invalid(lseg, &lo->plh_return_segs))
1410 : 0 : continue;
1411 : 0 : pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
1412 : : }
1413 : :
1414 : 0 : if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
1415 : : goto out_noroc;
1416 : :
1417 : : /* ROC in two conditions:
1418 : : * 1. there are ROC lsegs
1419 : : * 2. we don't send layoutreturn
1420 : : */
1421 : : /* lo ref dropped in pnfs_roc_release() */
1422 : 0 : layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
1423 : : /* If the creds don't match, we can't compound the layoutreturn */
1424 : 0 : if (!layoutreturn || cred_fscmp(cred, lo->plh_lc_cred) != 0)
1425 : : goto out_noroc;
1426 : :
1427 : : roc = layoutreturn;
1428 : 0 : pnfs_init_layoutreturn_args(args, lo, &stateid, iomode);
1429 : 0 : res->lrs_present = 0;
1430 : : layoutreturn = false;
1431 : :
1432 : : out_noroc:
1433 : : spin_unlock(&ino->i_lock);
1434 : : rcu_read_unlock();
1435 : 0 : pnfs_layoutcommit_inode(ino, true);
1436 : 0 : if (roc) {
1437 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
1438 : 0 : if (ld->prepare_layoutreturn)
1439 : 0 : ld->prepare_layoutreturn(args);
1440 : 0 : pnfs_put_layout_hdr(lo);
1441 : 0 : return true;
1442 : : }
1443 : 0 : if (layoutreturn)
1444 : 0 : pnfs_send_layoutreturn(lo, &stateid, iomode, true);
1445 : 0 : pnfs_put_layout_hdr(lo);
1446 : 0 : return false;
1447 : : }
1448 : :
1449 : 0 : int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
1450 : : struct nfs4_layoutreturn_args **argpp,
1451 : : struct nfs4_layoutreturn_res **respp,
1452 : : int *ret)
1453 : : {
1454 : 0 : struct nfs4_layoutreturn_args *arg = *argpp;
1455 : : int retval = -EAGAIN;
1456 : :
1457 : 0 : if (!arg)
1458 : : return 0;
1459 : : /* Handle Layoutreturn errors */
1460 : 0 : switch (*ret) {
1461 : : case 0:
1462 : : retval = 0;
1463 : 0 : break;
1464 : : case -NFS4ERR_NOMATCHING_LAYOUT:
1465 : : /* Was there an RPC level error? If not, retry */
1466 : 0 : if (task->tk_rpc_status == 0)
1467 : : break;
1468 : : /* If the call was not sent, let caller handle it */
1469 : 0 : if (!RPC_WAS_SENT(task))
1470 : : return 0;
1471 : : /*
1472 : : * Otherwise, assume the call succeeded and
1473 : : * that we need to release the layout
1474 : : */
1475 : 0 : *ret = 0;
1476 : 0 : (*respp)->lrs_present = 0;
1477 : : retval = 0;
1478 : 0 : break;
1479 : : case -NFS4ERR_DELAY:
1480 : : /* Let the caller handle the retry */
1481 : 0 : *ret = -NFS4ERR_NOMATCHING_LAYOUT;
1482 : 0 : return 0;
1483 : : case -NFS4ERR_OLD_STATEID:
1484 : 0 : if (!nfs4_layout_refresh_old_stateid(&arg->stateid,
1485 : : &arg->range, inode))
1486 : : break;
1487 : 0 : *ret = -NFS4ERR_NOMATCHING_LAYOUT;
1488 : 0 : return -EAGAIN;
1489 : : }
1490 : 0 : *argpp = NULL;
1491 : 0 : *respp = NULL;
1492 : 0 : return retval;
1493 : : }
1494 : :
1495 : 0 : void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
1496 : : struct nfs4_layoutreturn_res *res,
1497 : : int ret)
1498 : : {
1499 : 0 : struct pnfs_layout_hdr *lo = args->layout;
1500 : : const nfs4_stateid *arg_stateid = NULL;
1501 : : const nfs4_stateid *res_stateid = NULL;
1502 : 0 : struct nfs4_xdr_opaque_data *ld_private = args->ld_private;
1503 : :
1504 : 0 : switch (ret) {
1505 : : case -NFS4ERR_NOMATCHING_LAYOUT:
1506 : : break;
1507 : : case 0:
1508 : 0 : if (res->lrs_present)
1509 : 0 : res_stateid = &res->stateid;
1510 : : /* Fallthrough */
1511 : : default:
1512 : 0 : arg_stateid = &args->stateid;
1513 : : }
1514 : 0 : pnfs_layoutreturn_free_lsegs(lo, arg_stateid, &args->range,
1515 : : res_stateid);
1516 : 0 : if (ld_private && ld_private->ops && ld_private->ops->free)
1517 : 0 : ld_private->ops->free(ld_private);
1518 : 0 : pnfs_put_layout_hdr(lo);
1519 : 0 : trace_nfs4_layoutreturn_on_close(args->inode, 0);
1520 : 0 : }
1521 : :
1522 : 0 : bool pnfs_wait_on_layoutreturn(struct inode *ino, struct rpc_task *task)
1523 : : {
1524 : : struct nfs_inode *nfsi = NFS_I(ino);
1525 : : struct pnfs_layout_hdr *lo;
1526 : : bool sleep = false;
1527 : :
1528 : : /* we might not have grabbed lo reference. so need to check under
1529 : : * i_lock */
1530 : : spin_lock(&ino->i_lock);
1531 : 0 : lo = nfsi->layout;
1532 : 0 : if (lo && test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
1533 : 0 : rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
1534 : : sleep = true;
1535 : : }
1536 : : spin_unlock(&ino->i_lock);
1537 : 0 : return sleep;
1538 : : }
1539 : :
1540 : : /*
1541 : : * Compare two layout segments for sorting into layout cache.
1542 : : * We want to preferentially return RW over RO layouts, so ensure those
1543 : : * are seen first.
1544 : : */
1545 : : static s64
1546 : : pnfs_lseg_range_cmp(const struct pnfs_layout_range *l1,
1547 : : const struct pnfs_layout_range *l2)
1548 : : {
1549 : : s64 d;
1550 : :
1551 : : /* high offset > low offset */
1552 : 0 : d = l1->offset - l2->offset;
1553 : 0 : if (d)
1554 : : return d;
1555 : :
1556 : : /* short length > long length */
1557 : 0 : d = l2->length - l1->length;
1558 : 0 : if (d)
1559 : : return d;
1560 : :
1561 : : /* read > read/write */
1562 : 0 : return (int)(l1->iomode == IOMODE_READ) - (int)(l2->iomode == IOMODE_READ);
1563 : : }
1564 : :
1565 : : static bool
1566 : 0 : pnfs_lseg_range_is_after(const struct pnfs_layout_range *l1,
1567 : : const struct pnfs_layout_range *l2)
1568 : : {
1569 : 0 : return pnfs_lseg_range_cmp(l1, l2) > 0;
1570 : : }
1571 : :
1572 : : static bool
1573 : 0 : pnfs_lseg_no_merge(struct pnfs_layout_segment *lseg,
1574 : : struct pnfs_layout_segment *old)
1575 : : {
1576 : 0 : return false;
1577 : : }
1578 : :
1579 : : void
1580 : 0 : pnfs_generic_layout_insert_lseg(struct pnfs_layout_hdr *lo,
1581 : : struct pnfs_layout_segment *lseg,
1582 : : bool (*is_after)(const struct pnfs_layout_range *,
1583 : : const struct pnfs_layout_range *),
1584 : : bool (*do_merge)(struct pnfs_layout_segment *,
1585 : : struct pnfs_layout_segment *),
1586 : : struct list_head *free_me)
1587 : : {
1588 : : struct pnfs_layout_segment *lp, *tmp;
1589 : :
1590 : : dprintk("%s:Begin\n", __func__);
1591 : :
1592 : 0 : list_for_each_entry_safe(lp, tmp, &lo->plh_segs, pls_list) {
1593 : 0 : if (test_bit(NFS_LSEG_VALID, &lp->pls_flags) == 0)
1594 : 0 : continue;
1595 : 0 : if (do_merge(lseg, lp)) {
1596 : 0 : mark_lseg_invalid(lp, free_me);
1597 : 0 : continue;
1598 : : }
1599 : 0 : if (is_after(&lseg->pls_range, &lp->pls_range))
1600 : 0 : continue;
1601 : 0 : list_add_tail(&lseg->pls_list, &lp->pls_list);
1602 : : dprintk("%s: inserted lseg %p "
1603 : : "iomode %d offset %llu length %llu before "
1604 : : "lp %p iomode %d offset %llu length %llu\n",
1605 : : __func__, lseg, lseg->pls_range.iomode,
1606 : : lseg->pls_range.offset, lseg->pls_range.length,
1607 : : lp, lp->pls_range.iomode, lp->pls_range.offset,
1608 : : lp->pls_range.length);
1609 : : goto out;
1610 : : }
1611 : 0 : list_add_tail(&lseg->pls_list, &lo->plh_segs);
1612 : : dprintk("%s: inserted lseg %p "
1613 : : "iomode %d offset %llu length %llu at tail\n",
1614 : : __func__, lseg, lseg->pls_range.iomode,
1615 : : lseg->pls_range.offset, lseg->pls_range.length);
1616 : : out:
1617 : : pnfs_get_layout_hdr(lo);
1618 : :
1619 : : dprintk("%s:Return\n", __func__);
1620 : 0 : }
1621 : : EXPORT_SYMBOL_GPL(pnfs_generic_layout_insert_lseg);
1622 : :
1623 : : static void
1624 : 0 : pnfs_layout_insert_lseg(struct pnfs_layout_hdr *lo,
1625 : : struct pnfs_layout_segment *lseg,
1626 : : struct list_head *free_me)
1627 : : {
1628 : 0 : struct inode *inode = lo->plh_inode;
1629 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
1630 : :
1631 : 0 : if (ld->add_lseg != NULL)
1632 : 0 : ld->add_lseg(lo, lseg, free_me);
1633 : : else
1634 : 0 : pnfs_generic_layout_insert_lseg(lo, lseg,
1635 : : pnfs_lseg_range_is_after,
1636 : : pnfs_lseg_no_merge,
1637 : : free_me);
1638 : 0 : }
1639 : :
1640 : : static struct pnfs_layout_hdr *
1641 : 0 : alloc_init_layout_hdr(struct inode *ino,
1642 : : struct nfs_open_context *ctx,
1643 : : gfp_t gfp_flags)
1644 : : {
1645 : : struct pnfs_layout_hdr *lo;
1646 : :
1647 : : lo = pnfs_alloc_layout_hdr(ino, gfp_flags);
1648 : 0 : if (!lo)
1649 : : return NULL;
1650 : : refcount_set(&lo->plh_refcount, 1);
1651 : 0 : INIT_LIST_HEAD(&lo->plh_layouts);
1652 : 0 : INIT_LIST_HEAD(&lo->plh_segs);
1653 : 0 : INIT_LIST_HEAD(&lo->plh_return_segs);
1654 : 0 : INIT_LIST_HEAD(&lo->plh_bulk_destroy);
1655 : 0 : lo->plh_inode = ino;
1656 : 0 : lo->plh_lc_cred = get_cred(ctx->cred);
1657 : 0 : lo->plh_flags |= 1 << NFS_LAYOUT_INVALID_STID;
1658 : 0 : return lo;
1659 : : }
1660 : :
1661 : : static struct pnfs_layout_hdr *
1662 : 0 : pnfs_find_alloc_layout(struct inode *ino,
1663 : : struct nfs_open_context *ctx,
1664 : : gfp_t gfp_flags)
1665 : : __releases(&ino->i_lock)
1666 : : __acquires(&ino->i_lock)
1667 : : {
1668 : : struct nfs_inode *nfsi = NFS_I(ino);
1669 : : struct pnfs_layout_hdr *new = NULL;
1670 : :
1671 : : dprintk("%s Begin ino=%p layout=%p\n", __func__, ino, nfsi->layout);
1672 : :
1673 : 0 : if (nfsi->layout != NULL)
1674 : : goto out_existing;
1675 : : spin_unlock(&ino->i_lock);
1676 : 0 : new = alloc_init_layout_hdr(ino, ctx, gfp_flags);
1677 : : spin_lock(&ino->i_lock);
1678 : :
1679 : 0 : if (likely(nfsi->layout == NULL)) { /* Won the race? */
1680 : 0 : nfsi->layout = new;
1681 : 0 : return new;
1682 : 0 : } else if (new != NULL)
1683 : 0 : pnfs_free_layout_hdr(new);
1684 : : out_existing:
1685 : 0 : pnfs_get_layout_hdr(nfsi->layout);
1686 : 0 : return nfsi->layout;
1687 : : }
1688 : :
1689 : : /*
1690 : : * iomode matching rules:
1691 : : * iomode lseg strict match
1692 : : * iomode
1693 : : * ----- ----- ------ -----
1694 : : * ANY READ N/A true
1695 : : * ANY RW N/A true
1696 : : * RW READ N/A false
1697 : : * RW RW N/A true
1698 : : * READ READ N/A true
1699 : : * READ RW true false
1700 : : * READ RW false true
1701 : : */
1702 : : static bool
1703 : 0 : pnfs_lseg_range_match(const struct pnfs_layout_range *ls_range,
1704 : : const struct pnfs_layout_range *range,
1705 : : bool strict_iomode)
1706 : : {
1707 : : struct pnfs_layout_range range1;
1708 : :
1709 : 0 : if ((range->iomode == IOMODE_RW &&
1710 : 0 : ls_range->iomode != IOMODE_RW) ||
1711 : 0 : (range->iomode != ls_range->iomode &&
1712 : 0 : strict_iomode) ||
1713 : 0 : !pnfs_lseg_range_intersecting(ls_range, range))
1714 : : return false;
1715 : :
1716 : : /* range1 covers only the first byte in the range */
1717 : 0 : range1 = *range;
1718 : : range1.length = 1;
1719 : 0 : return pnfs_lseg_range_contained(ls_range, &range1);
1720 : : }
1721 : :
1722 : : /*
1723 : : * lookup range in layout
1724 : : */
1725 : : static struct pnfs_layout_segment *
1726 : 0 : pnfs_find_lseg(struct pnfs_layout_hdr *lo,
1727 : : struct pnfs_layout_range *range,
1728 : : bool strict_iomode)
1729 : : {
1730 : : struct pnfs_layout_segment *lseg, *ret = NULL;
1731 : :
1732 : : dprintk("%s:Begin\n", __func__);
1733 : :
1734 : 0 : list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
1735 : 0 : if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
1736 : 0 : pnfs_lseg_range_match(&lseg->pls_range, range,
1737 : : strict_iomode)) {
1738 : : ret = pnfs_get_lseg(lseg);
1739 : 0 : break;
1740 : : }
1741 : : }
1742 : :
1743 : : dprintk("%s:Return lseg %p ref %d\n",
1744 : : __func__, ret, ret ? refcount_read(&ret->pls_refcount) : 0);
1745 : 0 : return ret;
1746 : : }
1747 : :
1748 : : /*
1749 : : * Use mdsthreshold hints set at each OPEN to determine if I/O should go
1750 : : * to the MDS or over pNFS
1751 : : *
1752 : : * The nfs_inode read_io and write_io fields are cumulative counters reset
1753 : : * when there are no layout segments. Note that in pnfs_update_layout iomode
1754 : : * is set to IOMODE_READ for a READ request, and set to IOMODE_RW for a
1755 : : * WRITE request.
1756 : : *
1757 : : * A return of true means use MDS I/O.
1758 : : *
1759 : : * From rfc 5661:
1760 : : * If a file's size is smaller than the file size threshold, data accesses
1761 : : * SHOULD be sent to the metadata server. If an I/O request has a length that
1762 : : * is below the I/O size threshold, the I/O SHOULD be sent to the metadata
1763 : : * server. If both file size and I/O size are provided, the client SHOULD
1764 : : * reach or exceed both thresholds before sending its read or write
1765 : : * requests to the data server.
1766 : : */
1767 : 0 : static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
1768 : : struct inode *ino, int iomode)
1769 : : {
1770 : 0 : struct nfs4_threshold *t = ctx->mdsthreshold;
1771 : : struct nfs_inode *nfsi = NFS_I(ino);
1772 : : loff_t fsize = i_size_read(ino);
1773 : : bool size = false, size_set = false, io = false, io_set = false, ret = false;
1774 : :
1775 : 0 : if (t == NULL)
1776 : : return ret;
1777 : :
1778 : : dprintk("%s bm=0x%x rd_sz=%llu wr_sz=%llu rd_io=%llu wr_io=%llu\n",
1779 : : __func__, t->bm, t->rd_sz, t->wr_sz, t->rd_io_sz, t->wr_io_sz);
1780 : :
1781 : 0 : switch (iomode) {
1782 : : case IOMODE_READ:
1783 : 0 : if (t->bm & THRESHOLD_RD) {
1784 : : dprintk("%s fsize %llu\n", __func__, fsize);
1785 : : size_set = true;
1786 : 0 : if (fsize < t->rd_sz)
1787 : : size = true;
1788 : : }
1789 : 0 : if (t->bm & THRESHOLD_RD_IO) {
1790 : : dprintk("%s nfsi->read_io %llu\n", __func__,
1791 : : nfsi->read_io);
1792 : : io_set = true;
1793 : 0 : if (nfsi->read_io < t->rd_io_sz)
1794 : : io = true;
1795 : : }
1796 : : break;
1797 : : case IOMODE_RW:
1798 : 0 : if (t->bm & THRESHOLD_WR) {
1799 : : dprintk("%s fsize %llu\n", __func__, fsize);
1800 : : size_set = true;
1801 : 0 : if (fsize < t->wr_sz)
1802 : : size = true;
1803 : : }
1804 : 0 : if (t->bm & THRESHOLD_WR_IO) {
1805 : : dprintk("%s nfsi->write_io %llu\n", __func__,
1806 : : nfsi->write_io);
1807 : : io_set = true;
1808 : 0 : if (nfsi->write_io < t->wr_io_sz)
1809 : : io = true;
1810 : : }
1811 : : break;
1812 : : }
1813 : 0 : if (size_set && io_set) {
1814 : 0 : if (size && io)
1815 : : ret = true;
1816 : 0 : } else if (size || io)
1817 : : ret = true;
1818 : :
1819 : : dprintk("<-- %s size %d io %d ret %d\n", __func__, size, io, ret);
1820 : 0 : return ret;
1821 : : }
1822 : :
1823 : 0 : static int pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
1824 : : {
1825 : : /*
1826 : : * send layoutcommit as it can hold up layoutreturn due to lseg
1827 : : * reference
1828 : : */
1829 : 0 : pnfs_layoutcommit_inode(lo->plh_inode, false);
1830 : 0 : return wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
1831 : : nfs_wait_bit_killable,
1832 : : TASK_KILLABLE);
1833 : : }
1834 : :
1835 : : static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
1836 : : {
1837 : 0 : atomic_inc(&lo->plh_outstanding);
1838 : : }
1839 : :
1840 : 0 : static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
1841 : : {
1842 : 0 : if (atomic_dec_and_test(&lo->plh_outstanding))
1843 : 0 : wake_up_var(&lo->plh_outstanding);
1844 : 0 : }
1845 : :
1846 : 0 : static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo)
1847 : : {
1848 : 0 : unsigned long *bitlock = &lo->plh_flags;
1849 : :
1850 : 0 : clear_bit_unlock(NFS_LAYOUT_FIRST_LAYOUTGET, bitlock);
1851 : 0 : smp_mb__after_atomic();
1852 : 0 : wake_up_bit(bitlock, NFS_LAYOUT_FIRST_LAYOUTGET);
1853 : 0 : }
1854 : :
1855 : 0 : static void _add_to_server_list(struct pnfs_layout_hdr *lo,
1856 : : struct nfs_server *server)
1857 : : {
1858 : 0 : if (list_empty(&lo->plh_layouts)) {
1859 : 0 : struct nfs_client *clp = server->nfs_client;
1860 : :
1861 : : /* The lo must be on the clp list if there is any
1862 : : * chance of a CB_LAYOUTRECALL(FILE) coming in.
1863 : : */
1864 : : spin_lock(&clp->cl_lock);
1865 : 0 : if (list_empty(&lo->plh_layouts))
1866 : 0 : list_add_tail(&lo->plh_layouts, &server->layouts);
1867 : : spin_unlock(&clp->cl_lock);
1868 : : }
1869 : 0 : }
1870 : :
1871 : : /*
1872 : : * Layout segment is retreived from the server if not cached.
1873 : : * The appropriate layout segment is referenced and returned to the caller.
1874 : : */
1875 : : struct pnfs_layout_segment *
1876 : 0 : pnfs_update_layout(struct inode *ino,
1877 : : struct nfs_open_context *ctx,
1878 : : loff_t pos,
1879 : : u64 count,
1880 : : enum pnfs_iomode iomode,
1881 : : bool strict_iomode,
1882 : : gfp_t gfp_flags)
1883 : : {
1884 : 0 : struct pnfs_layout_range arg = {
1885 : : .iomode = iomode,
1886 : : .offset = pos,
1887 : : .length = count,
1888 : : };
1889 : : unsigned pg_offset;
1890 : : struct nfs_server *server = NFS_SERVER(ino);
1891 : 0 : struct nfs_client *clp = server->nfs_client;
1892 : : struct pnfs_layout_hdr *lo = NULL;
1893 : : struct pnfs_layout_segment *lseg = NULL;
1894 : : struct nfs4_layoutget *lgp;
1895 : : nfs4_stateid stateid;
1896 : 0 : long timeout = 0;
1897 : 0 : unsigned long giveup = jiffies + (clp->cl_lease_time << 1);
1898 : : bool first;
1899 : :
1900 : 0 : if (!pnfs_enabled_sb(NFS_SERVER(ino))) {
1901 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1902 : : PNFS_UPDATE_LAYOUT_NO_PNFS);
1903 : 0 : goto out;
1904 : : }
1905 : :
1906 : 0 : if (pnfs_within_mdsthreshold(ctx, ino, iomode)) {
1907 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1908 : : PNFS_UPDATE_LAYOUT_MDSTHRESH);
1909 : 0 : goto out;
1910 : : }
1911 : :
1912 : : lookup_again:
1913 : 0 : lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp));
1914 : 0 : if (IS_ERR(lseg))
1915 : : goto out;
1916 : : first = false;
1917 : : spin_lock(&ino->i_lock);
1918 : 0 : lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
1919 : 0 : if (lo == NULL) {
1920 : : spin_unlock(&ino->i_lock);
1921 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1922 : : PNFS_UPDATE_LAYOUT_NOMEM);
1923 : 0 : goto out;
1924 : : }
1925 : :
1926 : : /* Do we even need to bother with this? */
1927 : 0 : if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
1928 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1929 : : PNFS_UPDATE_LAYOUT_BULK_RECALL);
1930 : : dprintk("%s matches recall, use MDS\n", __func__);
1931 : 0 : goto out_unlock;
1932 : : }
1933 : :
1934 : : /* if LAYOUTGET already failed once we don't try again */
1935 : 0 : if (pnfs_layout_io_test_failed(lo, iomode)) {
1936 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1937 : : PNFS_UPDATE_LAYOUT_IO_TEST_FAIL);
1938 : 0 : goto out_unlock;
1939 : : }
1940 : :
1941 : : /*
1942 : : * If the layout segment list is empty, but there are outstanding
1943 : : * layoutget calls, then they might be subject to a layoutrecall.
1944 : : */
1945 : 0 : if (list_empty(&lo->plh_segs) &&
1946 : 0 : atomic_read(&lo->plh_outstanding) != 0) {
1947 : : spin_unlock(&ino->i_lock);
1948 : 0 : lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
1949 : : !atomic_read(&lo->plh_outstanding)));
1950 : 0 : if (IS_ERR(lseg))
1951 : : goto out_put_layout_hdr;
1952 : 0 : pnfs_put_layout_hdr(lo);
1953 : 0 : goto lookup_again;
1954 : : }
1955 : :
1956 : 0 : lseg = pnfs_find_lseg(lo, &arg, strict_iomode);
1957 : 0 : if (lseg) {
1958 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
1959 : : PNFS_UPDATE_LAYOUT_FOUND_CACHED);
1960 : 0 : goto out_unlock;
1961 : : }
1962 : :
1963 : : /*
1964 : : * Choose a stateid for the LAYOUTGET. If we don't have a layout
1965 : : * stateid, or it has been invalidated, then we must use the open
1966 : : * stateid.
1967 : : */
1968 : 0 : if (test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags)) {
1969 : : int status;
1970 : :
1971 : : /*
1972 : : * The first layoutget for the file. Need to serialize per
1973 : : * RFC 5661 Errata 3208.
1974 : : */
1975 : 0 : if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET,
1976 : : &lo->plh_flags)) {
1977 : : spin_unlock(&ino->i_lock);
1978 : 0 : lseg = ERR_PTR(wait_on_bit(&lo->plh_flags,
1979 : : NFS_LAYOUT_FIRST_LAYOUTGET,
1980 : : TASK_KILLABLE));
1981 : 0 : if (IS_ERR(lseg))
1982 : : goto out_put_layout_hdr;
1983 : 0 : pnfs_put_layout_hdr(lo);
1984 : : dprintk("%s retrying\n", __func__);
1985 : 0 : goto lookup_again;
1986 : : }
1987 : :
1988 : : first = true;
1989 : 0 : status = nfs4_select_rw_stateid(ctx->state,
1990 : : iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ,
1991 : : NULL, &stateid, NULL);
1992 : 0 : if (status != 0) {
1993 : : lseg = ERR_PTR(status);
1994 : 0 : trace_pnfs_update_layout(ino, pos, count,
1995 : : iomode, lo, lseg,
1996 : : PNFS_UPDATE_LAYOUT_INVALID_OPEN);
1997 : 0 : if (status != -EAGAIN)
1998 : : goto out_unlock;
1999 : : spin_unlock(&ino->i_lock);
2000 : 0 : nfs4_schedule_stateid_recovery(server, ctx->state);
2001 : 0 : pnfs_clear_first_layoutget(lo);
2002 : 0 : pnfs_put_layout_hdr(lo);
2003 : 0 : goto lookup_again;
2004 : : }
2005 : : } else {
2006 : : nfs4_stateid_copy(&stateid, &lo->plh_stateid);
2007 : : }
2008 : :
2009 : : /*
2010 : : * Because we free lsegs before sending LAYOUTRETURN, we need to wait
2011 : : * for LAYOUTRETURN even if first is true.
2012 : : */
2013 : 0 : if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
2014 : : spin_unlock(&ino->i_lock);
2015 : : dprintk("%s wait for layoutreturn\n", __func__);
2016 : 0 : lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
2017 : 0 : if (!IS_ERR(lseg)) {
2018 : 0 : if (first)
2019 : 0 : pnfs_clear_first_layoutget(lo);
2020 : 0 : pnfs_put_layout_hdr(lo);
2021 : : dprintk("%s retrying\n", __func__);
2022 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo,
2023 : : lseg, PNFS_UPDATE_LAYOUT_RETRY);
2024 : 0 : goto lookup_again;
2025 : : }
2026 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
2027 : : PNFS_UPDATE_LAYOUT_RETURN);
2028 : 0 : goto out_put_layout_hdr;
2029 : : }
2030 : :
2031 : 0 : if (pnfs_layoutgets_blocked(lo)) {
2032 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
2033 : : PNFS_UPDATE_LAYOUT_BLOCKED);
2034 : 0 : goto out_unlock;
2035 : : }
2036 : : nfs_layoutget_begin(lo);
2037 : : spin_unlock(&ino->i_lock);
2038 : :
2039 : 0 : _add_to_server_list(lo, server);
2040 : :
2041 : 0 : pg_offset = arg.offset & ~PAGE_MASK;
2042 : 0 : if (pg_offset) {
2043 : 0 : arg.offset -= pg_offset;
2044 : 0 : arg.length += pg_offset;
2045 : : }
2046 : 0 : if (arg.length != NFS4_MAX_UINT64)
2047 : 0 : arg.length = PAGE_ALIGN(arg.length);
2048 : :
2049 : 0 : lgp = pnfs_alloc_init_layoutget_args(ino, ctx, &stateid, &arg, gfp_flags);
2050 : 0 : if (!lgp) {
2051 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, NULL,
2052 : : PNFS_UPDATE_LAYOUT_NOMEM);
2053 : 0 : nfs_layoutget_end(lo);
2054 : 0 : goto out_put_layout_hdr;
2055 : : }
2056 : :
2057 : 0 : lseg = nfs4_proc_layoutget(lgp, &timeout);
2058 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
2059 : : PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
2060 : 0 : nfs_layoutget_end(lo);
2061 : 0 : if (IS_ERR(lseg)) {
2062 : 0 : switch(PTR_ERR(lseg)) {
2063 : : case -EBUSY:
2064 : 0 : if (time_after(jiffies, giveup))
2065 : : lseg = NULL;
2066 : : break;
2067 : : case -ERECALLCONFLICT:
2068 : : case -EAGAIN:
2069 : : break;
2070 : : default:
2071 : 0 : if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
2072 : 0 : pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
2073 : : lseg = NULL;
2074 : : }
2075 : : goto out_put_layout_hdr;
2076 : : }
2077 : 0 : if (lseg) {
2078 : 0 : if (first)
2079 : 0 : pnfs_clear_first_layoutget(lo);
2080 : 0 : trace_pnfs_update_layout(ino, pos, count,
2081 : : iomode, lo, lseg, PNFS_UPDATE_LAYOUT_RETRY);
2082 : 0 : pnfs_put_layout_hdr(lo);
2083 : 0 : goto lookup_again;
2084 : : }
2085 : : } else {
2086 : 0 : pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
2087 : : }
2088 : :
2089 : : out_put_layout_hdr:
2090 : 0 : if (first)
2091 : 0 : pnfs_clear_first_layoutget(lo);
2092 : 0 : trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
2093 : : PNFS_UPDATE_LAYOUT_EXIT);
2094 : 0 : pnfs_put_layout_hdr(lo);
2095 : : out:
2096 : : dprintk("%s: inode %s/%llu pNFS layout segment %s for "
2097 : : "(%s, offset: %llu, length: %llu)\n",
2098 : : __func__, ino->i_sb->s_id,
2099 : : (unsigned long long)NFS_FILEID(ino),
2100 : : IS_ERR_OR_NULL(lseg) ? "not found" : "found",
2101 : : iomode==IOMODE_RW ? "read/write" : "read-only",
2102 : : (unsigned long long)pos,
2103 : : (unsigned long long)count);
2104 : 0 : return lseg;
2105 : : out_unlock:
2106 : : spin_unlock(&ino->i_lock);
2107 : : goto out_put_layout_hdr;
2108 : : }
2109 : : EXPORT_SYMBOL_GPL(pnfs_update_layout);
2110 : :
2111 : : static bool
2112 : 0 : pnfs_sanity_check_layout_range(struct pnfs_layout_range *range)
2113 : : {
2114 : 0 : switch (range->iomode) {
2115 : : case IOMODE_READ:
2116 : : case IOMODE_RW:
2117 : : break;
2118 : : default:
2119 : : return false;
2120 : : }
2121 : 0 : if (range->offset == NFS4_MAX_UINT64)
2122 : : return false;
2123 : 0 : if (range->length == 0)
2124 : : return false;
2125 : 0 : if (range->length != NFS4_MAX_UINT64 &&
2126 : 0 : range->length > NFS4_MAX_UINT64 - range->offset)
2127 : : return false;
2128 : 0 : return true;
2129 : : }
2130 : :
2131 : : static struct pnfs_layout_hdr *
2132 : 0 : _pnfs_grab_empty_layout(struct inode *ino, struct nfs_open_context *ctx)
2133 : : {
2134 : : struct pnfs_layout_hdr *lo;
2135 : :
2136 : : spin_lock(&ino->i_lock);
2137 : 0 : lo = pnfs_find_alloc_layout(ino, ctx, GFP_KERNEL);
2138 : 0 : if (!lo)
2139 : : goto out_unlock;
2140 : 0 : if (!test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags))
2141 : : goto out_unlock;
2142 : 0 : if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
2143 : : goto out_unlock;
2144 : 0 : if (pnfs_layoutgets_blocked(lo))
2145 : : goto out_unlock;
2146 : 0 : if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags))
2147 : : goto out_unlock;
2148 : : nfs_layoutget_begin(lo);
2149 : : spin_unlock(&ino->i_lock);
2150 : 0 : _add_to_server_list(lo, NFS_SERVER(ino));
2151 : 0 : return lo;
2152 : :
2153 : : out_unlock:
2154 : : spin_unlock(&ino->i_lock);
2155 : 0 : pnfs_put_layout_hdr(lo);
2156 : 0 : return NULL;
2157 : : }
2158 : :
2159 : : extern const nfs4_stateid current_stateid;
2160 : :
2161 : 0 : static void _lgopen_prepare_attached(struct nfs4_opendata *data,
2162 : : struct nfs_open_context *ctx)
2163 : : {
2164 : 0 : struct inode *ino = data->dentry->d_inode;
2165 : 0 : struct pnfs_layout_range rng = {
2166 : 0 : .iomode = (data->o_arg.fmode & FMODE_WRITE) ?
2167 : : IOMODE_RW: IOMODE_READ,
2168 : : .offset = 0,
2169 : : .length = NFS4_MAX_UINT64,
2170 : : };
2171 : : struct nfs4_layoutget *lgp;
2172 : : struct pnfs_layout_hdr *lo;
2173 : :
2174 : : /* Heuristic: don't send layoutget if we have cached data */
2175 : 0 : if (rng.iomode == IOMODE_READ &&
2176 : 0 : (i_size_read(ino) == 0 || ino->i_mapping->nrpages != 0))
2177 : 0 : return;
2178 : :
2179 : 0 : lo = _pnfs_grab_empty_layout(ino, ctx);
2180 : 0 : if (!lo)
2181 : : return;
2182 : 0 : lgp = pnfs_alloc_init_layoutget_args(ino, ctx, ¤t_stateid,
2183 : : &rng, GFP_KERNEL);
2184 : 0 : if (!lgp) {
2185 : 0 : pnfs_clear_first_layoutget(lo);
2186 : 0 : pnfs_put_layout_hdr(lo);
2187 : 0 : return;
2188 : : }
2189 : 0 : data->lgp = lgp;
2190 : 0 : data->o_arg.lg_args = &lgp->args;
2191 : 0 : data->o_res.lg_res = &lgp->res;
2192 : : }
2193 : :
2194 : 0 : static void _lgopen_prepare_floating(struct nfs4_opendata *data,
2195 : : struct nfs_open_context *ctx)
2196 : : {
2197 : 0 : struct pnfs_layout_range rng = {
2198 : 0 : .iomode = (data->o_arg.fmode & FMODE_WRITE) ?
2199 : : IOMODE_RW: IOMODE_READ,
2200 : : .offset = 0,
2201 : : .length = NFS4_MAX_UINT64,
2202 : : };
2203 : : struct nfs4_layoutget *lgp;
2204 : :
2205 : 0 : lgp = pnfs_alloc_init_layoutget_args(NULL, ctx, ¤t_stateid,
2206 : : &rng, GFP_KERNEL);
2207 : 0 : if (!lgp)
2208 : 0 : return;
2209 : 0 : data->lgp = lgp;
2210 : 0 : data->o_arg.lg_args = &lgp->args;
2211 : 0 : data->o_res.lg_res = &lgp->res;
2212 : : }
2213 : :
2214 : 0 : void pnfs_lgopen_prepare(struct nfs4_opendata *data,
2215 : : struct nfs_open_context *ctx)
2216 : : {
2217 : 0 : struct nfs_server *server = NFS_SERVER(data->dir->d_inode);
2218 : :
2219 : 0 : if (!(pnfs_enabled_sb(server) &&
2220 : 0 : server->pnfs_curr_ld->flags & PNFS_LAYOUTGET_ON_OPEN))
2221 : : return;
2222 : : /* Could check on max_ops, but currently hardcoded high enough */
2223 : 0 : if (!nfs_server_capable(data->dir->d_inode, NFS_CAP_LGOPEN))
2224 : : return;
2225 : 0 : if (data->state)
2226 : 0 : _lgopen_prepare_attached(data, ctx);
2227 : : else
2228 : 0 : _lgopen_prepare_floating(data, ctx);
2229 : : }
2230 : :
2231 : 0 : void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
2232 : : struct nfs_open_context *ctx)
2233 : : {
2234 : : struct pnfs_layout_hdr *lo;
2235 : : struct pnfs_layout_segment *lseg;
2236 : : struct nfs_server *srv = NFS_SERVER(ino);
2237 : : u32 iomode;
2238 : :
2239 : 0 : if (!lgp)
2240 : : return;
2241 : : dprintk("%s: entered with status %i\n", __func__, lgp->res.status);
2242 : 0 : if (lgp->res.status) {
2243 : 0 : switch (lgp->res.status) {
2244 : : default:
2245 : : break;
2246 : : /*
2247 : : * Halt lgopen attempts if the server doesn't recognise
2248 : : * the "current stateid" value, the layout type, or the
2249 : : * layoutget operation as being valid.
2250 : : * Also if it complains about too many ops in the compound
2251 : : * or of the request/reply being too big.
2252 : : */
2253 : : case -NFS4ERR_BAD_STATEID:
2254 : : case -NFS4ERR_NOTSUPP:
2255 : : case -NFS4ERR_REP_TOO_BIG:
2256 : : case -NFS4ERR_REP_TOO_BIG_TO_CACHE:
2257 : : case -NFS4ERR_REQ_TOO_BIG:
2258 : : case -NFS4ERR_TOO_MANY_OPS:
2259 : : case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
2260 : 0 : srv->caps &= ~NFS_CAP_LGOPEN;
2261 : : }
2262 : : return;
2263 : : }
2264 : 0 : if (!lgp->args.inode) {
2265 : 0 : lo = _pnfs_grab_empty_layout(ino, ctx);
2266 : 0 : if (!lo)
2267 : : return;
2268 : 0 : lgp->args.inode = ino;
2269 : : } else
2270 : 0 : lo = NFS_I(lgp->args.inode)->layout;
2271 : :
2272 : 0 : lseg = pnfs_layout_process(lgp);
2273 : 0 : if (!IS_ERR(lseg)) {
2274 : 0 : iomode = lgp->args.range.iomode;
2275 : 0 : pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
2276 : 0 : pnfs_put_lseg(lseg);
2277 : : }
2278 : : }
2279 : :
2280 : 0 : void nfs4_lgopen_release(struct nfs4_layoutget *lgp)
2281 : : {
2282 : 0 : if (lgp != NULL) {
2283 : 0 : struct inode *inode = lgp->args.inode;
2284 : 0 : if (inode) {
2285 : 0 : struct pnfs_layout_hdr *lo = NFS_I(inode)->layout;
2286 : 0 : pnfs_clear_first_layoutget(lo);
2287 : 0 : nfs_layoutget_end(lo);
2288 : : }
2289 : 0 : pnfs_layoutget_free(lgp);
2290 : : }
2291 : 0 : }
2292 : :
2293 : : struct pnfs_layout_segment *
2294 : 0 : pnfs_layout_process(struct nfs4_layoutget *lgp)
2295 : : {
2296 : 0 : struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout;
2297 : 0 : struct nfs4_layoutget_res *res = &lgp->res;
2298 : : struct pnfs_layout_segment *lseg;
2299 : 0 : struct inode *ino = lo->plh_inode;
2300 : 0 : LIST_HEAD(free_me);
2301 : :
2302 : 0 : if (!pnfs_sanity_check_layout_range(&res->range))
2303 : : return ERR_PTR(-EINVAL);
2304 : :
2305 : : /* Inject layout blob into I/O device driver */
2306 : 0 : lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags);
2307 : 0 : if (IS_ERR_OR_NULL(lseg)) {
2308 : 0 : if (!lseg)
2309 : : lseg = ERR_PTR(-ENOMEM);
2310 : :
2311 : : dprintk("%s: Could not allocate layout: error %ld\n",
2312 : : __func__, PTR_ERR(lseg));
2313 : 0 : return lseg;
2314 : : }
2315 : :
2316 : 0 : pnfs_init_lseg(lo, lseg, &res->range, &res->stateid);
2317 : :
2318 : : spin_lock(&ino->i_lock);
2319 : 0 : if (pnfs_layoutgets_blocked(lo)) {
2320 : : dprintk("%s forget reply due to state\n", __func__);
2321 : : goto out_forget;
2322 : : }
2323 : :
2324 : 0 : if (!pnfs_layout_is_valid(lo)) {
2325 : : /* We have a completely new layout */
2326 : 0 : pnfs_set_layout_stateid(lo, &res->stateid, true);
2327 : 0 : } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
2328 : : /* existing state ID, make sure the sequence number matches. */
2329 : 0 : if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
2330 : : dprintk("%s forget reply due to sequence\n", __func__);
2331 : : goto out_forget;
2332 : : }
2333 : 0 : pnfs_set_layout_stateid(lo, &res->stateid, false);
2334 : : } else {
2335 : : /*
2336 : : * We got an entirely new state ID. Mark all segments for the
2337 : : * inode invalid, and retry the layoutget
2338 : : */
2339 : 0 : pnfs_mark_layout_stateid_invalid(lo, &free_me);
2340 : 0 : goto out_forget;
2341 : : }
2342 : :
2343 : : pnfs_get_lseg(lseg);
2344 : 0 : pnfs_layout_insert_lseg(lo, lseg, &free_me);
2345 : :
2346 : :
2347 : 0 : if (res->return_on_close)
2348 : 0 : set_bit(NFS_LSEG_ROC, &lseg->pls_flags);
2349 : :
2350 : : spin_unlock(&ino->i_lock);
2351 : 0 : pnfs_free_lseg_list(&free_me);
2352 : 0 : return lseg;
2353 : :
2354 : : out_forget:
2355 : : spin_unlock(&ino->i_lock);
2356 : 0 : lseg->pls_layout = lo;
2357 : 0 : NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg);
2358 : 0 : return ERR_PTR(-EAGAIN);
2359 : : }
2360 : :
2361 : : /**
2362 : : * pnfs_mark_matching_lsegs_return - Free or return matching layout segments
2363 : : * @lo: pointer to layout header
2364 : : * @tmp_list: list header to be used with pnfs_free_lseg_list()
2365 : : * @return_range: describe layout segment ranges to be returned
2366 : : * @seq: stateid seqid to match
2367 : : *
2368 : : * This function is mainly intended for use by layoutrecall. It attempts
2369 : : * to free the layout segment immediately, or else to mark it for return
2370 : : * as soon as its reference count drops to zero.
2371 : : *
2372 : : * Returns
2373 : : * - 0: a layoutreturn needs to be scheduled.
2374 : : * - EBUSY: there are layout segment that are still in use.
2375 : : * - ENOENT: there are no layout segments that need to be returned.
2376 : : */
2377 : : int
2378 : 0 : pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
2379 : : struct list_head *tmp_list,
2380 : : const struct pnfs_layout_range *return_range,
2381 : : u32 seq)
2382 : : {
2383 : : struct pnfs_layout_segment *lseg, *next;
2384 : : int remaining = 0;
2385 : :
2386 : : dprintk("%s:Begin lo %p\n", __func__, lo);
2387 : :
2388 : 0 : assert_spin_locked(&lo->plh_inode->i_lock);
2389 : :
2390 : 0 : list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
2391 : 0 : if (pnfs_match_lseg_recall(lseg, return_range, seq)) {
2392 : : dprintk("%s: marking lseg %p iomode %d "
2393 : : "offset %llu length %llu\n", __func__,
2394 : : lseg, lseg->pls_range.iomode,
2395 : : lseg->pls_range.offset,
2396 : : lseg->pls_range.length);
2397 : 0 : if (mark_lseg_invalid(lseg, tmp_list))
2398 : 0 : continue;
2399 : 0 : remaining++;
2400 : 0 : set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
2401 : : }
2402 : :
2403 : 0 : if (remaining) {
2404 : 0 : pnfs_set_plh_return_info(lo, return_range->iomode, seq);
2405 : 0 : return -EBUSY;
2406 : : }
2407 : :
2408 : 0 : if (!list_empty(&lo->plh_return_segs)) {
2409 : 0 : pnfs_set_plh_return_info(lo, return_range->iomode, seq);
2410 : 0 : return 0;
2411 : : }
2412 : :
2413 : : return -ENOENT;
2414 : : }
2415 : :
2416 : 0 : void pnfs_error_mark_layout_for_return(struct inode *inode,
2417 : : struct pnfs_layout_segment *lseg)
2418 : : {
2419 : 0 : struct pnfs_layout_hdr *lo = NFS_I(inode)->layout;
2420 : 0 : struct pnfs_layout_range range = {
2421 : 0 : .iomode = lseg->pls_range.iomode,
2422 : : .offset = 0,
2423 : : .length = NFS4_MAX_UINT64,
2424 : : };
2425 : : bool return_now = false;
2426 : :
2427 : : spin_lock(&inode->i_lock);
2428 : 0 : if (!pnfs_layout_is_valid(lo)) {
2429 : : spin_unlock(&inode->i_lock);
2430 : 0 : return;
2431 : : }
2432 : 0 : pnfs_set_plh_return_info(lo, range.iomode, 0);
2433 : : /*
2434 : : * mark all matching lsegs so that we are sure to have no live
2435 : : * segments at hand when sending layoutreturn. See pnfs_put_lseg()
2436 : : * for how it works.
2437 : : */
2438 : 0 : if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, &range, 0) != -EBUSY) {
2439 : : nfs4_stateid stateid;
2440 : : enum pnfs_iomode iomode;
2441 : :
2442 : 0 : return_now = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
2443 : : spin_unlock(&inode->i_lock);
2444 : 0 : if (return_now)
2445 : 0 : pnfs_send_layoutreturn(lo, &stateid, iomode, false);
2446 : : } else {
2447 : : spin_unlock(&inode->i_lock);
2448 : 0 : nfs_commit_inode(inode, 0);
2449 : : }
2450 : : }
2451 : : EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return);
2452 : :
2453 : : void
2454 : 0 : pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio)
2455 : : {
2456 : 0 : if (pgio->pg_lseg == NULL ||
2457 : : test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags))
2458 : 0 : return;
2459 : 0 : pnfs_put_lseg(pgio->pg_lseg);
2460 : 0 : pgio->pg_lseg = NULL;
2461 : : }
2462 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout);
2463 : :
2464 : : /*
2465 : : * Check for any intersection between the request and the pgio->pg_lseg,
2466 : : * and if none, put this pgio->pg_lseg away.
2467 : : */
2468 : : static void
2469 : 0 : pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
2470 : : {
2471 : 0 : if (pgio->pg_lseg && !pnfs_lseg_request_intersecting(pgio->pg_lseg, req)) {
2472 : 0 : pnfs_put_lseg(pgio->pg_lseg);
2473 : 0 : pgio->pg_lseg = NULL;
2474 : : }
2475 : 0 : }
2476 : :
2477 : : void
2478 : 0 : pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
2479 : : {
2480 : : u64 rd_size = req->wb_bytes;
2481 : :
2482 : 0 : pnfs_generic_pg_check_layout(pgio);
2483 : 0 : pnfs_generic_pg_check_range(pgio, req);
2484 : 0 : if (pgio->pg_lseg == NULL) {
2485 : 0 : if (pgio->pg_dreq == NULL)
2486 : 0 : rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
2487 : : else
2488 : 0 : rd_size = nfs_dreq_bytes_left(pgio->pg_dreq);
2489 : :
2490 : 0 : pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
2491 : : nfs_req_openctx(req),
2492 : : req_offset(req),
2493 : : rd_size,
2494 : : IOMODE_READ,
2495 : : false,
2496 : : GFP_KERNEL);
2497 : 0 : if (IS_ERR(pgio->pg_lseg)) {
2498 : 0 : pgio->pg_error = PTR_ERR(pgio->pg_lseg);
2499 : 0 : pgio->pg_lseg = NULL;
2500 : 0 : return;
2501 : : }
2502 : : }
2503 : : /* If no lseg, fall back to read through mds */
2504 : 0 : if (pgio->pg_lseg == NULL)
2505 : 0 : nfs_pageio_reset_read_mds(pgio);
2506 : :
2507 : : }
2508 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read);
2509 : :
2510 : : void
2511 : 0 : pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
2512 : : struct nfs_page *req, u64 wb_size)
2513 : : {
2514 : 0 : pnfs_generic_pg_check_layout(pgio);
2515 : 0 : pnfs_generic_pg_check_range(pgio, req);
2516 : 0 : if (pgio->pg_lseg == NULL) {
2517 : 0 : pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
2518 : : nfs_req_openctx(req),
2519 : : req_offset(req),
2520 : : wb_size,
2521 : : IOMODE_RW,
2522 : : false,
2523 : : GFP_KERNEL);
2524 : 0 : if (IS_ERR(pgio->pg_lseg)) {
2525 : 0 : pgio->pg_error = PTR_ERR(pgio->pg_lseg);
2526 : 0 : pgio->pg_lseg = NULL;
2527 : 0 : return;
2528 : : }
2529 : : }
2530 : : /* If no lseg, fall back to write through mds */
2531 : 0 : if (pgio->pg_lseg == NULL)
2532 : 0 : nfs_pageio_reset_write_mds(pgio);
2533 : : }
2534 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write);
2535 : :
2536 : : void
2537 : 0 : pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *desc)
2538 : : {
2539 : 0 : if (desc->pg_lseg) {
2540 : 0 : pnfs_put_lseg(desc->pg_lseg);
2541 : 0 : desc->pg_lseg = NULL;
2542 : : }
2543 : 0 : }
2544 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup);
2545 : :
2546 : : /*
2547 : : * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number
2548 : : * of bytes (maximum @req->wb_bytes) that can be coalesced.
2549 : : */
2550 : : size_t
2551 : 0 : pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
2552 : : struct nfs_page *prev, struct nfs_page *req)
2553 : : {
2554 : : unsigned int size;
2555 : : u64 seg_end, req_start, seg_left;
2556 : :
2557 : 0 : size = nfs_generic_pg_test(pgio, prev, req);
2558 : 0 : if (!size)
2559 : : return 0;
2560 : :
2561 : : /*
2562 : : * 'size' contains the number of bytes left in the current page (up
2563 : : * to the original size asked for in @req->wb_bytes).
2564 : : *
2565 : : * Calculate how many bytes are left in the layout segment
2566 : : * and if there are less bytes than 'size', return that instead.
2567 : : *
2568 : : * Please also note that 'end_offset' is actually the offset of the
2569 : : * first byte that lies outside the pnfs_layout_range. FIXME?
2570 : : *
2571 : : */
2572 : 0 : if (pgio->pg_lseg) {
2573 : 0 : seg_end = pnfs_end_offset(pgio->pg_lseg->pls_range.offset,
2574 : : pgio->pg_lseg->pls_range.length);
2575 : 0 : req_start = req_offset(req);
2576 : :
2577 : : /* start of request is past the last byte of this segment */
2578 : 0 : if (req_start >= seg_end)
2579 : : return 0;
2580 : :
2581 : : /* adjust 'size' iff there are fewer bytes left in the
2582 : : * segment than what nfs_generic_pg_test returned */
2583 : 0 : seg_left = seg_end - req_start;
2584 : 0 : if (seg_left < size)
2585 : 0 : size = (unsigned int)seg_left;
2586 : : }
2587 : :
2588 : 0 : return size;
2589 : : }
2590 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
2591 : :
2592 : 0 : int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *hdr)
2593 : : {
2594 : : struct nfs_pageio_descriptor pgio;
2595 : :
2596 : : /* Resend all requests through the MDS */
2597 : 0 : nfs_pageio_init_write(&pgio, hdr->inode, FLUSH_STABLE, true,
2598 : : hdr->completion_ops);
2599 : 0 : set_bit(NFS_CONTEXT_RESEND_WRITES, &hdr->args.context->flags);
2600 : 0 : return nfs_pageio_resend(&pgio, hdr);
2601 : : }
2602 : : EXPORT_SYMBOL_GPL(pnfs_write_done_resend_to_mds);
2603 : :
2604 : 0 : static void pnfs_ld_handle_write_error(struct nfs_pgio_header *hdr)
2605 : : {
2606 : :
2607 : : dprintk("pnfs write error = %d\n", hdr->pnfs_error);
2608 : 0 : if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
2609 : : PNFS_LAYOUTRET_ON_ERROR) {
2610 : 0 : pnfs_return_layout(hdr->inode);
2611 : : }
2612 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
2613 : 0 : hdr->task.tk_status = pnfs_write_done_resend_to_mds(hdr);
2614 : 0 : }
2615 : :
2616 : : /*
2617 : : * Called by non rpc-based layout drivers
2618 : : */
2619 : 0 : void pnfs_ld_write_done(struct nfs_pgio_header *hdr)
2620 : : {
2621 : 0 : if (likely(!hdr->pnfs_error)) {
2622 : 0 : pnfs_set_layoutcommit(hdr->inode, hdr->lseg,
2623 : 0 : hdr->mds_offset + hdr->res.count);
2624 : 0 : hdr->mds_ops->rpc_call_done(&hdr->task, hdr);
2625 : : }
2626 : 0 : trace_nfs4_pnfs_write(hdr, hdr->pnfs_error);
2627 : 0 : if (unlikely(hdr->pnfs_error))
2628 : 0 : pnfs_ld_handle_write_error(hdr);
2629 : 0 : hdr->mds_ops->rpc_release(hdr);
2630 : 0 : }
2631 : : EXPORT_SYMBOL_GPL(pnfs_ld_write_done);
2632 : :
2633 : : static void
2634 : 0 : pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
2635 : : struct nfs_pgio_header *hdr)
2636 : : {
2637 : 0 : struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
2638 : :
2639 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
2640 : 0 : list_splice_tail_init(&hdr->pages, &mirror->pg_list);
2641 : 0 : nfs_pageio_reset_write_mds(desc);
2642 : 0 : mirror->pg_recoalesce = 1;
2643 : : }
2644 : 0 : hdr->completion_ops->completion(hdr);
2645 : 0 : }
2646 : :
2647 : : static enum pnfs_try_status
2648 : 0 : pnfs_try_to_write_data(struct nfs_pgio_header *hdr,
2649 : : const struct rpc_call_ops *call_ops,
2650 : : struct pnfs_layout_segment *lseg,
2651 : : int how)
2652 : : {
2653 : 0 : struct inode *inode = hdr->inode;
2654 : : enum pnfs_try_status trypnfs;
2655 : : struct nfs_server *nfss = NFS_SERVER(inode);
2656 : :
2657 : 0 : hdr->mds_ops = call_ops;
2658 : :
2659 : : dprintk("%s: Writing ino:%lu %u@%llu (how %d)\n", __func__,
2660 : : inode->i_ino, hdr->args.count, hdr->args.offset, how);
2661 : 0 : trypnfs = nfss->pnfs_curr_ld->write_pagelist(hdr, how);
2662 : 0 : if (trypnfs != PNFS_NOT_ATTEMPTED)
2663 : 0 : nfs_inc_stats(inode, NFSIOS_PNFS_WRITE);
2664 : : dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs);
2665 : 0 : return trypnfs;
2666 : : }
2667 : :
2668 : : static void
2669 : 0 : pnfs_do_write(struct nfs_pageio_descriptor *desc,
2670 : : struct nfs_pgio_header *hdr, int how)
2671 : : {
2672 : 0 : const struct rpc_call_ops *call_ops = desc->pg_rpc_callops;
2673 : 0 : struct pnfs_layout_segment *lseg = desc->pg_lseg;
2674 : : enum pnfs_try_status trypnfs;
2675 : :
2676 : 0 : trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how);
2677 : 0 : switch (trypnfs) {
2678 : : case PNFS_NOT_ATTEMPTED:
2679 : 0 : pnfs_write_through_mds(desc, hdr);
2680 : : case PNFS_ATTEMPTED:
2681 : : break;
2682 : : case PNFS_TRY_AGAIN:
2683 : : /* cleanup hdr and prepare to redo pnfs */
2684 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
2685 : 0 : struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
2686 : 0 : list_splice_init(&hdr->pages, &mirror->pg_list);
2687 : 0 : mirror->pg_recoalesce = 1;
2688 : : }
2689 : 0 : hdr->mds_ops->rpc_release(hdr);
2690 : : }
2691 : 0 : }
2692 : :
2693 : 0 : static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
2694 : : {
2695 : 0 : pnfs_put_lseg(hdr->lseg);
2696 : 0 : nfs_pgio_header_free(hdr);
2697 : 0 : }
2698 : :
2699 : : int
2700 : 0 : pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
2701 : : {
2702 : : struct nfs_pgio_header *hdr;
2703 : : int ret;
2704 : :
2705 : 0 : hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
2706 : 0 : if (!hdr) {
2707 : 0 : desc->pg_error = -ENOMEM;
2708 : 0 : return desc->pg_error;
2709 : : }
2710 : 0 : nfs_pgheader_init(desc, hdr, pnfs_writehdr_free);
2711 : :
2712 : 0 : hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
2713 : 0 : ret = nfs_generic_pgio(desc, hdr);
2714 : 0 : if (!ret)
2715 : 0 : pnfs_do_write(desc, hdr, desc->pg_ioflags);
2716 : :
2717 : 0 : return ret;
2718 : : }
2719 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
2720 : :
2721 : 0 : int pnfs_read_done_resend_to_mds(struct nfs_pgio_header *hdr)
2722 : : {
2723 : : struct nfs_pageio_descriptor pgio;
2724 : :
2725 : : /* Resend all requests through the MDS */
2726 : 0 : nfs_pageio_init_read(&pgio, hdr->inode, true, hdr->completion_ops);
2727 : 0 : return nfs_pageio_resend(&pgio, hdr);
2728 : : }
2729 : : EXPORT_SYMBOL_GPL(pnfs_read_done_resend_to_mds);
2730 : :
2731 : 0 : static void pnfs_ld_handle_read_error(struct nfs_pgio_header *hdr)
2732 : : {
2733 : : dprintk("pnfs read error = %d\n", hdr->pnfs_error);
2734 : 0 : if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
2735 : : PNFS_LAYOUTRET_ON_ERROR) {
2736 : 0 : pnfs_return_layout(hdr->inode);
2737 : : }
2738 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
2739 : 0 : hdr->task.tk_status = pnfs_read_done_resend_to_mds(hdr);
2740 : 0 : }
2741 : :
2742 : : /*
2743 : : * Called by non rpc-based layout drivers
2744 : : */
2745 : 0 : void pnfs_ld_read_done(struct nfs_pgio_header *hdr)
2746 : : {
2747 : 0 : if (likely(!hdr->pnfs_error))
2748 : 0 : hdr->mds_ops->rpc_call_done(&hdr->task, hdr);
2749 : 0 : trace_nfs4_pnfs_read(hdr, hdr->pnfs_error);
2750 : 0 : if (unlikely(hdr->pnfs_error))
2751 : 0 : pnfs_ld_handle_read_error(hdr);
2752 : 0 : hdr->mds_ops->rpc_release(hdr);
2753 : 0 : }
2754 : : EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
2755 : :
2756 : : static void
2757 : 0 : pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
2758 : : struct nfs_pgio_header *hdr)
2759 : : {
2760 : 0 : struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
2761 : :
2762 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
2763 : 0 : list_splice_tail_init(&hdr->pages, &mirror->pg_list);
2764 : 0 : nfs_pageio_reset_read_mds(desc);
2765 : 0 : mirror->pg_recoalesce = 1;
2766 : : }
2767 : 0 : hdr->completion_ops->completion(hdr);
2768 : 0 : }
2769 : :
2770 : : /*
2771 : : * Call the appropriate parallel I/O subsystem read function.
2772 : : */
2773 : : static enum pnfs_try_status
2774 : 0 : pnfs_try_to_read_data(struct nfs_pgio_header *hdr,
2775 : : const struct rpc_call_ops *call_ops,
2776 : : struct pnfs_layout_segment *lseg)
2777 : : {
2778 : 0 : struct inode *inode = hdr->inode;
2779 : : struct nfs_server *nfss = NFS_SERVER(inode);
2780 : : enum pnfs_try_status trypnfs;
2781 : :
2782 : 0 : hdr->mds_ops = call_ops;
2783 : :
2784 : : dprintk("%s: Reading ino:%lu %u@%llu\n",
2785 : : __func__, inode->i_ino, hdr->args.count, hdr->args.offset);
2786 : :
2787 : 0 : trypnfs = nfss->pnfs_curr_ld->read_pagelist(hdr);
2788 : 0 : if (trypnfs != PNFS_NOT_ATTEMPTED)
2789 : 0 : nfs_inc_stats(inode, NFSIOS_PNFS_READ);
2790 : : dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs);
2791 : 0 : return trypnfs;
2792 : : }
2793 : :
2794 : : /* Resend all requests through pnfs. */
2795 : 0 : void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
2796 : : {
2797 : : struct nfs_pageio_descriptor pgio;
2798 : :
2799 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
2800 : : /* Prevent deadlocks with layoutreturn! */
2801 : 0 : pnfs_put_lseg(hdr->lseg);
2802 : 0 : hdr->lseg = NULL;
2803 : :
2804 : 0 : nfs_pageio_init_read(&pgio, hdr->inode, false,
2805 : : hdr->completion_ops);
2806 : 0 : hdr->task.tk_status = nfs_pageio_resend(&pgio, hdr);
2807 : : }
2808 : 0 : }
2809 : : EXPORT_SYMBOL_GPL(pnfs_read_resend_pnfs);
2810 : :
2811 : : static void
2812 : 0 : pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr)
2813 : : {
2814 : 0 : const struct rpc_call_ops *call_ops = desc->pg_rpc_callops;
2815 : 0 : struct pnfs_layout_segment *lseg = desc->pg_lseg;
2816 : : enum pnfs_try_status trypnfs;
2817 : :
2818 : 0 : trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
2819 : 0 : switch (trypnfs) {
2820 : : case PNFS_NOT_ATTEMPTED:
2821 : 0 : pnfs_read_through_mds(desc, hdr);
2822 : : case PNFS_ATTEMPTED:
2823 : : break;
2824 : : case PNFS_TRY_AGAIN:
2825 : : /* cleanup hdr and prepare to redo pnfs */
2826 : 0 : if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
2827 : 0 : struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
2828 : 0 : list_splice_init(&hdr->pages, &mirror->pg_list);
2829 : 0 : mirror->pg_recoalesce = 1;
2830 : : }
2831 : 0 : hdr->mds_ops->rpc_release(hdr);
2832 : : }
2833 : 0 : }
2834 : :
2835 : 0 : static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
2836 : : {
2837 : 0 : pnfs_put_lseg(hdr->lseg);
2838 : 0 : nfs_pgio_header_free(hdr);
2839 : 0 : }
2840 : :
2841 : : int
2842 : 0 : pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
2843 : : {
2844 : : struct nfs_pgio_header *hdr;
2845 : : int ret;
2846 : :
2847 : 0 : hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
2848 : 0 : if (!hdr) {
2849 : 0 : desc->pg_error = -ENOMEM;
2850 : 0 : return desc->pg_error;
2851 : : }
2852 : 0 : nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
2853 : 0 : hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
2854 : 0 : ret = nfs_generic_pgio(desc, hdr);
2855 : 0 : if (!ret)
2856 : 0 : pnfs_do_read(desc, hdr);
2857 : 0 : return ret;
2858 : : }
2859 : : EXPORT_SYMBOL_GPL(pnfs_generic_pg_readpages);
2860 : :
2861 : 0 : static void pnfs_clear_layoutcommitting(struct inode *inode)
2862 : : {
2863 : 0 : unsigned long *bitlock = &NFS_I(inode)->flags;
2864 : :
2865 : 0 : clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
2866 : 0 : smp_mb__after_atomic();
2867 : 0 : wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
2868 : 0 : }
2869 : :
2870 : : /*
2871 : : * There can be multiple RW segments.
2872 : : */
2873 : 0 : static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
2874 : : {
2875 : : struct pnfs_layout_segment *lseg;
2876 : :
2877 : 0 : list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
2878 : 0 : if (lseg->pls_range.iomode == IOMODE_RW &&
2879 : 0 : test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
2880 : 0 : list_add(&lseg->pls_lc_list, listp);
2881 : : }
2882 : 0 : }
2883 : :
2884 : 0 : static void pnfs_list_write_lseg_done(struct inode *inode, struct list_head *listp)
2885 : : {
2886 : : struct pnfs_layout_segment *lseg, *tmp;
2887 : :
2888 : : /* Matched by references in pnfs_set_layoutcommit */
2889 : 0 : list_for_each_entry_safe(lseg, tmp, listp, pls_lc_list) {
2890 : : list_del_init(&lseg->pls_lc_list);
2891 : 0 : pnfs_put_lseg(lseg);
2892 : : }
2893 : :
2894 : 0 : pnfs_clear_layoutcommitting(inode);
2895 : 0 : }
2896 : :
2897 : 0 : void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
2898 : : {
2899 : 0 : pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode);
2900 : 0 : }
2901 : : EXPORT_SYMBOL_GPL(pnfs_set_lo_fail);
2902 : :
2903 : : void
2904 : 0 : pnfs_set_layoutcommit(struct inode *inode, struct pnfs_layout_segment *lseg,
2905 : : loff_t end_pos)
2906 : : {
2907 : : struct nfs_inode *nfsi = NFS_I(inode);
2908 : : bool mark_as_dirty = false;
2909 : :
2910 : : spin_lock(&inode->i_lock);
2911 : 0 : if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
2912 : 0 : nfsi->layout->plh_lwb = end_pos;
2913 : : mark_as_dirty = true;
2914 : : dprintk("%s: Set layoutcommit for inode %lu ",
2915 : : __func__, inode->i_ino);
2916 : 0 : } else if (end_pos > nfsi->layout->plh_lwb)
2917 : 0 : nfsi->layout->plh_lwb = end_pos;
2918 : 0 : if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) {
2919 : : /* references matched in nfs4_layoutcommit_release */
2920 : : pnfs_get_lseg(lseg);
2921 : : }
2922 : : spin_unlock(&inode->i_lock);
2923 : : dprintk("%s: lseg %p end_pos %llu\n",
2924 : : __func__, lseg, nfsi->layout->plh_lwb);
2925 : :
2926 : : /* if pnfs_layoutcommit_inode() runs between inode locks, the next one
2927 : : * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */
2928 : 0 : if (mark_as_dirty)
2929 : : mark_inode_dirty_sync(inode);
2930 : 0 : }
2931 : : EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit);
2932 : :
2933 : 0 : void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data)
2934 : : {
2935 : 0 : struct nfs_server *nfss = NFS_SERVER(data->args.inode);
2936 : :
2937 : 0 : if (nfss->pnfs_curr_ld->cleanup_layoutcommit)
2938 : 0 : nfss->pnfs_curr_ld->cleanup_layoutcommit(data);
2939 : 0 : pnfs_list_write_lseg_done(data->args.inode, &data->lseg_list);
2940 : 0 : }
2941 : :
2942 : : /*
2943 : : * For the LAYOUT4_NFSV4_1_FILES layout type, NFS_DATA_SYNC WRITEs and
2944 : : * NFS_UNSTABLE WRITEs with a COMMIT to data servers must store enough
2945 : : * data to disk to allow the server to recover the data if it crashes.
2946 : : * LAYOUTCOMMIT is only needed when the NFL4_UFLG_COMMIT_THRU_MDS flag
2947 : : * is off, and a COMMIT is sent to a data server, or
2948 : : * if WRITEs to a data server return NFS_DATA_SYNC.
2949 : : */
2950 : : int
2951 : 0 : pnfs_layoutcommit_inode(struct inode *inode, bool sync)
2952 : : {
2953 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
2954 : : struct nfs4_layoutcommit_data *data;
2955 : : struct nfs_inode *nfsi = NFS_I(inode);
2956 : : loff_t end_pos;
2957 : : int status;
2958 : :
2959 : 0 : if (!pnfs_layoutcommit_outstanding(inode))
2960 : : return 0;
2961 : :
2962 : : dprintk("--> %s inode %lu\n", __func__, inode->i_ino);
2963 : :
2964 : : status = -EAGAIN;
2965 : 0 : if (test_and_set_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags)) {
2966 : 0 : if (!sync)
2967 : : goto out;
2968 : 0 : status = wait_on_bit_lock_action(&nfsi->flags,
2969 : : NFS_INO_LAYOUTCOMMITTING,
2970 : : nfs_wait_bit_killable,
2971 : : TASK_KILLABLE);
2972 : 0 : if (status)
2973 : : goto out;
2974 : : }
2975 : :
2976 : : status = -ENOMEM;
2977 : : /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
2978 : 0 : data = kzalloc(sizeof(*data), GFP_NOFS);
2979 : 0 : if (!data)
2980 : : goto clear_layoutcommitting;
2981 : :
2982 : : status = 0;
2983 : : spin_lock(&inode->i_lock);
2984 : 0 : if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
2985 : : goto out_unlock;
2986 : :
2987 : 0 : INIT_LIST_HEAD(&data->lseg_list);
2988 : 0 : pnfs_list_write_lseg(inode, &data->lseg_list);
2989 : :
2990 : 0 : end_pos = nfsi->layout->plh_lwb;
2991 : :
2992 : : nfs4_stateid_copy(&data->args.stateid, &nfsi->layout->plh_stateid);
2993 : : spin_unlock(&inode->i_lock);
2994 : :
2995 : 0 : data->args.inode = inode;
2996 : 0 : data->cred = get_cred(nfsi->layout->plh_lc_cred);
2997 : 0 : nfs_fattr_init(&data->fattr);
2998 : 0 : data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
2999 : 0 : data->res.fattr = &data->fattr;
3000 : 0 : if (end_pos != 0)
3001 : 0 : data->args.lastbytewritten = end_pos - 1;
3002 : : else
3003 : 0 : data->args.lastbytewritten = U64_MAX;
3004 : 0 : data->res.server = NFS_SERVER(inode);
3005 : :
3006 : 0 : if (ld->prepare_layoutcommit) {
3007 : 0 : status = ld->prepare_layoutcommit(&data->args);
3008 : 0 : if (status) {
3009 : 0 : put_cred(data->cred);
3010 : : spin_lock(&inode->i_lock);
3011 : 0 : set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags);
3012 : 0 : if (end_pos > nfsi->layout->plh_lwb)
3013 : 0 : nfsi->layout->plh_lwb = end_pos;
3014 : : goto out_unlock;
3015 : : }
3016 : : }
3017 : :
3018 : :
3019 : 0 : status = nfs4_proc_layoutcommit(data, sync);
3020 : : out:
3021 : 0 : if (status)
3022 : : mark_inode_dirty_sync(inode);
3023 : : dprintk("<-- %s status %d\n", __func__, status);
3024 : 0 : return status;
3025 : : out_unlock:
3026 : : spin_unlock(&inode->i_lock);
3027 : 0 : kfree(data);
3028 : : clear_layoutcommitting:
3029 : 0 : pnfs_clear_layoutcommitting(inode);
3030 : 0 : goto out;
3031 : : }
3032 : : EXPORT_SYMBOL_GPL(pnfs_layoutcommit_inode);
3033 : :
3034 : : int
3035 : 0 : pnfs_generic_sync(struct inode *inode, bool datasync)
3036 : : {
3037 : 0 : return pnfs_layoutcommit_inode(inode, true);
3038 : : }
3039 : : EXPORT_SYMBOL_GPL(pnfs_generic_sync);
3040 : :
3041 : 0 : struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
3042 : : {
3043 : : struct nfs4_threshold *thp;
3044 : :
3045 : 0 : thp = kzalloc(sizeof(*thp), GFP_NOFS);
3046 : 0 : if (!thp) {
3047 : : dprintk("%s mdsthreshold allocation failed\n", __func__);
3048 : : return NULL;
3049 : : }
3050 : 0 : return thp;
3051 : : }
3052 : :
3053 : : #if IS_ENABLED(CONFIG_NFS_V4_2)
3054 : : int
3055 : 0 : pnfs_report_layoutstat(struct inode *inode, gfp_t gfp_flags)
3056 : : {
3057 : 0 : struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
3058 : : struct nfs_server *server = NFS_SERVER(inode);
3059 : : struct nfs_inode *nfsi = NFS_I(inode);
3060 : : struct nfs42_layoutstat_data *data;
3061 : : struct pnfs_layout_hdr *hdr;
3062 : : int status = 0;
3063 : :
3064 : 0 : if (!pnfs_enabled_sb(server) || !ld->prepare_layoutstats)
3065 : : goto out;
3066 : :
3067 : 0 : if (!nfs_server_capable(inode, NFS_CAP_LAYOUTSTATS))
3068 : : goto out;
3069 : :
3070 : 0 : if (test_and_set_bit(NFS_INO_LAYOUTSTATS, &nfsi->flags))
3071 : : goto out;
3072 : :
3073 : : spin_lock(&inode->i_lock);
3074 : 0 : if (!NFS_I(inode)->layout) {
3075 : : spin_unlock(&inode->i_lock);
3076 : : goto out_clear_layoutstats;
3077 : : }
3078 : : hdr = NFS_I(inode)->layout;
3079 : : pnfs_get_layout_hdr(hdr);
3080 : : spin_unlock(&inode->i_lock);
3081 : :
3082 : 0 : data = kzalloc(sizeof(*data), gfp_flags);
3083 : 0 : if (!data) {
3084 : : status = -ENOMEM;
3085 : : goto out_put;
3086 : : }
3087 : :
3088 : 0 : data->args.fh = NFS_FH(inode);
3089 : 0 : data->args.inode = inode;
3090 : 0 : status = ld->prepare_layoutstats(&data->args);
3091 : 0 : if (status)
3092 : : goto out_free;
3093 : :
3094 : 0 : status = nfs42_proc_layoutstats_generic(NFS_SERVER(inode), data);
3095 : :
3096 : : out:
3097 : : dprintk("%s returns %d\n", __func__, status);
3098 : 0 : return status;
3099 : :
3100 : : out_free:
3101 : 0 : kfree(data);
3102 : : out_put:
3103 : 0 : pnfs_put_layout_hdr(hdr);
3104 : : out_clear_layoutstats:
3105 : 0 : smp_mb__before_atomic();
3106 : 0 : clear_bit(NFS_INO_LAYOUTSTATS, &nfsi->flags);
3107 : 0 : smp_mb__after_atomic();
3108 : 0 : goto out;
3109 : : }
3110 : : EXPORT_SYMBOL_GPL(pnfs_report_layoutstat);
3111 : : #endif
3112 : :
3113 : : unsigned int layoutstats_timer;
3114 : : module_param(layoutstats_timer, uint, 0644);
3115 : : EXPORT_SYMBOL_GPL(layoutstats_timer);
|