hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/nfs/flexfilelayout/flexfilelayoutdev.c
....@@ -183,56 +183,6 @@
183183 return NULL;
184184 }
185185
186
-static void ff_layout_mark_devid_invalid(struct pnfs_layout_segment *lseg,
187
- struct nfs4_deviceid_node *devid)
188
-{
189
- nfs4_delete_deviceid(devid->ld, devid->nfs_client, &devid->deviceid);
190
- if (!ff_layout_has_available_ds(lseg))
191
- pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
192
- lseg);
193
-}
194
-
195
-static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg,
196
- struct nfs4_ff_layout_mirror *mirror,
197
- bool create)
198
-{
199
- if (mirror == NULL || IS_ERR(mirror->mirror_ds))
200
- goto outerr;
201
- if (mirror->mirror_ds == NULL) {
202
- if (create) {
203
- struct nfs4_deviceid_node *node;
204
- struct pnfs_layout_hdr *lh = lseg->pls_layout;
205
- struct nfs4_ff_layout_ds *mirror_ds = ERR_PTR(-ENODEV);
206
-
207
- node = nfs4_find_get_deviceid(NFS_SERVER(lh->plh_inode),
208
- &mirror->devid, lh->plh_lc_cred,
209
- GFP_KERNEL);
210
- if (node)
211
- mirror_ds = FF_LAYOUT_MIRROR_DS(node);
212
-
213
- /* check for race with another call to this function */
214
- if (cmpxchg(&mirror->mirror_ds, NULL, mirror_ds) &&
215
- mirror_ds != ERR_PTR(-ENODEV))
216
- nfs4_put_deviceid_node(node);
217
- } else
218
- goto outerr;
219
- }
220
-
221
- if (IS_ERR(mirror->mirror_ds))
222
- goto outerr;
223
-
224
- if (mirror->mirror_ds->ds == NULL) {
225
- struct nfs4_deviceid_node *devid;
226
- devid = &mirror->mirror_ds->id_node;
227
- ff_layout_mark_devid_invalid(lseg, devid);
228
- return false;
229
- }
230
- return true;
231
-outerr:
232
- pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode, lseg);
233
- return false;
234
-}
235
-
236186 static void extend_ds_error(struct nfs4_ff_layout_ds_err *err,
237187 u64 offset, u64 length)
238188 {
....@@ -326,14 +276,13 @@
326276 spin_lock(&flo->generic_hdr.plh_inode->i_lock);
327277 ff_layout_add_ds_error_locked(flo, dserr);
328278 spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
329
-
330279 return 0;
331280 }
332281
333
-static struct rpc_cred *
282
+static const struct cred *
334283 ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
335284 {
336
- struct rpc_cred *cred, __rcu **pcred;
285
+ const struct cred *cred, __rcu **pcred;
337286
338287 if (iomode == IOMODE_READ)
339288 pcred = &mirror->ro_cred;
....@@ -346,53 +295,61 @@
346295 if (!cred)
347296 break;
348297
349
- cred = get_rpccred_rcu(cred);
298
+ cred = get_cred_rcu(cred);
350299 } while(!cred);
351300 rcu_read_unlock();
352301 return cred;
353302 }
354303
355304 struct nfs_fh *
356
-nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx)
305
+nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror)
357306 {
358
- struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
359
- struct nfs_fh *fh = NULL;
360
-
361
- if (!ff_layout_mirror_valid(lseg, mirror, false)) {
362
- pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n",
363
- __func__, mirror_idx);
364
- goto out;
365
- }
366
-
367307 /* FIXME: For now assume there is only 1 version available for the DS */
368
- fh = &mirror->fh_versions[0];
369
-out:
370
- return fh;
308
+ return &mirror->fh_versions[0];
371309 }
372310
373
-int
374
-nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
375
- u32 mirror_idx,
376
- nfs4_stateid *stateid)
311
+void
312
+nfs4_ff_layout_select_ds_stateid(const struct nfs4_ff_layout_mirror *mirror,
313
+ nfs4_stateid *stateid)
377314 {
378
- struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
315
+ if (nfs4_ff_layout_ds_version(mirror) == 4)
316
+ nfs4_stateid_copy(stateid, &mirror->stateid);
317
+}
379318
380
- if (!ff_layout_mirror_valid(lseg, mirror, false)) {
381
- pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n",
382
- __func__, mirror_idx);
383
- goto out;
319
+static bool
320
+ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo,
321
+ struct nfs4_ff_layout_mirror *mirror)
322
+{
323
+ if (mirror == NULL)
324
+ goto outerr;
325
+ if (mirror->mirror_ds == NULL) {
326
+ struct nfs4_deviceid_node *node;
327
+ struct nfs4_ff_layout_ds *mirror_ds = ERR_PTR(-ENODEV);
328
+
329
+ node = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode),
330
+ &mirror->devid, lo->plh_lc_cred,
331
+ GFP_KERNEL);
332
+ if (node)
333
+ mirror_ds = FF_LAYOUT_MIRROR_DS(node);
334
+
335
+ /* check for race with another call to this function */
336
+ if (cmpxchg(&mirror->mirror_ds, NULL, mirror_ds) &&
337
+ mirror_ds != ERR_PTR(-ENODEV))
338
+ nfs4_put_deviceid_node(node);
384339 }
385340
386
- nfs4_stateid_copy(stateid, &mirror->stateid);
387
- return 1;
388
-out:
389
- return 0;
341
+ if (IS_ERR(mirror->mirror_ds))
342
+ goto outerr;
343
+
344
+ return true;
345
+outerr:
346
+ return false;
390347 }
391348
392349 /**
393350 * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call
394351 * @lseg: the layout segment we're operating on
395
- * @ds_idx: index of the DS to use
352
+ * @mirror: layout mirror describing the DS to use
396353 * @fail_return: return layout on connect failure?
397354 *
398355 * Try to prepare a DS connection to accept an RPC call. This involves
....@@ -407,26 +364,18 @@
407364 * Returns a pointer to a connected DS object on success or NULL on failure.
408365 */
409366 struct nfs4_pnfs_ds *
410
-nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
367
+nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
368
+ struct nfs4_ff_layout_mirror *mirror,
411369 bool fail_return)
412370 {
413
- struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
414371 struct nfs4_pnfs_ds *ds = NULL;
415
- struct nfs4_deviceid_node *devid;
416372 struct inode *ino = lseg->pls_layout->plh_inode;
417373 struct nfs_server *s = NFS_SERVER(ino);
418374 unsigned int max_payload;
419375 int status;
420376
421
- if (!ff_layout_mirror_valid(lseg, mirror, true)) {
422
- pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
423
- __func__, ds_idx);
424
- goto out;
425
- }
426
-
427
- devid = &mirror->mirror_ds->id_node;
428
- if (ff_layout_test_devid_unavailable(devid))
429
- goto out_fail;
377
+ if (!ff_layout_init_mirror_ds(lseg->pls_layout, mirror))
378
+ goto noconnect;
430379
431380 ds = mirror->mirror_ds->ds;
432381 if (READ_ONCE(ds->ds_clp))
....@@ -437,8 +386,8 @@
437386 /* FIXME: For now we assume the server sent only one version of NFS
438387 * to use for the DS.
439388 */
440
- status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
441
- dataserver_retrans,
389
+ status = nfs4_pnfs_ds_connect(s, ds, &mirror->mirror_ds->id_node,
390
+ dataserver_timeo, dataserver_retrans,
442391 mirror->mirror_ds->ds_versions[0].version,
443392 mirror->mirror_ds->ds_versions[0].minor_version);
444393
....@@ -453,11 +402,12 @@
453402 mirror->mirror_ds->ds_versions[0].wsize = max_payload;
454403 goto out;
455404 }
456
-out_fail:
405
+noconnect:
457406 ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
458407 mirror, lseg->pls_range.offset,
459408 lseg->pls_range.length, NFS4ERR_NXIO,
460409 OP_ILLEGAL, GFP_NOIO);
410
+ ff_layout_send_layouterror(lseg);
461411 if (fail_return || !ff_layout_has_available_ds(lseg))
462412 pnfs_error_mark_layout_for_return(ino, lseg);
463413 ds = NULL;
....@@ -465,33 +415,36 @@
465415 return ds;
466416 }
467417
468
-struct rpc_cred *
469
-ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx,
470
- struct rpc_cred *mdscred)
418
+const struct cred *
419
+ff_layout_get_ds_cred(struct nfs4_ff_layout_mirror *mirror,
420
+ const struct pnfs_layout_range *range,
421
+ const struct cred *mdscred)
471422 {
472
- struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
473
- struct rpc_cred *cred;
423
+ const struct cred *cred;
474424
475
- if (mirror) {
476
- cred = ff_layout_get_mirror_cred(mirror, lseg->pls_range.iomode);
425
+ if (mirror && !mirror->mirror_ds->ds_versions[0].tightly_coupled) {
426
+ cred = ff_layout_get_mirror_cred(mirror, range->iomode);
477427 if (!cred)
478
- cred = get_rpccred(mdscred);
428
+ cred = get_cred(mdscred);
479429 } else {
480
- cred = get_rpccred(mdscred);
430
+ cred = get_cred(mdscred);
481431 }
482432 return cred;
483433 }
484434
485435 /**
486
-* Find or create a DS rpc client with th MDS server rpc client auth flavor
487
-* in the nfs_client cl_ds_clients list.
488
-*/
436
+ * nfs4_ff_find_or_create_ds_client - Find or create a DS rpc client
437
+ * @mirror: pointer to the mirror
438
+ * @ds_clp: nfs_client for the DS
439
+ * @inode: pointer to inode
440
+ *
441
+ * Find or create a DS rpc client with th MDS server rpc client auth flavor
442
+ * in the nfs_client cl_ds_clients list.
443
+ */
489444 struct rpc_clnt *
490
-nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg, u32 ds_idx,
445
+nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror,
491446 struct nfs_client *ds_clp, struct inode *inode)
492447 {
493
- struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
494
-
495448 switch (mirror->mirror_ds->ds_versions[0].version) {
496449 case 3:
497450 /* For NFSv3 DS, flavor is set when creating DS connections */
....@@ -608,7 +561,7 @@
608561 if (IS_ERR(mirror->mirror_ds))
609562 continue;
610563 devid = &mirror->mirror_ds->id_node;
611
- if (!ff_layout_test_devid_unavailable(devid))
564
+ if (!nfs4_test_deviceid_unavailable(devid))
612565 return true;
613566 }
614567 }
....@@ -629,7 +582,7 @@
629582 if (!mirror->mirror_ds)
630583 continue;
631584 devid = &mirror->mirror_ds->id_node;
632
- if (ff_layout_test_devid_unavailable(devid))
585
+ if (nfs4_test_deviceid_unavailable(devid))
633586 return false;
634587 }
635588