dmu_objset.c revision 71eb05381846ad14a2087631474e832d0f316654
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/zfs_context.h>
#include <sys/dmu_objset.h>
#include <sys/dsl_dataset.h>
#include <sys/dsl_prop.h>
#include <sys/dsl_pool.h>
#include <sys/dsl_synctask.h>
#include <sys/dsl_deleg.h>
#include <sys/zio_checksum.h>
#include <sys/dmu_impl.h>
#include <sys/zfs_ioctl.h>
spa_t *
{
}
zilog_t *
{
}
{
else
}
{
return (os->os_dsl_dataset);
}
{
}
void
{
}
{
}
{
return (os->os_logbias);
}
static void
{
/*
* Inheritance should have been done by now.
*/
}
static void
{
/*
* Inheritance and range checking should have been done by now.
*/
}
static void
{
/*
* Inheritance and range checking should have been done by now.
*/
}
static void
{
/*
* Inheritance and range checking should have been done by now.
*/
newval == ZFS_CACHE_METADATA);
}
static void
{
/*
* Inheritance and range checking should have been done by now.
*/
newval == ZFS_CACHE_METADATA);
}
static void
{
}
void
{
if (size == sizeof (objset_phys_t)) {
}
}
int
{
int i, err;
if (DMU_OS_IS_L2CACHEABLE(os))
aflags |= ARC_L2CACHE;
/*
* 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.
*/
if (err) {
/* convert checksum errors into IO errors */
return (err);
}
/* Increase the blocksize if we are permitted. */
&os->os_phys_buf);
}
} else {
sizeof (objset_phys_t) : OBJSET_OLD_PHYS_SIZE;
}
/*
* Note: the changed_cb will be called once before the register
* func returns, thus changing the checksum/compression from the
*/
if (ds) {
if (err == 0)
if (!dsl_dataset_is_snapshot(ds)) {
if (err == 0)
if (err == 0)
if (err == 0)
if (err == 0)
}
if (err) {
return (err);
}
/* It's the meta-objset. */
}
for (i = 0; i < TXG_SIZE; i++) {
}
}
/*
* We should be the only thread trying to do this because we
* have ds_opening_lock
*/
if (ds) {
}
return (0);
}
int
{
int err = 0;
}
return (err);
}
/* called from zpl */
int
{
int err;
if (err)
return (err);
if (err)
return (err);
}
/* called from zpl */
int
{
int err;
if (err)
return (err);
if (err) {
return (EINVAL);
}
return (err);
}
void
{
}
void
{
}
int
{
/* process the mdn last, since the other dnodes have holds on it */
/*
* Find the first dnode with holds. We have to do this dance
* because dnode_add_ref() only works if you already have a
* hold. If there are no holds then it has no dbufs so OK to
* skip.
*/
continue;
while (dn) {
do {
}
}
void
{
int i;
for (i = 0; i < TXG_SIZE; i++) {
}
if (ds) {
if (!dsl_dataset_is_snapshot(ds)) {
copies_changed_cb, os));
logbias_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.
*/
(void) dmu_objset_evict_dbufs(os);
if (os->os_userused_dnode) {
}
}
{
}
/* called from dsl for meta-objset */
objset_t *
{
if (ds)
if (ds)
/*
* We don't want to have to increase the meta-dnode's nlevels
* later, because then we could do it in quescing context while
* we are also accessing it in open context.
*
* This precaution is not necessary for the MOS (ds == NULL),
* because the MOS is only updated in syncing context.
* This is most fortunate: the MOS is the only objset that
* needs to be synced multiple times as spa_sync() iterates
* to convergence, so minimizing its dn_nlevels matters.
*/
int levels = 1;
/*
* Determine the number of levels necessary for the meta-dnode
* to contain DN_MAX_OBJECT dnodes.
*/
DN_MAX_OBJECT * sizeof (dnode_phys_t))
levels++;
}
if (dmu_objset_userused_enabled(os)) {
}
return (os);
}
struct oscarg {
void *userarg;
const char *lastname;
};
/*ARGSUSED*/
static int
{
int err;
/* You can't clone across pools. */
return (EXDEV);
/* You can only clone snapshots, not the head datasets. */
return (EINVAL);
}
return (0);
}
static void
{
}
}
int
{
const char *tail;
int err = 0;
if (err)
return (err);
return (EEXIST);
}
return (err);
}
int
{
const char *tail;
int err = 0;
if (err)
return (err);
return (EEXIST);
}
return (err);
}
int
{
int error;
/*
* dsl_dataset_destroy() can free any claimed-but-unplayed
* intent log, but if there is an active log, it has blocks that
* are allocated, but may not yet be reflected in the on-disk
* structure. Only the ZIL knows how to free them, so we have
* to call into it here.
*/
if (error == 0) {
/* dsl_dataset_destroy() closes the ds. */
}
return (error);
}
struct snaparg {
char *snapname;
char failed[MAXPATHLEN];
};
static int
{
/* The props have already been checked by zfs_check_userprops(). */
}
static void
{
}
static int
{
int err;
/*
* Check permissions only when requested. This only applies when
* doing a recursive snapshot. The permission checks for the starting
* dataset have already been performed in zfs_secpolicy_snapshot()
*/
return (err);
if (err != 0)
return (err);
/* If the objset is in an inconsistent state, return busy */
return (EBUSY);
}
/*
* NB: we need to wait for all in-flight changes to get to disk,
* so that we snapshot those changes. zil_suspend does this as
* a side effect.
*/
if (err == 0) {
} else {
}
return (err);
}
int
{
int err;
if (err)
return (err);
if (recursive) {
} else {
}
if (err == 0)
}
if (err)
return (err);
}
static void
{
/*
* Initialize dn_zio outside dnode_sync() because the
* meta-dnode needs to set it ouside dnode_sync().
*/
if (newlist) {
}
}
}
/* ARGSUSED */
static void
{
/*
* Update rootbp fill count: it should be the number of objects
* allocated in the object set (not counting the "special"
* objects that are stored in the objset_phys_t -- the meta
*/
for (int i = 0; i < dnp->dn_nblkptr; i++)
} else {
}
}
/* called from dsl */
void
{
int txgoff;
writeprops_t wp = { 0 };
/* XXX the write_done callback should really give us the tx... */
/*
* This is the MOS. If we have upgraded,
* spa_max_replication() could change, so reset
* os_copies here.
*/
}
/*
* Create the root block IO
*/
}
/*
* Sync special dnodes - the parent IO for the sync is the root block
*/
if (os->os_userused_dnode &&
}
if (dmu_objset_userused_enabled(os)) {
/*
* We must create the list here because it uses the
* dn_dirty_link[] of this txg.
*/
}
}
/*
* Free intent log blocks up to this tx.
*/
}
void
{
}
{
}
void
{
static const char zerobuf[DN_MAX_BONUSLEN] = {0};
}
/*
* If the object was not previously
* accounted, pretend that it was free.
*/
}
/*
* If the object was freed, use the previous bonustype.
*/
DN_MAX_BONUSLEN) == 0 &&
DN_MAX_BONUSLEN) == 0 &&
/*
* The mutex is needed here for interlock with dnode_allocate.
*/
}
}
{
}
int
{
int err = 0;
return (0);
if (!dmu_objset_userused_enabled(os))
return (ENOTSUP);
if (dmu_objset_is_snapshot(os))
return (EINVAL);
/*
* We simply need to mark every object dirty, so that it will be
* synced out and now accounted. If this is called
* concurrently, or if we already did some work before crashing,
* that's fine, since we track each object's accounted state
* independently.
*/
int objerr;
return (EINTR);
if (objerr)
continue;
if (objerr) {
continue;
}
}
return (0);
}
void
{
}
{
}
void
{
if (os->os_dsl_dataset)
}
void
{
}
int
{
else
return (B_FALSE);
}
int
{
return (ENOENT);
}
int
{
return (ENOENT);
return (ENOENT);
}
return (ENAMETOOLONG);
}
if (idp)
if (case_conflict)
return (0);
}
int
{
/* there is no next dir on a snapshot! */
return (ENOENT);
return (ENOENT);
}
return (ENAMETOOLONG);
}
if (idp)
return (0);
}
struct findarg {
int (*func)(char *, void *);
void *arg;
};
/* ARGSUSED */
static int
{
}
/*
* Find all objsets under name, and for each, call 'func(child_name, arg)'.
* Perhaps change all callers to use dmu_objset_find_spa()?
*/
int
{
}
/*
* Find all objsets under name, call func on each
*/
int
{
dsl_pool_t *dp;
char *child;
int err;
if (err)
return (err);
/* Don't visit hidden ($MOS & $ORIGIN) objsets. */
return (0);
}
/*
* Iterate over all children.
*/
if (flags & DS_FIND_CHILDREN) {
(void) zap_cursor_advance(&zc)) {
if (err)
break;
}
if (err) {
return (err);
}
}
/*
* Iterate over all snapshots.
*/
if (flags & DS_FIND_SNAPSHOTS) {
if (!dsl_pool_sync_context(dp))
if (!dsl_pool_sync_context(dp))
if (err == 0) {
(void) zap_cursor_advance(&zc)) {
sizeof (uint64_t));
if (err)
break;
}
}
}
if (err)
return (err);
/*
* Apply to self if appropriate.
*/
return (err);
}
/* ARGSUSED */
int
{
return (0);
}
}
return (0);
}
void
{
}
void *
{
return (os->os_user_ptr);
}