Print this page
3888 zfs recv -F should destroy any snapshots created since the incremental source
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Peng Dai <peng.dai@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_dataset.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_dataset.c
↓ open down ↓ 1525 lines elided ↑ open up ↑
1526 1526                          *availbytesp = MIN(*availbytesp,
1527 1527                              ds->ds_quota - *refdbytesp);
1528 1528                  else
1529 1529                          *availbytesp = 0;
1530 1530          }
1531 1531          *usedobjsp = ds->ds_phys->ds_bp.blk_fill;
1532 1532          *availobjsp = DN_MAX_OBJECT - *usedobjsp;
1533 1533  }
1534 1534  
1535 1535  boolean_t
1536      -dsl_dataset_modified_since_lastsnap(dsl_dataset_t *ds)
     1536 +dsl_dataset_modified_since_snap(dsl_dataset_t *ds, dsl_dataset_t *snap)
1537 1537  {
1538 1538          dsl_pool_t *dp = ds->ds_dir->dd_pool;
1539 1539  
1540 1540          ASSERT(dsl_pool_config_held(dp));
1541      -        if (ds->ds_prev == NULL)
     1541 +        if (snap == NULL)
1542 1542                  return (B_FALSE);
1543 1543          if (ds->ds_phys->ds_bp.blk_birth >
1544      -            ds->ds_prev->ds_phys->ds_creation_txg) {
1545      -                objset_t *os, *os_prev;
     1544 +            snap->ds_phys->ds_creation_txg) {
     1545 +                objset_t *os, *os_snap;
1546 1546                  /*
1547 1547                   * It may be that only the ZIL differs, because it was
1548 1548                   * reset in the head.  Don't count that as being
1549 1549                   * modified.
1550 1550                   */
1551 1551                  if (dmu_objset_from_ds(ds, &os) != 0)
1552 1552                          return (B_TRUE);
1553      -                if (dmu_objset_from_ds(ds->ds_prev, &os_prev) != 0)
     1553 +                if (dmu_objset_from_ds(snap, &os_snap) != 0)
1554 1554                          return (B_TRUE);
1555 1555                  return (bcmp(&os->os_phys->os_meta_dnode,
1556      -                    &os_prev->os_phys->os_meta_dnode,
     1556 +                    &os_snap->os_phys->os_meta_dnode,
1557 1557                      sizeof (os->os_phys->os_meta_dnode)) != 0);
1558 1558          }
1559 1559          return (B_FALSE);
1560 1560  }
1561 1561  
1562 1562  typedef struct dsl_dataset_rename_snapshot_arg {
1563 1563          const char *ddrsa_fsname;
1564 1564          const char *ddrsa_oldsnapname;
1565 1565          const char *ddrsa_newsnapname;
1566 1566          boolean_t ddrsa_recursive;
↓ open down ↓ 782 lines elided ↑ open up ↑
2349 2349  dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
2350 2350      dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx)
2351 2351  {
2352 2352          int64_t unused_refres_delta;
2353 2353  
2354 2354          /* they should both be heads */
2355 2355          if (dsl_dataset_is_snapshot(clone) ||
2356 2356              dsl_dataset_is_snapshot(origin_head))
2357 2357                  return (SET_ERROR(EINVAL));
2358 2358  
2359      -        /* the branch point should be just before them */
2360      -        if (clone->ds_prev != origin_head->ds_prev)
     2359 +        /* if we are not forcing, the branch point should be just before them */
     2360 +        if (!force && clone->ds_prev != origin_head->ds_prev)
2361 2361                  return (SET_ERROR(EINVAL));
2362 2362  
2363 2363          /* clone should be the clone (unless they are unrelated) */
2364 2364          if (clone->ds_prev != NULL &&
2365 2365              clone->ds_prev != clone->ds_dir->dd_pool->dp_origin_snap &&
2366      -            origin_head->ds_object !=
2367      -            clone->ds_prev->ds_phys->ds_next_snap_obj)
     2366 +            origin_head->ds_dir != clone->ds_prev->ds_dir)
2368 2367                  return (SET_ERROR(EINVAL));
2369 2368  
2370 2369          /* the clone should be a child of the origin */
2371 2370          if (clone->ds_dir->dd_parent != origin_head->ds_dir)
2372 2371                  return (SET_ERROR(EINVAL));
2373 2372  
2374 2373          /* origin_head shouldn't be modified unless 'force' */
2375      -        if (!force && dsl_dataset_modified_since_lastsnap(origin_head))
     2374 +        if (!force &&
     2375 +            dsl_dataset_modified_since_snap(origin_head, origin_head->ds_prev))
2376 2376                  return (SET_ERROR(ETXTBSY));
2377 2377  
2378 2378          /* origin_head should have no long holds (e.g. is not mounted) */
2379 2379          if (dsl_dataset_handoff_check(origin_head, owner, tx))
2380 2380                  return (SET_ERROR(EBUSY));
2381 2381  
2382 2382          /* check amount of any unconsumed refreservation */
2383 2383          unused_refres_delta =
2384 2384              (int64_t)MIN(origin_head->ds_reserved,
2385 2385              origin_head->ds_phys->ds_unique_bytes) -
↓ open down ↓ 16 lines elided ↑ open up ↑
2402 2402  void
2403 2403  dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
2404 2404      dsl_dataset_t *origin_head, dmu_tx_t *tx)
2405 2405  {
2406 2406          dsl_pool_t *dp = dmu_tx_pool(tx);
2407 2407          int64_t unused_refres_delta;
2408 2408  
2409 2409          ASSERT(clone->ds_reserved == 0);
2410 2410          ASSERT(origin_head->ds_quota == 0 ||
2411 2411              clone->ds_phys->ds_unique_bytes <= origin_head->ds_quota);
     2412 +        ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev);
2412 2413  
2413 2414          dmu_buf_will_dirty(clone->ds_dbuf, tx);
2414 2415          dmu_buf_will_dirty(origin_head->ds_dbuf, tx);
2415 2416  
2416 2417          if (clone->ds_objset != NULL) {
2417 2418                  dmu_objset_evict(clone->ds_objset);
2418 2419                  clone->ds_objset = NULL;
2419 2420          }
2420 2421  
2421 2422          if (origin_head->ds_objset != NULL) {
↓ open down ↓ 572 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX