X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fdmu_send.c;h=b2568036025b644438f431a7bf28d8ef042ec7cb;hb=389cf730cedd42dd1ef653e9358635c114e458d5;hp=97c23cb076c1a1be4baed5ba391d84d3adf1cf8e;hpb=9ae529ec5dbdc828ff8326beae58062971d74b2e;p=zfs.git diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 97c23cb..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; @@ -1609,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); @@ -1646,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); }