mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 03:08:51 +03:00
Remove dependency on linear ABD
Wherever possible it's best to avoid depending on a linear ABD. Update the code accordingly in the following areas. - vdev_raidz - zio, zio_checksum - zfs_fm - change abd_alloc_for_io() to use abd_alloc() Reviewed-by: David Quigley <david.quigley@intel.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Gvozden Neskovic <neskovic@gmail.com> Closes #5668
This commit is contained in:
committed by
Brian Behlendorf
parent
2035575fd6
commit
84c07adadb
+41
-51
@@ -134,21 +134,16 @@ 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);
|
||||
@@ -181,14 +176,14 @@ vdev_raidz_cksum_free(void *arg, size_t ignored)
|
||||
}
|
||||
|
||||
static void
|
||||
vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
|
||||
vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const abd_t *good_data)
|
||||
{
|
||||
raidz_map_t *rm = zcr->zcr_cbdata;
|
||||
size_t c = zcr->zcr_cbinfo;
|
||||
size_t x;
|
||||
const size_t c = zcr->zcr_cbinfo;
|
||||
size_t x, offset;
|
||||
|
||||
const char *good = NULL;
|
||||
char *bad;
|
||||
const abd_t *good = NULL;
|
||||
const abd_t *bad = rm->rm_col[c].rc_abd;
|
||||
|
||||
if (good_data == NULL) {
|
||||
zfs_ereport_finish_checksum(zcr, NULL, NULL, B_FALSE);
|
||||
@@ -203,8 +198,6 @@ vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
|
||||
*/
|
||||
if (rm->rm_col[0].rc_gdata == NULL) {
|
||||
abd_t *bad_parity[VDEV_RAIDZ_MAXPARITY];
|
||||
char *buf;
|
||||
int offset;
|
||||
|
||||
/*
|
||||
* Set up the rm_col[]s to generate the parity for
|
||||
@@ -213,20 +206,21 @@ vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
|
||||
*/
|
||||
for (x = 0; x < rm->rm_firstdatacol; x++) {
|
||||
bad_parity[x] = rm->rm_col[x].rc_abd;
|
||||
rm->rm_col[x].rc_gdata =
|
||||
zio_buf_alloc(rm->rm_col[x].rc_size);
|
||||
rm->rm_col[x].rc_abd =
|
||||
abd_get_from_buf(rm->rm_col[x].rc_gdata,
|
||||
rm->rm_col[x].rc_gdata =
|
||||
abd_alloc_sametype(rm->rm_col[x].rc_abd,
|
||||
rm->rm_col[x].rc_size);
|
||||
}
|
||||
|
||||
/* fill in the data columns from good_data */
|
||||
buf = (char *)good_data;
|
||||
offset = 0;
|
||||
for (; x < rm->rm_cols; x++) {
|
||||
abd_put(rm->rm_col[x].rc_abd);
|
||||
rm->rm_col[x].rc_abd = abd_get_from_buf(buf,
|
||||
rm->rm_col[x].rc_size);
|
||||
buf += rm->rm_col[x].rc_size;
|
||||
|
||||
rm->rm_col[x].rc_abd =
|
||||
abd_get_offset_size((abd_t *)good_data,
|
||||
offset, rm->rm_col[x].rc_size);
|
||||
offset += rm->rm_col[x].rc_size;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -235,10 +229,8 @@ vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
|
||||
vdev_raidz_generate_parity(rm);
|
||||
|
||||
/* restore everything back to its original state */
|
||||
for (x = 0; x < rm->rm_firstdatacol; x++) {
|
||||
abd_put(rm->rm_col[x].rc_abd);
|
||||
for (x = 0; x < rm->rm_firstdatacol; x++)
|
||||
rm->rm_col[x].rc_abd = bad_parity[x];
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
for (x = rm->rm_firstdatacol; x < rm->rm_cols; x++) {
|
||||
@@ -251,19 +243,21 @@ vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const void *good_data)
|
||||
}
|
||||
|
||||
ASSERT3P(rm->rm_col[c].rc_gdata, !=, NULL);
|
||||
good = rm->rm_col[c].rc_gdata;
|
||||
good = abd_get_offset_size(rm->rm_col[c].rc_gdata, 0,
|
||||
rm->rm_col[c].rc_size);
|
||||
} else {
|
||||
/* adjust good_data to point at the start of our column */
|
||||
good = good_data;
|
||||
|
||||
offset = 0;
|
||||
for (x = rm->rm_firstdatacol; x < c; x++)
|
||||
good += rm->rm_col[x].rc_size;
|
||||
offset += rm->rm_col[x].rc_size;
|
||||
|
||||
good = abd_get_offset_size((abd_t *)good_data, offset,
|
||||
rm->rm_col[c].rc_size);
|
||||
}
|
||||
|
||||
bad = abd_borrow_buf_copy(rm->rm_col[c].rc_abd, rm->rm_col[c].rc_size);
|
||||
/* we drop the ereport if it ends up that the data was good */
|
||||
zfs_ereport_finish_checksum(zcr, good, bad, B_TRUE);
|
||||
abd_return_buf(rm->rm_col[c].rc_abd, bad, rm->rm_col[c].rc_size);
|
||||
abd_put((abd_t *)good);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,8 +300,7 @@ 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];
|
||||
@@ -315,6 +308,7 @@ vdev_raidz_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg)
|
||||
col->rc_size);
|
||||
|
||||
abd_copy(tmp, col->rc_abd, col->rc_size);
|
||||
|
||||
abd_put(col->rc_abd);
|
||||
col->rc_abd = tmp;
|
||||
|
||||
@@ -1757,9 +1751,8 @@ vdev_raidz_io_start(zio_t *zio)
|
||||
* Report a checksum error for a child of a RAID-Z device.
|
||||
*/
|
||||
static void
|
||||
raidz_checksum_error(zio_t *zio, raidz_col_t *rc, void *bad_data)
|
||||
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)) {
|
||||
@@ -1773,11 +1766,9 @@ raidz_checksum_error(zio_t *zio, raidz_col_t *rc, void *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,
|
||||
rc->rc_offset, rc->rc_size, buf, bad_data,
|
||||
rc->rc_offset, rc->rc_size, rc->rc_abd, bad_data,
|
||||
&zbc);
|
||||
abd_return_buf(rc->rc_abd, buf, rc->rc_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1810,7 +1801,7 @@ raidz_checksum_verify(zio_t *zio)
|
||||
static int
|
||||
raidz_parity_verify(zio_t *zio, raidz_map_t *rm)
|
||||
{
|
||||
void *orig[VDEV_RAIDZ_MAXPARITY];
|
||||
abd_t *orig[VDEV_RAIDZ_MAXPARITY];
|
||||
int c, ret = 0;
|
||||
raidz_col_t *rc;
|
||||
|
||||
@@ -1825,8 +1816,9 @@ raidz_parity_verify(zio_t *zio, raidz_map_t *rm)
|
||||
rc = &rm->rm_col[c];
|
||||
if (!rc->rc_tried || rc->rc_error != 0)
|
||||
continue;
|
||||
orig[c] = zio_buf_alloc(rc->rc_size);
|
||||
abd_copy_to_buf(orig[c], rc->rc_abd, rc->rc_size);
|
||||
|
||||
orig[c] = abd_alloc_sametype(rc->rc_abd, rc->rc_size);
|
||||
abd_copy(orig[c], rc->rc_abd, rc->rc_size);
|
||||
}
|
||||
|
||||
vdev_raidz_generate_parity(rm);
|
||||
@@ -1835,12 +1827,12 @@ raidz_parity_verify(zio_t *zio, raidz_map_t *rm)
|
||||
rc = &rm->rm_col[c];
|
||||
if (!rc->rc_tried || rc->rc_error != 0)
|
||||
continue;
|
||||
if (bcmp(orig[c], abd_to_buf(rc->rc_abd), rc->rc_size) != 0) {
|
||||
if (abd_cmp(orig[c], rc->rc_abd) != 0) {
|
||||
raidz_checksum_error(zio, rc, orig[c]);
|
||||
rc->rc_error = SET_ERROR(ECKSUM);
|
||||
ret++;
|
||||
}
|
||||
zio_buf_free(orig[c], rc->rc_size);
|
||||
abd_free(orig[c]);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
@@ -1870,7 +1862,7 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
|
||||
{
|
||||
raidz_map_t *rm = zio->io_vsd;
|
||||
raidz_col_t *rc;
|
||||
void *orig[VDEV_RAIDZ_MAXPARITY];
|
||||
abd_t *orig[VDEV_RAIDZ_MAXPARITY];
|
||||
int tstore[VDEV_RAIDZ_MAXPARITY + 2];
|
||||
int *tgts = &tstore[1];
|
||||
int curr, next, i, c, n;
|
||||
@@ -1919,7 +1911,8 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
|
||||
ASSERT(orig[i] != NULL);
|
||||
}
|
||||
|
||||
orig[n - 1] = zio_buf_alloc(rm->rm_col[0].rc_size);
|
||||
orig[n - 1] = abd_alloc_sametype(rm->rm_col[0].rc_abd,
|
||||
rm->rm_col[0].rc_size);
|
||||
|
||||
curr = 0;
|
||||
next = tgts[curr];
|
||||
@@ -1938,8 +1931,7 @@ 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_to_buf(orig[i], rc->rc_abd,
|
||||
rc->rc_size);
|
||||
abd_copy(orig[i], rc->rc_abd, rc->rc_size);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1969,8 +1961,7 @@ 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],
|
||||
rc->rc_size);
|
||||
abd_copy(rc->rc_abd, orig[i], rc->rc_size);
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -2007,9 +1998,8 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
|
||||
}
|
||||
n--;
|
||||
done:
|
||||
for (i = 0; i < n; i++) {
|
||||
zio_buf_free(orig[i], rm->rm_col[0].rc_size);
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
abd_free(orig[i]);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user