diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2011-05-26 14:49:46 -0400 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2011-05-29 13:54:45 -0400 |
commit | adb58535e604a564495a7d50dfb0afa0ddc21bcb (patch) | |
tree | 54af4fe9569650342e61dbb314334e3617c48dc2 /fs/nfs/objlayout/objio_osd.c | |
parent | 04a555498e03b3804e2dec916a4669f5f560e503 (diff) |
pnfs-obj: report errors and .encode_layoutreturn Implementation.
An io_state pre-allocates an error information structure for each
possible osd-device that might error during IO. When IO is done if all
was well the io_state is freed. (as today). If the I/O has ended with an
error, the io_state is queued on a per-layout err_list. When eventually
encode_layoutreturn() is called, each error is properly encoded on the
XDR buffer and only then the io_state is removed from err_list and
de-allocated.
It is up to the io_engine to fill in the segment that fault and the type
of osd_error that occurred. By calling objlayout_io_set_result() for
each failing device.
In objio_osd:
* Allocate io-error descriptors space as part of io_state
* Use generic objlayout error reporting at end of io.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'fs/nfs/objlayout/objio_osd.c')
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 4e8de3ec9a63..8bca5e13f3ef 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -396,12 +396,16 @@ int objio_alloc_io_state(struct pnfs_layout_segment *lseg, | |||
396 | struct objio_state *ios; | 396 | struct objio_state *ios; |
397 | const unsigned first_size = sizeof(*ios) + | 397 | const unsigned first_size = sizeof(*ios) + |
398 | objio_seg->num_comps * sizeof(ios->per_dev[0]); | 398 | objio_seg->num_comps * sizeof(ios->per_dev[0]); |
399 | const unsigned sec_size = objio_seg->num_comps * | ||
400 | sizeof(ios->ol_state.ioerrs[0]); | ||
399 | 401 | ||
400 | ios = kzalloc(first_size, gfp_flags); | 402 | ios = kzalloc(first_size + sec_size, gfp_flags); |
401 | if (unlikely(!ios)) | 403 | if (unlikely(!ios)) |
402 | return -ENOMEM; | 404 | return -ENOMEM; |
403 | 405 | ||
404 | ios->layout = objio_seg; | 406 | ios->layout = objio_seg; |
407 | ios->ol_state.ioerrs = ((void *)ios) + first_size; | ||
408 | ios->ol_state.num_comps = objio_seg->num_comps; | ||
405 | 409 | ||
406 | *outp = &ios->ol_state; | 410 | *outp = &ios->ol_state; |
407 | return 0; | 411 | return 0; |
@@ -415,6 +419,36 @@ void objio_free_io_state(struct objlayout_io_state *ol_state) | |||
415 | kfree(ios); | 419 | kfree(ios); |
416 | } | 420 | } |
417 | 421 | ||
422 | enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) | ||
423 | { | ||
424 | switch (oep) { | ||
425 | case OSD_ERR_PRI_NO_ERROR: | ||
426 | return (enum pnfs_osd_errno)0; | ||
427 | |||
428 | case OSD_ERR_PRI_CLEAR_PAGES: | ||
429 | BUG_ON(1); | ||
430 | return 0; | ||
431 | |||
432 | case OSD_ERR_PRI_RESOURCE: | ||
433 | return PNFS_OSD_ERR_RESOURCE; | ||
434 | case OSD_ERR_PRI_BAD_CRED: | ||
435 | return PNFS_OSD_ERR_BAD_CRED; | ||
436 | case OSD_ERR_PRI_NO_ACCESS: | ||
437 | return PNFS_OSD_ERR_NO_ACCESS; | ||
438 | case OSD_ERR_PRI_UNREACHABLE: | ||
439 | return PNFS_OSD_ERR_UNREACHABLE; | ||
440 | case OSD_ERR_PRI_NOT_FOUND: | ||
441 | return PNFS_OSD_ERR_NOT_FOUND; | ||
442 | case OSD_ERR_PRI_NO_SPACE: | ||
443 | return PNFS_OSD_ERR_NO_SPACE; | ||
444 | default: | ||
445 | WARN_ON(1); | ||
446 | /* fallthrough */ | ||
447 | case OSD_ERR_PRI_EIO: | ||
448 | return PNFS_OSD_ERR_EIO; | ||
449 | } | ||
450 | } | ||
451 | |||
418 | static void _clear_bio(struct bio *bio) | 452 | static void _clear_bio(struct bio *bio) |
419 | { | 453 | { |
420 | struct bio_vec *bv; | 454 | struct bio_vec *bv; |
@@ -461,6 +495,12 @@ static int _io_check(struct objio_state *ios, bool is_write) | |||
461 | continue; /* we recovered */ | 495 | continue; /* we recovered */ |
462 | } | 496 | } |
463 | dev = ios->per_dev[i].dev; | 497 | dev = ios->per_dev[i].dev; |
498 | objlayout_io_set_result(&ios->ol_state, dev, | ||
499 | &ios->layout->comps[dev].oc_object_id, | ||
500 | osd_pri_2_pnfs_err(osi.osd_err_pri), | ||
501 | ios->per_dev[i].offset, | ||
502 | ios->per_dev[i].length, | ||
503 | is_write); | ||
464 | 504 | ||
465 | if (osi.osd_err_pri >= oep) { | 505 | if (osi.osd_err_pri >= oep) { |
466 | oep = osi.osd_err_pri; | 506 | oep = osi.osd_err_pri; |
@@ -977,6 +1017,8 @@ static struct pnfs_layoutdriver_type objlayout_type = { | |||
977 | .pg_test = objlayout_pg_test, | 1017 | .pg_test = objlayout_pg_test, |
978 | 1018 | ||
979 | .free_deviceid_node = objio_free_deviceid_node, | 1019 | .free_deviceid_node = objio_free_deviceid_node, |
1020 | |||
1021 | .encode_layoutreturn = objlayout_encode_layoutreturn, | ||
980 | }; | 1022 | }; |
981 | 1023 | ||
982 | MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects"); | 1024 | MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects"); |