/* * dsl_pool must not be held when this is called. * Upon successful return, there will be a longhold on the dataset, * and the dsl_pool will not be held. */ int dmu_objset_own(const char *name, dmu_objset_type_t type, boolean_t readonly, void *tag, objset_t **osp) { dsl_pool_t *dp; dsl_dataset_t *ds; int err; err = dsl_pool_hold(name, FTAG, &dp); if (err != 0) return (err); err = dsl_dataset_own(dp, name, tag, &ds); if (err != 0) { dsl_pool_rele(dp, FTAG); return (err); } err = dmu_objset_from_ds(ds, osp); dsl_pool_rele(dp, FTAG); if (err != 0) { dsl_dataset_disown(ds, tag); } else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) { dsl_dataset_disown(ds, tag); return (SET_ERROR(EINVAL)); } else if (!readonly && dsl_dataset_is_snapshot(ds)) { dsl_dataset_disown(ds, tag); return (SET_ERROR(EROFS)); } return (err); }
/* called from zpl */ int dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, 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); 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); if (err) { kmem_free(os, sizeof (objset_t)); return (err); } 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); }
static int dmu_objset_own_impl(dsl_dataset_t *ds, dmu_objset_type_t type, boolean_t readonly, void *tag, objset_t **osp) { int err; err = dmu_objset_from_ds(ds, osp); if (err != 0) { dsl_dataset_disown(ds, tag); } else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) { dsl_dataset_disown(ds, tag); return (SET_ERROR(EINVAL)); } else if (!readonly && dsl_dataset_is_snapshot(ds)) { dsl_dataset_disown(ds, tag); return (SET_ERROR(EROFS)); } return (err); }
void dmu_objset_close(objset_t *os) { 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); 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)); }
/* called from zpl */ int dmu_objset_own(const char *name, dmu_objset_type_t type, boolean_t readonly, void *tag, objset_t **osp) { dsl_dataset_t *ds; int err; err = dsl_dataset_own(name, B_FALSE, tag, &ds); if (err) return (err); err = dmu_objset_from_ds(ds, osp); if (err) { dsl_dataset_disown(ds, tag); } else if (type != DMU_OST_ANY && type != (*osp)->os_phys->os_type) { dmu_objset_disown(*osp, tag); return (EINVAL); } else if (!readonly && dsl_dataset_is_snapshot(ds)) { dmu_objset_disown(*osp, tag); return (EROFS); } return (err); }
/* * This will close the objset. */ int dmu_objset_rollback(objset_t *os) { int err; dsl_dataset_t *ds; ds = os->os->os_dsl_dataset; if (!dsl_dataset_tryown(ds, TRUE, os)) { dmu_objset_close(os); return (EBUSY); } err = dsl_dataset_rollback(ds, os->os->os_phys->os_type); /* * NB: we close the objset manually because the rollback * actually implicitly called dmu_objset_evict(), thus freeing * the objset_impl_t. */ dsl_dataset_disown(ds, os); kmem_free(os, sizeof (objset_t)); return (err); }
void dmu_objset_disown(objset_t *os, void *tag) { dsl_dataset_disown(os->os_dsl_dataset, tag); }