Skip to content

Commit

Permalink
Correct vdev_raidz calling ereport to use abd.
Browse files Browse the repository at this point in the history
  • Loading branch information
lundman committed Oct 6, 2017
1 parent e055647 commit ad60b8f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 44 deletions.
2 changes: 1 addition & 1 deletion usr/src/uts/common/fs/zfs/sys/zio.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ extern void zfs_ereport_free_checksum(zio_cksum_report_t *report);
/* If we have the good data in hand, this function can be used */
extern void zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd,
zbookmark_phys_t *zb, struct zio *zio, uint64_t offset, uint64_t length,
const void *good_data, const void *bad_data, struct zio_bad_cksum *info);
const abd_t *good_data, const abd_t *bad_data, struct zio_bad_cksum *info);

/* Called from spa_sync(), but primarily an injection handler */
extern void spa_handle_ignored_writes(spa_t *spa);
Expand Down
102 changes: 60 additions & 42 deletions usr/src/uts/common/fs/zfs/vdev_raidz.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,21 +263,17 @@ static void
vdev_raidz_map_free(raidz_map_t *rm)
{
int c;
size_t size;

for (c = 0; c < rm->rm_firstdatacol; c++) {
abd_free(rm->rm_col[c].rc_abd);

if (rm->rm_col[c].rc_gdata != NULL)
zio_buf_free(rm->rm_col[c].rc_gdata,
rm->rm_col[c].rc_size);
abd_free(rm->rm_col[c].rc_gdata);

}

size = 0;
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++)
abd_put(rm->rm_col[c].rc_abd);
size += rm->rm_col[c].rc_size;
}

if (rm->rm_abd_copy != NULL)
abd_free(rm->rm_abd_copy);
Expand Down Expand Up @@ -434,14 +430,16 @@ vdev_raidz_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg)
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++)
size += rm->rm_col[c].rc_size;

rm->rm_abd_copy =
abd_alloc_sametype(rm->rm_col[rm->rm_firstdatacol].rc_abd, size);
rm->rm_abd_copy = abd_alloc_for_io(size, B_FALSE);

for (offset = 0, c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
raidz_col_t *col = &rm->rm_col[c];
abd_t *tmp = abd_get_offset(rm->rm_abd_copy, offset);
abd_t *tmp = abd_get_offset_size(rm->rm_abd_copy, offset,
col->rc_size);

abd_copy(tmp, col->rc_abd, col->rc_size);
ASSERT3S(tmp->abd_size, >=, col->rc_size);
ASSERT3S(col->rc_abd->abd_size, >=, col->rc_size);
abd_copy_off(tmp, col->rc_abd, 0, 0, col->rc_size);
abd_put(col->rc_abd);
col->rc_abd = tmp;

Expand Down Expand Up @@ -558,13 +556,15 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,

for (c = 0; c < rm->rm_firstdatacol; c++)
rm->rm_col[c].rc_abd =
abd_alloc_linear(rm->rm_col[c].rc_size, B_TRUE);
abd_alloc_linear(rm->rm_col[c].rc_size, B_FALSE);

rm->rm_col[c].rc_abd = abd_get_offset(abd, 0);
rm->rm_col[c].rc_abd = abd_get_offset_size(abd, 0,
rm->rm_col[c].rc_size);
off = rm->rm_col[c].rc_size;

for (c = c + 1; c < acols; c++) {
rm->rm_col[c].rc_abd = abd_get_offset(abd, off);
rm->rm_col[c].rc_abd = abd_get_offset_size(abd, off,
rm->rm_col[c].rc_size);
off += rm->rm_col[c].rc_size;
}

Expand Down Expand Up @@ -679,7 +679,8 @@ vdev_raidz_generate_parity_p(raidz_map_t *rm)
p = abd_to_buf(rm->rm_col[VDEV_RAIDZ_P].rc_abd);

if (c == rm->rm_firstdatacol) {
abd_copy_to_buf(p, src, rm->rm_col[c].rc_size);
ASSERT3U(src->abd_size, >=, rm->rm_col[c].rc_size);
abd_copy_to_buf_off(p, src, 0, rm->rm_col[c].rc_size);
} else {
struct pqr_struct pqr = { p, NULL, NULL };
(void) abd_iterate_func(src, 0, rm->rm_col[c].rc_size,
Expand Down Expand Up @@ -707,20 +708,22 @@ vdev_raidz_generate_parity_pq(raidz_map_t *rm)
ccnt = rm->rm_col[c].rc_size / sizeof (p[0]);

if (c == rm->rm_firstdatacol) {
abd_copy_to_buf(p, src, rm->rm_col[c].rc_size);
(void) memcpy(q, p, rm->rm_col[c].rc_size);
} else {
struct pqr_struct pqr = { p, q, NULL };
(void) abd_iterate_func(src, 0, rm->rm_col[c].rc_size,
vdev_raidz_pq_func, &pqr);
}
ASSERT(ccnt == pcnt || ccnt == 0);

if (c == rm->rm_firstdatacol) {
abd_copy_to_buf_off(p, src, 0, rm->rm_col[c].rc_size);
(void) memcpy(q, p, rm->rm_col[c].rc_size);
for (i = ccnt; i < pcnt; i++) {
p[i] = 0;
q[i] = 0;
}
} else {
struct pqr_struct pqr = { p, q, NULL };

ASSERT(ccnt <= pcnt);

(void) abd_iterate_func(src, 0, rm->rm_col[c].rc_size,
vdev_raidz_pq_func, &pqr);

/*
* Treat short columns as though they are full of 0s.
* Note that there's therefore nothing needed for P.
Expand Down Expand Up @@ -754,22 +757,24 @@ vdev_raidz_generate_parity_pqr(raidz_map_t *rm)
ccnt = rm->rm_col[c].rc_size / sizeof (p[0]);

if (c == rm->rm_firstdatacol) {
abd_copy_to_buf(p, src, rm->rm_col[c].rc_size);
ASSERT3S(src->abd_size, >=, rm->rm_col[c].rc_size);
ASSERT(ccnt == pcnt || ccnt == 0);
abd_copy_to_buf_off(p, src, 0, rm->rm_col[c].rc_size);
(void) memcpy(q, p, rm->rm_col[c].rc_size);
(void) memcpy(r, p, rm->rm_col[c].rc_size);
} else {
struct pqr_struct pqr = { p, q, r };
(void) abd_iterate_func(src, 0, rm->rm_col[c].rc_size,
vdev_raidz_pqr_func, &pqr);
}

if (c == rm->rm_firstdatacol) {
for (i = ccnt; i < pcnt; i++) {
p[i] = 0;
q[i] = 0;
r[i] = 0;
}
} else {
struct pqr_struct pqr = { p, q, r };

ASSERT(ccnt <= pcnt);
(void) abd_iterate_func(src, 0, rm->rm_col[c].rc_size,
vdev_raidz_pqr_func, &pqr);

/*
* Treat short columns as though they are full of 0s.
* Note that there's therefore nothing needed for P.
Expand Down Expand Up @@ -937,7 +942,9 @@ vdev_raidz_reconstruct_p(raidz_map_t *rm, int *tgts, int ntgts)
src = rm->rm_col[VDEV_RAIDZ_P].rc_abd;
dst = rm->rm_col[x].rc_abd;

abd_copy(dst, src, rm->rm_col[x].rc_size);
ASSERT3S(dst->abd_size, >=, rm->rm_col[x].rc_size);
ASSERT3S(src->abd_size, >=, rm->rm_col[x].rc_size);
abd_copy_off(dst, src, 0, 0, rm->rm_col[x].rc_size);

for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
uint64_t size = MIN(rm->rm_col[x].rc_size,
Expand Down Expand Up @@ -975,14 +982,19 @@ vdev_raidz_reconstruct_q(raidz_map_t *rm, int *tgts, int ntgts)
dst = rm->rm_col[x].rc_abd;

if (c == rm->rm_firstdatacol) {
abd_copy(dst, src, size);
if (dst != src) {
ASSERT3S(dst->abd_size, >=, size);
ASSERT3S(src->abd_size, >=, size);
abd_copy_off(dst, src, 0, 0, size);
}
if (rm->rm_col[x].rc_size > size)
abd_zero_off(dst, size,
rm->rm_col[x].rc_size - size);
} else {
ASSERT3U(size, <=, rm->rm_col[x].rc_size);
(void) abd_iterate_func2(dst, src, 0, 0, size,
vdev_raidz_reconst_q_pre_func, NULL);
if (src != dst)
(void) abd_iterate_func2(dst, src, 0, 0, size,
vdev_raidz_reconst_q_pre_func, NULL);
(void) abd_iterate_func(dst,
size, rm->rm_col[x].rc_size - size,
vdev_raidz_reconst_q_pre_tail_func, NULL);
Expand Down Expand Up @@ -1471,7 +1483,9 @@ vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts)

bufs[c] = col->rc_abd;
col->rc_abd = abd_alloc_linear(col->rc_size, B_TRUE);
abd_copy(col->rc_abd, bufs[c], col->rc_size);
ASSERT3S(col->rc_abd->abd_size, >=, col->rc_size);
ASSERT3S(bufs[c]->abd_size, >=, col->rc_size);
abd_copy_off(col->rc_abd, bufs[c], 0, 0, col->rc_size);
}
}

Expand Down Expand Up @@ -1567,7 +1581,9 @@ vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts)
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
raidz_col_t *col = &rm->rm_col[c];

abd_copy(bufs[c], col->rc_abd, col->rc_size);
ASSERT3S(bufs[c]->abd_size, >=, col->rc_size);
ASSERT3S(col->rc_abd->abd_size, >=, col->rc_size);
abd_copy_off(bufs[c], col->rc_abd, 0, 0, col->rc_size);
abd_free(col->rc_abd);
col->rc_abd = bufs[c];
}
Expand Down Expand Up @@ -2000,7 +2016,6 @@ vdev_raidz_io_start(zio_t *zio)
static void
raidz_checksum_error(zio_t *zio, raidz_col_t *rc, abd_t *bad_data)
{
void *buf;
vdev_t *vd = zio->io_vd->vdev_child[rc->rc_devidx];

if (!(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
Expand All @@ -2014,11 +2029,9 @@ raidz_checksum_error(zio_t *zio, raidz_col_t *rc, abd_t *bad_data)
zbc.zbc_has_cksum = 0;
zbc.zbc_injected = rm->rm_ecksuminjected;

buf = abd_borrow_buf_copy(rc->rc_abd, rc->rc_size);
zfs_ereport_post_checksum(zio->io_spa, vd,
&zio->io_bookmark, zio, rc->rc_offset, rc->rc_size,
buf, bad_data, &zbc);
abd_return_buf(rc->rc_abd, buf, rc->rc_size);
rc->rc_abd, bad_data, &zbc);
}
}

Expand Down Expand Up @@ -2182,7 +2195,10 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
ASSERT3S(c, >=, 0);
ASSERT3S(c, <, rm->rm_cols);
rc = &rm->rm_col[c];
abd_copy(orig[i], rc->rc_abd, rc->rc_size);
ASSERT3S(orig[i]->abd_size, >=, rc->rc_size);
ASSERT3S(rc->rc_abd->abd_size, >=, rc->rc_size);
abd_copy_off(orig[i], rc->rc_abd, 0, 0,
rc->rc_size);
}

/*
Expand Down Expand Up @@ -2213,7 +2229,9 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
for (i = 0; i < n; i++) {
c = tgts[i];
rc = &rm->rm_col[c];
abd_copy_from_buf(rc->rc_abd, orig[i],
ASSERT3S(rc->rc_abd->abd_size, >=, rc->rc_size);
ASSERT3S(orig[i]->abd_size, >=, rc->rc_size);
abd_copy_off(rc->rc_abd, orig[i], 0, 0,
rc->rc_size);
}

Expand Down
2 changes: 1 addition & 1 deletion usr/src/uts/common/fs/zfs/zfs_fm.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ zfs_ereport_send_interim_checksum(zio_cksum_report_t *report)
void
zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd, zbookmark_phys_t *zb,
struct zio *zio, uint64_t offset, uint64_t length,
const void *good_data, const void *bad_data, zio_bad_cksum_t *zbc)
const abd_t *good_data, const abd_t *bad_data, zio_bad_cksum_t *zbc)
{
#ifdef _KERNEL
nvlist_t *ereport = NULL;
Expand Down

0 comments on commit ad60b8f

Please sign in to comment.