]> granicus.if.org Git - zfs/commitdiff
Merge branch 'feature-zap-cursor-to-key' into refs/top-bases/feature-branch
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 6 Jul 2009 20:15:35 +0000 (13:15 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 6 Jul 2009 20:15:35 +0000 (13:15 -0700)
Conflicts:

cmd/ztest/ztest.c

1  2 
cmd/zdb/zdb.c
cmd/ztest/ztest.c
lib/libzpool/include/sys/zfs_context.h
lib/libzpool/taskq.c
module/zfs/dmu_tx.c
module/zfs/include/sys/dmu.h

diff --cc cmd/zdb/zdb.c
Simple merge
index 13080637845ca32e824897968c7cf91ef23cf9da,746db0c070a5d991aa8239d9c1f854541436c868..181d4fc2aec245b049ab342d88617f6ecebe194b
@@@ -162,9 -164,9 +164,10 @@@ typedef void ztest_func_t(ztest_args_t 
   * Note: these aren't static because we want dladdr() to work.
   */
  ztest_func_t ztest_dmu_read_write;
+ ztest_func_t ztest_dmu_read_write_zcopy;
  ztest_func_t ztest_dmu_write_parallel;
  ztest_func_t ztest_dmu_object_alloc_free;
 +ztest_func_t ztest_dmu_commit_callbacks;
  ztest_func_t ztest_zap;
  ztest_func_t ztest_zap_parallel;
  ztest_func_t ztest_traverse;
@@@ -197,9 -200,9 +201,10 @@@ uint64_t zopt_rarely = 60;                /* every 6
  
  ztest_info_t ztest_info[] = {
        { ztest_dmu_read_write,                 1,      &zopt_always    },
+       { ztest_dmu_read_write_zcopy,           1,      &zopt_always    },
        { ztest_dmu_write_parallel,             30,     &zopt_always    },
        { ztest_dmu_object_alloc_free,          1,      &zopt_always    },
 +      { ztest_dmu_commit_callbacks,           10,     &zopt_always    },
        { ztest_zap,                            30,     &zopt_always    },
        { ztest_zap_parallel,                   100,    &zopt_always    },
        { ztest_dsl_prop_get_set,               1,      &zopt_sometimes },
@@@ -1145,9 -1140,98 +1153,98 @@@ ztest_vdev_attach_detach(ztest_args_t *
                    (longlong_t)newsize, replacing, error, expected_error);
        }
  
 -      (void) mutex_unlock(&ztest_shared->zs_vdev_lock);
 +      (void) pthread_mutex_unlock(&ztest_shared->zs_vdev_lock);
  }
  
+ /*
+  * Callback function which expands the physical size of the vdev.
+  */
+ vdev_t *
+ grow_vdev(vdev_t *vd, void *arg)
+ {
+       spa_t *spa = vd->vdev_spa;
+       size_t *newsize = arg;
+       size_t fsize;
+       int fd;
+       ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
+       ASSERT(vd->vdev_ops->vdev_op_leaf);
+       if ((fd = open(vd->vdev_path, O_RDWR)) == -1)
+               return (vd);
+       fsize = lseek(fd, 0, SEEK_END);
+       (void) ftruncate(fd, *newsize);
+       if (zopt_verbose >= 6) {
+               (void) printf("%s grew from %lu to %lu bytes\n",
+                   vd->vdev_path, (ulong_t)fsize, (ulong_t)*newsize);
+       }
+       (void) close(fd);
+       return (NULL);
+ }
+ /*
+  * Callback function which expands a given vdev by calling vdev_online().
+  */
+ /* ARGSUSED */
+ vdev_t *
+ online_vdev(vdev_t *vd, void *arg)
+ {
+       spa_t *spa = vd->vdev_spa;
+       vdev_t *tvd = vd->vdev_top;
+       vdev_t *pvd = vd->vdev_parent;
+       uint64_t guid = vd->vdev_guid;
+       ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
+       ASSERT(vd->vdev_ops->vdev_op_leaf);
+       /* Calling vdev_online will initialize the new metaslabs */
+       spa_config_exit(spa, SCL_STATE, spa);
+       (void) vdev_online(spa, guid, ZFS_ONLINE_EXPAND, NULL);
+       spa_config_enter(spa, SCL_STATE, spa, RW_READER);
+       /*
+        * Since we dropped the lock we need to ensure that we're
+        * still talking to the original vdev. It's possible this
+        * vdev may have been detached/replaced while we were
+        * trying to online it.
+        */
+       if (vd != vdev_lookup_by_guid(tvd, guid) || vd->vdev_parent != pvd) {
+               if (zopt_verbose >= 6) {
+                       (void) printf("vdev %p has disappeared, was "
+                           "guid %llu\n", (void *)vd, (u_longlong_t)guid);
+               }
+               return (vd);
+       }
+       return (NULL);
+ }
+ /*
+  * Traverse the vdev tree calling the supplied function.
+  * We continue to walk the tree until we either have walked all
+  * children or we receive a non-NULL return from the callback.
+  * If a NULL callback is passed, then we just return back the first
+  * leaf vdev we encounter.
+  */
+ vdev_t *
+ vdev_walk_tree(vdev_t *vd, vdev_t *(*func)(vdev_t *, void *), void *arg)
+ {
+       if (vd->vdev_ops->vdev_op_leaf) {
+               if (func == NULL)
+                       return (vd);
+               else
+                       return (func(vd, arg));
+       }
+       for (uint_t c = 0; c < vd->vdev_children; c++) {
+               vdev_t *cvd = vd->vdev_child[c];
+               if ((cvd = vdev_walk_tree(cvd, func, arg)) != NULL)
+                       return (cvd);
+       }
+       return (NULL);
+ }
  /*
   * Verify that dynamic LUN growth works as expected.
   */
@@@ -1443,9 -1592,151 +1605,151 @@@ ztest_dmu_snapshot_create_destroy(ztest
                ztest_record_enospc("dmu_take_snapshot");
        else if (error != 0 && error != EEXIST)
                fatal(0, "dmu_take_snapshot() = %d", error);
 -      (void) rw_unlock(&ztest_shared->zs_name_lock);
 +      (void) pthread_rwlock_unlock(&ztest_shared->zs_name_lock);
  }
  
+ /*
+  * Cleanup non-standard snapshots and clones.
+  */
+ void
+ ztest_dsl_dataset_cleanup(char *osname, uint64_t curval)
+ {
+       char snap1name[100];
+       char clone1name[100];
+       char snap2name[100];
+       char clone2name[100];
+       char snap3name[100];
+       int error;
+       (void) snprintf(snap1name, 100, "%s@s1_%llu", osname, curval);
+       (void) snprintf(clone1name, 100, "%s/c1_%llu", osname, curval);
+       (void) snprintf(snap2name, 100, "%s@s2_%llu", clone1name, curval);
+       (void) snprintf(clone2name, 100, "%s/c2_%llu", osname, curval);
+       (void) snprintf(snap3name, 100, "%s@s3_%llu", clone1name, curval);
+       error = dmu_objset_destroy(clone2name);
+       if (error && error != ENOENT)
+               fatal(0, "dmu_objset_destroy(%s) = %d", clone2name, error);
+       error = dmu_objset_destroy(snap3name);
+       if (error && error != ENOENT)
+               fatal(0, "dmu_objset_destroy(%s) = %d", snap3name, error);
+       error = dmu_objset_destroy(snap2name);
+       if (error && error != ENOENT)
+               fatal(0, "dmu_objset_destroy(%s) = %d", snap2name, error);
+       error = dmu_objset_destroy(clone1name);
+       if (error && error != ENOENT)
+               fatal(0, "dmu_objset_destroy(%s) = %d", clone1name, error);
+       error = dmu_objset_destroy(snap1name);
+       if (error && error != ENOENT)
+               fatal(0, "dmu_objset_destroy(%s) = %d", snap1name, error);
+ }
+ /*
+  * Verify dsl_dataset_promote handles EBUSY
+  */
+ void
+ ztest_dsl_dataset_promote_busy(ztest_args_t *za)
+ {
+       int error;
+       objset_t *os = za->za_os;
+       objset_t *clone;
+       dsl_dataset_t *ds;
+       char snap1name[100];
+       char clone1name[100];
+       char snap2name[100];
+       char clone2name[100];
+       char snap3name[100];
+       char osname[MAXNAMELEN];
+       uint64_t curval = za->za_instance;
+       (void) rw_rdlock(&ztest_shared->zs_name_lock);
+       dmu_objset_name(os, osname);
+       ztest_dsl_dataset_cleanup(osname, curval);
+       (void) snprintf(snap1name, 100, "%s@s1_%llu", osname, curval);
+       (void) snprintf(clone1name, 100, "%s/c1_%llu", osname, curval);
+       (void) snprintf(snap2name, 100, "%s@s2_%llu", clone1name, curval);
+       (void) snprintf(clone2name, 100, "%s/c2_%llu", osname, curval);
+       (void) snprintf(snap3name, 100, "%s@s3_%llu", clone1name, curval);
+       error = dmu_objset_snapshot(osname, strchr(snap1name, '@')+1,
+           NULL, FALSE);
+       if (error && error != EEXIST) {
+               if (error == ENOSPC) {
+                       ztest_record_enospc("dmu_take_snapshot");
+                       goto out;
+               }
+               fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error);
+       }
+       error = dmu_objset_open(snap1name, DMU_OST_OTHER,
+           DS_MODE_USER | DS_MODE_READONLY, &clone);
+       if (error)
+               fatal(0, "dmu_open_snapshot(%s) = %d", snap1name, error);
+       error = dmu_objset_create(clone1name, DMU_OST_OTHER, clone, 0,
+           NULL, NULL);
+       dmu_objset_close(clone);
+       if (error) {
+               if (error == ENOSPC) {
+                       ztest_record_enospc("dmu_objset_create");
+                       goto out;
+               }
+               fatal(0, "dmu_objset_create(%s) = %d", clone1name, error);
+       }
+       error = dmu_objset_snapshot(clone1name, strchr(snap2name, '@')+1,
+           NULL, FALSE);
+       if (error && error != EEXIST) {
+               if (error == ENOSPC) {
+                       ztest_record_enospc("dmu_take_snapshot");
+                       goto out;
+               }
+               fatal(0, "dmu_open_snapshot(%s) = %d", snap2name, error);
+       }
+       error = dmu_objset_snapshot(clone1name, strchr(snap3name, '@')+1,
+           NULL, FALSE);
+       if (error && error != EEXIST) {
+               if (error == ENOSPC) {
+                       ztest_record_enospc("dmu_take_snapshot");
+                       goto out;
+               }
+               fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
+       }
+       error = dmu_objset_open(snap3name, DMU_OST_OTHER,
+           DS_MODE_USER | DS_MODE_READONLY, &clone);
+       if (error)
+               fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
+       error = dmu_objset_create(clone2name, DMU_OST_OTHER, clone, 0,
+           NULL, NULL);
+       dmu_objset_close(clone);
+       if (error) {
+               if (error == ENOSPC) {
+                       ztest_record_enospc("dmu_objset_create");
+                       goto out;
+               }
+               fatal(0, "dmu_objset_create(%s) = %d", clone2name, error);
+       }
+       error = dsl_dataset_own(snap1name, DS_MODE_READONLY, FTAG, &ds);
+       if (error)
+               fatal(0, "dsl_dataset_own(%s) = %d", snap1name, error);
+       error = dsl_dataset_promote(clone2name);
+       if (error != EBUSY)
+               fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name,
+                   error);
+       dsl_dataset_disown(ds, FTAG);
+ out:
+       ztest_dsl_dataset_cleanup(osname, curval);
+       (void) rw_unlock(&ztest_shared->zs_name_lock);
+ }
  /*
   * Verify that dmu_object_{alloc,free} work as expected.
   */
@@@ -2040,11 -2653,15 +2666,15 @@@ ztest_dmu_write_parallel(ztest_args_t *
                za->za_dbuf = NULL;
        } else if (do_free) {
                VERIFY(dmu_free_range(os, ZTEST_DIROBJ, off, bs, tx) == 0);
-       } else {
+       } else if (abuf == NULL) {
                dmu_write(os, ZTEST_DIROBJ, off, btsize, wbt, tx);
+       } else {
+               bcopy(wbt, abuf->b_data, btsize);
+               dmu_assign_arcbuf(bonus_db, off, abuf, tx);
+               dmu_buf_rele(bonus_db, FTAG);
        }
  
 -      (void) mutex_unlock(lp);
 +      (void) pthread_mutex_unlock(lp);
  
        if (ztest_random(1000) == 0)
                (void) poll(NULL, 0, 1); /* open dn_notxholds window */
@@@ -3158,9 -3578,8 +3792,9 @@@ ztest_resume(void *arg
                spa_vdev_state_enter(spa);
                vdev_clear(spa, NULL);
                (void) spa_vdev_state_exit(spa, NULL, 0);
-               zio_resume(spa);
+               (void) zio_resume(spa);
        }
 +      return (NULL);
  }
  
  static void *
@@@ -3434,9 -3850,13 +4068,13 @@@ ztest_run(char *pool
                (void) snprintf(name, 100, "%s/%s_%d", pool, pool, d);
                if (zopt_verbose >= 3)
                        (void) printf("Destroying %s to free up space\n", name);
+               /* Cleanup any non-standard clones and snapshots */
+               ztest_dsl_dataset_cleanup(name, za[d].za_instance);
                (void) dmu_objset_find(name, ztest_destroy_cb, &za[d],
                    DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
 -              (void) rw_unlock(&ztest_shared->zs_name_lock);
 +              (void) pthread_rwlock_unlock(&ztest_shared->zs_name_lock);
        }
  
        txg_wait_synced(spa_get_dsl(spa), 0);
Simple merge
Simple merge
Simple merge