X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fdmu_send.c;h=b2568036025b644438f431a7bf28d8ef042ec7cb;hb=c12936b141e7479a1402561e9e528731d763747e;hp=949f4d7737eef6c788fc981744522ff56dd14ced;hpb=37abac6d559a1da8ab8e5379442f491b73998f6a;p=zfs.git diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 949f4d7..b256803 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -53,21 +54,48 @@ int zfs_send_corrupt_data = B_FALSE; static char *dmu_recv_tag = "dmu_recv_tag"; -static int -dump_bytes(dmu_sendarg_t *dsp, void *buf, int len) +typedef struct dump_bytes_io { + dmu_sendarg_t *dbi_dsp; + void *dbi_buf; + int dbi_len; +} dump_bytes_io_t; + +static void +dump_bytes_strategy(void *arg) { + dump_bytes_io_t *dbi = (dump_bytes_io_t *)arg; + dmu_sendarg_t *dsp = dbi->dbi_dsp; dsl_dataset_t *ds = dsp->dsa_os->os_dsl_dataset; ssize_t resid; /* have to get resid to get detailed errno */ - ASSERT3U(len % 8, ==, 0); + ASSERT0(dbi->dbi_len % 8); - fletcher_4_incremental_native(buf, len, &dsp->dsa_zc); + fletcher_4_incremental_native(dbi->dbi_buf, dbi->dbi_len, &dsp->dsa_zc); dsp->dsa_err = vn_rdwr(UIO_WRITE, dsp->dsa_vp, - (caddr_t)buf, len, + (caddr_t)dbi->dbi_buf, dbi->dbi_len, 0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid); mutex_enter(&ds->ds_sendstream_lock); - *dsp->dsa_off += len; + *dsp->dsa_off += dbi->dbi_len; mutex_exit(&ds->ds_sendstream_lock); +} + +static int +dump_bytes(dmu_sendarg_t *dsp, void *buf, int len) +{ + dump_bytes_io_t dbi; + + dbi.dbi_dsp = dsp; + dbi.dbi_buf = buf; + dbi.dbi_len = len; + + /* + * The vn_rdwr() call is performed in a taskq to ensure that there is + * always enough stack space to write safely to the target filesystem. + * The ZIO_TYPE_FREE threads are used because there can be a lot of + * them and they are used in vdev_file.c for a similar purpose. + */ + spa_taskq_dispatch_sync(dmu_objset_spa(dsp->dsa_os), ZIO_TYPE_FREE, + ZIO_TASKQ_ISSUE, dump_bytes_strategy, &dbi, TQ_SLEEP); return (dsp->dsa_err); } @@ -373,7 +401,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf, for (ptr = abuf->b_data; (char *)ptr < (char *)abuf->b_data + blksz; ptr++) - *ptr = 0x2f5baddb10c; + *ptr = 0x2f5baddb10cULL; } else { return (EIO); } @@ -960,7 +988,7 @@ restore_read(struct restorearg *ra, int len) int done = 0; /* some things will require 8-byte alignment, so everything must */ - ASSERT3U(len % 8, ==, 0); + ASSERT0(len % 8); while (done < len) { ssize_t resid; @@ -1077,8 +1105,8 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) void *data = NULL; if (drro->drr_type == DMU_OT_NONE || - drro->drr_type >= DMU_OT_NUMTYPES || - drro->drr_bonustype >= DMU_OT_NUMTYPES || + !DMU_OT_IS_VALID(drro->drr_type) || + !DMU_OT_IS_VALID(drro->drr_bonustype) || drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS || drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS || P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) || @@ -1143,7 +1171,9 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) ASSERT3U(db->db_size, >=, drro->drr_bonuslen); bcopy(data, db->db_data, drro->drr_bonuslen); if (ra->byteswap) { - dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data, + dmu_object_byteswap_t byteswap = + DMU_OT_BYTESWAP(drro->drr_bonustype); + dmu_ot_byteswap[byteswap].ob_func(db->db_data, drro->drr_bonuslen); } dmu_buf_rele(db, FTAG); @@ -1186,7 +1216,7 @@ restore_write(struct restorearg *ra, objset_t *os, int err; if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset || - drrw->drr_type >= DMU_OT_NUMTYPES) + !DMU_OT_IS_VALID(drrw->drr_type)) return (EINVAL); data = restore_read(ra, drrw->drr_length); @@ -1205,8 +1235,11 @@ restore_write(struct restorearg *ra, objset_t *os, dmu_tx_abort(tx); return (err); } - if (ra->byteswap) - dmu_ot[drrw->drr_type].ot_byteswap(data, drrw->drr_length); + if (ra->byteswap) { + dmu_object_byteswap_t byteswap = + DMU_OT_BYTESWAP(drrw->drr_type); + dmu_ot_byteswap[byteswap].ob_func(data, drrw->drr_length); + } dmu_write(os, drrw->drr_object, drrw->drr_offset, drrw->drr_length, data, tx); dmu_tx_commit(tx); @@ -1604,13 +1637,6 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc) dsl_dataset_t *ds = drc->drc_logical_ds; int err, myerr; - /* - * XXX hack; seems the ds is still dirty and dsl_pool_zil_clean() - * expects it to have a ds_user_ptr (and zil), but clone_swap() - * can close it. - */ - txg_wait_synced(ds->ds_dir->dd_pool, 0); - if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) { err = dsl_dataset_clone_swap(drc->drc_real_ds, ds, drc->drc_force); @@ -1641,7 +1667,7 @@ out: (void) add_ds_to_guidmap(drc->drc_guid_to_ds_map, ds); dsl_dataset_disown(ds, dmu_recv_tag); myerr = dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag, B_FALSE); - ASSERT3U(myerr, ==, 0); + ASSERT0(myerr); return (err); }