Mercurial > illumos > illumos-gate
changeset 10298:a0d52501437c
6860996 %temporary clones are not automatically destroyed on error
6863088 zfs panic in dnode_hold_impl from readdir()
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c Wed Aug 12 22:11:31 2009 -0700 @@ -241,7 +241,7 @@ objset_name(uintptr_t addr, char *buf) { static int gotid; - static mdb_ctf_id_t osi_id, ds_id; + static mdb_ctf_id_t os_id, ds_id; uintptr_t os_dsl_dataset; char ds_snapname[MAXNAMELEN]; uintptr_t ds_dir; @@ -249,9 +249,9 @@ buf[0] = '\0'; if (!gotid) { - if (mdb_ctf_lookup_by_name("struct objset_impl", - &osi_id) == -1) { - mdb_warn("couldn't find struct objset_impl"); + if (mdb_ctf_lookup_by_name("struct objset", + &os_id) == -1) { + mdb_warn("couldn't find struct objset"); return (DCMD_ERR); } if (mdb_ctf_lookup_by_name("struct dsl_dataset", @@ -263,7 +263,7 @@ gotid = TRUE; } - if (GETMEMBID(addr, &osi_id, os_dsl_dataset, os_dsl_dataset)) + if (GETMEMBID(addr, &os_id, os_dsl_dataset, os_dsl_dataset)) return (DCMD_ERR); if (os_dsl_dataset == 0) { @@ -2158,7 +2158,7 @@ { "dbuf", ":", "print dmu_buf_impl_t", dbuf }, { "dbuf_stats", ":", "dbuf stats", dbuf_stats }, { "dbufs", - "\t[-O objset_impl_t*] [-n objset_name | \"mos\"] " + "\t[-O objset_t*] [-n objset_name | \"mos\"] " "[-o object | \"mdn\"] \n" "\t[-l level] [-b blkid | \"bonus\"]", "find dmu_buf_impl_t's that match specified criteria", dbufs },
--- a/usr/src/cmd/zdb/zdb.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/cmd/zdb/zdb.c Wed Aug 12 22:11:31 2009 -0700 @@ -724,11 +724,11 @@ (void) printf("Indirect blocks:\n"); - SET_BOOKMARK(&czb, dmu_objset_id(&dn->dn_objset->os), + SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset), dn->dn_object, dnp->dn_nlevels - 1, 0); for (j = 0; j < dnp->dn_nblkptr; j++) { czb.zb_blkid = j; - (void) visit_indirect(dmu_objset_spa(&dn->dn_objset->os), dnp, + (void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp, &dnp->dn_blkptr[j], &czb); } @@ -1073,7 +1073,7 @@ } if (object == 0) { - dn = os->os->os_meta_dnode; + dn = os->os_meta_dnode; } else { error = dmu_bonus_hold(os, object, FTAG, &db); if (error) @@ -1191,21 +1191,21 @@ if (dds.dds_type == DMU_OST_META) { dds.dds_creation_txg = TXG_INITIAL; - usedobjs = os->os->os_rootbp->blk_fill; - refdbytes = os->os->os_spa->spa_dsl_pool-> + usedobjs = os->os_rootbp->blk_fill; + refdbytes = os->os_spa->spa_dsl_pool-> dp_mos_dir->dd_phys->dd_used_bytes; } else { dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch); } - ASSERT3U(usedobjs, ==, os->os->os_rootbp->blk_fill); + ASSERT3U(usedobjs, ==, os->os_rootbp->blk_fill); nicenum(refdbytes, numbuf); if (verbosity >= 4) { (void) sprintf(blkbuf + strlen(blkbuf), ", rootbp "); (void) sprintf_blkptr(blkbuf + strlen(blkbuf), - BP_SPRINTF_LEN - strlen(blkbuf), os->os->os_rootbp); + BP_SPRINTF_LEN - strlen(blkbuf), os->os_rootbp); } else { blkbuf[0] = '\0'; } @@ -1227,7 +1227,7 @@ if (verbosity < 2) return; - if (os->os->os_rootbp->blk_birth == 0) + if (os->os_rootbp->blk_birth == 0) return; if (zopt_objects != 0) { @@ -1240,8 +1240,8 @@ dump_object(os, 0, verbosity, &print_header); object_count = 0; - if (os->os->os_userused_dnode && - os->os->os_userused_dnode->dn_type != 0) { + if (os->os_userused_dnode && + os->os_userused_dnode->dn_type != 0) { dump_object(os, DMU_USERUSED_OBJECT, verbosity, &print_header); dump_object(os, DMU_GROUPUSED_OBJECT, verbosity, &print_header); } @@ -1398,14 +1398,13 @@ int error; objset_t *os; - error = dmu_objset_open(dsname, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os); + error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os); if (error) { (void) printf("Could not open %s\n", dsname); return (0); } dump_dir(os); - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); fuid_table_destroy(); return (0); } @@ -2474,8 +2473,8 @@ if (error == 0) { if (strchr(argv[0], '/') != NULL) { - error = dmu_objset_open(argv[0], DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os); + error = dmu_objset_own(argv[0], DMU_OST_ANY, + B_TRUE, FTAG, &os); } else { error = spa_open(argv[0], &spa, FTAG); } @@ -2499,7 +2498,7 @@ if (os != NULL) { dump_dir(os); - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); } else { dump_zpool(spa); spa_close(spa, FTAG);
--- a/usr/src/cmd/zinject/translate.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/cmd/zinject/translate.c Wed Aug 12 22:11:31 2009 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -162,8 +162,8 @@ */ sync(); - if ((err = dmu_objset_open(dataset, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { + err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, FTAG, &os); + if (err != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); return (-1); @@ -172,7 +172,7 @@ record->zi_objset = dmu_objset_id(os); record->zi_object = statbuf->st_ino; - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); return (0); } @@ -247,17 +247,17 @@ * Get the dnode associated with object, so we can calculate the block * size. */ - if ((err = dmu_objset_open(dataset, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) { + if ((err = dmu_objset_own(dataset, DMU_OST_ANY, + B_TRUE, FTAG, &os)) != 0) { (void) fprintf(stderr, "cannot open dataset '%s': %s\n", dataset, strerror(err)); goto out; } if (record->zi_object == 0) { - dn = os->os->os_meta_dnode; + dn = os->os_meta_dnode; } else { - err = dnode_hold(os->os, record->zi_object, FTAG, &dn); + err = dnode_hold(os, record->zi_object, FTAG, &dn); if (err != 0) { (void) fprintf(stderr, "failed to hold dnode " "for object %llu\n", @@ -306,11 +306,11 @@ ret = 0; out: if (dn) { - if (dn != os->os->os_meta_dnode) + if (dn != os->os_meta_dnode) dnode_rele(dn, FTAG); } if (os) - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); return (ret); }
--- a/usr/src/cmd/ztest/ztest.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/cmd/ztest/ztest.c Wed Aug 12 22:11:31 2009 -0700 @@ -1372,8 +1372,7 @@ /* * Verify that the dataset contains a directory object. */ - error = dmu_objset_open(name, DMU_OST_OTHER, - DS_MODE_USER | DS_MODE_READONLY, &os); + error = dmu_objset_hold(name, FTAG, &os); ASSERT3U(error, ==, 0); error = dmu_object_info(os, ZTEST_DIROBJ, doi); if (error != ENOENT) { @@ -1382,16 +1381,15 @@ ASSERT3U(doi->doi_type, ==, DMU_OT_UINT64_OTHER); ASSERT3S(doi->doi_physical_blks, >=, 0); } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); /* * Destroy the dataset. */ error = dmu_objset_destroy(name, B_FALSE); if (error) { - (void) dmu_objset_open(name, DMU_OST_OTHER, - DS_MODE_USER | DS_MODE_READONLY, &os); - fatal(0, "dmu_objset_destroy(os=%p) = %d\n", &os, error); + (void) dmu_objset_hold(name, FTAG, &os); + fatal(0, "dmu_objset_destroy(os=%p) = %d\n", os, error); } return (0); } @@ -1434,7 +1432,6 @@ int error; objset_t *os, *os2; char name[100]; - int basemode, expected_error; zilog_t *zilog; uint64_t seq; uint64_t objects; @@ -1443,19 +1440,15 @@ (void) snprintf(name, 100, "%s/%s_temp_%llu", za->za_pool, za->za_pool, (u_longlong_t)za->za_instance); - basemode = DS_MODE_TYPE(za->za_instance); - if (basemode != DS_MODE_USER && basemode != DS_MODE_OWNER) - basemode = DS_MODE_USER; - /* * If this dataset exists from a previous run, process its replay log * half of the time. If we don't replay it, then dmu_objset_destroy() * (invoked from ztest_destroy_cb() below) should just throw it away. */ if (ztest_random(2) == 0 && - dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_OWNER, &os) == 0) { + dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os) == 0) { zil_replay(os, os, ztest_replay_vector); - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); } /* @@ -1469,7 +1462,7 @@ /* * Verify that the destroyed dataset is no longer in the namespace. */ - error = dmu_objset_open(name, DMU_OST_OTHER, basemode, &os); + error = dmu_objset_hold(name, FTAG, &os); if (error != ENOENT) fatal(1, "dmu_objset_open(%s) found destroyed dataset %p", name, os); @@ -1488,7 +1481,7 @@ fatal(0, "dmu_objset_create(%s) = %d", name, error); } - error = dmu_objset_open(name, DMU_OST_OTHER, basemode, &os); + error = dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os); if (error) { fatal(0, "dmu_objset_open(%s) = %d", name, error); } @@ -1538,27 +1531,23 @@ fatal(0, "created existing dataset, error = %d", error); /* - * Verify that multiple dataset holds are allowed, but only when - * the new access mode is compatible with the base mode. + * Verify that we can hold an objset that is also owned. */ - if (basemode == DS_MODE_OWNER) { - error = dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_USER, - &os2); - if (error) - fatal(0, "dmu_objset_open('%s') = %d", name, error); - else - dmu_objset_close(os2); - } - error = dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_OWNER, &os2); - expected_error = (basemode == DS_MODE_OWNER) ? EBUSY : 0; - if (error != expected_error) - fatal(0, "dmu_objset_open('%s') = %d, expected %d", - name, error, expected_error); - if (error == 0) - dmu_objset_close(os2); + error = dmu_objset_hold(name, FTAG, &os2); + if (error) + fatal(0, "dmu_objset_open('%s') = %d", name, error); + dmu_objset_rele(os2, FTAG); + + /* + * Verify that we can not own an objset that is already owned. + */ + error = dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os2); + if (error != EBUSY) + fatal(0, "dmu_objset_open('%s') = %d, expected EBUSY", + name, error); zil_close(zilog); - dmu_objset_close(os); + dmu_objset_disown(os, FTAG); error = dmu_objset_destroy(name, B_FALSE); if (error) @@ -1670,13 +1659,12 @@ fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error); } - error = dmu_objset_open(snap1name, DMU_OST_OTHER, - DS_MODE_USER | DS_MODE_READONLY, &clone); + error = dmu_objset_hold(snap1name, FTAG, &clone); if (error) fatal(0, "dmu_open_snapshot(%s) = %d", snap1name, error); error = dmu_objset_clone(clone1name, dmu_objset_ds(clone), 0); - dmu_objset_close(clone); + dmu_objset_rele(clone, FTAG); if (error) { if (error == ENOSPC) { ztest_record_enospc("dmu_objset_create"); @@ -1705,13 +1693,12 @@ fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); } - error = dmu_objset_open(snap3name, DMU_OST_OTHER, - DS_MODE_USER | DS_MODE_READONLY, &clone); + error = dmu_objset_hold(snap3name, FTAG, &clone); if (error) fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); error = dmu_objset_clone(clone2name, dmu_objset_ds(clone), 0); - dmu_objset_close(clone); + dmu_objset_rele(clone, FTAG); if (error) { if (error == ENOSPC) { ztest_record_enospc("dmu_objset_create"); @@ -1720,7 +1707,7 @@ fatal(0, "dmu_objset_create(%s) = %d", clone2name, error); } - error = dsl_dataset_own(snap1name, DS_MODE_READONLY, FTAG, &ds); + error = dsl_dataset_own(snap1name, B_FALSE, FTAG, &ds); if (error) fatal(0, "dsl_dataset_own(%s) = %d", snap1name, error); error = dsl_dataset_promote(clone2name); @@ -3806,8 +3793,7 @@ fatal(0, "dmu_objset_create(%s) = %d", name, error); } - error = dmu_objset_open(name, DMU_OST_OTHER, - DS_MODE_USER, &za[d].za_os); + error = dmu_objset_hold(name, FTAG, &za[d].za_os); if (error) fatal(0, "dmu_objset_open('%s') = %d", name, error); @@ -3827,7 +3813,7 @@ VERIFY(thr_join(za[t].za_thread, NULL, NULL) == 0); if (t < zopt_datasets) { zil_close(za[t].za_zilog); - dmu_objset_close(za[t].za_os); + dmu_objset_rele(za[t].za_os, FTAG); } }
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Wed Aug 12 22:11:31 2009 -0700 @@ -401,70 +401,8 @@ static int make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc) { - char *logstr; - libzfs_handle_t *hdl = zhp->zfs_hdl; - - /* - * Preserve history log string. - * any changes performed here will be - * logged as an internal event. - */ - logstr = zhp->zfs_hdl->libzfs_log_str; - zhp->zfs_hdl->libzfs_log_str = NULL; - -top: - if (put_stats_zhdl(zhp, zc) != 0) { - zhp->zfs_hdl->libzfs_log_str = logstr; + if (put_stats_zhdl(zhp, zc) != 0) return (-1); - } - - - if (zhp->zfs_dmustats.dds_inconsistent) { - zfs_cmd_t zc2 = { 0 }; - - /* - * If it is dds_inconsistent, then we've caught it in - * the middle of a 'zfs receive' or 'zfs destroy', and - * it is inconsistent from the ZPL's point of view, so - * can't be mounted. However, it could also be that we - * have crashed in the middle of one of those - * operations, in which case we need to get rid of the - * inconsistent state. We do that by either rolling - * back to the previous snapshot (which will fail if - * there is none), or destroying the filesystem. Note - * that if we are still in the middle of an active - * 'receive' or 'destroy', then the rollback and destroy - * will fail with EBUSY and we will drive on as usual. - */ - - (void) strlcpy(zc2.zc_name, zhp->zfs_name, - sizeof (zc2.zc_name)); - - if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) { - (void) zvol_remove_link(hdl, zhp->zfs_name); - zc2.zc_objset_type = DMU_OST_ZVOL; - } else { - zc2.zc_objset_type = DMU_OST_ZFS; - } - - /* - * If we can successfully destroy it, pretend that it - * never existed. - */ - if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc2) == 0) { - zhp->zfs_hdl->libzfs_log_str = logstr; - errno = ENOENT; - return (-1); - } - /* If we can successfully roll it back, reset the stats */ - if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc2) == 0) { - if (get_stats_ioctl(zhp, zc) != 0) { - zhp->zfs_hdl->libzfs_log_str = logstr; - return (-1); - } - goto top; - } - } /* * We've managed to open the dataset and gather statistics. Determine @@ -486,7 +424,6 @@ else abort(); /* we should never see any other types */ - zhp->zfs_hdl->libzfs_log_str = logstr; zhp->zpool_hdl = zpool_handle(zhp); return (0); }
--- a/usr/src/uts/common/fs/zfs/dbuf.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dbuf.c Wed Aug 12 22:11:31 2009 -0700 @@ -109,7 +109,7 @@ dbuf_find(dnode_t *dn, uint8_t level, uint64_t blkid) { dbuf_hash_table_t *h = &dbuf_hash_table; - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; uint64_t obj = dn->dn_object; uint64_t hv = DBUF_HASH(os, obj, level, blkid); uint64_t idx = hv & h->hash_table_mask; @@ -140,7 +140,7 @@ dbuf_hash_insert(dmu_buf_impl_t *db) { dbuf_hash_table_t *h = &dbuf_hash_table; - objset_impl_t *os = db->db_objset; + objset_t *os = db->db_objset; uint64_t obj = db->db.db_object; int level = db->db_level; uint64_t blkid = db->db_blkid; @@ -894,7 +894,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) { dnode_t *dn = db->db_dnode; - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; dbuf_dirty_record_t **drp, *dr; int drop_struct_lock = FALSE; boolean_t do_free_accounting = B_FALSE; @@ -1488,7 +1488,7 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, dmu_buf_impl_t *parent, blkptr_t *blkptr) { - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; dmu_buf_impl_t *db, *odb; ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock)); @@ -2011,7 +2011,7 @@ arc_buf_t **datap = &dr->dt.dl.dr_data; dmu_buf_impl_t *db = dr->dr_dbuf; dnode_t *dn = db->db_dnode; - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; uint64_t txg = tx->tx_txg; ASSERT(dmu_tx_is_syncing(tx)); @@ -2182,7 +2182,7 @@ { dmu_buf_impl_t *db = dr->dr_dbuf; dnode_t *dn = db->db_dnode; - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; dmu_buf_impl_t *parent = db->db_parent; uint64_t txg = tx->tx_txg; zbookmark_t zb; @@ -2279,7 +2279,7 @@ { dmu_buf_impl_t *db = vdb; dnode_t *dn = db->db_dnode; - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; blkptr_t *bp = zio->io_bp; blkptr_t *bp_orig = &zio->io_bp_orig; uint64_t fill = 0;
--- a/usr/src/uts/common/fs/zfs/dmu.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu.c Wed Aug 12 22:11:31 2009 -0700 @@ -99,7 +99,7 @@ dmu_buf_impl_t *db; int err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); blkid = dbuf_whichblock(dn, offset); @@ -150,7 +150,7 @@ dmu_buf_impl_t *db; int error; - error = dnode_hold(os->os, object, FTAG, &dn); + error = dnode_hold(os, object, FTAG, &dn); if (error) return (error); @@ -282,7 +282,7 @@ dnode_t *dn; int err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); @@ -335,7 +335,7 @@ return; if (len == 0) { /* they're interested in the bonus buffer */ - dn = os->os->os_meta_dnode; + dn = os->os_meta_dnode; if (object == 0 || object >= DN_MAX_OBJECT) return; @@ -352,7 +352,7 @@ * already cached, we will do a *synchronous* read in the * dnode_hold() call. The same is true for any indirects. */ - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err != 0) return; @@ -484,7 +484,7 @@ dnode_t *dn; int err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err != 0) return (err); err = dmu_free_long_range_impl(os, dn, offset, length, FALSE); @@ -499,7 +499,7 @@ dmu_tx_t *tx; int err; - err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED, + err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED, FTAG, &dn); if (err != 0) return (err); @@ -527,7 +527,7 @@ uint64_t size, dmu_tx_t *tx) { dnode_t *dn; - int err = dnode_hold(os->os, object, FTAG, &dn); + int err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); ASSERT(offset < UINT64_MAX); @@ -545,7 +545,7 @@ dmu_buf_t **dbp; int numbufs, err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); @@ -852,8 +852,7 @@ dbuf_rele(db, FTAG); } else { dbuf_rele(db, FTAG); - ASSERT(dn->dn_objset->os.os == dn->dn_objset); - dmu_write(&dn->dn_objset->os, dn->dn_object, offset, blksz, + dmu_write(dn->dn_objset, dn->dn_object, offset, blksz, buf->b_data, tx); dmu_return_arcbuf(buf); } @@ -930,7 +929,7 @@ blkptr_t *bp, uint64_t txg, dmu_sync_cb_t *done, void *arg) { dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake; - objset_impl_t *os = db->db_objset; + objset_t *os = db->db_objset; dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool; tx_state_t *tx = &dp->dp_tx; dbuf_dirty_record_t *dr; @@ -1078,7 +1077,7 @@ dnode_t *dn; int err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); err = dnode_set_blksz(dn, size, ibs, tx); @@ -1093,7 +1092,7 @@ dnode_t *dn; /* XXX assumes dnode_hold will not get an i/o error */ - (void) dnode_hold(os->os, object, FTAG, &dn); + (void) dnode_hold(os, object, FTAG, &dn); ASSERT(checksum < ZIO_CHECKSUM_FUNCTIONS); dn->dn_checksum = checksum; dnode_setdirty(dn, tx); @@ -1107,7 +1106,7 @@ dnode_t *dn; /* XXX assumes dnode_hold will not get an i/o error */ - (void) dnode_hold(os->os, object, FTAG, &dn); + (void) dnode_hold(os, object, FTAG, &dn); ASSERT(compress < ZIO_COMPRESS_FUNCTIONS); dn->dn_compress = compress; dnode_setdirty(dn, tx); @@ -1120,7 +1119,7 @@ dnode_t *dn; int i, err; - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); /* @@ -1134,7 +1133,7 @@ if (i != TXG_SIZE) { dnode_rele(dn, FTAG); txg_wait_synced(dmu_objset_pool(os), 0); - err = dnode_hold(os->os, object, FTAG, &dn); + err = dnode_hold(os, object, FTAG, &dn); if (err) return (err); } @@ -1176,7 +1175,7 @@ dmu_object_info(objset_t *os, uint64_t object, dmu_object_info_t *doi) { dnode_t *dn; - int err = dnode_hold(os->os, object, FTAG, &dn); + int err = dnode_hold(os, object, FTAG, &dn); if (err) return (err);
--- a/usr/src/uts/common/fs/zfs/dmu_object.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu_object.c Wed Aug 12 22:11:31 2009 -0700 @@ -32,16 +32,15 @@ dmu_object_alloc(objset_t *os, dmu_object_type_t ot, int blocksize, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx) { - objset_impl_t *osi = os->os; uint64_t object; uint64_t L2_dnode_count = DNODES_PER_BLOCK << - (osi->os_meta_dnode->dn_indblkshift - SPA_BLKPTRSHIFT); + (os->os_meta_dnode->dn_indblkshift - SPA_BLKPTRSHIFT); dnode_t *dn = NULL; int restarted = B_FALSE; - mutex_enter(&osi->os_obj_lock); + mutex_enter(&os->os_obj_lock); for (;;) { - object = osi->os_obj_next; + object = os->os_obj_next; /* * Each time we polish off an L2 bp worth of dnodes * (2^13 objects), move to another L2 bp that's still @@ -51,14 +50,14 @@ */ if (P2PHASE(object, L2_dnode_count) == 0) { uint64_t offset = restarted ? object << DNODE_SHIFT : 0; - int error = dnode_next_offset(osi->os_meta_dnode, + int error = dnode_next_offset(os->os_meta_dnode, DNODE_FIND_HOLE, &offset, 2, DNODES_PER_BLOCK >> 2, 0); restarted = B_TRUE; if (error == 0) object = offset >> DNODE_SHIFT; } - osi->os_obj_next = ++object; + os->os_obj_next = ++object; /* * XXX We should check for an i/o error here and return @@ -66,19 +65,19 @@ * dmu_tx_assign(), but there is currently no mechanism * to do so. */ - (void) dnode_hold_impl(os->os, object, DNODE_MUST_BE_FREE, + (void) dnode_hold_impl(os, object, DNODE_MUST_BE_FREE, FTAG, &dn); if (dn) break; if (dmu_object_next(os, &object, B_TRUE, 0) == 0) - osi->os_obj_next = object - 1; + os->os_obj_next = object - 1; } dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, tx); dnode_rele(dn, FTAG); - mutex_exit(&osi->os_obj_lock); + mutex_exit(&os->os_obj_lock); dmu_tx_add_new_object(tx, os, object); return (object); @@ -94,7 +93,7 @@ if (object == DMU_META_DNODE_OBJECT && !dmu_tx_private_ok(tx)) return (EBADF); - err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_FREE, FTAG, &dn); + err = dnode_hold_impl(os, object, DNODE_MUST_BE_FREE, FTAG, &dn); if (err) return (err); dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, tx); @@ -116,7 +115,7 @@ if (object == DMU_META_DNODE_OBJECT) return (EBADF); - err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED, + err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED, FTAG, &dn); if (err) return (err); @@ -166,7 +165,7 @@ ASSERT(object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx)); - err = dnode_hold_impl(os->os, object, DNODE_MUST_BE_ALLOCATED, + err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED, FTAG, &dn); if (err) return (err); @@ -185,7 +184,7 @@ uint64_t offset = (*objectp + 1) << DNODE_SHIFT; int error; - error = dnode_next_offset(os->os->os_meta_dnode, + error = dnode_next_offset(os->os_meta_dnode, (hole ? DNODE_FIND_HOLE : 0), &offset, 0, DNODES_PER_BLOCK, txg); *objectp = offset >> DNODE_SHIFT;
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c Wed Aug 12 22:11:31 2009 -0700 @@ -45,13 +45,13 @@ spa_t * dmu_objset_spa(objset_t *os) { - return (os->os->os_spa); + return (os->os_spa); } zilog_t * dmu_objset_zil(objset_t *os) { - return (os->os->os_zil); + return (os->os_zil); } dsl_pool_t * @@ -59,34 +59,34 @@ { dsl_dataset_t *ds; - if ((ds = os->os->os_dsl_dataset) != NULL && ds->ds_dir) + if ((ds = os->os_dsl_dataset) != NULL && ds->ds_dir) return (ds->ds_dir->dd_pool); else - return (spa_get_dsl(os->os->os_spa)); + return (spa_get_dsl(os->os_spa)); } dsl_dataset_t * dmu_objset_ds(objset_t *os) { - return (os->os->os_dsl_dataset); + return (os->os_dsl_dataset); } dmu_objset_type_t dmu_objset_type(objset_t *os) { - return (os->os->os_phys->os_type); + return (os->os_phys->os_type); } void dmu_objset_name(objset_t *os, char *buf) { - dsl_dataset_name(os->os->os_dsl_dataset, buf); + dsl_dataset_name(os->os_dsl_dataset, buf); } uint64_t dmu_objset_id(objset_t *os) { - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; return (ds ? ds->ds_object : 0); } @@ -94,47 +94,47 @@ static void checksum_changed_cb(void *arg, uint64_t newval) { - objset_impl_t *osi = arg; + objset_t *os = arg; /* * Inheritance should have been done by now. */ ASSERT(newval != ZIO_CHECKSUM_INHERIT); - osi->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE); + os->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE); } static void compression_changed_cb(void *arg, uint64_t newval) { - objset_impl_t *osi = arg; + objset_t *os = arg; /* * Inheritance and range checking should have been done by now. */ ASSERT(newval != ZIO_COMPRESS_INHERIT); - osi->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE); + os->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE); } static void copies_changed_cb(void *arg, uint64_t newval) { - objset_impl_t *osi = arg; + objset_t *os = arg; /* * Inheritance and range checking should have been done by now. */ ASSERT(newval > 0); - ASSERT(newval <= spa_max_replication(osi->os_spa)); + ASSERT(newval <= spa_max_replication(os->os_spa)); - osi->os_copies = newval; + os->os_copies = newval; } static void primary_cache_changed_cb(void *arg, uint64_t newval) { - objset_impl_t *osi = arg; + objset_t *os = arg; /* * Inheritance and range checking should have been done by now. @@ -142,13 +142,13 @@ ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || newval == ZFS_CACHE_METADATA); - osi->os_primary_cache = newval; + os->os_primary_cache = newval; } static void secondary_cache_changed_cb(void *arg, uint64_t newval) { - objset_impl_t *osi = arg; + objset_t *os = arg; /* * Inheritance and range checking should have been done by now. @@ -156,7 +156,7 @@ ASSERT(newval == ZFS_CACHE_ALL || newval == ZFS_CACHE_NONE || newval == ZFS_CACHE_METADATA); - osi->os_secondary_cache = newval; + os->os_secondary_cache = newval; } void @@ -177,39 +177,38 @@ int dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, - objset_impl_t **osip) + objset_t **osp) { - objset_impl_t *osi; + objset_t *os; int i, err; ASSERT(ds == NULL || MUTEX_HELD(&ds->ds_opening_lock)); - osi = kmem_zalloc(sizeof (objset_impl_t), KM_SLEEP); - osi->os.os = osi; - osi->os_dsl_dataset = ds; - osi->os_spa = spa; - osi->os_rootbp = bp; - if (!BP_IS_HOLE(osi->os_rootbp)) { + os = kmem_zalloc(sizeof (objset_t), KM_SLEEP); + os->os_dsl_dataset = ds; + os->os_spa = spa; + os->os_rootbp = bp; + if (!BP_IS_HOLE(os->os_rootbp)) { uint32_t aflags = ARC_WAIT; zbookmark_t zb; zb.zb_objset = ds ? ds->ds_object : 0; zb.zb_object = 0; zb.zb_level = -1; zb.zb_blkid = 0; - if (DMU_OS_IS_L2CACHEABLE(osi)) + if (DMU_OS_IS_L2CACHEABLE(os)) aflags |= ARC_L2CACHE; - dprintf_bp(osi->os_rootbp, "reading %s", ""); + dprintf_bp(os->os_rootbp, "reading %s", ""); /* * NB: when bprewrite scrub can change the bp, * and this is called from dmu_objset_open_ds_os, the bp * could change, and we'll need a lock. */ - err = arc_read_nolock(NULL, spa, osi->os_rootbp, - arc_getbuf_func, &osi->os_phys_buf, + err = arc_read_nolock(NULL, spa, os->os_rootbp, + arc_getbuf_func, &os->os_phys_buf, ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &aflags, &zb); if (err) { - kmem_free(osi, sizeof (objset_impl_t)); + kmem_free(os, sizeof (objset_t)); /* convert checksum errors into IO errors */ if (err == ECKSUM) err = EIO; @@ -218,27 +217,27 @@ /* Increase the blocksize if we are permitted. */ if (spa_version(spa) >= SPA_VERSION_USERSPACE && - arc_buf_size(osi->os_phys_buf) < sizeof (objset_phys_t)) { + arc_buf_size(os->os_phys_buf) < sizeof (objset_phys_t)) { arc_buf_t *buf = arc_buf_alloc(spa, - sizeof (objset_phys_t), &osi->os_phys_buf, + sizeof (objset_phys_t), &os->os_phys_buf, ARC_BUFC_METADATA); bzero(buf->b_data, sizeof (objset_phys_t)); - bcopy(osi->os_phys_buf->b_data, buf->b_data, - arc_buf_size(osi->os_phys_buf)); - (void) arc_buf_remove_ref(osi->os_phys_buf, - &osi->os_phys_buf); - osi->os_phys_buf = buf; + bcopy(os->os_phys_buf->b_data, buf->b_data, + arc_buf_size(os->os_phys_buf)); + (void) arc_buf_remove_ref(os->os_phys_buf, + &os->os_phys_buf); + os->os_phys_buf = buf; } - osi->os_phys = osi->os_phys_buf->b_data; - osi->os_flags = osi->os_phys->os_flags; + os->os_phys = os->os_phys_buf->b_data; + os->os_flags = os->os_phys->os_flags; } else { int size = spa_version(spa) >= SPA_VERSION_USERSPACE ? sizeof (objset_phys_t) : OBJSET_OLD_PHYS_SIZE; - osi->os_phys_buf = arc_buf_alloc(spa, size, - &osi->os_phys_buf, ARC_BUFC_METADATA); - osi->os_phys = osi->os_phys_buf->b_data; - bzero(osi->os_phys, size); + os->os_phys_buf = arc_buf_alloc(spa, size, + &os->os_phys_buf, ARC_BUFC_METADATA); + os->os_phys = os->os_phys_buf->b_data; + bzero(os->os_phys, size); } /* @@ -249,61 +248,61 @@ */ if (ds) { err = dsl_prop_register(ds, "primarycache", - primary_cache_changed_cb, osi); + primary_cache_changed_cb, os); if (err == 0) err = dsl_prop_register(ds, "secondarycache", - secondary_cache_changed_cb, osi); + secondary_cache_changed_cb, os); if (!dsl_dataset_is_snapshot(ds)) { if (err == 0) err = dsl_prop_register(ds, "checksum", - checksum_changed_cb, osi); + checksum_changed_cb, os); if (err == 0) err = dsl_prop_register(ds, "compression", - compression_changed_cb, osi); + compression_changed_cb, os); if (err == 0) err = dsl_prop_register(ds, "copies", - copies_changed_cb, osi); + copies_changed_cb, os); } if (err) { - VERIFY(arc_buf_remove_ref(osi->os_phys_buf, - &osi->os_phys_buf) == 1); - kmem_free(osi, sizeof (objset_impl_t)); + VERIFY(arc_buf_remove_ref(os->os_phys_buf, + &os->os_phys_buf) == 1); + kmem_free(os, sizeof (objset_t)); return (err); } } else if (ds == NULL) { /* It's the meta-objset. */ - osi->os_checksum = ZIO_CHECKSUM_FLETCHER_4; - osi->os_compress = ZIO_COMPRESS_LZJB; - osi->os_copies = spa_max_replication(spa); - osi->os_primary_cache = ZFS_CACHE_ALL; - osi->os_secondary_cache = ZFS_CACHE_ALL; + os->os_checksum = ZIO_CHECKSUM_FLETCHER_4; + os->os_compress = ZIO_COMPRESS_LZJB; + os->os_copies = spa_max_replication(spa); + os->os_primary_cache = ZFS_CACHE_ALL; + os->os_secondary_cache = ZFS_CACHE_ALL; } - osi->os_zil_header = osi->os_phys->os_zil_header; - osi->os_zil = zil_alloc(&osi->os, &osi->os_zil_header); + os->os_zil_header = os->os_phys->os_zil_header; + os->os_zil = zil_alloc(os, &os->os_zil_header); for (i = 0; i < TXG_SIZE; i++) { - list_create(&osi->os_dirty_dnodes[i], sizeof (dnode_t), + list_create(&os->os_dirty_dnodes[i], sizeof (dnode_t), offsetof(dnode_t, dn_dirty_link[i])); - list_create(&osi->os_free_dnodes[i], sizeof (dnode_t), + list_create(&os->os_free_dnodes[i], sizeof (dnode_t), offsetof(dnode_t, dn_dirty_link[i])); } - list_create(&osi->os_dnodes, sizeof (dnode_t), + list_create(&os->os_dnodes, sizeof (dnode_t), offsetof(dnode_t, dn_link)); - list_create(&osi->os_downgraded_dbufs, sizeof (dmu_buf_impl_t), + list_create(&os->os_downgraded_dbufs, sizeof (dmu_buf_impl_t), offsetof(dmu_buf_impl_t, db_link)); - mutex_init(&osi->os_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&osi->os_obj_lock, NULL, MUTEX_DEFAULT, NULL); - mutex_init(&osi->os_user_ptr_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&os->os_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&os->os_obj_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&os->os_user_ptr_lock, NULL, MUTEX_DEFAULT, NULL); - osi->os_meta_dnode = dnode_special_open(osi, - &osi->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT); - if (arc_buf_size(osi->os_phys_buf) >= sizeof (objset_phys_t)) { - osi->os_userused_dnode = dnode_special_open(osi, - &osi->os_phys->os_userused_dnode, DMU_USERUSED_OBJECT); - osi->os_groupused_dnode = dnode_special_open(osi, - &osi->os_phys->os_groupused_dnode, DMU_GROUPUSED_OBJECT); + os->os_meta_dnode = dnode_special_open(os, + &os->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT); + if (arc_buf_size(os->os_phys_buf) >= sizeof (objset_phys_t)) { + os->os_userused_dnode = dnode_special_open(os, + &os->os_phys->os_userused_dnode, DMU_USERUSED_OBJECT); + os->os_groupused_dnode = dnode_special_open(os, + &os->os_phys->os_groupused_dnode, DMU_GROUPUSED_OBJECT); } /* @@ -311,117 +310,95 @@ * have ds_opening_lock */ if (ds) { - VERIFY(NULL == dsl_dataset_set_user_ptr(ds, osi, - dmu_objset_evict)); + mutex_enter(&ds->ds_lock); + ASSERT(ds->ds_objset == NULL); + ds->ds_objset = os; + mutex_exit(&ds->ds_lock); } - *osip = osi; - return (0); -} - -static int -dmu_objset_open_ds_os(dsl_dataset_t *ds, objset_t *os, dmu_objset_type_t type) -{ - objset_impl_t *osi; - - mutex_enter(&ds->ds_opening_lock); - osi = dsl_dataset_get_user_ptr(ds); - if (osi == NULL) { - int err; - - err = dmu_objset_open_impl(dsl_dataset_get_spa(ds), - ds, &ds->ds_phys->ds_bp, &osi); - if (err) { - mutex_exit(&ds->ds_opening_lock); - return (err); - } - } - mutex_exit(&ds->ds_opening_lock); - - os->os = osi; - os->os_mode = DS_MODE_NOHOLD; - - if (type != DMU_OST_ANY && type != os->os->os_phys->os_type) - return (EINVAL); + *osp = os; return (0); } int -dmu_objset_open_ds(dsl_dataset_t *ds, dmu_objset_type_t type, objset_t **osp) +dmu_objset_from_ds(dsl_dataset_t *ds, objset_t **osp) { - objset_t *os; + int err = 0; + + mutex_enter(&ds->ds_opening_lock); + *osp = ds->ds_objset; + if (*osp == NULL) { + err = dmu_objset_open_impl(dsl_dataset_get_spa(ds), + ds, &ds->ds_phys->ds_bp, osp); + } + mutex_exit(&ds->ds_opening_lock); + return (err); +} + +/* called from zpl */ +int +dmu_objset_hold(const char *name, void *tag, objset_t **osp) +{ + dsl_dataset_t *ds; int err; - os = kmem_alloc(sizeof (objset_t), KM_SLEEP); - err = dmu_objset_open_ds_os(ds, os, type); + err = dsl_dataset_hold(name, tag, &ds); if (err) - kmem_free(os, sizeof (objset_t)); - else - *osp = os; + return (err); + + err = dmu_objset_from_ds(ds, osp); + if (err) + dsl_dataset_rele(ds, tag); + return (err); } /* called from zpl */ int -dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, - objset_t **osp) +dmu_objset_own(const char *name, dmu_objset_type_t type, + boolean_t readonly, void *tag, objset_t **osp) { - objset_t *os; dsl_dataset_t *ds; int err; - ASSERT(DS_MODE_TYPE(mode) == DS_MODE_USER || - DS_MODE_TYPE(mode) == DS_MODE_OWNER); + err = dsl_dataset_own(name, B_FALSE, tag, &ds); + if (err) + return (err); - os = kmem_alloc(sizeof (objset_t), KM_SLEEP); - if (DS_MODE_TYPE(mode) == DS_MODE_USER) - err = dsl_dataset_hold(name, os, &ds); - else - err = dsl_dataset_own(name, mode, os, &ds); + err = dmu_objset_from_ds(ds, osp); if (err) { - kmem_free(os, sizeof (objset_t)); - return (err); + dsl_dataset_disown(ds, tag); + } else if ((type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) || + (!readonly && dsl_dataset_is_snapshot(ds))) { + dmu_objset_disown(*osp, tag); + return (EINVAL); } - err = dmu_objset_open_ds_os(ds, os, type); - if (err) { - if (DS_MODE_TYPE(mode) == DS_MODE_USER) - dsl_dataset_rele(ds, os); - else - dsl_dataset_disown(ds, os); - kmem_free(os, sizeof (objset_t)); - } else { - os->os_mode = mode; - *osp = os; - } return (err); } void -dmu_objset_close(objset_t *os) +dmu_objset_rele(objset_t *os, void *tag) { - ASSERT(DS_MODE_TYPE(os->os_mode) == DS_MODE_USER || - DS_MODE_TYPE(os->os_mode) == DS_MODE_OWNER || - DS_MODE_TYPE(os->os_mode) == DS_MODE_NOHOLD); + dsl_dataset_rele(os->os_dsl_dataset, tag); +} - if (DS_MODE_TYPE(os->os_mode) == DS_MODE_USER) - dsl_dataset_rele(os->os->os_dsl_dataset, os); - else if (DS_MODE_TYPE(os->os_mode) == DS_MODE_OWNER) - dsl_dataset_disown(os->os->os_dsl_dataset, os); - kmem_free(os, sizeof (objset_t)); +void +dmu_objset_disown(objset_t *os, void *tag) +{ + dsl_dataset_disown(os->os_dsl_dataset, tag); } int dmu_objset_evict_dbufs(objset_t *os) { - objset_impl_t *osi = os->os; dnode_t *dn; - mutex_enter(&osi->os_lock); + mutex_enter(&os->os_lock); /* process the mdn last, since the other dnodes have holds on it */ - list_remove(&osi->os_dnodes, osi->os_meta_dnode); - list_insert_tail(&osi->os_dnodes, osi->os_meta_dnode); + list_remove(&os->os_dnodes, os->os_meta_dnode); + list_insert_tail(&os->os_dnodes, os->os_meta_dnode); /* * Find the first dnode with holds. We have to do this dance @@ -429,93 +406,91 @@ * hold. If there are no holds then it has no dbufs so OK to * skip. */ - for (dn = list_head(&osi->os_dnodes); + for (dn = list_head(&os->os_dnodes); dn && !dnode_add_ref(dn, FTAG); - dn = list_next(&osi->os_dnodes, dn)) + dn = list_next(&os->os_dnodes, dn)) continue; while (dn) { dnode_t *next_dn = dn; do { - next_dn = list_next(&osi->os_dnodes, next_dn); + next_dn = list_next(&os->os_dnodes, next_dn); } while (next_dn && !dnode_add_ref(next_dn, FTAG)); - mutex_exit(&osi->os_lock); + mutex_exit(&os->os_lock); dnode_evict_dbufs(dn); dnode_rele(dn, FTAG); - mutex_enter(&osi->os_lock); + mutex_enter(&os->os_lock); dn = next_dn; } - mutex_exit(&osi->os_lock); - return (list_head(&osi->os_dnodes) != osi->os_meta_dnode); + mutex_exit(&os->os_lock); + return (list_head(&os->os_dnodes) != os->os_meta_dnode); } void -dmu_objset_evict(dsl_dataset_t *ds, void *arg) +dmu_objset_evict(objset_t *os) { - objset_impl_t *osi = arg; - objset_t os; + dsl_dataset_t *ds = os->os_dsl_dataset; int i; for (i = 0; i < TXG_SIZE; i++) { - ASSERT(list_head(&osi->os_dirty_dnodes[i]) == NULL); - ASSERT(list_head(&osi->os_free_dnodes[i]) == NULL); + ASSERT(list_head(&os->os_dirty_dnodes[i]) == NULL); + ASSERT(list_head(&os->os_free_dnodes[i]) == NULL); } if (ds) { if (!dsl_dataset_is_snapshot(ds)) { VERIFY(0 == dsl_prop_unregister(ds, "checksum", - checksum_changed_cb, osi)); + checksum_changed_cb, os)); VERIFY(0 == dsl_prop_unregister(ds, "compression", - compression_changed_cb, osi)); + compression_changed_cb, os)); VERIFY(0 == dsl_prop_unregister(ds, "copies", - copies_changed_cb, osi)); + copies_changed_cb, os)); } VERIFY(0 == dsl_prop_unregister(ds, "primarycache", - primary_cache_changed_cb, osi)); + primary_cache_changed_cb, os)); VERIFY(0 == dsl_prop_unregister(ds, "secondarycache", - secondary_cache_changed_cb, osi)); + secondary_cache_changed_cb, os)); } /* * We should need only a single pass over the dnode list, since * nothing can be added to the list at this point. */ - os.os = osi; - (void) dmu_objset_evict_dbufs(&os); + (void) dmu_objset_evict_dbufs(os); - dnode_special_close(osi->os_meta_dnode); - if (osi->os_userused_dnode) { - dnode_special_close(osi->os_userused_dnode); - dnode_special_close(osi->os_groupused_dnode); + dnode_special_close(os->os_meta_dnode); + if (os->os_userused_dnode) { + dnode_special_close(os->os_userused_dnode); + dnode_special_close(os->os_groupused_dnode); } - zil_free(osi->os_zil); + zil_free(os->os_zil); - ASSERT3P(list_head(&osi->os_dnodes), ==, NULL); + ASSERT3P(list_head(&os->os_dnodes), ==, NULL); - VERIFY(arc_buf_remove_ref(osi->os_phys_buf, &osi->os_phys_buf) == 1); - mutex_destroy(&osi->os_lock); - mutex_destroy(&osi->os_obj_lock); - mutex_destroy(&osi->os_user_ptr_lock); - kmem_free(osi, sizeof (objset_impl_t)); + VERIFY(arc_buf_remove_ref(os->os_phys_buf, &os->os_phys_buf) == 1); + mutex_destroy(&os->os_lock); + mutex_destroy(&os->os_obj_lock); + mutex_destroy(&os->os_user_ptr_lock); + kmem_free(os, sizeof (objset_t)); } /* called from dsl for meta-objset */ -objset_impl_t * +objset_t * dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx) { - objset_impl_t *osi; + objset_t *os; dnode_t *mdn; ASSERT(dmu_tx_is_syncing(tx)); if (ds) mutex_enter(&ds->ds_opening_lock); - VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &osi)); + VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &os)); if (ds) mutex_exit(&ds->ds_opening_lock); - mdn = osi->os_meta_dnode; + mdn = os->os_meta_dnode; dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT, DN_MAX_INDBLKSHIFT, DMU_OT_NONE, 0, tx); @@ -550,15 +525,15 @@ ASSERT(type != DMU_OST_NONE); ASSERT(type != DMU_OST_ANY); ASSERT(type < DMU_OST_NUMTYPES); - osi->os_phys->os_type = type; - if (dmu_objset_userused_enabled(osi)) { - osi->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; - osi->os_flags = osi->os_phys->os_flags; + os->os_phys->os_type = type; + if (dmu_objset_userused_enabled(os)) { + os->os_phys->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; + os->os_flags = os->os_phys->os_flags; } dsl_dataset_dirty(ds, tx); - return (osi); + return (os); } struct oscarg { @@ -613,18 +588,18 @@ if (oa->clone_origin == NULL) { dsl_dataset_t *ds; blkptr_t *bp; - objset_impl_t *osi; + objset_t *os; VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, dsobj, FTAG, &ds)); bp = dsl_dataset_get_blkptr(ds); ASSERT(BP_IS_HOLE(bp)); - osi = dmu_objset_create_impl(dsl_dataset_get_spa(ds), + os = dmu_objset_create_impl(dsl_dataset_get_spa(ds), ds, bp, oa->type, tx); if (oa->userfunc) - oa->userfunc(&osi->os, oa->userarg, cr, tx); + oa->userfunc(os, oa->userarg, cr, tx); dsl_dataset_rele(ds, FTAG); } @@ -692,7 +667,7 @@ int dmu_objset_destroy(const char *name, boolean_t defer) { - objset_t *os; + dsl_dataset_t *ds; int error; /* @@ -702,15 +677,13 @@ * structure. Only the ZIL knows how to free them, so we have * to call into it here. */ - error = dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_OWNER|DS_MODE_READONLY|DS_MODE_INCONSISTENT, &os); + error = dsl_dataset_own(name, B_TRUE, FTAG, &ds); if (error == 0) { - dsl_dataset_t *ds = os->os->os_dsl_dataset; - zil_destroy(dmu_objset_zil(os), B_FALSE); - - error = dsl_dataset_destroy(ds, os, defer); + objset_t *os; + if (dmu_objset_from_ds(ds, &os) == 0) + zil_destroy(dmu_objset_zil(os), B_FALSE); + error = dsl_dataset_destroy(ds, FTAG, defer); /* dsl_dataset_destroy() closes the ds. */ - kmem_free(os, sizeof (objset_t)); } return (error); @@ -732,7 +705,7 @@ /* The props have already been checked by zfs_check_userprops(). */ - return (dsl_dataset_snapshot_check(os->os->os_dsl_dataset, + return (dsl_dataset_snapshot_check(os->os_dsl_dataset, sn->snapname, tx)); } @@ -740,7 +713,7 @@ snapshot_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) { objset_t *os = arg1; - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; struct snaparg *sn = arg2; dsl_dataset_snapshot_sync(ds, sn->snapname, cr, tx); @@ -767,13 +740,13 @@ (err = zfs_secpolicy_snapshot_perms(name, CRED()))) return (err); - err = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_USER, &os); + err = dmu_objset_hold(name, sn, &os); if (err != 0) return (err); /* If the objset is in an inconsistent state, return busy */ - if (os->os->os_dsl_dataset->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) { - dmu_objset_close(os); + if (os->os_dsl_dataset->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) { + dmu_objset_rele(os, sn); return (EBUSY); } @@ -787,7 +760,7 @@ dsl_sync_task_create(sn->dstg, snapshot_check, snapshot_sync, os, sn, 3); } else { - dmu_objset_close(os); + dmu_objset_rele(os, sn); } return (err); @@ -827,11 +800,11 @@ 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); zil_resume(dmu_objset_zil(os)); - dmu_objset_close(os); + dmu_objset_rele(os, &sn); } if (err) @@ -874,7 +847,7 @@ { blkptr_t *bp = zio->io_bp; blkptr_t *bp_orig = &zio->io_bp_orig; - objset_impl_t *os = arg; + objset_t *os = arg; dnode_phys_t *dnp = &os->os_phys->os_meta_dnode; ASSERT(bp == os->os_rootbp); @@ -903,7 +876,7 @@ /* called from dsl */ void -dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx) +dmu_objset_sync(objset_t *os, zio_t *pio, dmu_tx_t *tx) { int txgoff; zbookmark_t zb; @@ -1008,7 +981,7 @@ } boolean_t -dmu_objset_userused_enabled(objset_impl_t *os) +dmu_objset_userused_enabled(objset_t *os) { return (spa_version(os->os_spa) >= SPA_VERSION_USERSPACE && used_cbs[os->os_phys->os_type] && @@ -1016,7 +989,7 @@ } void -dmu_objset_do_userquota_callbacks(objset_impl_t *os, dmu_tx_t *tx) +dmu_objset_do_userquota_callbacks(objset_t *os, dmu_tx_t *tx) { dnode_t *dn; list_t *list = &os->os_synced_dnodes; @@ -1035,10 +1008,10 @@ /* Allocate the user/groupused objects if necessary. */ if (os->os_userused_dnode->dn_type == DMU_OT_NONE) { - VERIFY(0 == zap_create_claim(&os->os, + VERIFY(0 == zap_create_claim(os, DMU_USERUSED_OBJECT, DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); - VERIFY(0 == zap_create_claim(&os->os, + VERIFY(0 == zap_create_claim(os, DMU_GROUPUSED_OBJECT, DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); } @@ -1065,7 +1038,7 @@ (bcmp(DN_BONUS(dn->dn_oldphys), zerobuf, DN_MAX_BONUSLEN) == 0 && DN_USED_BYTES(dn->dn_oldphys) == 0)); - used_cbs[os->os_phys->os_type](&os->os, bonustype, + used_cbs[os->os_phys->os_type](os, bonustype, DN_BONUS(dn->dn_oldphys), DN_BONUS(dn->dn_phys), DN_USED_BYTES(dn->dn_oldphys), DN_USED_BYTES(dn->dn_phys), tx); @@ -1086,7 +1059,7 @@ boolean_t dmu_objset_userspace_present(objset_t *os) { - return (os->os->os_phys->os_flags & + return (os->os_phys->os_flags & OBJSET_FLAG_USERACCOUNTING_COMPLETE); } @@ -1098,7 +1071,7 @@ if (dmu_objset_userspace_present(os)) return (0); - if (!dmu_objset_userused_enabled(os->os)) + if (!dmu_objset_userused_enabled(os)) return (ENOTSUP); if (dmu_objset_is_snapshot(os)) return (EINVAL); @@ -1134,7 +1107,7 @@ dmu_tx_commit(tx); } - os->os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; + os->os_flags |= OBJSET_FLAG_USERACCOUNTING_COMPLETE; txg_wait_synced(dmu_objset_pool(os), 0); return (0); } @@ -1143,35 +1116,35 @@ dmu_objset_space(objset_t *os, uint64_t *refdbytesp, uint64_t *availbytesp, uint64_t *usedobjsp, uint64_t *availobjsp) { - dsl_dataset_space(os->os->os_dsl_dataset, refdbytesp, availbytesp, + dsl_dataset_space(os->os_dsl_dataset, refdbytesp, availbytesp, usedobjsp, availobjsp); } uint64_t dmu_objset_fsid_guid(objset_t *os) { - return (dsl_dataset_fsid_guid(os->os->os_dsl_dataset)); + return (dsl_dataset_fsid_guid(os->os_dsl_dataset)); } void dmu_objset_fast_stat(objset_t *os, dmu_objset_stats_t *stat) { - stat->dds_type = os->os->os_phys->os_type; - if (os->os->os_dsl_dataset) - dsl_dataset_fast_stat(os->os->os_dsl_dataset, stat); + stat->dds_type = os->os_phys->os_type; + if (os->os_dsl_dataset) + dsl_dataset_fast_stat(os->os_dsl_dataset, stat); } void dmu_objset_stats(objset_t *os, nvlist_t *nv) { - ASSERT(os->os->os_dsl_dataset || - os->os->os_phys->os_type == DMU_OST_META); + ASSERT(os->os_dsl_dataset || + os->os_phys->os_type == DMU_OST_META); - if (os->os->os_dsl_dataset != NULL) - dsl_dataset_stats(os->os->os_dsl_dataset, nv); + if (os->os_dsl_dataset != NULL) + dsl_dataset_stats(os->os_dsl_dataset, nv); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_TYPE, - os->os->os_phys->os_type); + os->os_phys->os_type); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERACCOUNTING, dmu_objset_userspace_present(os)); } @@ -1179,8 +1152,8 @@ int dmu_objset_is_snapshot(objset_t *os) { - if (os->os->os_dsl_dataset != NULL) - return (dsl_dataset_is_snapshot(os->os->os_dsl_dataset)); + if (os->os_dsl_dataset != NULL) + return (dsl_dataset_is_snapshot(os->os_dsl_dataset)); else return (B_FALSE); } @@ -1189,7 +1162,7 @@ dmu_snapshot_realname(objset_t *os, char *name, char *real, int maxlen, boolean_t *conflict) { - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; uint64_t ignored; if (ds->ds_phys->ds_snapnames_zapobj == 0) @@ -1204,7 +1177,7 @@ dmu_snapshot_list_next(objset_t *os, int namelen, char *name, uint64_t *idp, uint64_t *offp, boolean_t *case_conflict) { - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; zap_cursor_t cursor; zap_attribute_t attr; @@ -1241,12 +1214,12 @@ dmu_dir_list_next(objset_t *os, int namelen, char *name, uint64_t *idp, uint64_t *offp) { - dsl_dir_t *dd = os->os->os_dsl_dataset->ds_dir; + dsl_dir_t *dd = os->os_dsl_dataset->ds_dir; zap_cursor_t cursor; zap_attribute_t attr; /* there is no next dir on a snapshot! */ - if (os->os->os_dsl_dataset->ds_object != + if (os->os_dsl_dataset->ds_object != dd->dd_phys->dd_head_dataset_obj) return (ENOENT); @@ -1420,7 +1393,7 @@ if (!BP_IS_HOLE(&ds->ds_phys->ds_bp)) { mutex_enter(&ds->ds_opening_lock); - if (!dsl_dataset_get_user_ptr(ds)) { + if (ds->ds_objset == NULL) { uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH; zbookmark_t zb; @@ -1445,13 +1418,13 @@ void dmu_objset_set_user(objset_t *os, void *user_ptr) { - ASSERT(MUTEX_HELD(&os->os->os_user_ptr_lock)); - os->os->os_user_ptr = user_ptr; + ASSERT(MUTEX_HELD(&os->os_user_ptr_lock)); + os->os_user_ptr = user_ptr; } void * dmu_objset_get_user(objset_t *os) { - ASSERT(MUTEX_HELD(&os->os->os_user_ptr_lock)); - return (os->os->os_user_ptr); + ASSERT(MUTEX_HELD(&os->os_user_ptr_lock)); + return (os->os_user_ptr); }
--- a/usr/src/uts/common/fs/zfs/dmu_send.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu_send.c Wed Aug 12 22:11:31 2009 -0700 @@ -216,8 +216,8 @@ dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin, vnode_t *vp, offset_t *off) { - dsl_dataset_t *ds = tosnap->os->os_dsl_dataset; - dsl_dataset_t *fromds = fromsnap ? fromsnap->os->os_dsl_dataset : NULL; + dsl_dataset_t *ds = tosnap->os_dsl_dataset; + dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL; dmu_replay_record_t *drr; struct backuparg ba; int err; @@ -257,7 +257,7 @@ drr->drr_u.drr_begin.drr_version = DMU_BACKUP_STREAM_VERSION; drr->drr_u.drr_begin.drr_creation_time = ds->ds_phys->ds_creation_time; - drr->drr_u.drr_begin.drr_type = tosnap->os->os_phys->os_type; + drr->drr_u.drr_begin.drr_type = tosnap->os_phys->os_type; if (fromorigin) drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE; drr->drr_u.drr_begin.drr_toguid = ds->ds_phys->ds_guid; @@ -362,7 +362,7 @@ dsobj = dsl_dataset_create_sync(dd, strrchr(rbsa->tofs, '/') + 1, rbsa->origin, flags, cr, tx); VERIFY(0 == dsl_dataset_own_obj(dd->dd_pool, dsobj, - DS_MODE_INCONSISTENT, dmu_recv_tag, &rbsa->ds)); + B_TRUE, dmu_recv_tag, &rbsa->ds)); if (rbsa->origin == NULL) { (void) dmu_objset_create_impl(dd->dd_pool->dp_spa, @@ -431,8 +431,7 @@ /* create and open the temporary clone */ dsobj = dsl_dataset_create_sync(ohds->ds_dir, rbsa->clonelastname, ohds->ds_prev, flags, cr, tx); - VERIFY(0 == dsl_dataset_own_obj(dp, dsobj, - DS_MODE_INCONSISTENT, dmu_recv_tag, &cds)); + VERIFY(0 == dsl_dataset_own_obj(dp, dsobj, B_TRUE, dmu_recv_tag, &cds)); /* * If we actually created a non-clone, we need to create the @@ -477,7 +476,7 @@ rbsa.tofs = tofs; rbsa.tosnap = tosnap; - rbsa.origin = origin ? origin->os->os_dsl_dataset : NULL; + rbsa.origin = origin ? origin->os_dsl_dataset : NULL; rbsa.fromguid = drrb->drr_fromguid; rbsa.type = drrb->drr_type; rbsa.tag = FTAG; @@ -880,7 +879,7 @@ /* * Open the objset we are modifying. */ - VERIFY(dmu_objset_open_ds(drc->drc_real_ds, DMU_OST_ANY, &os) == 0); + VERIFY(dmu_objset_from_ds(drc->drc_real_ds, &os) == 0); ASSERT(drc->drc_real_ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT); @@ -950,8 +949,6 @@ ASSERT(ra.err != 0); out: - dmu_objset_close(os); - if (ra.err != 0) { /* * destroy what we created, so we don't leave it in the
--- a/usr/src/uts/common/fs/zfs/dmu_tx.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dmu_tx.c Wed Aug 12 22:11:31 2009 -0700 @@ -58,9 +58,9 @@ dmu_tx_t * dmu_tx_create(objset_t *os) { - dmu_tx_t *tx = dmu_tx_create_dd(os->os->os_dsl_dataset->ds_dir); + dmu_tx_t *tx = dmu_tx_create_dd(os->os_dsl_dataset->ds_dir); tx->tx_objset = os; - tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os->os_dsl_dataset); + tx->tx_lastsnap_txg = dsl_dataset_prev_snap_txg(os->os_dsl_dataset); return (tx); } @@ -98,7 +98,7 @@ int err; if (object != DMU_NEW_OBJECT) { - err = dnode_hold(os->os, object, tx, &dn); + err = dnode_hold(os, object, tx, &dn); if (err) { tx->tx_err = err; return (NULL); @@ -376,7 +376,7 @@ dmu_tx_count_dnode(dmu_tx_hold_t *txh) { dnode_t *dn = txh->txh_dnode; - dnode_t *mdn = txh->txh_tx->tx_objset->os->os_meta_dnode; + dnode_t *mdn = txh->txh_tx->tx_objset->os_meta_dnode; uint64_t space = mdn->dn_datablksz + ((mdn->dn_nlevels-1) << mdn->dn_indblkshift); @@ -688,7 +688,7 @@ * access the name in this fat-zap so that we'll check * for i/o errors to the leaf blocks, etc. */ - err = zap_lookup(&dn->dn_objset->os, dn->dn_object, name, + err = zap_lookup(dn->dn_objset, dn->dn_object, name, 8, 0, NULL); if (err == EIO) { tx->tx_err = err; @@ -696,7 +696,7 @@ } } - err = zap_count_write(&dn->dn_objset->os, dn->dn_object, name, add, + err = zap_count_write(dn->dn_objset, dn->dn_object, name, add, &txh->txh_space_towrite, &txh->txh_space_tooverwrite); /* @@ -771,7 +771,7 @@ dnode_t *dn = db->db_dnode; ASSERT(tx->tx_txg != 0); - ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset->os); + ASSERT(tx->tx_objset == NULL || dn->dn_objset == tx->tx_objset); ASSERT3U(dn->dn_object, ==, db->db.db_object); if (tx->tx_anyobj) @@ -931,7 +931,7 @@ * assume that we won't be able to free or overwrite anything. */ if (tx->tx_objset && - dsl_dataset_prev_snap_txg(tx->tx_objset->os->os_dsl_dataset) > + dsl_dataset_prev_snap_txg(tx->tx_objset->os_dsl_dataset) > tx->tx_lastsnap_txg) { towrite += tooverwrite; tooverwrite = tofree = 0;
--- a/usr/src/uts/common/fs/zfs/dnode.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dnode.c Wed Aug 12 22:11:31 2009 -0700 @@ -272,7 +272,7 @@ } static dnode_t * -dnode_create(objset_impl_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db, +dnode_create(objset_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db, uint64_t object) { dnode_t *dn = kmem_cache_alloc(dnode_cache, KM_SLEEP); @@ -309,7 +309,7 @@ static void dnode_destroy(dnode_t *dn) { - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; #ifdef ZFS_DEBUG int i; @@ -488,7 +488,7 @@ } dnode_t * -dnode_special_open(objset_impl_t *os, dnode_phys_t *dnp, uint64_t object) +dnode_special_open(objset_t *os, dnode_phys_t *dnp, uint64_t object) { dnode_t *dn = dnode_create(os, dnp, NULL, object); DNODE_VERIFY(dn); @@ -535,7 +535,7 @@ * succeeds even for free dnodes. */ int -dnode_hold_impl(objset_impl_t *os, uint64_t object, int flag, +dnode_hold_impl(objset_t *os, uint64_t object, int flag, void *tag, dnode_t **dnp) { int epb, idx, err; @@ -650,7 +650,7 @@ * Return held dnode if the object is allocated, NULL if not. */ int -dnode_hold(objset_impl_t *os, uint64_t object, void *tag, dnode_t **dnp) +dnode_hold(objset_t *os, uint64_t object, void *tag, dnode_t **dnp) { return (dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED, tag, dnp)); } @@ -689,7 +689,7 @@ void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx) { - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; uint64_t txg = tx->tx_txg; if (DMU_OBJECT_IS_SPECIAL(dn->dn_object)) { @@ -1248,7 +1248,7 @@ void dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx) { - objset_impl_t *os = dn->dn_objset; + objset_t *os = dn->dn_objset; dsl_dataset_t *ds = os->os_dsl_dataset; if (space > 0)
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Aug 12 22:11:31 2009 -0700 @@ -244,8 +244,8 @@ unique_remove(ds->ds_fsid_guid); - if (ds->ds_user_ptr != NULL) - ds->ds_user_evict_func(ds, ds->ds_user_ptr); + if (ds->ds_objset != NULL) + dmu_objset_evict(ds->ds_objset); if (ds->ds_prev) { dsl_dataset_drop_ref(ds->ds_prev, ds); @@ -545,17 +545,14 @@ } int -dsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj, int flags, void *owner, - dsl_dataset_t **dsp) +dsl_dataset_own_obj(dsl_pool_t *dp, uint64_t dsobj, boolean_t inconsistentok, + void *tag, dsl_dataset_t **dsp) { - int err = dsl_dataset_hold_obj(dp, dsobj, owner, dsp); - - ASSERT(DS_MODE_TYPE(flags) != DS_MODE_USER); - + int err = dsl_dataset_hold_obj(dp, dsobj, tag, dsp); if (err) return (err); - if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { - dsl_dataset_rele(*dsp, owner); + if (!dsl_dataset_tryown(*dsp, inconsistentok, tag)) { + dsl_dataset_rele(*dsp, tag); *dsp = NULL; return (EBUSY); } @@ -622,18 +619,14 @@ } int -dsl_dataset_own(const char *name, int flags, void *owner, dsl_dataset_t **dsp) +dsl_dataset_own(const char *name, boolean_t inconsistentok, + void *tag, dsl_dataset_t **dsp) { - int err = dsl_dataset_hold(name, owner, dsp); + int err = dsl_dataset_hold(name, tag, dsp); if (err) return (err); - if ((*dsp)->ds_phys->ds_num_children > 0 && - !DS_MODE_IS_READONLY(flags)) { - dsl_dataset_rele(*dsp, owner); - return (EROFS); - } - if (!dsl_dataset_tryown(*dsp, DS_MODE_IS_INCONSISTENT(flags), owner)) { - dsl_dataset_rele(*dsp, owner); + if (!dsl_dataset_tryown(*dsp, inconsistentok, tag)) { + dsl_dataset_rele(*dsp, tag); return (EBUSY); } return (0); @@ -705,9 +698,9 @@ } void -dsl_dataset_disown(dsl_dataset_t *ds, void *owner) +dsl_dataset_disown(dsl_dataset_t *ds, void *tag) { - ASSERT((ds->ds_owner == owner && ds->ds_dbuf) || + ASSERT((ds->ds_owner == tag && ds->ds_dbuf) || (DSL_DATASET_IS_DESTROYED(ds) && ds->ds_dbuf == NULL)); mutex_enter(&ds->ds_lock); @@ -718,20 +711,20 @@ } mutex_exit(&ds->ds_lock); if (ds->ds_dbuf) - dsl_dataset_drop_ref(ds, owner); + dsl_dataset_drop_ref(ds, tag); else dsl_dataset_evict(ds->ds_dbuf, ds); } boolean_t -dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, void *owner) +dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, void *tag) { boolean_t gotit = FALSE; mutex_enter(&ds->ds_lock); if (ds->ds_owner == NULL && (!DS_IS_INCONSISTENT(ds) || inconsistentok)) { - ds->ds_owner = owner; + ds->ds_owner = tag; if (!dsl_pool_sync_context(ds->ds_dir->dd_pool)) rw_exit(&ds->ds_rwlock); gotit = TRUE; @@ -865,16 +858,15 @@ char *dsname; dsname = kmem_asprintf("%s@%s", name, da->snapname); - err = dsl_dataset_own(dsname, DS_MODE_READONLY | DS_MODE_INCONSISTENT, - da->dstg, &ds); + err = dsl_dataset_own(dsname, B_TRUE, da->dstg, &ds); strfree(dsname); if (err == 0) { struct dsl_ds_destroyarg *dsda; dsl_dataset_make_exclusive(ds, da->dstg); - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; + if (ds->ds_objset != NULL) { + dmu_objset_evict(ds->ds_objset); + ds->ds_objset = NULL; } dsda = kmem_zalloc(sizeof (struct dsl_ds_destroyarg), KM_SLEEP); dsda->ds = ds; @@ -958,13 +950,12 @@ int error; objset_t *os; - error = dmu_objset_open_ds(ds, DMU_OST_ANY, &os); + error = dmu_objset_from_ds(ds, &os); if (error) return (error); if (dmu_objset_type(os) == DMU_OST_ZVOL) error = zvol_remove_minor(name); - dmu_objset_close(os); return (error); } @@ -1003,9 +994,7 @@ return (error); } #endif - error = dsl_dataset_own(name, - DS_MODE_READONLY | DS_MODE_INCONSISTENT, - tag, &origin); + error = dsl_dataset_own(name, B_TRUE, tag, &origin); kmem_free(name, namelen); if (error) return (error); @@ -1036,9 +1025,9 @@ /* Destroying a snapshot is simpler */ dsl_dataset_make_exclusive(ds, tag); - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; + if (ds->ds_objset != NULL) { + dmu_objset_evict(ds->ds_objset); + ds->ds_objset = NULL; } /* NOTE: defer is always B_FALSE for non-snapshots */ dsda.defer = defer; @@ -1060,7 +1049,7 @@ if (err) goto out; - err = dmu_objset_open_ds(ds, DMU_OST_ANY, &os); + err = dmu_objset_from_ds(ds, &os); if (err) goto out; @@ -1089,7 +1078,7 @@ * context, the user space accounting should be zero. */ if (ds->ds_phys->ds_bp.blk_fill == 0 && - dmu_objset_userused_enabled(os->os)) { + dmu_objset_userused_enabled(os)) { uint64_t count; ASSERT(zap_count(os, DMU_USERUSED_OBJECT, &count) != 0 || @@ -1098,7 +1087,6 @@ count == 0); } - dmu_objset_close(os); if (err != ESRCH) goto out; @@ -1109,7 +1097,7 @@ if (err) goto out; - if (ds->ds_user_ptr) { + if (ds->ds_objset) { /* * We need to sync out all in-flight IO before we try * to evict (the dataset evict func is trying to clear @@ -1122,9 +1110,9 @@ * Blow away the dsl_dir + head dataset. */ dsl_dataset_make_exclusive(ds, tag); - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; + if (ds->ds_objset) { + dmu_objset_evict(ds->ds_objset); + ds->ds_objset = NULL; } /* @@ -1173,28 +1161,6 @@ return (err); } -void * -dsl_dataset_set_user_ptr(dsl_dataset_t *ds, - void *p, dsl_dataset_evict_func_t func) -{ - void *old; - - mutex_enter(&ds->ds_lock); - old = ds->ds_user_ptr; - if (old == NULL) { - ds->ds_user_ptr = p; - ds->ds_user_evict_func = func; - } - mutex_exit(&ds->ds_lock); - return (old); -} - -void * -dsl_dataset_get_user_ptr(dsl_dataset_t *ds) -{ - return (ds->ds_user_ptr); -} - blkptr_t * dsl_dataset_get_blkptr(dsl_dataset_t *ds) { @@ -1228,7 +1194,7 @@ if (ds == NULL) /* this is the meta-objset */ return; - ASSERT(ds->ds_user_ptr != NULL); + ASSERT(ds->ds_objset != NULL); if (ds->ds_phys->ds_next_snap_obj != 0) panic("dirtying snapshot!"); @@ -1820,12 +1786,12 @@ struct dsl_ds_destroyarg ndsda = {0}; ASSERT3P(origin, ==, dsda->rm_origin); - if (origin->ds_user_ptr) { - origin->ds_user_evict_func(origin, origin->ds_user_ptr); - origin->ds_user_ptr = NULL; + if (origin->ds_objset) { + dmu_objset_evict(origin->ds_objset); + origin->ds_objset = NULL; } - dsl_dataset_rele(origin, ds); + dsl_dataset_rele(ds->ds_prev, ds); ds->ds_prev = NULL; ndsda.ds = origin; @@ -2010,7 +1976,7 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) { ASSERT(dmu_tx_is_syncing(tx)); - ASSERT(ds->ds_user_ptr != NULL); + ASSERT(ds->ds_objset != NULL); ASSERT(ds->ds_phys->ds_next_snap_obj == 0); /* @@ -2021,7 +1987,7 @@ ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid; dsl_dir_dirty(ds->ds_dir, tx); - dmu_objset_sync(ds->ds_user_ptr, zio, tx); + dmu_objset_sync(ds->ds_objset, zio, tx); } void @@ -2577,9 +2543,9 @@ dsl_dataset_t *ds = snap->ds; /* unregister props as dsl_dir is changing */ - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; + if (ds->ds_objset) { + dmu_objset_evict(ds->ds_objset); + ds->ds_objset = NULL; } /* move snap name entry */ VERIFY(0 == dsl_dataset_get_snapname(ds)); @@ -2879,15 +2845,14 @@ dmu_buf_will_dirty(csa->cds->ds_dbuf, tx); dmu_buf_will_dirty(csa->ohds->ds_dbuf, tx); - if (csa->cds->ds_user_ptr != NULL) { - csa->cds->ds_user_evict_func(csa->cds, csa->cds->ds_user_ptr); - csa->cds->ds_user_ptr = NULL; + if (csa->cds->ds_objset != NULL) { + dmu_objset_evict(csa->cds->ds_objset); + csa->cds->ds_objset = NULL; } - if (csa->ohds->ds_user_ptr != NULL) { - csa->ohds->ds_user_evict_func(csa->ohds, - csa->ohds->ds_user_ptr); - csa->ohds->ds_user_ptr = NULL; + if (csa->ohds->ds_objset != NULL) { + dmu_objset_evict(csa->ohds->ds_objset); + csa->ohds->ds_objset = NULL; } /* @@ -3463,9 +3428,9 @@ */ if (!ra->own) return (EBUSY); - if (ds->ds_user_ptr) { - ds->ds_user_evict_func(ds, ds->ds_user_ptr); - ds->ds_user_ptr = NULL; + if (ds->ds_objset) { + dmu_objset_evict(ds->ds_objset); + ds->ds_objset = NULL; } } dsda.ds = ds; @@ -3557,8 +3522,7 @@ return (error); } #endif - if (!dsl_dataset_tryown(ds, - DS_MODE_READONLY | DS_MODE_INCONSISTENT, dtag)) { + if (!dsl_dataset_tryown(ds, B_TRUE, dtag)) { dsl_dataset_rele(ds, dtag); return (EBUSY); } else { @@ -3666,3 +3630,24 @@ dsl_dataset_rele(ds, FTAG); return (0); } + +/* + * Note, this fuction is used as the callback for dmu_objset_find(). We + * always return 0 so that we will continue to find and process + * inconsistent datasets, even if we encounter an error trying to + * process one of them. + */ +/* ARGSUSED */ +int +dsl_destroy_inconsistent(char *dsname, void *arg) +{ + dsl_dataset_t *ds; + + if (dsl_dataset_own(dsname, B_TRUE, FTAG, &ds) == 0) { + if (DS_IS_INCONSISTENT(ds)) + (void) dsl_dataset_destroy(ds, FTAG, B_FALSE); + else + dsl_dataset_disown(ds, FTAG); + } + return (0); +}
--- a/usr/src/uts/common/fs/zfs/dsl_deleg.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_deleg.c Wed Aug 12 22:11:31 2009 -0700 @@ -739,5 +739,5 @@ boolean_t dsl_delegation_on(objset_t *os) { - return (os->os->os_spa->spa_delegation); + return (os->os_spa->spa_delegation); }
--- a/usr/src/uts/common/fs/zfs/dsl_dir.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_dir.c Wed Aug 12 22:11:31 2009 -0700 @@ -703,7 +703,7 @@ */ if (first && tx->tx_objset) { int error; - dsl_dataset_t *ds = tx->tx_objset->os->os_dsl_dataset; + dsl_dataset_t *ds = tx->tx_objset->os_dsl_dataset; error = dsl_dataset_check_quota(ds, checkrefquota, asize, est_inflight, &used_on_disk, &ref_rsrv);
--- a/usr/src/uts/common/fs/zfs/dsl_pool.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c Wed Aug 12 22:11:31 2009 -0700 @@ -103,13 +103,12 @@ dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); dsl_dir_t *dd; dsl_dataset_t *ds; - objset_impl_t *osi; rw_enter(&dp->dp_config_rwlock, RW_WRITER); - err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp, &osi); + err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp, + &dp->dp_meta_objset); if (err) goto out; - dp->dp_meta_objset = &osi->os; err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1, @@ -219,7 +218,7 @@ /* undo the dmu_objset_open_impl(mos) from dsl_pool_open() */ if (dp->dp_meta_objset) - dmu_objset_evict(NULL, dp->dp_meta_objset->os); + dmu_objset_evict(dp->dp_meta_objset); txg_list_destroy(&dp->dp_dirty_datasets); txg_list_destroy(&dp->dp_dirty_dirs); @@ -242,13 +241,13 @@ int err; dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg); - objset_impl_t *osip; + objset_t *os; dsl_dataset_t *ds; uint64_t dsobj; /* create and open the MOS (meta-objset) */ - dp->dp_meta_objset = &dmu_objset_create_impl(spa, - NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx)->os; + dp->dp_meta_objset = dmu_objset_create_impl(spa, + NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx); /* create the pool directory */ err = zap_create_claim(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, @@ -273,10 +272,10 @@ /* create the root objset */ VERIFY(0 == dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds)); - osip = dmu_objset_create_impl(dp->dp_spa, ds, + os = dmu_objset_create_impl(dp->dp_spa, ds, dsl_dataset_get_blkptr(ds), DMU_OST_ZFS, tx); #ifdef _KERNEL - zfs_create_fs(&osip->os, kcred, zplprops, tx); + zfs_create_fs(os, kcred, zplprops, tx); #endif dsl_dataset_rele(ds, FTAG); @@ -293,7 +292,7 @@ dsl_dir_t *dd; dsl_dataset_t *ds; dsl_sync_task_group_t *dstg; - objset_impl_t *mosi = dp->dp_meta_objset->os; + objset_t *mos = dp->dp_meta_objset; hrtime_t start, write_time; uint64_t data_written; int err; @@ -323,7 +322,7 @@ for (ds = list_head(&dp->dp_synced_datasets); ds; ds = list_next(&dp->dp_synced_datasets, ds)) - dmu_objset_do_userquota_callbacks(ds->ds_user_ptr, tx); + dmu_objset_do_userquota_callbacks(ds->ds_objset, tx); /* * Sync the datasets again to push out the changes due to @@ -358,10 +357,10 @@ dsl_pool_scrub_sync(dp, tx); start = gethrtime(); - if (list_head(&mosi->os_dirty_dnodes[txg & TXG_MASK]) != NULL || - list_head(&mosi->os_free_dnodes[txg & TXG_MASK]) != NULL) { + if (list_head(&mos->os_dirty_dnodes[txg & TXG_MASK]) != NULL || + list_head(&mos->os_free_dnodes[txg & TXG_MASK]) != NULL) { zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); - dmu_objset_sync(mosi, zio, tx); + dmu_objset_sync(mos, zio, tx); err = zio_wait(zio); ASSERT(err == 0); dprintf_bp(&dp->dp_meta_rootbp, "meta objset rootbp is %s", ""); @@ -421,8 +420,8 @@ while (ds = list_head(&dp->dp_synced_datasets)) { list_remove(&dp->dp_synced_datasets, ds); - ASSERT(ds->ds_user_ptr != NULL); - zil_clean(((objset_impl_t *)ds->ds_user_ptr)->os_zil); + ASSERT(ds->ds_objset != NULL); + zil_clean(ds->ds_objset->os_zil); dmu_buf_rele(ds->ds_dbuf, ds); } }
--- a/usr/src/uts/common/fs/zfs/dsl_prop.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_prop.c Wed Aug 12 22:11:31 2009 -0700 @@ -552,7 +552,7 @@ int dsl_prop_get_all(objset_t *os, nvlist_t **nvp, boolean_t local) { - dsl_dataset_t *ds = os->os->os_dsl_dataset; + dsl_dataset_t *ds = os->os_dsl_dataset; dsl_dir_t *dd = ds->ds_dir; boolean_t snapshot = dsl_dataset_is_snapshot(ds); int err = 0;
--- a/usr/src/uts/common/fs/zfs/spa.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/spa.c Wed Aug 12 22:11:31 2009 -0700 @@ -371,12 +371,14 @@ break; } - if (error = dmu_objset_open(strval, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &os)) + if (error = dmu_objset_hold(strval, FTAG, &os)) break; - /* We don't support gzip bootable datasets */ - if ((error = dsl_prop_get_integer(strval, + /* Must be ZPL and not gzip compressed. */ + + if (dmu_objset_type(os) != DMU_OST_ZFS) { + error = ENOTSUP; + } else if ((error = dsl_prop_get_integer(strval, zfs_prop_to_name(ZFS_PROP_COMPRESSION), &compress, NULL)) == 0 && !BOOTFS_COMPRESS_VALID(compress)) { @@ -384,7 +386,7 @@ } else { objnum = dmu_objset_id(os); } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); } break; @@ -1598,6 +1600,12 @@ */ if (vdev_resilver_needed(rvd, NULL, NULL)) spa_async_request(spa, SPA_ASYNC_RESILVER); + + /* + * Delete any inconsistent datasets. + */ + (void) dmu_objset_find(spa_name(spa), + dsl_destroy_inconsistent, NULL, DS_FIND_CHILDREN); } error = 0;
--- a/usr/src/uts/common/fs/zfs/sys/dbuf.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dbuf.h Wed Aug 12 22:11:31 2009 -0700 @@ -75,7 +75,6 @@ DB_EVICTING } dbuf_states_t; -struct objset_impl; struct dnode; struct dmu_tx; @@ -148,7 +147,7 @@ dmu_buf_t db; /* the objset we belong to */ - struct objset_impl *db_objset; + struct objset *db_objset; /* * the dnode we belong to (NULL when evicted)
--- a/usr/src/uts/common/fs/zfs/sys/dmu.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dmu.h Wed Aug 12 22:11:31 2009 -0700 @@ -59,7 +59,6 @@ struct zbookmark; struct spa; struct nvlist; -struct objset_impl; struct arc_buf; typedef struct objset objset_t; @@ -140,16 +139,6 @@ void zfs_acl_byteswap(void *buf, size_t size); void zfs_znode_byteswap(void *buf, size_t size); -#define DS_MODE_NOHOLD 0 /* internal use only */ -#define DS_MODE_USER 1 /* simple access, no special needs */ -#define DS_MODE_OWNER 2 /* the "main" access, e.g. a mount */ -#define DS_MODE_TYPE_MASK 0x3 -#define DS_MODE_TYPE(x) ((x) & DS_MODE_TYPE_MASK) -#define DS_MODE_READONLY 0x8 -#define DS_MODE_IS_READONLY(x) ((x) & DS_MODE_READONLY) -#define DS_MODE_INCONSISTENT 0x10 -#define DS_MODE_IS_INCONSISTENT(x) ((x) & DS_MODE_INCONSISTENT) - #define DS_FIND_SNAPSHOTS (1<<0) #define DS_FIND_CHILDREN (1<<1) @@ -166,11 +155,13 @@ /* * Public routines to create, destroy, open, and close objsets. */ -int dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, - objset_t **osp); -int dmu_objset_open_ds(struct dsl_dataset *ds, dmu_objset_type_t type, - objset_t **osp); -void dmu_objset_close(objset_t *os); +int dmu_objset_hold(const char *name, void *tag, objset_t **osp); +int dmu_objset_own(const char *name, dmu_objset_type_t type, + boolean_t readonly, void *tag, objset_t **osp); +void dmu_objset_rele(objset_t *os, void *tag); +void dmu_objset_disown(objset_t *os, void *tag); +int dmu_objset_open_ds(struct dsl_dataset *ds, objset_t **osp); + int dmu_objset_evict_dbufs(objset_t *os); int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags, void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg); @@ -309,7 +300,7 @@ * Decide how many copies of a given block we should make. Can be from * 1 to SPA_DVAS_PER_BP. */ -int dmu_get_replication_level(struct objset_impl *, struct zbookmark *zb, +int dmu_get_replication_level(objset_t *os, struct zbookmark *zb, dmu_object_type_t ot); /* * The bonus data is accessed more or less like a regular buffer.
--- a/usr/src/uts/common/fs/zfs/sys/dmu_impl.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dmu_impl.h Wed Aug 12 22:11:31 2009 -0700 @@ -210,8 +210,7 @@ * * ds_lock * protects: - * ds_user_ptr - * ds_user_evict_func + * ds_objset * ds_open_refcount * ds_snapname * ds_phys accounting
--- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Wed Aug 12 22:11:31 2009 -0700 @@ -40,7 +40,6 @@ struct dsl_dataset; struct dmu_tx; -struct objset_impl; #define OBJSET_PHYS_SIZE 2048 #define OBJSET_OLD_PHYS_SIZE 1024 @@ -59,11 +58,6 @@ } objset_phys_t; struct objset { - struct objset_impl *os; - int os_mode; -}; - -typedef struct objset_impl { /* Immutable: */ struct dsl_dataset *os_dsl_dataset; spa_t *os_spa; @@ -73,7 +67,6 @@ dnode_t *os_userused_dnode; dnode_t *os_groupused_dnode; zilog_t *os_zil; - objset_t os; uint8_t os_checksum; /* can change, under dsl_dir's locks */ uint8_t os_compress; /* can change, under dsl_dir's locks */ uint8_t os_copies; /* can change, under dsl_dir's locks */ @@ -101,7 +94,7 @@ /* stuff we store for the user */ kmutex_t os_user_ptr_lock; void *os_user_ptr; -} objset_impl_t; +}; #define DMU_META_DNODE_OBJECT 0 #define DMU_OBJECT_IS_SPECIAL(obj) ((int64_t)(obj) <= 0) @@ -111,9 +104,13 @@ (os)->os_secondary_cache == ZFS_CACHE_METADATA) /* called from zpl */ -int dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, - objset_t **osp); -void dmu_objset_close(objset_t *os); +int dmu_objset_hold(const char *name, void *tag, objset_t **osp); +int dmu_objset_own(const char *name, dmu_objset_type_t type, + boolean_t readonly, void *tag, objset_t **osp); +void dmu_objset_rele(objset_t *os, void *tag); +void dmu_objset_disown(objset_t *os, void *tag); +int dmu_objset_from_ds(struct dsl_dataset *ds, objset_t **osp); + int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags, void (*func)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx), void *arg); int dmu_objset_clone(const char *name, struct dsl_dataset *clone_origin, @@ -135,14 +132,14 @@ int dmu_objset_evict_dbufs(objset_t *os); /* called from dsl */ -void dmu_objset_sync(objset_impl_t *os, zio_t *zio, dmu_tx_t *tx); -objset_impl_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds, +void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx); +objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx); int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp, - objset_impl_t **osip); -void dmu_objset_evict(struct dsl_dataset *ds, void *arg); -void dmu_objset_do_userquota_callbacks(objset_impl_t *os, dmu_tx_t *tx); -boolean_t dmu_objset_userused_enabled(objset_impl_t *os); + objset_t **osp); +void dmu_objset_evict(objset_t *os); +void dmu_objset_do_userquota_callbacks(objset_t *os, dmu_tx_t *tx); +boolean_t dmu_objset_userused_enabled(objset_t *os); int dmu_objset_userspace_upgrade(objset_t *os); boolean_t dmu_objset_userspace_present(objset_t *os);
--- a/usr/src/uts/common/fs/zfs/sys/dnode.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dnode.h Wed Aug 12 22:11:31 2009 -0700 @@ -88,7 +88,7 @@ #define EPB(blkshift, typeshift) (1 << (blkshift - typeshift)) struct dmu_buf_impl; -struct objset_impl; +struct objset; struct zio; enum dnode_dirtycontext { @@ -136,7 +136,7 @@ list_node_t dn_link; /* immutable: */ - struct objset_impl *dn_objset; + struct objset *dn_objset; uint64_t dn_object; struct dmu_buf_impl *dn_dbuf; dnode_phys_t *dn_phys; /* pointer into dn->dn_dbuf->db.db_data */ @@ -202,14 +202,14 @@ uint64_t fr_nblks; } free_range_t; -dnode_t *dnode_special_open(struct objset_impl *dd, dnode_phys_t *dnp, +dnode_t *dnode_special_open(struct objset *dd, dnode_phys_t *dnp, uint64_t object); void dnode_special_close(dnode_t *dn); void dnode_setbonuslen(dnode_t *dn, int newsize, dmu_tx_t *tx); -int dnode_hold(struct objset_impl *dd, uint64_t object, +int dnode_hold(struct objset *dd, uint64_t object, void *ref, dnode_t **dnp); -int dnode_hold_impl(struct objset_impl *dd, uint64_t object, int flag, +int dnode_hold_impl(struct objset *dd, uint64_t object, int flag, void *ref, dnode_t **dnp); boolean_t dnode_add_ref(dnode_t *dn, void *ref); void dnode_rele(dnode_t *dn, void *ref);
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h Wed Aug 12 22:11:31 2009 -0700 @@ -42,8 +42,6 @@ struct dsl_dir; struct dsl_pool; -typedef void dsl_dataset_evict_func_t(struct dsl_dataset *, void *); - #define DS_FLAG_INCONSISTENT (1ULL<<0) #define DS_IS_INCONSISTENT(ds) \ ((ds)->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) @@ -132,8 +130,7 @@ * Protected by ds_lock: */ kmutex_t ds_lock; - void *ds_user_ptr; - dsl_dataset_evict_func_t *ds_user_evict_func; + objset_t *ds_objset; uint64_t ds_userrefs; /* @@ -174,17 +171,17 @@ int dsl_dataset_hold(const char *name, void *tag, dsl_dataset_t **dsp); int dsl_dataset_hold_obj(struct dsl_pool *dp, uint64_t dsobj, void *tag, dsl_dataset_t **); -int dsl_dataset_own(const char *name, int flags, void *owner, - dsl_dataset_t **dsp); +int dsl_dataset_own(const char *name, boolean_t inconsistentok, + void *tag, dsl_dataset_t **dsp); int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj, - int flags, void *owner, dsl_dataset_t **); + boolean_t inconsistentok, void *tag, dsl_dataset_t **dsp); void dsl_dataset_name(dsl_dataset_t *ds, char *name); void dsl_dataset_rele(dsl_dataset_t *ds, void *tag); -void dsl_dataset_disown(dsl_dataset_t *ds, void *owner); +void dsl_dataset_disown(dsl_dataset_t *ds, void *tag); void dsl_dataset_drop_ref(dsl_dataset_t *ds, void *tag); boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, boolean_t inconsistentok, - void *owner); -void dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *owner); + void *tag); +void dsl_dataset_make_exclusive(dsl_dataset_t *ds, void *tag); uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname, dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *); uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, @@ -205,10 +202,6 @@ boolean_t recursive); int dsl_dataset_get_holds(const char *dsname, nvlist_t **nvp); -void *dsl_dataset_set_user_ptr(dsl_dataset_t *ds, - void *p, dsl_dataset_evict_func_t func); -void *dsl_dataset_get_user_ptr(dsl_dataset_t *ds); - blkptr_t *dsl_dataset_get_blkptr(dsl_dataset_t *ds); void dsl_dataset_set_blkptr(dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx); @@ -245,6 +238,8 @@ int64_t dsl_dataset_new_refreservation(dsl_dataset_t *ds, uint64_t reservation, dmu_tx_t *tx); +int dsl_destroy_inconsistent(char *dsname, void *arg); + #ifdef ZFS_DEBUG #define dprintf_ds(ds, fmt, ...) do { \ if (zfs_flags & ZFS_DEBUG_DPRINTF) { \
--- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h Wed Aug 12 22:11:31 2009 -0700 @@ -132,8 +132,8 @@ extern uint_t zfs_fsyncer_key; -extern int zfs_suspend_fs(zfsvfs_t *zfsvfs, char *osname, int *mode); -extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname, int mode); +extern int zfs_suspend_fs(zfsvfs_t *zfsvfs); +extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname); extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, const char *domain, uint64_t rid, uint64_t *valuep); extern int zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, @@ -143,7 +143,7 @@ extern boolean_t zfs_usergroup_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid); extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers); -extern int zfsvfs_create(const char *name, int mode, zfsvfs_t **zvp); +extern int zfsvfs_create(const char *name, zfsvfs_t **zvp); extern void zfsvfs_free(zfsvfs_t *zfsvfs); #ifdef __cplusplus
--- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c Wed Aug 12 22:11:31 2009 -0700 @@ -853,8 +853,7 @@ */ return (err == EILSEQ ? ENOENT : err); } - if (dmu_objset_open(snapname, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &snap) != 0) { + if (dmu_objset_hold(snapname, FTAG, &snap) != 0) { mutex_exit(&sdp->sd_lock); ZFS_EXIT(zfsvfs); return (ENOENT); @@ -866,7 +865,7 @@ *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap)); avl_insert(&sdp->sd_snaps, sep, where); - dmu_objset_close(snap); + dmu_objset_rele(snap, FTAG); domount: mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) + strlen("/.zfs/snapshot/") + strlen(nm) + 1;
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c Wed Aug 12 22:11:31 2009 -0700 @@ -175,22 +175,15 @@ static boolean_t zfs_is_bootfs(const char *name) { - spa_t *spa; - boolean_t ret = B_FALSE; - - if (spa_open(name, &spa, FTAG) == 0) { - if (spa->spa_bootfs) { - objset_t *os; - - if (dmu_objset_open(name, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { - ret = (dmu_objset_id(os) == spa->spa_bootfs); - dmu_objset_close(os); - } - } - spa_close(spa, FTAG); + objset_t *os; + + if (dmu_objset_hold(name, FTAG, &os) == 0) { + boolean_t ret; + ret = (dmu_objset_id(os) == dmu_objset_spa(os)->spa_bootfs); + dmu_objset_rele(os, FTAG); + return (ret); } - return (ret); + return (B_FALSE); } /* @@ -224,13 +217,17 @@ objset_t *os; boolean_t rc = B_TRUE; - if (dmu_objset_open(name, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + if (dmu_objset_hold(name, FTAG, &os) == 0) { uint64_t zplversion; + if (dmu_objset_type(os) != DMU_OST_ZFS) { + dmu_objset_rele(os, FTAG); + return (B_TRUE); + } + /* XXX reading from non-owned objset */ if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0) rc = zplversion < version; - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); } return (rc); } @@ -548,20 +545,19 @@ if (error) return (error); - error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &clone); + error = dmu_objset_hold(zc->zc_name, FTAG, &clone); if (error == 0) { dsl_dataset_t *pclone = NULL; dsl_dir_t *dd; - dd = clone->os->os_dsl_dataset->ds_dir; + dd = clone->os_dsl_dataset->ds_dir; rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); error = dsl_dataset_hold_obj(dd->dd_pool, dd->dd_phys->dd_origin_obj, FTAG, &pclone); rw_exit(&dd->dd_pool->dp_config_rwlock); if (error) { - dmu_objset_close(clone); + dmu_objset_rele(clone, FTAG); return (error); } @@ -569,7 +565,7 @@ ZFS_DELEG_PERM_MOUNT, cr); dsl_dataset_name(pclone, parentname); - dmu_objset_close(clone); + dmu_objset_rele(clone, FTAG); dsl_dataset_rele(pclone, FTAG); if (error == 0) error = zfs_secpolicy_write_perms(parentname, @@ -840,20 +836,23 @@ objset_t *os; int error; - error = dmu_objset_open(dsname, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &os); + error = dmu_objset_hold(dsname, FTAG, &os); if (error) return (error); - - mutex_enter(&os->os->os_user_ptr_lock); + if (dmu_objset_type(os) != DMU_OST_ZFS) { + dmu_objset_rele(os, FTAG); + return (EINVAL); + } + + mutex_enter(&os->os_user_ptr_lock); *zvp = dmu_objset_get_user(os); if (*zvp) { VFS_HOLD((*zvp)->z_vfs); } else { error = ESRCH; } - mutex_exit(&os->os->os_user_ptr_lock); - dmu_objset_close(os); + mutex_exit(&os->os_user_ptr_lock); + dmu_objset_rele(os, FTAG); return (error); } @@ -862,13 +861,12 @@ * case its z_vfs will be NULL, and it will be opened as the owner. */ static int -zfsvfs_hold(const char *name, boolean_t readonly, void *tag, zfsvfs_t **zvp) +zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zvp) { int error = 0; - int mode = DS_MODE_OWNER | (readonly ? DS_MODE_READONLY : 0); if (getzfsvfs(name, zvp) != 0) - error = zfsvfs_create(name, mode, zvp); + error = zfsvfs_create(name, zvp); if (error == 0) { rrw_enter(&(*zvp)->z_teardown_lock, RW_READER, tag); if ((*zvp)->z_unmounted) { @@ -892,7 +890,7 @@ if (zfsvfs->z_vfs) { VFS_RELE(zfsvfs->z_vfs); } else { - dmu_objset_close(zfsvfs->z_os); + dmu_objset_disown(zfsvfs->z_os, zfsvfs); zfsvfs_free(zfsvfs); } } @@ -1186,18 +1184,30 @@ return (0); } +/* + * inputs: + * zc_name name of filesystem + * zc_obj object to find + * + * outputs: + * zc_value name of object + */ static int zfs_ioc_obj_to_path(zfs_cmd_t *zc) { - objset_t *osp; + objset_t *os; int error; - if ((error = dmu_objset_open(zc->zc_name, DMU_OST_ZFS, - DS_MODE_USER | DS_MODE_READONLY, &osp)) != 0) + /* XXX reading from objset not owned */ + if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0) return (error); - error = zfs_obj_to_path(osp, zc->zc_obj, zc->zc_value, + if (dmu_objset_type(os) != DMU_OST_ZFS) { + dmu_objset_rele(os, FTAG); + return (EINVAL); + } + error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value, sizeof (zc->zc_value)); - dmu_objset_close(osp); + dmu_objset_rele(os, FTAG); return (error); } @@ -1380,8 +1390,7 @@ int error; nvlist_t *nv; - if (error = dmu_objset_open(zc->zc_name, - DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) + if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) return (error); dmu_objset_fast_stat(os, &zc->zc_objset_stats); @@ -1394,6 +1403,7 @@ * which we aren't supposed to do with a * DS_MODE_USER hold, because it could be * inconsistent. So this is a bit of a workaround... + * XXX reading with out owning */ if (!zc->zc_objset_stats.dds_inconsistent) { if (dmu_objset_type(os) == DMU_OST_ZVOL) @@ -1403,7 +1413,7 @@ nvlist_free(nv); } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (error); } @@ -1438,8 +1448,8 @@ objset_t *os; int err; - if (err = dmu_objset_open(zc->zc_name, - DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) + /* XXX reading without owning */ + if (err = dmu_objset_hold(zc->zc_name, FTAG, &os)) return (err); dmu_objset_fast_stat(os, &zc->zc_objset_stats); @@ -1464,7 +1474,7 @@ } else { err = ENOENT; } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (err); } @@ -1505,8 +1515,7 @@ int error; char *p; - if (error = dmu_objset_open(zc->zc_name, - DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) { + if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) { if (error == ENOENT) error = ESRCH; return (error); @@ -1536,7 +1545,7 @@ if (error == ENOENT) error = ESRCH; } while (error == 0 && dataset_name_hidden(zc->zc_name)); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); if (error == 0) error = zfs_ioc_objset_stats(zc); /* fill in the stats */ @@ -1562,8 +1571,7 @@ objset_t *os; int error; - error = dmu_objset_open(zc->zc_name, - DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os); + error = dmu_objset_hold(zc->zc_name, FTAG, &os); if (error) return (error == ENOENT ? ESRCH : error); @@ -1576,14 +1584,14 @@ * so exit immediately. */ if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (ESRCH); } error = dmu_snapshot_list_next(os, sizeof (zc->zc_name) - strlen(zc->zc_name), zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie, NULL); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); if (error == 0) error = zfs_ioc_objset_stats(zc); /* fill in the stats */ else if (error == ENOENT) @@ -1726,8 +1734,7 @@ domain = propname + strlen(zfs_userquota_prop_prefixes[type]); - error = zfsvfs_hold(name, B_FALSE, FTAG, - &zfsvfs); + error = zfsvfs_hold(name, FTAG, &zfsvfs); if (error == 0) { error = zfs_set_userquota(zfsvfs, type, domain, rid, quota); @@ -1794,8 +1801,7 @@ if ((error = nvpair_value_uint64(elem, &intval)) != 0) goto out; - if ((error = zfsvfs_hold(name, B_FALSE, FTAG, - &zfsvfs)) != 0) + if ((error = zfsvfs_hold(name, FTAG, &zfsvfs)) != 0) goto out; error = zfs_set_version(zfsvfs, intval); zfsvfs_rele(zfsvfs, FTAG); @@ -1911,13 +1917,12 @@ nvlist_t *origprops; objset_t *os; - if (dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + if (dmu_objset_hold(zc->zc_name, FTAG, &os) == 0) { if (dsl_prop_get_all(os, &origprops, TRUE) == 0) { clear_props(zc->zc_name, origprops, nvl); nvlist_free(origprops); } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); } } @@ -2316,13 +2321,12 @@ /* * Open parent object set so we can inherit zplprop values. */ - if ((error = dmu_objset_open(parentname, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) + if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0) return (error); error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, createprops, zplprops, is_ci); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (error); } @@ -2399,15 +2403,14 @@ return (EINVAL); } - error = dmu_objset_open(zc->zc_value, type, - DS_MODE_USER | DS_MODE_READONLY, &clone); + error = dmu_objset_hold(zc->zc_value, FTAG, &clone); if (error) { nvlist_free(nvprops); return (error); } error = dmu_objset_clone(zc->zc_name, dmu_objset_ds(clone), 0); - dmu_objset_close(clone); + dmu_objset_rele(clone, FTAG); if (error) { nvlist_free(nvprops); return (error); @@ -2644,7 +2647,7 @@ if (error) goto out; - error = dsl_dataset_own(clone_name, DS_MODE_INCONSISTENT, FTAG, &clone); + error = dsl_dataset_own(clone_name, B_TRUE, FTAG, &clone); if (error) goto out; @@ -2652,9 +2655,7 @@ * Do clone swap. */ if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { - int mode; - - error = zfs_suspend_fs(zfsvfs, NULL, &mode); + error = zfs_suspend_fs(zfsvfs); if (error == 0) { int resume_err; @@ -2666,7 +2667,7 @@ } else { error = EBUSY; } - resume_err = zfs_resume_fs(zfsvfs, zc->zc_name, mode); + resume_err = zfs_resume_fs(zfsvfs, zc->zc_name); error = error ? error : resume_err; } VFS_RELE(zfsvfs->z_vfs); @@ -2796,20 +2797,18 @@ return (EBADF); } - if (props && dmu_objset_open(tofs, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { + if (props && dmu_objset_hold(tofs, FTAG, &os) == 0) { /* * If new properties are supplied, they are to completely * replace the existing ones, so stash away the existing ones. */ - (void) dsl_prop_get_all(os, &origprops, TRUE); - - dmu_objset_close(os); + (void) dsl_prop_get_all(os, &origprops, B_TRUE); + + dmu_objset_rele(os, FTAG); } if (zc->zc_string[0]) { - error = dmu_objset_open(zc->zc_string, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &origin); + error = dmu_objset_hold(zc->zc_string, FTAG, &origin); if (error) goto out; } @@ -2817,7 +2816,7 @@ error = dmu_recv_begin(tofs, tosnap, &zc->zc_begin_record, force, origin, &drc); if (origin) - dmu_objset_close(origin); + dmu_objset_rele(origin, FTAG); if (error) goto out; @@ -2842,11 +2841,8 @@ if (getzfsvfs(tofs, &zfsvfs) == 0) { /* online recv */ int end_err; - char *osname; - int mode; - - osname = kmem_alloc(MAXNAMELEN, KM_SLEEP); - error = zfs_suspend_fs(zfsvfs, osname, &mode); + + error = zfs_suspend_fs(zfsvfs); /* * If the suspend fails, then the recv_end will * likely also fail, and clean up after itself. @@ -2854,12 +2850,11 @@ end_err = dmu_recv_end(&drc); if (error == 0) { int resume_err = - zfs_resume_fs(zfsvfs, osname, mode); + zfs_resume_fs(zfsvfs, tofs); error = error ? error : resume_err; } error = error ? error : end_err; VFS_RELE(zfsvfs->z_vfs); - kmem_free(osname, MAXNAMELEN); } else { error = dmu_recv_end(&drc); } @@ -2901,8 +2896,7 @@ int error; offset_t off; - error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &tosnap); + error = dmu_objset_hold(zc->zc_name, FTAG, &tosnap); if (error) return (error); @@ -2916,20 +2910,19 @@ if (cp) *(cp+1) = 0; (void) strncat(buf, zc->zc_value, MAXPATHLEN); - error = dmu_objset_open(buf, DMU_OST_ANY, - DS_MODE_USER | DS_MODE_READONLY, &fromsnap); + error = dmu_objset_hold(buf, FTAG, &fromsnap); kmem_free(buf, MAXPATHLEN); if (error) { - dmu_objset_close(tosnap); + dmu_objset_rele(tosnap, FTAG); return (error); } } fp = getf(zc->zc_cookie); if (fp == NULL) { - dmu_objset_close(tosnap); + dmu_objset_rele(tosnap, FTAG); if (fromsnap) - dmu_objset_close(fromsnap); + dmu_objset_rele(fromsnap, FTAG); return (EBADF); } @@ -2940,8 +2933,8 @@ fp->f_offset = off; releasef(zc->zc_cookie); if (fromsnap) - dmu_objset_close(fromsnap); - dmu_objset_close(tosnap); + dmu_objset_rele(fromsnap, FTAG); + dmu_objset_rele(tosnap, FTAG); return (error); } @@ -3099,7 +3092,7 @@ if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) return (EINVAL); - error = zfsvfs_hold(zc->zc_name, B_TRUE, FTAG, &zfsvfs); + error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs); if (error) return (error); @@ -3127,7 +3120,7 @@ zfsvfs_t *zfsvfs; int error; - error = zfsvfs_hold(zc->zc_name, B_TRUE, FTAG, &zfsvfs); + error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs); if (error) return (error); @@ -3163,30 +3156,27 @@ zfsvfs_t *zfsvfs; if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { - if (!dmu_objset_userused_enabled(zfsvfs->z_os->os)) { + if (!dmu_objset_userused_enabled(zfsvfs->z_os)) { /* * If userused is not enabled, it may be because the * objset needs to be closed & reopened (to grow the * objset_phys_t). Suspend/resume the fs will do that. */ - int mode; - error = zfs_suspend_fs(zfsvfs, NULL, &mode); - if (error == 0) { - error = zfs_resume_fs(zfsvfs, - zc->zc_name, mode); - } + error = zfs_suspend_fs(zfsvfs); + if (error == 0) + error = zfs_resume_fs(zfsvfs, zc->zc_name); } if (error == 0) error = dmu_objset_userspace_upgrade(zfsvfs->z_os); VFS_RELE(zfsvfs->z_vfs); } else { - error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, - DS_MODE_USER, &os); + /* XXX kind of reading contents without owning */ + error = dmu_objset_hold(zc->zc_name, FTAG, &os); if (error) return (error); error = dmu_objset_userspace_upgrade(os); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); } return (error);
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c Wed Aug 12 22:11:31 2009 -0700 @@ -835,32 +835,30 @@ } int -zfsvfs_create(const char *osname, int mode, zfsvfs_t **zvp) +zfsvfs_create(const char *osname, zfsvfs_t **zvp) { objset_t *os; zfsvfs_t *zfsvfs; uint64_t zval; int i, error; - if (error = dsl_prop_get_integer(osname, "readonly", &zval, NULL)) - return (error); - if (zval) - mode |= DS_MODE_READONLY; + zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); - error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os); - if (error == EROFS) { - mode |= DS_MODE_READONLY; - error = dmu_objset_open(osname, DMU_OST_ZFS, mode, &os); + /* + * We claim to always be readonly so we can open snapshots; + * other ZPL code will prevent us from writing to snapshots. + */ + error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os); + if (error) { + kmem_free(zfsvfs, sizeof (zfsvfs_t)); + return (error); } - if (error) - return (error); /* * Initialize the zfs-specific filesystem structure. * Should probably make this a kmem cache, shuffle fields, * and just bzero up to z_hold_mtx[]. */ - zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP); zfsvfs->z_vfs = NULL; zfsvfs->z_parent = zfsvfs; zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE; @@ -948,7 +946,7 @@ return (0); out: - dmu_objset_close(os); + dmu_objset_disown(os, zfsvfs); *zvp = NULL; kmem_free(zfsvfs, sizeof (zfsvfs_t)); return (error); @@ -966,9 +964,9 @@ /* * Set the objset user_ptr to track its zfsvfs. */ - mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock); + mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); dmu_objset_set_user(zfsvfs->z_os, zfsvfs); - mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock); + mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data); if (zil_disable) { @@ -1084,7 +1082,7 @@ ASSERT(vfsp); ASSERT(osname); - error = zfsvfs_create(osname, DS_MODE_OWNER, &zfsvfs); + error = zfsvfs_create(osname, &zfsvfs); if (error) return (error); zfsvfs->z_vfs = vfsp; @@ -1146,9 +1144,9 @@ xattr_changed_cb(zfsvfs, pval); zfsvfs->z_issnap = B_TRUE; - mutex_enter(&zfsvfs->z_os->os->os_user_ptr_lock); + mutex_enter(&zfsvfs->z_os->os_user_ptr_lock); dmu_objset_set_user(zfsvfs->z_os, zfsvfs); - mutex_exit(&zfsvfs->z_os->os->os_user_ptr_lock); + mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); } else { error = zfsvfs_setup(zfsvfs, B_TRUE); } @@ -1157,7 +1155,7 @@ zfsctl_create(zfsvfs); out: if (error) { - dmu_objset_close(zfsvfs->z_os); + dmu_objset_disown(zfsvfs->z_os, zfsvfs); zfsvfs_free(zfsvfs); } else { atomic_add_32(&zfs_active_fs_count, 1); @@ -1725,14 +1723,14 @@ /* * Unset the objset user_ptr. */ - mutex_enter(&os->os->os_user_ptr_lock); + mutex_enter(&os->os_user_ptr_lock); dmu_objset_set_user(os, NULL); - mutex_exit(&os->os->os_user_ptr_lock); + mutex_exit(&os->os_user_ptr_lock); /* * Finally release the objset */ - dmu_objset_close(os); + dmu_objset_disown(os, zfsvfs); } /* @@ -1835,17 +1833,13 @@ * 'z_teardown_inactive_lock' write held. */ int -zfs_suspend_fs(zfsvfs_t *zfsvfs, char *name, int *modep) +zfs_suspend_fs(zfsvfs_t *zfsvfs) { int error; if ((error = zfsvfs_teardown(zfsvfs, B_FALSE)) != 0) return (error); - - *modep = zfsvfs->z_os->os_mode; - if (name) - dmu_objset_name(zfsvfs->z_os, name); - dmu_objset_close(zfsvfs->z_os); + dmu_objset_disown(zfsvfs->z_os, zfsvfs); return (0); } @@ -1854,14 +1848,15 @@ * Reopen zfsvfs_t::z_os and release VOPs. */ int -zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname, int mode) +zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname) { int err; ASSERT(RRW_WRITE_HELD(&zfsvfs->z_teardown_lock)); ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock)); - err = dmu_objset_open(osname, DMU_OST_ZFS, mode, &zfsvfs->z_os); + err = dmu_objset_own(osname, DMU_OST_ZFS, B_FALSE, zfsvfs, + &zfsvfs->z_os); if (err) { zfsvfs->z_os = NULL; } else {
--- a/usr/src/uts/common/fs/zfs/zil.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zil.c Wed Aug 12 22:11:31 2009 -0700 @@ -500,7 +500,7 @@ objset_t *os; int error; - error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); + error = dmu_objset_hold(osname, FTAG, &os); if (error) { cmn_err(CE_WARN, "can't open objset for %s", osname); return (0); @@ -549,7 +549,7 @@ } ASSERT3U(first_txg, ==, (spa_last_synced_txg(zilog->zl_spa) + 1)); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (0); } @@ -571,7 +571,7 @@ zil_trailer_t *ztp; int error; - error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); + error = dmu_objset_hold(osname, FTAG, &os); if (error) { cmn_err(CE_WARN, "can't open objset for %s", osname); return (0); @@ -581,7 +581,7 @@ zh = zil_header_in_syncing_context(zilog); blk = zh->zh_log; if (BP_IS_HOLE(&blk)) { - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (0); /* no chain */ } @@ -594,7 +594,7 @@ blk = ztp->zit_next_blk; VERIFY(arc_buf_remove_ref(abuf, &abuf) == 1); } - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); if (error == ECKSUM) return (0); /* normal end of chain */ return (error); @@ -1658,7 +1658,7 @@ zilog_t *zilog; int error; - error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); + error = dmu_objset_hold(osname, FTAG, &os); if (error) return (error); @@ -1667,6 +1667,6 @@ error = EEXIST; else zil_resume(zilog); - dmu_objset_close(os); + dmu_objset_rele(os, FTAG); return (error); }
--- a/usr/src/uts/common/fs/zfs/zvol.c Wed Aug 12 21:16:19 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zvol.c Wed Aug 12 22:11:31 2009 -0700 @@ -80,6 +80,7 @@ #include "zfs_namecheck.h" static void *zvol_state; +static char *zvol_tag = "zvol_tag"; #define ZVOL_DUMPSIZE "dumpsize" @@ -109,7 +110,7 @@ uint8_t zv_min_bs; /* minimum addressable block shift */ uint8_t zv_flags; /* readonly, dumpified, etc. */ objset_t *zv_objset; /* objset handle */ - uint32_t zv_mode; /* DS_MODE_* flags at open time */ + boolean_t zv_issnap; /* is a snapshot (read-only) */ uint32_t zv_open_count[OTYPCNT]; /* open counts */ uint32_t zv_total_opens; /* total open count */ zilog_t *zv_zilog; /* ZIL handle */ @@ -432,7 +433,6 @@ uint64_t volsize; minor_t minor = 0; struct pathname linkpath; - int ds_mode = DS_MODE_OWNER; vnode_t *vp = NULL; char *devpath; char chrbuf[30], blkbuf[30]; @@ -445,10 +445,8 @@ return (EEXIST); } - if (strchr(name, '@') != 0) - ds_mode |= DS_MODE_READONLY; - - error = dmu_objset_open(name, DMU_OST_ZVOL, ds_mode, &os); + /* lie and say we're read-only */ + error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, zvol_tag, &os); if (error) { mutex_exit(&zvol_state_lock); @@ -458,7 +456,7 @@ error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize); if (error) { - dmu_objset_close(os); + dmu_objset_disown(os, zvol_tag); mutex_exit(&zvol_state_lock); return (error); } @@ -500,13 +498,13 @@ minor = zvol_minor_alloc(); if (minor == 0) { - dmu_objset_close(os); + dmu_objset_disown(os, zvol_tag); mutex_exit(&zvol_state_lock); return (ENXIO); } if (ddi_soft_state_zalloc(zvol_state, minor) != DDI_SUCCESS) { - dmu_objset_close(os); + dmu_objset_disown(os, zvol_tag); mutex_exit(&zvol_state_lock); return (EAGAIN); } @@ -519,7 +517,7 @@ if (ddi_create_minor_node(zfs_dip, chrbuf, S_IFCHR, minor, DDI_PSEUDO, 0) == DDI_FAILURE) { ddi_soft_state_free(zvol_state, minor); - dmu_objset_close(os); + dmu_objset_disown(os, zvol_tag); mutex_exit(&zvol_state_lock); return (EAGAIN); } @@ -530,7 +528,7 @@ minor, DDI_PSEUDO, 0) == DDI_FAILURE) { ddi_remove_minor_node(zfs_dip, chrbuf); ddi_soft_state_free(zvol_state, minor); - dmu_objset_close(os); + dmu_objset_disown(os, zvol_tag); mutex_exit(&zvol_state_lock); return (EAGAIN); } @@ -542,7 +540,7 @@ zv->zv_minor = minor; zv->zv_volsize = volsize; zv->zv_objset = os; - zv->zv_mode = ds_mode; + zv->zv_issnap = dmu_objset_is_snapshot(os); zv->zv_zilog = zil_open(os, zvol_get_data); mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL); avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare, @@ -600,7 +598,7 @@ zil_close(zv->zv_zilog); zv->zv_zilog = NULL; - dmu_objset_close(zv->zv_objset); + dmu_objset_disown(zv->zv_objset, zvol_tag); zv->zv_objset = NULL; avl_destroy(&zv->zv_znode.z_range_avl); mutex_destroy(&zv->zv_znode.z_range_lock); @@ -704,7 +702,7 @@ * If we are doing a "zfs clone -o volsize=", then the * minor node won't exist yet. */ - error = dmu_objset_open(name, DMU_OST_ZVOL, DS_MODE_OWNER, + error = dmu_objset_own(name, DMU_OST_ZVOL, B_FALSE, FTAG, &state.zv_objset); if (error != 0) goto out; @@ -717,7 +715,7 @@ doi.doi_data_block_size)) != 0) goto out; - if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) { + if (zv->zv_flags & ZVOL_RDONLY || zv->zv_issnap) { error = EROFS; goto out; } @@ -760,7 +758,7 @@ out: if (state.zv_objset) - dmu_objset_close(state.zv_objset); + dmu_objset_disown(state.zv_objset, FTAG); mutex_exit(&zvol_state_lock); @@ -788,7 +786,7 @@ mutex_exit(&zvol_state_lock); return (ENXIO); } - if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) { + if (zv->zv_flags & ZVOL_RDONLY || zv->zv_issnap) { if (needlock) mutex_exit(&zvol_state_lock); return (EROFS); @@ -836,7 +834,7 @@ ASSERT(zv->zv_objset != NULL); if ((flag & FWRITE) && - (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY))) { + (zv->zv_flags & ZVOL_RDONLY || zv->zv_issnap)) { mutex_exit(&zvol_state_lock); return (EROFS); } @@ -1160,8 +1158,7 @@ } if (!(bp->b_flags & B_READ) && - (zv->zv_flags & ZVOL_RDONLY || - zv->zv_mode & DS_MODE_READONLY)) { + (zv->zv_flags & ZVOL_RDONLY || zv->zv_issnap)) { bioerror(bp, EROFS); biodone(bp); return (0); @@ -1721,7 +1718,7 @@ dmu_tx_t *tx; objset_t *os = zv->zv_objset; - if (zv->zv_flags & ZVOL_RDONLY || (zv->zv_mode & DS_MODE_READONLY)) + if (zv->zv_flags & ZVOL_RDONLY || zv->zv_issnap) return (EROFS); /*