Skip to content

Commit

Permalink
Patch most files in module/zfs. Still working on dsl_dataset.c and zf…
Browse files Browse the repository at this point in the history
…s_ioctl.c.
  • Loading branch information
dweeezil committed May 21, 2013
1 parent 028f8a6 commit b5e40e8
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 244 deletions.
110 changes: 56 additions & 54 deletions module/zfs/dmu_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,9 +416,48 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
return (err);
}

/*
* Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline.
* For example, they could both be snapshots of the same filesystem, and
* 'earlier' is before 'later'. Or 'earlier' could be the origin of
* 'later's filesystem. Or 'earlier' could be an older snapshot in the origin's
* filesystem. Or 'earlier' could be the origin's origin.
*/
static boolean_t
is_before(dsl_dataset_t *later, dsl_dataset_t *earlier)
{
dsl_pool_t *dp = later->ds_dir->dd_pool;
int error;
boolean_t ret;
dsl_dataset_t *origin;

if (earlier->ds_phys->ds_creation_txg >=
later->ds_phys->ds_creation_txg)
return (B_FALSE);

if (later->ds_dir == earlier->ds_dir)
return (B_TRUE);
if (!dsl_dir_is_clone(later->ds_dir))
return (B_FALSE);

rw_enter(&dp->dp_config_rwlock, RW_READER);
if (later->ds_dir->dd_phys->dd_origin_obj == earlier->ds_object) {
rw_exit(&dp->dp_config_rwlock);
return (B_TRUE);
}
error = dsl_dataset_hold_obj(dp,
later->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin);
rw_exit(&dp->dp_config_rwlock);
if (error != 0)
return (B_FALSE);
ret = is_before(origin, earlier);
dsl_dataset_rele(origin, FTAG);
return (ret);
}

int
dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
int outfd, vnode_t *vp, offset_t *off)
dmu_send(objset_t *tosnap, objset_t *fromsnap, int outfd, vnode_t *vp,
offset_t *off)
{
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
Expand All @@ -431,30 +470,13 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
if (ds->ds_phys->ds_next_snap_obj == 0)
return (EINVAL);

/* fromsnap must be an earlier snapshot from the same fs as tosnap */
if (fromds && (ds->ds_dir != fromds->ds_dir ||
fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
/*
* fromsnap must be an earlier snapshot from the same fs as tosnap,
* or the origin's fs.
*/
if (fromds != NULL && !is_before(ds, fromds))
return (EXDEV);

if (fromorigin) {
dsl_pool_t *dp = ds->ds_dir->dd_pool;

if (fromsnap)
return (EINVAL);

if (dsl_dir_is_clone(ds->ds_dir)) {
rw_enter(&dp->dp_config_rwlock, RW_READER);
err = dsl_dataset_hold_obj(dp,
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
rw_exit(&dp->dp_config_rwlock);
if (err)
return (err);
} else {
fromorigin = B_FALSE;
}
}


drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
drr->drr_type = DRR_BEGIN;
drr->drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
Expand All @@ -479,7 +501,7 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
drr->drr_u.drr_begin.drr_creation_time =
ds->ds_phys->ds_creation_time;
drr->drr_u.drr_begin.drr_type = tosnap->os_phys->os_type;
if (fromorigin)
if (fromds != NULL && ds->ds_dir != fromds->ds_dir)
drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
drr->drr_u.drr_begin.drr_toguid = ds->ds_phys->ds_guid;
if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET)
Expand All @@ -491,8 +513,6 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,

if (fromds)
fromtxg = fromds->ds_phys->ds_creation_txg;
if (fromorigin)
dsl_dataset_rele(fromds, FTAG);

dsp = kmem_zalloc(sizeof (dmu_sendarg_t), KM_SLEEP);

Expand Down Expand Up @@ -550,8 +570,7 @@ dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
}

int
dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
uint64_t *sizep)
dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, uint64_t *sizep)
{
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
Expand All @@ -563,36 +582,20 @@ dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
if (ds->ds_phys->ds_next_snap_obj == 0)
return (EINVAL);

/* fromsnap must be an earlier snapshot from the same fs as tosnap */
if (fromds && (ds->ds_dir != fromds->ds_dir ||
fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
/*
* fromsnap must be an earlier snapshot from the same fs as tosnap,
* or the origin's fs.
*/
if (fromds != NULL && !is_before(ds, fromds))
return (EXDEV);

if (fromorigin) {
if (fromsnap)
return (EINVAL);

if (dsl_dir_is_clone(ds->ds_dir)) {
rw_enter(&dp->dp_config_rwlock, RW_READER);
err = dsl_dataset_hold_obj(dp,
ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
rw_exit(&dp->dp_config_rwlock);
if (err)
return (err);
} else {
fromorigin = B_FALSE;
}
}

/* Get uncompressed size estimate of changed data. */
if (fromds == NULL) {
size = ds->ds_phys->ds_uncompressed_bytes;
} else {
uint64_t used, comp;
err = dsl_dataset_space_written(fromds, ds,
&used, &comp, &size);
if (fromorigin)
dsl_dataset_rele(fromds, FTAG);
if (err)
return (err);
}
Expand Down Expand Up @@ -690,8 +693,7 @@ recv_new_sync(void *arg1, void *arg2, dmu_tx_t *tx)
rbsa->ds, &rbsa->ds->ds_phys->ds_bp, rbsa->type, tx);
}

spa_history_log_internal(LOG_DS_REPLAY_FULL_SYNC,
dd->dd_pool->dp_spa, tx, "dataset = %lld", dsobj);
spa_history_log_internal_ds(rbsa->ds, "receive new", tx, "");
}

/* ARGSUSED */
Expand Down Expand Up @@ -792,8 +794,7 @@ recv_existing_sync(void *arg1, void *arg2, dmu_tx_t *tx)

rbsa->ds = cds;

spa_history_log_internal(LOG_DS_REPLAY_INC_SYNC,
dp->dp_spa, tx, "dataset = %lld", dsobj);
spa_history_log_internal_ds(cds, "receive over existing", tx, "");
}

static boolean_t
Expand Down Expand Up @@ -1604,6 +1605,7 @@ recv_end_sync(void *arg1, void *arg2, dmu_tx_t *tx)

dmu_buf_will_dirty(ds->ds_dbuf, tx);
ds->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
spa_history_log_internal_ds(ds, "finished receiving", tx, "");
}

static int
Expand Down
2 changes: 1 addition & 1 deletion module/zfs/dmu_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dmu_tx_create_dd(dsl_dir_t *dd)
{
dmu_tx_t *tx = kmem_zalloc(sizeof (dmu_tx_t), KM_PUSHPAGE);
tx->tx_dir = dd;
if (dd)
if (dd != NULL)
tx->tx_pool = dd->dd_pool;
list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t),
offsetof(dmu_tx_hold_t, txh_node));
Expand Down
28 changes: 10 additions & 18 deletions module/zfs/dsl_deleg.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,8 @@ dsl_deleg_set_sync(void *arg1, void *arg2, dmu_tx_t *tx)

VERIFY(zap_update(mos, jumpobj,
perm, 8, 1, &n, tx) == 0);
spa_history_log_internal(LOG_DS_PERM_UPDATE,
dd->dd_pool->dp_spa, tx,
"%s %s dataset = %llu", whokey, perm,
dd->dd_phys->dd_head_dataset_obj);
spa_history_log_internal_dd(dd, "permission update", tx,
"%s %s", whokey, perm);
}
}
}
Expand Down Expand Up @@ -213,10 +211,8 @@ dsl_deleg_unset_sync(void *arg1, void *arg2, dmu_tx_t *tx)
(void) zap_remove(mos, zapobj, whokey, tx);
VERIFY(0 == zap_destroy(mos, jumpobj, tx));
}
spa_history_log_internal(LOG_DS_PERM_WHO_REMOVE,
dd->dd_pool->dp_spa, tx,
"%s dataset = %llu", whokey,
dd->dd_phys->dd_head_dataset_obj);
spa_history_log_internal_dd(dd, "permission who remove",
tx, "%s", whokey);
continue;
}

Expand All @@ -234,10 +230,8 @@ dsl_deleg_unset_sync(void *arg1, void *arg2, dmu_tx_t *tx)
VERIFY(0 == zap_destroy(mos,
jumpobj, tx));
}
spa_history_log_internal(LOG_DS_PERM_REMOVE,
dd->dd_pool->dp_spa, tx,
"%s %s dataset = %llu", whokey, perm,
dd->dd_phys->dd_head_dataset_obj);
spa_history_log_internal_dd(dd, "permission remove", tx,
"%s %s", whokey, perm);
}
}
}
Expand Down Expand Up @@ -533,12 +527,10 @@ dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
}

/*
* Check if user has requested permission. If descendent is set, must have
* descendent perms.
* Check if user has requested permission.
*/
int
dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
cred_t *cr)
dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
{
dsl_dir_t *dd;
dsl_pool_t *dp;
Expand All @@ -559,7 +551,7 @@ dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
SPA_VERSION_DELEGATED_PERMS)
return (EPERM);

if (dsl_dataset_is_snapshot(ds) || descendent) {
if (dsl_dataset_is_snapshot(ds)) {
/*
* Snapshots are treated as descendents only,
* local permissions do not apply.
Expand Down Expand Up @@ -652,7 +644,7 @@ dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr)
if (error)
return (error);

error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
error = dsl_deleg_access_impl(ds, perm, cr);
dsl_dataset_rele(ds, FTAG);

return (error);
Expand Down
Loading

0 comments on commit b5e40e8

Please sign in to comment.