xref: /linux/fs/nfs/pnfs_nfs.c (revision 73e3f0710014fe6d4ed98cfc02292f6121db7558)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Common NFS I/O  operations for the pnfs file based
4  * layout drivers.
5  *
6  * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
7  *
8  * Tom Haynes <loghyr@primarydata.com>
9  */
10 
11 #include <linux/nfs_fs.h>
12 #include <linux/nfs_page.h>
13 #include <linux/sunrpc/addr.h>
14 #include <linux/module.h>
15 
16 #include "nfs4session.h"
17 #include "internal.h"
18 #include "pnfs.h"
19 #include "netns.h"
20 #include "nfs4trace.h"
21 
22 #define NFSDBG_FACILITY		NFSDBG_PNFS
23 
pnfs_generic_rw_release(void * data)24 void pnfs_generic_rw_release(void *data)
25 {
26 	struct nfs_pgio_header *hdr = data;
27 
28 	nfs_put_client(hdr->ds_clp);
29 	hdr->mds_ops->rpc_release(data);
30 }
31 EXPORT_SYMBOL_GPL(pnfs_generic_rw_release);
32 
33 /* Fake up some data that will cause nfs_commit_release to retry the writes. */
pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data * data)34 void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data)
35 {
36 	struct nfs_writeverf *verf = data->res.verf;
37 
38 	data->task.tk_status = 0;
39 	memset(&verf->verifier, 0, sizeof(verf->verifier));
40 	verf->committed = NFS_UNSTABLE;
41 }
42 EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes);
43 
pnfs_generic_write_commit_done(struct rpc_task * task,void * data)44 void pnfs_generic_write_commit_done(struct rpc_task *task, void *data)
45 {
46 	struct nfs_commit_data *wdata = data;
47 
48 	/* Note this may cause RPC to be resent */
49 	wdata->mds_ops->rpc_call_done(task, data);
50 }
51 EXPORT_SYMBOL_GPL(pnfs_generic_write_commit_done);
52 
pnfs_generic_commit_release(void * calldata)53 void pnfs_generic_commit_release(void *calldata)
54 {
55 	struct nfs_commit_data *data = calldata;
56 
57 	data->completion_ops->completion(data);
58 	pnfs_put_lseg(data->lseg);
59 	nfs_put_client(data->ds_clp);
60 	nfs_commitdata_release(data);
61 }
62 EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
63 
64 static struct pnfs_layout_segment *
pnfs_free_bucket_lseg(struct pnfs_commit_bucket * bucket)65 pnfs_free_bucket_lseg(struct pnfs_commit_bucket *bucket)
66 {
67 	if (list_empty(&bucket->committing) && list_empty(&bucket->written)) {
68 		struct pnfs_layout_segment *freeme = bucket->lseg;
69 		bucket->lseg = NULL;
70 		return freeme;
71 	}
72 	return NULL;
73 }
74 
75 /* The generic layer is about to remove the req from the commit list.
76  * If this will make the bucket empty, it will need to put the lseg reference.
77  * Note this must be called holding nfsi->commit_mutex
78  */
79 void
pnfs_generic_clear_request_commit(struct nfs_page * req,struct nfs_commit_info * cinfo)80 pnfs_generic_clear_request_commit(struct nfs_page *req,
81 				  struct nfs_commit_info *cinfo)
82 {
83 	struct pnfs_commit_bucket *bucket = NULL;
84 
85 	if (!test_and_clear_bit(PG_COMMIT_TO_DS, &req->wb_flags))
86 		goto out;
87 	cinfo->ds->nwritten--;
88 	if (list_is_singular(&req->wb_list))
89 		bucket = list_first_entry(&req->wb_list,
90 					  struct pnfs_commit_bucket, written);
91 out:
92 	nfs_request_remove_commit_list(req, cinfo);
93 	if (bucket)
94 		pnfs_put_lseg(pnfs_free_bucket_lseg(bucket));
95 }
96 EXPORT_SYMBOL_GPL(pnfs_generic_clear_request_commit);
97 
98 struct pnfs_commit_array *
pnfs_alloc_commit_array(size_t n,gfp_t gfp_flags)99 pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags)
100 {
101 	struct pnfs_commit_array *p;
102 	struct pnfs_commit_bucket *b;
103 
104 	p = kmalloc_flex(*p, buckets, n, gfp_flags);
105 	if (!p)
106 		return NULL;
107 	p->nbuckets = n;
108 	INIT_LIST_HEAD(&p->cinfo_list);
109 	INIT_LIST_HEAD(&p->lseg_list);
110 	p->lseg = NULL;
111 	for (b = &p->buckets[0]; n != 0; b++, n--) {
112 		INIT_LIST_HEAD(&b->written);
113 		INIT_LIST_HEAD(&b->committing);
114 		b->lseg = NULL;
115 		b->direct_verf.committed = NFS_INVALID_STABLE_HOW;
116 	}
117 	return p;
118 }
119 EXPORT_SYMBOL_GPL(pnfs_alloc_commit_array);
120 
121 void
pnfs_free_commit_array(struct pnfs_commit_array * p)122 pnfs_free_commit_array(struct pnfs_commit_array *p)
123 {
124 	kfree_rcu(p, rcu);
125 }
126 EXPORT_SYMBOL_GPL(pnfs_free_commit_array);
127 
128 static struct pnfs_commit_array *
pnfs_find_commit_array_by_lseg(struct pnfs_ds_commit_info * fl_cinfo,struct pnfs_layout_segment * lseg)129 pnfs_find_commit_array_by_lseg(struct pnfs_ds_commit_info *fl_cinfo,
130 		struct pnfs_layout_segment *lseg)
131 {
132 	struct pnfs_commit_array *array;
133 
134 	list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
135 		if (array->lseg == lseg)
136 			return array;
137 	}
138 	return NULL;
139 }
140 
141 struct pnfs_commit_array *
pnfs_add_commit_array(struct pnfs_ds_commit_info * fl_cinfo,struct pnfs_commit_array * new,struct pnfs_layout_segment * lseg)142 pnfs_add_commit_array(struct pnfs_ds_commit_info *fl_cinfo,
143 		struct pnfs_commit_array *new,
144 		struct pnfs_layout_segment *lseg)
145 {
146 	struct pnfs_commit_array *array;
147 
148 	array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
149 	if (array)
150 		return array;
151 	new->lseg = lseg;
152 	refcount_set(&new->refcount, 1);
153 	list_add_rcu(&new->cinfo_list, &fl_cinfo->commits);
154 	list_add(&new->lseg_list, &lseg->pls_commits);
155 	return new;
156 }
157 EXPORT_SYMBOL_GPL(pnfs_add_commit_array);
158 
159 static struct pnfs_commit_array *
pnfs_lookup_commit_array(struct pnfs_ds_commit_info * fl_cinfo,struct pnfs_layout_segment * lseg)160 pnfs_lookup_commit_array(struct pnfs_ds_commit_info *fl_cinfo,
161 		struct pnfs_layout_segment *lseg)
162 {
163 	struct pnfs_commit_array *array;
164 
165 	rcu_read_lock();
166 	array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
167 	if (!array) {
168 		rcu_read_unlock();
169 		fl_cinfo->ops->setup_ds_info(fl_cinfo, lseg);
170 		rcu_read_lock();
171 		array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
172 	}
173 	rcu_read_unlock();
174 	return array;
175 }
176 
177 static void
pnfs_release_commit_array_locked(struct pnfs_commit_array * array)178 pnfs_release_commit_array_locked(struct pnfs_commit_array *array)
179 {
180 	list_del_rcu(&array->cinfo_list);
181 	list_del(&array->lseg_list);
182 	pnfs_free_commit_array(array);
183 }
184 
185 static void
pnfs_put_commit_array_locked(struct pnfs_commit_array * array)186 pnfs_put_commit_array_locked(struct pnfs_commit_array *array)
187 {
188 	if (refcount_dec_and_test(&array->refcount))
189 		pnfs_release_commit_array_locked(array);
190 }
191 
192 static void
pnfs_put_commit_array(struct pnfs_commit_array * array,struct inode * inode)193 pnfs_put_commit_array(struct pnfs_commit_array *array, struct inode *inode)
194 {
195 	if (refcount_dec_and_lock(&array->refcount, &inode->i_lock)) {
196 		pnfs_release_commit_array_locked(array);
197 		spin_unlock(&inode->i_lock);
198 	}
199 }
200 
201 static struct pnfs_commit_array *
pnfs_get_commit_array(struct pnfs_commit_array * array)202 pnfs_get_commit_array(struct pnfs_commit_array *array)
203 {
204 	if (refcount_inc_not_zero(&array->refcount))
205 		return array;
206 	return NULL;
207 }
208 
209 static void
pnfs_remove_and_free_commit_array(struct pnfs_commit_array * array)210 pnfs_remove_and_free_commit_array(struct pnfs_commit_array *array)
211 {
212 	array->lseg = NULL;
213 	list_del_init(&array->lseg_list);
214 	pnfs_put_commit_array_locked(array);
215 }
216 
217 void
pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info * fl_cinfo,struct pnfs_layout_segment * lseg)218 pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info *fl_cinfo,
219 		struct pnfs_layout_segment *lseg)
220 {
221 	struct pnfs_commit_array *array, *tmp;
222 
223 	list_for_each_entry_safe(array, tmp, &lseg->pls_commits, lseg_list)
224 		pnfs_remove_and_free_commit_array(array);
225 }
226 EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_release_lseg);
227 
228 void
pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info * fl_cinfo)229 pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info *fl_cinfo)
230 {
231 	struct pnfs_commit_array *array, *tmp;
232 
233 	list_for_each_entry_safe(array, tmp, &fl_cinfo->commits, cinfo_list)
234 		pnfs_remove_and_free_commit_array(array);
235 }
236 EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_destroy);
237 
238 /*
239  * Locks the nfs_page requests for commit and moves them to
240  * @bucket->committing.
241  */
242 static int
pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket * bucket,struct nfs_commit_info * cinfo,int max)243 pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
244 				struct nfs_commit_info *cinfo,
245 				int max)
246 {
247 	struct list_head *src = &bucket->written;
248 	struct list_head *dst = &bucket->committing;
249 	int ret;
250 
251 	lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex);
252 	ret = nfs_scan_commit_list(src, dst, cinfo, max);
253 	if (ret) {
254 		cinfo->ds->nwritten -= ret;
255 		cinfo->ds->ncommitting += ret;
256 	}
257 	return ret;
258 }
259 
pnfs_bucket_scan_array(struct nfs_commit_info * cinfo,struct pnfs_commit_bucket * buckets,unsigned int nbuckets,int max)260 static int pnfs_bucket_scan_array(struct nfs_commit_info *cinfo,
261 				  struct pnfs_commit_bucket *buckets,
262 				  unsigned int nbuckets,
263 				  int max)
264 {
265 	unsigned int i;
266 	int rv = 0, cnt;
267 
268 	for (i = 0; i < nbuckets && max != 0; i++) {
269 		cnt = pnfs_bucket_scan_ds_commit_list(&buckets[i], cinfo, max);
270 		rv += cnt;
271 		max -= cnt;
272 	}
273 	return rv;
274 }
275 
276 /* Move reqs from written to committing lists, returning count
277  * of number moved.
278  */
pnfs_generic_scan_commit_lists(struct nfs_commit_info * cinfo,int max)279 int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max)
280 {
281 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
282 	struct pnfs_commit_array *array;
283 	int rv = 0, cnt;
284 
285 	rcu_read_lock();
286 	list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
287 		if (!array->lseg || !pnfs_get_commit_array(array))
288 			continue;
289 		rcu_read_unlock();
290 		cnt = pnfs_bucket_scan_array(cinfo, array->buckets,
291 				array->nbuckets, max);
292 		rcu_read_lock();
293 		pnfs_put_commit_array(array, cinfo->inode);
294 		rv += cnt;
295 		max -= cnt;
296 		if (!max)
297 			break;
298 	}
299 	rcu_read_unlock();
300 	return rv;
301 }
302 EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
303 
304 static unsigned int
pnfs_bucket_recover_commit_reqs(struct list_head * dst,struct pnfs_commit_bucket * buckets,unsigned int nbuckets,struct nfs_commit_info * cinfo)305 pnfs_bucket_recover_commit_reqs(struct list_head *dst,
306 			        struct pnfs_commit_bucket *buckets,
307 				unsigned int nbuckets,
308 				struct nfs_commit_info *cinfo)
309 {
310 	struct pnfs_commit_bucket *b;
311 	struct pnfs_layout_segment *freeme;
312 	unsigned int nwritten, ret = 0;
313 	unsigned int i;
314 
315 restart:
316 	for (i = 0, b = buckets; i < nbuckets; i++, b++) {
317 		nwritten = nfs_scan_commit_list(&b->written, dst, cinfo, 0);
318 		if (!nwritten)
319 			continue;
320 		ret += nwritten;
321 		freeme = pnfs_free_bucket_lseg(b);
322 		if (freeme) {
323 			pnfs_put_lseg(freeme);
324 			goto restart;
325 		}
326 	}
327 	return ret;
328 }
329 
330 /* Pull everything off the committing lists and dump into @dst.  */
pnfs_generic_recover_commit_reqs(struct list_head * dst,struct nfs_commit_info * cinfo)331 void pnfs_generic_recover_commit_reqs(struct list_head *dst,
332 				      struct nfs_commit_info *cinfo)
333 {
334 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
335 	struct pnfs_commit_array *array;
336 	unsigned int nwritten;
337 
338 	lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex);
339 	rcu_read_lock();
340 	list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
341 		if (!array->lseg || !pnfs_get_commit_array(array))
342 			continue;
343 		rcu_read_unlock();
344 		nwritten = pnfs_bucket_recover_commit_reqs(dst,
345 							   array->buckets,
346 							   array->nbuckets,
347 							   cinfo);
348 		rcu_read_lock();
349 		pnfs_put_commit_array(array, cinfo->inode);
350 		fl_cinfo->nwritten -= nwritten;
351 	}
352 	rcu_read_unlock();
353 }
354 EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
355 
356 static struct pnfs_layout_segment *
pnfs_bucket_get_committing(struct list_head * head,struct pnfs_commit_bucket * bucket,struct nfs_commit_info * cinfo)357 pnfs_bucket_get_committing(struct list_head *head,
358 			   struct pnfs_commit_bucket *bucket,
359 			   struct nfs_commit_info *cinfo)
360 {
361 	struct pnfs_layout_segment *lseg;
362 	struct list_head *pos;
363 
364 	list_for_each(pos, &bucket->committing)
365 		cinfo->ds->ncommitting--;
366 	list_splice_init(&bucket->committing, head);
367 	lseg = pnfs_free_bucket_lseg(bucket);
368 	if (!lseg)
369 		lseg = pnfs_get_lseg(bucket->lseg);
370 	return lseg;
371 }
372 
373 static struct nfs_commit_data *
pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket * bucket,struct nfs_commit_info * cinfo)374 pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
375 			     struct nfs_commit_info *cinfo)
376 {
377 	struct nfs_commit_data *data = nfs_commitdata_alloc();
378 
379 	if (!data)
380 		return NULL;
381 	data->lseg = pnfs_bucket_get_committing(&data->pages, bucket, cinfo);
382 	return data;
383 }
384 
pnfs_generic_retry_commit(struct pnfs_commit_bucket * buckets,unsigned int nbuckets,struct nfs_commit_info * cinfo,unsigned int idx)385 static void pnfs_generic_retry_commit(struct pnfs_commit_bucket *buckets,
386 				      unsigned int nbuckets,
387 				      struct nfs_commit_info *cinfo,
388 				      unsigned int idx)
389 {
390 	struct pnfs_commit_bucket *bucket;
391 	struct pnfs_layout_segment *freeme;
392 	LIST_HEAD(pages);
393 
394 	for (bucket = buckets; idx < nbuckets; bucket++, idx++) {
395 		if (list_empty(&bucket->committing))
396 			continue;
397 		mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
398 		freeme = pnfs_bucket_get_committing(&pages, bucket, cinfo);
399 		mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
400 		nfs_retry_commit(&pages, freeme, cinfo, idx);
401 		pnfs_put_lseg(freeme);
402 	}
403 }
404 
405 static unsigned int
pnfs_bucket_alloc_ds_commits(struct list_head * list,struct pnfs_commit_bucket * buckets,unsigned int nbuckets,struct nfs_commit_info * cinfo)406 pnfs_bucket_alloc_ds_commits(struct list_head *list,
407 			     struct pnfs_commit_bucket *buckets,
408 			     unsigned int nbuckets,
409 			     struct nfs_commit_info *cinfo)
410 {
411 	struct pnfs_commit_bucket *bucket;
412 	struct nfs_commit_data *data;
413 	unsigned int i;
414 	unsigned int nreq = 0;
415 
416 	for (i = 0, bucket = buckets; i < nbuckets; i++, bucket++) {
417 		if (list_empty(&bucket->committing))
418 			continue;
419 		mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
420 		if (!list_empty(&bucket->committing)) {
421 			data = pnfs_bucket_fetch_commitdata(bucket, cinfo);
422 			if (!data)
423 				goto out_error;
424 			data->ds_commit_index = i;
425 			list_add_tail(&data->list, list);
426 			nreq++;
427 		}
428 		mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
429 	}
430 	return nreq;
431 out_error:
432 	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
433 	/* Clean up on error */
434 	pnfs_generic_retry_commit(buckets, nbuckets, cinfo, i);
435 	return nreq;
436 }
437 
438 static unsigned int
pnfs_alloc_ds_commits_list(struct list_head * list,struct pnfs_ds_commit_info * fl_cinfo,struct nfs_commit_info * cinfo)439 pnfs_alloc_ds_commits_list(struct list_head *list,
440 			   struct pnfs_ds_commit_info *fl_cinfo,
441 			   struct nfs_commit_info *cinfo)
442 {
443 	struct pnfs_commit_array *array;
444 	unsigned int ret = 0;
445 
446 	rcu_read_lock();
447 	list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
448 		if (!array->lseg || !pnfs_get_commit_array(array))
449 			continue;
450 		rcu_read_unlock();
451 		ret += pnfs_bucket_alloc_ds_commits(list, array->buckets,
452 				array->nbuckets, cinfo);
453 		rcu_read_lock();
454 		pnfs_put_commit_array(array, cinfo->inode);
455 	}
456 	rcu_read_unlock();
457 	return ret;
458 }
459 
460 /* This follows nfs_commit_list pretty closely */
461 int
pnfs_generic_commit_pagelist(struct inode * inode,struct list_head * mds_pages,int how,struct nfs_commit_info * cinfo,int (* initiate_commit)(struct nfs_commit_data * data,int how))462 pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
463 			     int how, struct nfs_commit_info *cinfo,
464 			     int (*initiate_commit)(struct nfs_commit_data *data,
465 						    int how))
466 {
467 	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
468 	struct nfs_commit_data *data, *tmp;
469 	LIST_HEAD(list);
470 	unsigned int nreq = 0;
471 
472 	if (!list_empty(mds_pages)) {
473 		data = nfs_commitdata_alloc();
474 		if (!data) {
475 			nfs_retry_commit(mds_pages, NULL, cinfo, -1);
476 			return -ENOMEM;
477 		}
478 		data->ds_commit_index = -1;
479 		list_splice_init(mds_pages, &data->pages);
480 		list_add_tail(&data->list, &list);
481 		nreq++;
482 	}
483 
484 	nreq += pnfs_alloc_ds_commits_list(&list, fl_cinfo, cinfo);
485 	if (nreq == 0)
486 		goto out;
487 
488 	list_for_each_entry_safe(data, tmp, &list, list) {
489 		list_del(&data->list);
490 		if (data->ds_commit_index < 0) {
491 			nfs_init_commit(data, NULL, NULL, cinfo);
492 			nfs_initiate_commit(NFS_CLIENT(inode), data,
493 					    NFS_PROTO(data->inode),
494 					    data->mds_ops, how,
495 					    RPC_TASK_CRED_NOREF, NULL);
496 		} else {
497 			nfs_init_commit(data, NULL, data->lseg, cinfo);
498 			initiate_commit(data, how);
499 		}
500 	}
501 out:
502 	return PNFS_ATTEMPTED;
503 }
504 EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);
505 
506 /*
507  * Data server cache
508  *
509  * Data servers can be mapped to different device ids, but should
510  * never be shared between net namespaces.
511  *
512  * nfs4_pnfs_ds reference counting:
513  *   - set to 1 on allocation
514  *   - incremented when a device id maps a data server already in the cache.
515  *   - decremented when deviceid is removed from the cache.
516  */
517 
518 /* Debug routines */
519 static void
print_ds(struct nfs4_pnfs_ds * ds)520 print_ds(struct nfs4_pnfs_ds *ds)
521 {
522 	if (ds == NULL) {
523 		printk(KERN_WARNING "%s NULL device\n", __func__);
524 		return;
525 	}
526 	printk(KERN_WARNING "        ds %s\n"
527 		"        ref count %d\n"
528 		"        client %p\n"
529 		"        cl_exchange_flags %x\n",
530 		ds->ds_remotestr,
531 		refcount_read(&ds->ds_count), ds->ds_clp,
532 		ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
533 }
534 
535 static bool
same_sockaddr(struct sockaddr * addr1,struct sockaddr * addr2)536 same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
537 {
538 	struct sockaddr_in *a, *b;
539 	struct sockaddr_in6 *a6, *b6;
540 
541 	if (addr1->sa_family != addr2->sa_family)
542 		return false;
543 
544 	switch (addr1->sa_family) {
545 	case AF_INET:
546 		a = (struct sockaddr_in *)addr1;
547 		b = (struct sockaddr_in *)addr2;
548 
549 		if (a->sin_addr.s_addr == b->sin_addr.s_addr &&
550 		    a->sin_port == b->sin_port)
551 			return true;
552 		break;
553 
554 	case AF_INET6:
555 		a6 = (struct sockaddr_in6 *)addr1;
556 		b6 = (struct sockaddr_in6 *)addr2;
557 
558 		/* LINKLOCAL addresses must have matching scope_id */
559 		if (ipv6_addr_src_scope(&a6->sin6_addr) ==
560 		    IPV6_ADDR_SCOPE_LINKLOCAL &&
561 		    a6->sin6_scope_id != b6->sin6_scope_id)
562 			return false;
563 
564 		if (ipv6_addr_equal(&a6->sin6_addr, &b6->sin6_addr) &&
565 		    a6->sin6_port == b6->sin6_port)
566 			return true;
567 		break;
568 
569 	default:
570 		dprintk("%s: unhandled address family: %u\n",
571 			__func__, addr1->sa_family);
572 		return false;
573 	}
574 
575 	return false;
576 }
577 
578 /*
579  * Checks if 'dsaddrs1' contains a subset of 'dsaddrs2'. If it does,
580  * declare a match.
581  */
582 static bool
_same_data_server_addrs_locked(const struct list_head * dsaddrs1,const struct list_head * dsaddrs2)583 _same_data_server_addrs_locked(const struct list_head *dsaddrs1,
584 			       const struct list_head *dsaddrs2)
585 {
586 	struct nfs4_pnfs_ds_addr *da1, *da2;
587 	struct sockaddr *sa1, *sa2;
588 	bool match = false;
589 
590 	list_for_each_entry(da1, dsaddrs1, da_node) {
591 		sa1 = (struct sockaddr *)&da1->da_addr;
592 		match = false;
593 		list_for_each_entry(da2, dsaddrs2, da_node) {
594 			sa2 = (struct sockaddr *)&da2->da_addr;
595 			match = same_sockaddr(sa1, sa2);
596 			if (match)
597 				break;
598 		}
599 		if (!match)
600 			break;
601 	}
602 	return match;
603 }
604 
605 /*
606  * Lookup DS by addresses and NFS version.  nfs4_ds_cache_lock is held
607  */
608 static struct nfs4_pnfs_ds *
_data_server_lookup_locked(const struct nfs_net * nn,const struct list_head * dsaddrs,u32 version)609 _data_server_lookup_locked(const struct nfs_net *nn,
610 			   const struct list_head *dsaddrs, u32 version)
611 {
612 	struct nfs4_pnfs_ds *ds;
613 
614 	list_for_each_entry(ds, &nn->nfs4_data_server_cache, ds_node)
615 		if (ds->ds_version == version &&
616 		    _same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs))
617 			return ds;
618 	return NULL;
619 }
620 
nfs4_pnfs_ds_addr_alloc(gfp_t gfp_flags)621 static struct nfs4_pnfs_ds_addr *nfs4_pnfs_ds_addr_alloc(gfp_t gfp_flags)
622 {
623 	struct nfs4_pnfs_ds_addr *da = kzalloc_obj(*da, gfp_flags);
624 	if (da)
625 		INIT_LIST_HEAD(&da->da_node);
626 	return da;
627 }
628 
nfs4_pnfs_ds_addr_free(struct nfs4_pnfs_ds_addr * da)629 static void nfs4_pnfs_ds_addr_free(struct nfs4_pnfs_ds_addr *da)
630 {
631 	kfree(da->da_remotestr);
632 	kfree(da->da_netid);
633 	kfree(da);
634 }
635 
destroy_ds(struct nfs4_pnfs_ds * ds)636 static void destroy_ds(struct nfs4_pnfs_ds *ds)
637 {
638 	struct nfs4_pnfs_ds_addr *da;
639 
640 	dprintk("--> %s\n", __func__);
641 	ifdebug(FACILITY)
642 		print_ds(ds);
643 
644 	nfs_put_client(ds->ds_clp);
645 
646 	while (!list_empty(&ds->ds_addrs)) {
647 		da = list_first_entry(&ds->ds_addrs,
648 				      struct nfs4_pnfs_ds_addr,
649 				      da_node);
650 		list_del_init(&da->da_node);
651 		nfs4_pnfs_ds_addr_free(da);
652 	}
653 
654 	kfree(ds->ds_remotestr);
655 	kfree(ds);
656 }
657 
nfs4_pnfs_ds_put(struct nfs4_pnfs_ds * ds)658 void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds)
659 {
660 	struct nfs_net *nn = net_generic(ds->ds_net, nfs_net_id);
661 
662 	if (refcount_dec_and_lock(&ds->ds_count, &nn->nfs4_data_server_lock)) {
663 		list_del_init(&ds->ds_node);
664 		spin_unlock(&nn->nfs4_data_server_lock);
665 		destroy_ds(ds);
666 	}
667 }
668 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_put);
669 
670 /*
671  * Create a string with a human readable address and port to avoid
672  * complicated setup around many dprinks.
673  */
674 static char *
nfs4_pnfs_remotestr(struct list_head * dsaddrs,gfp_t gfp_flags)675 nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)
676 {
677 	struct nfs4_pnfs_ds_addr *da;
678 	char *remotestr;
679 	size_t len;
680 	char *p;
681 
682 	len = 3;        /* '{', '}' and eol */
683 	list_for_each_entry(da, dsaddrs, da_node) {
684 		len += strlen(da->da_remotestr) + 1;    /* string plus comma */
685 	}
686 
687 	remotestr = kzalloc(len, gfp_flags);
688 	if (!remotestr)
689 		return NULL;
690 
691 	p = remotestr;
692 	*(p++) = '{';
693 	len--;
694 	list_for_each_entry(da, dsaddrs, da_node) {
695 		size_t ll = strlen(da->da_remotestr);
696 
697 		if (ll > len)
698 			goto out_err;
699 
700 		memcpy(p, da->da_remotestr, ll);
701 		p += ll;
702 		len -= ll;
703 
704 		if (len < 1)
705 			goto out_err;
706 		(*p++) = ',';
707 		len--;
708 	}
709 	if (len < 2)
710 		goto out_err;
711 	*(p++) = '}';
712 	*p = '\0';
713 	return remotestr;
714 out_err:
715 	kfree(remotestr);
716 	return NULL;
717 }
718 
719 /*
720  * Given a list of multipath struct nfs4_pnfs_ds_addr, add it to ds cache if
721  * uncached and return cached struct nfs4_pnfs_ds.
722  */
723 struct nfs4_pnfs_ds *
nfs4_pnfs_ds_add(const struct net * net,struct list_head * dsaddrs,u32 version,gfp_t gfp_flags)724 nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, u32 version,
725 		 gfp_t gfp_flags)
726 {
727 	struct nfs_net *nn = net_generic(net, nfs_net_id);
728 	struct nfs4_pnfs_ds *tmp_ds, *ds = NULL;
729 	char *remotestr;
730 
731 	if (list_empty(dsaddrs)) {
732 		dprintk("%s: no addresses defined\n", __func__);
733 		goto out;
734 	}
735 
736 	ds = kzalloc_obj(*ds, gfp_flags);
737 	if (!ds)
738 		goto out;
739 
740 	/* this is only used for debugging, so it's ok if its NULL */
741 	remotestr = nfs4_pnfs_remotestr(dsaddrs, gfp_flags);
742 
743 	spin_lock(&nn->nfs4_data_server_lock);
744 	tmp_ds = _data_server_lookup_locked(nn, dsaddrs, version);
745 	if (tmp_ds == NULL) {
746 		INIT_LIST_HEAD(&ds->ds_addrs);
747 		list_splice_init(dsaddrs, &ds->ds_addrs);
748 		ds->ds_remotestr = remotestr;
749 		refcount_set(&ds->ds_count, 1);
750 		INIT_LIST_HEAD(&ds->ds_node);
751 		ds->ds_net = net;
752 		ds->ds_clp = NULL;
753 		ds->ds_version = version;
754 		list_add(&ds->ds_node, &nn->nfs4_data_server_cache);
755 		dprintk("%s add new data server %s\n", __func__,
756 			ds->ds_remotestr);
757 	} else {
758 		kfree(remotestr);
759 		kfree(ds);
760 		refcount_inc(&tmp_ds->ds_count);
761 		dprintk("%s data server %s found, inc'ed ds_count to %d\n",
762 			__func__, tmp_ds->ds_remotestr,
763 			refcount_read(&tmp_ds->ds_count));
764 		ds = tmp_ds;
765 	}
766 	spin_unlock(&nn->nfs4_data_server_lock);
767 out:
768 	return ds;
769 }
770 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_add);
771 
nfs4_wait_ds_connect(struct nfs4_pnfs_ds * ds)772 static int nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds)
773 {
774 	might_sleep();
775 	return wait_on_bit(&ds->ds_state, NFS4DS_CONNECTING, TASK_KILLABLE);
776 }
777 
nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds * ds)778 static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
779 {
780 	smp_mb__before_atomic();
781 	clear_and_wake_up_bit(NFS4DS_CONNECTING, &ds->ds_state);
782 }
783 
784 static struct nfs_client *(*get_v3_ds_connect)(
785 			struct nfs_server *mds_srv,
786 			const struct sockaddr_storage *ds_addr,
787 			int ds_addrlen,
788 			int ds_proto,
789 			unsigned int ds_timeo,
790 			unsigned int ds_retrans);
791 
load_v3_ds_connect(void)792 static bool load_v3_ds_connect(void)
793 {
794 	if (!get_v3_ds_connect) {
795 		get_v3_ds_connect = symbol_request(nfs3_set_ds_client);
796 		WARN_ON_ONCE(!get_v3_ds_connect);
797 	}
798 
799 	return(get_v3_ds_connect != NULL);
800 }
801 
nfs4_pnfs_v3_ds_connect_unload(void)802 void nfs4_pnfs_v3_ds_connect_unload(void)
803 {
804 	if (get_v3_ds_connect) {
805 		symbol_put(nfs3_set_ds_client);
806 		get_v3_ds_connect = NULL;
807 	}
808 }
809 
_nfs4_pnfs_v3_ds_connect(struct nfs_server * mds_srv,struct nfs4_pnfs_ds * ds,unsigned int timeo,unsigned int retrans)810 static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
811 				 struct nfs4_pnfs_ds *ds,
812 				 unsigned int timeo,
813 				 unsigned int retrans)
814 {
815 	struct nfs_client *clp = ERR_PTR(-EIO);
816 	struct nfs_client *mds_clp = mds_srv->nfs_client;
817 	enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy;
818 	struct nfs4_pnfs_ds_addr *da;
819 	unsigned long connect_timeout = timeo * (retrans + 1) * HZ / 10;
820 	int ds_proto;
821 	int status = 0;
822 
823 	dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
824 
825 	if (!load_v3_ds_connect())
826 		return -EPROTONOSUPPORT;
827 
828 	list_for_each_entry(da, &ds->ds_addrs, da_node) {
829 		dprintk("%s: DS %s: trying address %s\n",
830 			__func__, ds->ds_remotestr, da->da_remotestr);
831 
832 		if (!IS_ERR(clp)) {
833 			struct xprt_create xprt_args = {
834 				.ident = da->da_transport,
835 				.net = clp->cl_net,
836 				.dstaddr = (struct sockaddr *)&da->da_addr,
837 				.addrlen = da->da_addrlen,
838 				.servername = clp->cl_hostname,
839 				.connect_timeout = connect_timeout,
840 				.reconnect_timeout = connect_timeout,
841 				.xprtsec = clp->cl_xprtsec,
842 			};
843 
844 			if (xprt_args.ident == XPRT_TRANSPORT_TCP &&
845 			    clp->cl_proto == XPRT_TRANSPORT_TCP_TLS)
846 				xprt_args.ident = XPRT_TRANSPORT_TCP_TLS;
847 
848 			if (xprt_args.ident != clp->cl_proto)
849 				continue;
850 			if (xprt_args.dstaddr->sa_family !=
851 			    clp->cl_addr.ss_family)
852 				continue;
853 			/* Add this address as an alias */
854 			rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
855 					  rpc_clnt_test_and_add_xprt, NULL);
856 			continue;
857 		}
858 
859 		ds_proto = da->da_transport;
860 		if (ds_proto == XPRT_TRANSPORT_TCP &&
861 		    xprtsec_policy != RPC_XPRTSEC_NONE)
862 			ds_proto = XPRT_TRANSPORT_TCP_TLS;
863 
864 		clp = get_v3_ds_connect(mds_srv, &da->da_addr, da->da_addrlen,
865 					ds_proto, timeo, retrans);
866 		if (IS_ERR(clp))
867 			continue;
868 		clp->cl_rpcclient->cl_softerr = 0;
869 		clp->cl_rpcclient->cl_softrtry = 0;
870 	}
871 
872 	if (IS_ERR(clp)) {
873 		status = PTR_ERR(clp);
874 		goto out;
875 	}
876 
877 	smp_wmb();
878 	WRITE_ONCE(ds->ds_clp, clp);
879 	dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
880 out:
881 	return status;
882 }
883 
_nfs4_pnfs_v4_ds_connect(struct nfs_server * mds_srv,struct nfs4_pnfs_ds * ds,unsigned int timeo,unsigned int retrans,u32 minor_version,bool tightly_coupled)884 static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
885 				 struct nfs4_pnfs_ds *ds,
886 				 unsigned int timeo,
887 				 unsigned int retrans,
888 				 u32 minor_version,
889 				 bool tightly_coupled)
890 {
891 	struct nfs_client *clp = ERR_PTR(-EIO);
892 	struct nfs_client *mds_clp = mds_srv->nfs_client;
893 	enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy;
894 	struct nfs4_pnfs_ds_addr *da;
895 	int ds_proto;
896 	int status = 0;
897 
898 	dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
899 
900 	list_for_each_entry(da, &ds->ds_addrs, da_node) {
901 		char servername[48];
902 
903 		dprintk("%s: DS %s: trying address %s\n",
904 			__func__, ds->ds_remotestr, da->da_remotestr);
905 
906 		if (!IS_ERR(clp) && clp->cl_mvops->session_trunk) {
907 			struct xprt_create xprt_args = {
908 				.ident = da->da_transport,
909 				.net = clp->cl_net,
910 				.dstaddr = (struct sockaddr *)&da->da_addr,
911 				.addrlen = da->da_addrlen,
912 				.servername = clp->cl_hostname,
913 				.xprtsec = clp->cl_xprtsec,
914 			};
915 			struct nfs4_add_xprt_data xprtdata = {
916 				.clp = clp,
917 			};
918 			struct rpc_add_xprt_test rpcdata = {
919 				.add_xprt_test = clp->cl_mvops->session_trunk,
920 				.data = &xprtdata,
921 			};
922 
923 			if (xprt_args.ident == XPRT_TRANSPORT_TCP &&
924 			    clp->cl_proto == XPRT_TRANSPORT_TCP_TLS) {
925 				struct sockaddr *addr =
926 					(struct sockaddr *)&da->da_addr;
927 				struct sockaddr_in *sin =
928 					(struct sockaddr_in *)&da->da_addr;
929 				struct sockaddr_in6 *sin6 =
930 					(struct sockaddr_in6 *)&da->da_addr;
931 
932 				/* for NFS with TLS we need to supply a correct
933 				 * servername of the trunked transport, not the
934 				 * servername of the main transport stored in
935 				 * clp->cl_hostname. And set the protocol to
936 				 * indicate to use TLS
937 				 */
938 				servername[0] = '\0';
939 				switch(addr->sa_family) {
940 				case AF_INET:
941 					snprintf(servername, sizeof(servername),
942 						"%pI4", &sin->sin_addr.s_addr);
943 					break;
944 				case AF_INET6:
945 					snprintf(servername, sizeof(servername),
946 						"%pI6", &sin6->sin6_addr);
947 					break;
948 				default:
949 					/* do not consider this address */
950 					continue;
951 				}
952 				xprt_args.ident = XPRT_TRANSPORT_TCP_TLS;
953 				xprt_args.servername = servername;
954 			}
955 			if (xprt_args.ident != clp->cl_proto)
956 				continue;
957 			if (xprt_args.dstaddr->sa_family !=
958 			    clp->cl_addr.ss_family)
959 				continue;
960 
961 			/**
962 			* Test this address for session trunking and
963 			* add as an alias
964 			*/
965 			xprtdata.cred = nfs4_get_clid_cred(clp);
966 			rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
967 					  rpc_clnt_setup_test_and_add_xprt,
968 					  &rpcdata);
969 			if (xprtdata.cred)
970 				put_cred(xprtdata.cred);
971 		} else {
972 			ds_proto = da->da_transport;
973 			if (ds_proto == XPRT_TRANSPORT_TCP &&
974 			    xprtsec_policy != RPC_XPRTSEC_NONE)
975 				ds_proto = XPRT_TRANSPORT_TCP_TLS;
976 
977 			clp = nfs4_set_ds_client(mds_srv, &da->da_addr,
978 						 da->da_addrlen, ds_proto,
979 						 timeo, retrans, minor_version,
980 						 tightly_coupled);
981 			if (IS_ERR(clp))
982 				continue;
983 
984 			status = nfs4_init_ds_session(clp,
985 					mds_srv->nfs_client->cl_lease_time,
986 					tightly_coupled);
987 			if (status) {
988 				nfs_put_client(clp);
989 				clp = ERR_PTR(-EIO);
990 				continue;
991 			}
992 		}
993 	}
994 
995 	if (IS_ERR(clp)) {
996 		status = PTR_ERR(clp);
997 		goto out;
998 	}
999 
1000 	smp_wmb();
1001 	WRITE_ONCE(ds->ds_clp, clp);
1002 	dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
1003 out:
1004 	return status;
1005 }
1006 
1007 /*
1008  * Create an rpc connection to the nfs4_pnfs_ds data server.
1009  * Currently only supports IPv4 and IPv6 addresses.
1010  * If connection fails, make devid unavailable and return a -errno.
1011  */
nfs4_pnfs_ds_connect(struct nfs_server * mds_srv,struct nfs4_pnfs_ds * ds,struct nfs4_deviceid_node * devid,unsigned int timeo,unsigned int retrans,u32 version,u32 minor_version,bool tightly_coupled)1012 int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
1013 			  struct nfs4_deviceid_node *devid, unsigned int timeo,
1014 			  unsigned int retrans, u32 version, u32 minor_version,
1015 			  bool tightly_coupled)
1016 {
1017 	int err;
1018 
1019 	do {
1020 		err = nfs4_wait_ds_connect(ds);
1021 		if (err || ds->ds_clp)
1022 			goto out;
1023 		if (nfs4_test_deviceid_unavailable(devid)) {
1024 			err = -ENODEV;
1025 			goto out;
1026 		}
1027 	} while (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) != 0);
1028 
1029 	if (ds->ds_clp)
1030 		goto connect_done;
1031 
1032 	switch (version) {
1033 	case 3:
1034 		err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, retrans);
1035 		break;
1036 	case 4:
1037 		err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo, retrans,
1038 					       minor_version, tightly_coupled);
1039 		break;
1040 	default:
1041 		dprintk("%s: unsupported DS version %d\n", __func__, version);
1042 		err = -EPROTONOSUPPORT;
1043 	}
1044 
1045 connect_done:
1046 	nfs4_clear_ds_conn_bit(ds);
1047 out:
1048 	/*
1049 	 * At this point the ds->ds_clp should be ready, but it might have
1050 	 * hit an error.
1051 	 */
1052 	if (!err) {
1053 		if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) {
1054 			WARN_ON_ONCE(ds->ds_clp ||
1055 				!nfs4_test_deviceid_unavailable(devid));
1056 			err = -EINVAL;
1057 		} else
1058 			err = nfs_client_init_status(ds->ds_clp);
1059 	}
1060 
1061 	trace_pnfs_ds_connect(ds->ds_remotestr, err);
1062 	return err;
1063 }
1064 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect);
1065 
1066 /*
1067  * Currently only supports ipv4, ipv6 and one multi-path address.
1068  */
1069 struct nfs4_pnfs_ds_addr *
nfs4_decode_mp_ds_addr(struct net * net,struct xdr_stream * xdr,gfp_t gfp_flags)1070 nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
1071 {
1072 	struct nfs4_pnfs_ds_addr *da = NULL;
1073 	char *buf, *portstr;
1074 	__be16 port;
1075 	ssize_t nlen, rlen;
1076 	int tmp[2];
1077 	char *netid;
1078 	size_t len;
1079 	char *startsep = "";
1080 	char *endsep = "";
1081 
1082 
1083 	/* r_netid */
1084 	nlen = xdr_stream_decode_string_dup(xdr, &netid, XDR_MAX_NETOBJ,
1085 					    gfp_flags);
1086 	if (unlikely(nlen <= 0))
1087 		goto out_err;
1088 
1089 	/* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */
1090 	/* port is ".ABC.DEF", 8 chars max */
1091 	rlen = xdr_stream_decode_string_dup(xdr, &buf, INET6_ADDRSTRLEN +
1092 					    IPV6_SCOPE_ID_LEN + 8, gfp_flags);
1093 	if (unlikely(rlen <= 0))
1094 		goto out_free_netid;
1095 
1096 	/* replace port '.' with '-' */
1097 	portstr = strrchr(buf, '.');
1098 	if (!portstr) {
1099 		dprintk("%s: Failed finding expected dot in port\n",
1100 			__func__);
1101 		goto out_free_buf;
1102 	}
1103 	*portstr = '-';
1104 
1105 	/* find '.' between address and port */
1106 	portstr = strrchr(buf, '.');
1107 	if (!portstr) {
1108 		dprintk("%s: Failed finding expected dot between address and "
1109 			"port\n", __func__);
1110 		goto out_free_buf;
1111 	}
1112 	*portstr = '\0';
1113 
1114 	da = nfs4_pnfs_ds_addr_alloc(gfp_flags);
1115 	if (unlikely(!da))
1116 		goto out_free_buf;
1117 
1118 	if (!rpc_pton(net, buf, portstr-buf, (struct sockaddr *)&da->da_addr,
1119 		      sizeof(da->da_addr))) {
1120 		dprintk("%s: error parsing address %s\n", __func__, buf);
1121 		goto out_free_da;
1122 	}
1123 
1124 	portstr++;
1125 	sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]);
1126 	port = htons((tmp[0] << 8) | (tmp[1]));
1127 
1128 	switch (da->da_addr.ss_family) {
1129 	case AF_INET:
1130 		((struct sockaddr_in *)&da->da_addr)->sin_port = port;
1131 		da->da_addrlen = sizeof(struct sockaddr_in);
1132 		break;
1133 
1134 	case AF_INET6:
1135 		((struct sockaddr_in6 *)&da->da_addr)->sin6_port = port;
1136 		da->da_addrlen = sizeof(struct sockaddr_in6);
1137 		startsep = "[";
1138 		endsep = "]";
1139 		break;
1140 
1141 	default:
1142 		dprintk("%s: unsupported address family: %u\n",
1143 			__func__, da->da_addr.ss_family);
1144 		goto out_free_da;
1145 	}
1146 
1147 	da->da_transport = xprt_find_transport_ident(netid);
1148 	if (da->da_transport < 0) {
1149 		dprintk("%s: ERROR: unknown r_netid \"%s\"\n",
1150 			__func__, netid);
1151 		goto out_free_da;
1152 	}
1153 
1154 	da->da_netid = netid;
1155 
1156 	/* save human readable address */
1157 	len = strlen(startsep) + strlen(buf) + strlen(endsep) + 7;
1158 	da->da_remotestr = kzalloc(len, gfp_flags);
1159 
1160 	/* NULL is ok, only used for dprintk */
1161 	if (da->da_remotestr)
1162 		snprintf(da->da_remotestr, len, "%s%s%s:%u", startsep,
1163 			 buf, endsep, ntohs(port));
1164 
1165 	dprintk("%s: Parsed DS addr %s\n", __func__, da->da_remotestr);
1166 	kfree(buf);
1167 	return da;
1168 
1169 out_free_da:
1170 	kfree(da);
1171 out_free_buf:
1172 	dprintk("%s: Error parsing DS addr: %s\n", __func__, buf);
1173 	kfree(buf);
1174 out_free_netid:
1175 	kfree(netid);
1176 out_err:
1177 	return NULL;
1178 }
1179 EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr);
1180 
1181 void
pnfs_layout_mark_request_commit(struct nfs_page * req,struct pnfs_layout_segment * lseg,struct nfs_commit_info * cinfo,u32 ds_commit_idx)1182 pnfs_layout_mark_request_commit(struct nfs_page *req,
1183 				struct pnfs_layout_segment *lseg,
1184 				struct nfs_commit_info *cinfo,
1185 				u32 ds_commit_idx)
1186 {
1187 	struct list_head *list;
1188 	struct pnfs_commit_array *array;
1189 	struct pnfs_commit_bucket *bucket;
1190 
1191 	mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
1192 	array = pnfs_lookup_commit_array(cinfo->ds, lseg);
1193 	if (!array || !pnfs_is_valid_lseg(lseg))
1194 		goto out_resched;
1195 	bucket = &array->buckets[ds_commit_idx];
1196 	list = &bucket->written;
1197 	/* Non-empty buckets hold a reference on the lseg.  That ref
1198 	 * is normally transferred to the COMMIT call and released
1199 	 * there.  It could also be released if the last req is pulled
1200 	 * off due to a rewrite, in which case it will be done in
1201 	 * pnfs_common_clear_request_commit
1202 	 */
1203 	if (!bucket->lseg)
1204 		bucket->lseg = pnfs_get_lseg(lseg);
1205 	set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
1206 	cinfo->ds->nwritten++;
1207 
1208 	nfs_request_add_commit_list_locked(req, list, cinfo);
1209 	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
1210 	nfs_folio_mark_unstable(req, cinfo);
1211 	return;
1212 out_resched:
1213 	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
1214 	cinfo->completion_ops->resched_write(cinfo, req);
1215 }
1216 EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
1217 
1218 int
pnfs_nfs_generic_sync(struct inode * inode,bool datasync)1219 pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
1220 {
1221 	int ret;
1222 
1223 	if (!pnfs_layoutcommit_outstanding(inode))
1224 		return 0;
1225 	ret = nfs_commit_inode(inode, FLUSH_SYNC);
1226 	if (ret < 0)
1227 		return ret;
1228 	if (datasync)
1229 		return 0;
1230 	return pnfs_layoutcommit_inode(inode, true);
1231 }
1232 EXPORT_SYMBOL_GPL(pnfs_nfs_generic_sync);
1233 
1234