From: Brian Behlendorf Date: Fri, 28 May 2010 22:45:38 +0000 (-0700) Subject: Merge branch 'gcc-branch' into refs/top-bases/zfs-branch X-Git-Tag: zfs-0.5.0~38^2^2~1^2^2~34^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e27754d9e8b8b9c33080adfe9f30b9084a0ecf48;p=zfs Merge branch 'gcc-branch' into refs/top-bases/zfs-branch Conflicts: cmd/ztest/ztest.c lib/libzfs/libzfs_sendrecv.c module/zfs/dmu_objset.c module/zfs/dnode.c module/zfs/dnode_sync.c module/zfs/dsl_dataset.c module/zfs/include/sys/dmu_tx.h module/zfs/include/sys/txg.h module/zfs/spa_history.c --- e27754d9e8b8b9c33080adfe9f30b9084a0ecf48 diff --cc lib/libzfs/libzfs_sendrecv.c index b07926a16,5cfda1377..eaa7d9a31 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@@ -1682,9 -2414,10 +2414,10 @@@ zfs_receive_one(libzfs_handle_t *hdl, i /* * Determine name of destination snapshot, store in zc_value. */ + (void) strcpy(zc.zc_top_ds, tosnap); (void) strcpy(zc.zc_value, tosnap); - (void) strlcat(zc.zc_value, drrb->drr_toname+choplen, - sizeof (zc.zc_value)); - (void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value)); ++ (void) strlcat(zc.zc_value, chopprefix, sizeof (zc.zc_value)); + free(cp); if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) { zcmd_free_nvlists(&zc); return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); diff --cc lib/libzpool/include/sys/zfs_context.h index 9c66c6cc1,9a6d712e5..8c16ec1ef --- a/lib/libzpool/include/sys/zfs_context.h +++ b/lib/libzpool/include/sys/zfs_context.h @@@ -75,13 -75,8 +75,14 @@@ extern "C" #include #include #include + #include +/* + * Stack + */ + +#define noinline __attribute__((noinline)) + /* * Debugging */ diff --cc module/zfs/dbuf.c index 0c8b8aaee,1b0c47ccd..05dbba872 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@@ -2072,11 -2190,8 +2200,12 @@@ dbuf_sync_leaf(dbuf_dirty_record_t *dr while (*drp != dr) drp = &(*drp)->dr_next; ASSERT(dr->dr_next == NULL); + ASSERT(dr->dr_dbuf == db); *drp = dr->dr_next; + if (dr->dr_dbuf->db_level != 0) { + mutex_destroy(&dr->dt.di.dr_mtx); + list_destroy(&dr->dt.di.dr_children); + } kmem_free(dr, sizeof (dbuf_dirty_record_t)); ASSERT(db->db_dirtycnt > 0); db->db_dirtycnt -= 1; diff --cc module/zfs/dmu_objset.c index f99e7dfca,7f149ab6f..c9d2112fd --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@@ -820,39 -883,35 +883,38 @@@ dmu_objset_snapshot(char *fsname, char spa_t *spa; int err; - (void) strcpy(sn.failed, fsname); + sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP); + (void) strcpy(sn->failed, fsname); err = spa_open(fsname, &spa, FTAG); - if (err) + if (err) { + kmem_free(sn, sizeof (struct snaparg)); return (err); + } - sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); - sn.snapname = snapname; - sn.props = props; - sn.recursive = recursive; + sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); + sn->snapname = snapname; + sn->props = props; ++ sn->recursive = recursive; if (recursive) { - sn->checkperms = B_TRUE; err = dmu_objset_find(fsname, - dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); + dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN); } else { - sn->checkperms = B_FALSE; - err = dmu_objset_snapshot_one(fsname, &sn); + err = dmu_objset_snapshot_one(fsname, sn); } if (err == 0) - err = dsl_sync_task_group_wait(sn.dstg); + err = dsl_sync_task_group_wait(sn->dstg); - for (dst = list_head(&sn.dstg->dstg_tasks); dst; - dst = list_next(&sn.dstg->dstg_tasks, dst)) { + for (dst = list_head(&sn->dstg->dstg_tasks); dst; + dst = list_next(&sn->dstg->dstg_tasks, dst)) { objset_t *os = dst->dst_arg1; - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; if (dst->dst_err) - dsl_dataset_name(ds, sn.failed); + dsl_dataset_name(ds, sn->failed); zil_resume(dmu_objset_zil(os)); - dmu_objset_close(os); + dmu_objset_rele(os, &sn); } if (err) diff --cc module/zfs/dmu_send.c index 266f35ad9,6b00b73b4..2f837a1e9 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@@ -882,8 -1145,116 +1145,116 @@@ restore_write(struct restorearg *ra, ob return (0); } + /* + * Handle a DRR_WRITE_BYREF record. This record is used in dedup'ed + * streams to refer to a copy of the data that is already on the + * system because it came in earlier in the stream. This function + * finds the earlier copy of the data, and uses that copy instead of + * data from the stream to fulfill this write. + */ + static int + restore_write_byref(struct restorearg *ra, objset_t *os, + struct drr_write_byref *drrwbr) + { + dmu_tx_t *tx; + int err; + guid_map_entry_t gmesrch; + guid_map_entry_t *gmep; + avl_index_t where; + objset_t *ref_os = NULL; + dmu_buf_t *dbp; + + if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset) + return (EINVAL); + + /* + * If the GUID of the referenced dataset is different from the + * GUID of the target dataset, find the referenced dataset. + */ + if (drrwbr->drr_toguid != drrwbr->drr_refguid) { + gmesrch.guid = drrwbr->drr_refguid; + if ((gmep = avl_find(&ra->guid_to_ds_map, &gmesrch, + &where)) == NULL) { + return (EINVAL); + } + if (dmu_objset_from_ds(gmep->gme_ds, &ref_os)) + return (EINVAL); + } else { + ref_os = os; + } + + if (err = dmu_buf_hold(ref_os, drrwbr->drr_refobject, + drrwbr->drr_refoffset, FTAG, &dbp, DMU_READ_PREFETCH)) + return (err); + + tx = dmu_tx_create(os); + + dmu_tx_hold_write(tx, drrwbr->drr_object, + drrwbr->drr_offset, drrwbr->drr_length); + err = dmu_tx_assign(tx, TXG_WAIT); + if (err) { + dmu_tx_abort(tx); + return (err); + } + dmu_write(os, drrwbr->drr_object, + drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx); + dmu_buf_rele(dbp, FTAG); + dmu_tx_commit(tx); + return (0); + } + + static int + restore_spill(struct restorearg *ra, objset_t *os, struct drr_spill *drrs) + { + dmu_tx_t *tx; + void *data; + dmu_buf_t *db, *db_spill; + int err; + + if (drrs->drr_length < SPA_MINBLOCKSIZE || + drrs->drr_length > SPA_MAXBLOCKSIZE) + return (EINVAL); + + data = restore_read(ra, drrs->drr_length); + if (data == NULL) + return (ra->err); + + if (dmu_object_info(os, drrs->drr_object, NULL) != 0) + return (EINVAL); + + VERIFY(0 == dmu_bonus_hold(os, drrs->drr_object, FTAG, &db)); + if ((err = dmu_spill_hold_by_bonus(db, FTAG, &db_spill)) != 0) { + dmu_buf_rele(db, FTAG); + return (err); + } + + tx = dmu_tx_create(os); + + dmu_tx_hold_spill(tx, db->db_object); + + err = dmu_tx_assign(tx, TXG_WAIT); + if (err) { + dmu_buf_rele(db, FTAG); + dmu_buf_rele(db_spill, FTAG); + dmu_tx_abort(tx); + return (err); + } + dmu_buf_will_dirty(db_spill, tx); + + if (db_spill->db_size < drrs->drr_length) + VERIFY(0 == dbuf_spill_set_blksz(db_spill, + drrs->drr_length, tx)); + bcopy(data, db_spill->db_data, drrs->drr_length); + + dmu_buf_rele(db, FTAG); + dmu_buf_rele(db_spill, FTAG); + + dmu_tx_commit(tx); + return (0); + } + /* ARGSUSED */ -static int +noinline static int restore_free(struct restorearg *ra, objset_t *os, struct drr_free *drrf) { diff --cc module/zfs/dnode.c index 35b6ee8b7,0480879f2..2e55e4f4c --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@@ -333,13 -318,9 +358,16 @@@ dnode_create(objset_t *os, dnode_phys_ dn->dn_bonustype = dnp->dn_bonustype; dn->dn_bonuslen = dnp->dn_bonuslen; dn->dn_maxblkid = dnp->dn_maxblkid; + dn->dn_allocated_txg = 0; + dn->dn_free_txg = 0; + dn->dn_assigned_txg = 0; + dn->dn_dirtyctx = DN_UNDIRTIED; + dn->dn_dirtyctx_firstset = NULL; + dn->dn_bonus = NULL; + dn->dn_zio = NULL; + dn->dn_have_spill = ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0); + dn->dn_id_flags = 0; + dmu_zfetch_init(&dn->dn_zfetch, dn); ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES); diff --cc module/zfs/dsl_dataset.c index 926034836,27ba7f934..d51d00230 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@@ -366,13 -393,13 +394,13 @@@ dsl_dataset_get_ref(dsl_pool_t *dp, uin mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&ds->ds_recvlock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&ds->ds_deadlist.bpl_lock, NULL, MUTEX_DEFAULT, - NULL); - rw_init(&ds->ds_rwlock, 0, 0, 0); + rw_init(&ds->ds_rwlock, NULL, RW_DEFAULT, NULL); cv_init(&ds->ds_exclusive_cv, NULL, CV_DEFAULT, NULL); - err = bplist_open(&ds->ds_deadlist, + bplist_create(&ds->ds_pending_deadlist); + dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj); + if (err == 0) { err = dsl_dir_open_obj(dp, ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir); diff --cc module/zfs/include/sys/dmu_zfetch.h index 372758ccb,78cadd2b1..ea73d8f02 --- a/module/zfs/include/sys/dmu_zfetch.h +++ b/module/zfs/include/sys/dmu_zfetch.h @@@ -63,11 -61,11 +61,14 @@@ typedef struct zfetch uint64_t zf_alloc_fail; /* # of failed attempts to alloc strm */ } zfetch_t; + void zfetch_init(void); + void zfetch_fini(void); + void dmu_zfetch_init(zfetch_t *, struct dnode *); void dmu_zfetch_rele(zfetch_t *); +void dmu_zfetch_cons(zfetch_t *); +void dmu_zfetch_dest(zfetch_t *); + void dmu_zfetch(zfetch_t *, uint64_t, uint64_t, int); diff --cc module/zfs/vdev.c index 57869b6e6,ccf235f61..8d677ee60 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@@ -323,9 -321,8 +321,10 @@@ vdev_alloc_common(spa_t *spa, uint_t id vd->vdev_guid_sum = guid; vd->vdev_ops = ops; vd->vdev_state = VDEV_STATE_CLOSED; + vd->vdev_ishole = (ops == &vdev_hole_ops); + list_link_init(&vd->vdev_config_dirty_node); + list_link_init(&vd->vdev_state_dirty_node); mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL);