From 976b01efda108e6b8b9606b5bf07676cda00e1dc Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 20 Nov 2008 12:09:33 -0800 Subject: [PATCH 1/7] Add feature-commit-cb branch --- .topdeps | 1 + .topmsg | 12 +++++ zfs/lib/libzcommon/include/sys/dmu.h | 27 ++++++++++ zfs/lib/libzcommon/include/sys/dmu_impl.h | 13 +++++ zfs/lib/libzcommon/include/sys/dmu_tx.h | 6 +++ zfs/lib/libzcommon/include/sys/txg.h | 1 + zfs/lib/libzcommon/include/sys/txg_impl.h | 1 + zfs/lib/libzpool/dmu_tx.c | 61 +++++++++++++++++++++++ zfs/lib/libzpool/txg.c | 40 ++++++++++++++- 9 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 .topdeps create mode 100644 .topmsg diff --git a/.topdeps b/.topdeps new file mode 100644 index 0000000000..1f7391f92b --- /dev/null +++ b/.topdeps @@ -0,0 +1 @@ +master diff --git a/.topmsg b/.topmsg new file mode 100644 index 0000000000..c3cc0c8de8 --- /dev/null +++ b/.topmsg @@ -0,0 +1,12 @@ +From: Brian Behlendorf +Subject: [PATCH] feature commit cb + +ZFS commit callbacks (v3) some version of this support is expected +to appear in an official release from the core ZFS team. + +NOTE: The ztest test case was dropped because it assumed userspace +pthreads support. We should certainly keep the test case but the +user space modification should be properly written to handle and +kernel space build as well. + +Signed-off-by: Brian Behlendorf diff --git a/zfs/lib/libzcommon/include/sys/dmu.h b/zfs/lib/libzcommon/include/sys/dmu.h index 2f1cdfc7f9..84bf6c0790 100644 --- a/zfs/lib/libzcommon/include/sys/dmu.h +++ b/zfs/lib/libzcommon/include/sys/dmu.h @@ -66,6 +66,7 @@ struct objset_impl; typedef struct objset objset_t; typedef struct dmu_tx dmu_tx_t; typedef struct dsl_dir dsl_dir_t; +typedef void dmu_callback_func_t(void *dcb_data, int error); typedef enum dmu_object_type { DMU_OT_NONE, @@ -416,6 +417,32 @@ int dmu_tx_assign(dmu_tx_t *tx, uint64_t txg_how); void dmu_tx_wait(dmu_tx_t *tx); void dmu_tx_commit(dmu_tx_t *tx); +/* + * To add a commit callback, you must first call dmu_tx_callback_data_create(). + * This will return a pointer to a memory area of size "bytes" (which can be 0, + * or just the size of a pointer if there is a large or existing external data + * struct to be referenced) that the caller and the callback can use to exchange + * data. + * + * The callback can then be registered by calling dmu_tx_callback_commit_add() + * with the pointer returned by dmu_tx_callback_data_create() passed in the + * dcb_data argument. The transaction must be already created, but it cannot + * be committed or aborted. It can be assigned to a txg or not. + * + * The callback will be called after the transaction has been safely written + * to stable storage and will also be called if the dmu_tx is aborted. + * If there is any error which prevents the transaction from being committed + * to disk, the callback will be called with a value of error != 0. + * + * When the callback data is no longer needed, it must be destroyed by the + * caller's code with dmu_tx_callback_data_destroy(). This is typically done at + * the end of the callback function. + */ +void *dmu_tx_callback_data_create(size_t bytes); +int dmu_tx_callback_commit_add(dmu_tx_t *tx, dmu_callback_func_t *dcb_func, + void *dcb_data); +int dmu_tx_callback_data_destroy(void *dcb_data); + /* * Free up the data blocks for a defined range of a file. If size is * zero, the range from offset to end-of-file is freed. diff --git a/zfs/lib/libzcommon/include/sys/dmu_impl.h b/zfs/lib/libzcommon/include/sys/dmu_impl.h index c06872bce0..44d588a1c2 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_impl.h +++ b/zfs/lib/libzcommon/include/sys/dmu_impl.h @@ -230,6 +230,19 @@ extern "C" { struct objset; struct dmu_pool; +#define DMU_CALLBACK_MAGIC 0xca11bac0ca11bacfull + +#define container_of(ptr, type, member) \ + ((type *)((char *)(ptr) - offsetof(type, member))) + +typedef struct dmu_callback { + list_node_t dcb_node; /* linked to tx_callbacks list */ + uint64_t dcb_magic; /* magic number to verify header */ + dmu_callback_func_t *dcb_func; /* caller function pointer */ + size_t dcb_bytes; /* caller private data size */ + char dcb_data[0]; /* caller private data */ +} dmu_callback_t; + #ifdef __cplusplus } #endif diff --git a/zfs/lib/libzcommon/include/sys/dmu_tx.h b/zfs/lib/libzcommon/include/sys/dmu_tx.h index 3c4ec9acdc..a90ab40915 100644 --- a/zfs/lib/libzcommon/include/sys/dmu_tx.h +++ b/zfs/lib/libzcommon/include/sys/dmu_tx.h @@ -59,6 +59,7 @@ struct dmu_tx { txg_handle_t tx_txgh; void *tx_tempreserve_cookie; struct dmu_tx_hold *tx_needassign_txh; + list_t tx_callbacks; /* list of dmu_callback_t on this dmu_tx */ uint8_t tx_anyobj; int tx_err; #ifdef ZFS_DEBUG @@ -107,6 +108,11 @@ void dmu_tx_abort(dmu_tx_t *tx); uint64_t dmu_tx_get_txg(dmu_tx_t *tx); void dmu_tx_wait(dmu_tx_t *tx); +void *dmu_tx_callback_data_create(size_t bytes); +int dmu_tx_callback_commit_add(dmu_tx_t *tx, dmu_callback_func_t *dcb_func, + void *dcb_data); +int dmu_tx_callback_data_destroy(void *dcb_data); + /* * These routines are defined in dmu_spa.h, and are called by the SPA. */ diff --git a/zfs/lib/libzcommon/include/sys/txg.h b/zfs/lib/libzcommon/include/sys/txg.h index d254d22784..617ff1e594 100644 --- a/zfs/lib/libzcommon/include/sys/txg.h +++ b/zfs/lib/libzcommon/include/sys/txg.h @@ -71,6 +71,7 @@ extern void txg_sync_stop(struct dsl_pool *dp); extern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp); extern void txg_rele_to_quiesce(txg_handle_t *txghp); extern void txg_rele_to_sync(txg_handle_t *txghp); +extern void txg_rele_commit_cb(txg_handle_t *txghp, list_t *tx_callbacks); extern void txg_suspend(struct dsl_pool *dp); extern void txg_resume(struct dsl_pool *dp); diff --git a/zfs/lib/libzcommon/include/sys/txg_impl.h b/zfs/lib/libzcommon/include/sys/txg_impl.h index d80062ab94..8c42e350a0 100644 --- a/zfs/lib/libzcommon/include/sys/txg_impl.h +++ b/zfs/lib/libzcommon/include/sys/txg_impl.h @@ -39,6 +39,7 @@ struct tx_cpu { kmutex_t tc_lock; kcondvar_t tc_cv[TXG_SIZE]; uint64_t tc_count[TXG_SIZE]; + list_t tc_callbacks[TXG_SIZE]; /* post-commit callbacks */ char tc_pad[16]; }; diff --git a/zfs/lib/libzpool/dmu_tx.c b/zfs/lib/libzpool/dmu_tx.c index 8c40c26800..6a28a19243 100644 --- a/zfs/lib/libzpool/dmu_tx.c +++ b/zfs/lib/libzpool/dmu_tx.c @@ -50,6 +50,8 @@ dmu_tx_create_dd(dsl_dir_t *dd) tx->tx_pool = dd->dd_pool; list_create(&tx->tx_holds, sizeof (dmu_tx_hold_t), offsetof(dmu_tx_hold_t, txh_node)); + list_create(&tx->tx_callbacks, sizeof (dmu_callback_t), + offsetof(dmu_callback_t, dcb_node)); #ifdef ZFS_DEBUG refcount_create(&tx->tx_space_written); refcount_create(&tx->tx_space_freed); @@ -986,6 +988,9 @@ dmu_tx_commit(dmu_tx_t *tx) if (tx->tx_tempreserve_cookie) dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx); + if (!list_is_empty(&tx->tx_callbacks)) + txg_rele_commit_cb(&tx->tx_txgh, &tx->tx_callbacks); + if (tx->tx_anyobj == FALSE) txg_rele_to_sync(&tx->tx_txgh); list_destroy(&tx->tx_holds); @@ -998,6 +1003,8 @@ dmu_tx_commit(dmu_tx_t *tx) refcount_destroy_many(&tx->tx_space_freed, refcount_count(&tx->tx_space_freed)); #endif + ASSERT(list_is_empty(&tx->tx_callbacks)); + list_destroy(&tx->tx_callbacks); kmem_free(tx, sizeof (dmu_tx_t)); } @@ -1005,6 +1012,7 @@ void dmu_tx_abort(dmu_tx_t *tx) { dmu_tx_hold_t *txh; + dmu_callback_t *dcb; ASSERT(tx->tx_txg == 0); @@ -1016,6 +1024,16 @@ dmu_tx_abort(dmu_tx_t *tx) if (dn != NULL) dnode_rele(dn, tx); } + + while (dcb = list_head(&tx->tx_callbacks)) { + list_remove(&tx->tx_callbacks, dcb); + + /* + * Call the callback with an error code. The callback will + * call dmu_tx_callback_data_destroy to free the memory. + */ + dcb->dcb_func(dcb->dcb_data, ECANCELED); + } list_destroy(&tx->tx_holds); #ifdef ZFS_DEBUG refcount_destroy_many(&tx->tx_space_written, @@ -1023,6 +1041,7 @@ dmu_tx_abort(dmu_tx_t *tx) refcount_destroy_many(&tx->tx_space_freed, refcount_count(&tx->tx_space_freed)); #endif + list_destroy(&tx->tx_callbacks); kmem_free(tx, sizeof (dmu_tx_t)); } @@ -1032,3 +1051,45 @@ dmu_tx_get_txg(dmu_tx_t *tx) ASSERT(tx->tx_txg != 0); return (tx->tx_txg); } + +void * +dmu_tx_callback_data_create(size_t bytes) +{ + dmu_callback_t *dcb; + + dcb = kmem_alloc(sizeof (dmu_callback_t) + bytes, KM_SLEEP); + + dcb->dcb_magic = DMU_CALLBACK_MAGIC; + dcb->dcb_bytes = bytes; + + return &dcb->dcb_data; +} + +int +dmu_tx_callback_commit_add(dmu_tx_t *tx, dmu_callback_func_t *dcb_func, + void *dcb_data) +{ + dmu_callback_t *dcb = container_of(dcb_data, dmu_callback_t, dcb_data); + + if (dcb->dcb_magic != DMU_CALLBACK_MAGIC) + return (EINVAL); + + dcb->dcb_func = dcb_func; + + list_insert_tail(&tx->tx_callbacks, dcb); + + return (0); +} + +int +dmu_tx_callback_data_destroy(void *dcb_data) +{ + dmu_callback_t *dcb = container_of(dcb_data, dmu_callback_t, dcb_data); + + if (dcb->dcb_magic != DMU_CALLBACK_MAGIC) + return (EINVAL); + + kmem_free(dcb, sizeof (dmu_callback_t) + dcb->dcb_bytes); + + return (0); +} diff --git a/zfs/lib/libzpool/txg.c b/zfs/lib/libzpool/txg.c index f810a0dc66..a745d3a56c 100644 --- a/zfs/lib/libzpool/txg.c +++ b/zfs/lib/libzpool/txg.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,9 @@ txg_init(dsl_pool_t *dp, uint64_t txg) for (i = 0; i < TXG_SIZE; i++) { cv_init(&tx->tx_cpu[c].tc_cv[i], NULL, CV_DEFAULT, NULL); + list_create(&tx->tx_cpu[c].tc_callbacks[i], + sizeof (dmu_callback_t), offsetof(dmu_callback_t, + dcb_node)); } } @@ -93,8 +97,11 @@ txg_fini(dsl_pool_t *dp) int i; mutex_destroy(&tx->tx_cpu[c].tc_lock); - for (i = 0; i < TXG_SIZE; i++) + for (i = 0; i < TXG_SIZE; i++) { cv_destroy(&tx->tx_cpu[c].tc_cv[i]); + ASSERT(list_is_empty(&tx->tx_cpu[c].tc_callbacks[i])); + list_destroy(&tx->tx_cpu[c].tc_callbacks[i]); + } } kmem_free(tx->tx_cpu, max_ncpus * sizeof (tx_cpu_t)); @@ -235,6 +242,21 @@ txg_rele_to_sync(txg_handle_t *th) th->th_cpu = NULL; /* defensive */ } +void +txg_rele_commit_cb(txg_handle_t *th, list_t *tx_callbacks) +{ + dmu_callback_t *dcb; + tx_cpu_t *tc = th->th_cpu; + int g = th->th_txg & TXG_MASK; + + mutex_enter(&tc->tc_lock); + while (dcb = list_head(tx_callbacks)) { + list_remove(tx_callbacks, dcb); + list_insert_tail(&tc->tc_callbacks[g], dcb); + } + mutex_exit(&tc->tc_lock); +} + static void txg_quiesce(dsl_pool_t *dp, uint64_t txg) { @@ -335,6 +357,21 @@ txg_sync_thread(dsl_pool_t *dp) spa_sync(dp->dp_spa, txg); delta = lbolt - start; + /* + * Call all the callbacks for this txg. The callbacks must + * call dmu_tx_callback_data_destroy to free memory. + */ + for (int c = 0; c < max_ncpus; c++) { + int g = txg & TXG_MASK; + tx_cpu_t *tc = &tx->tx_cpu[c]; + /* No need to lock tx_cpu_t */ + + while (dcb = list_head(&tc->tc_callbacks[g])) { + list_remove(&tc->tc_callbacks[g], dcb); + dcb->dcb_func(dcb->dcb_data, 0); + } + } + written = dp->dp_space_towrite[txg & TXG_MASK]; dp->dp_space_towrite[txg & TXG_MASK] = 0; ASSERT(dp->dp_tempreserved[txg & TXG_MASK] == 0); @@ -390,6 +427,7 @@ txg_quiesce_thread(dsl_pool_t *dp) { tx_state_t *tx = &dp->dp_tx; callb_cpr_t cpr; + dmu_callback_t *dcb; txg_thread_enter(tx, &cpr); From 97f0b79796f9edda8d0f21136d0a8a1c179baedc Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 20 Nov 2008 12:11:21 -0800 Subject: [PATCH 2/7] Add feature-zap-cursor-to-key branch --- .topdeps | 1 + .topmsg | 6 ++++ zfs/lib/libzcommon/include/sys/zap.h | 5 +++ zfs/lib/libzcommon/include/sys/zap_impl.h | 1 + zfs/lib/libzpool/zap.c | 24 ++++++++++++++ zfs/lib/libzpool/zap_micro.c | 39 +++++++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 .topdeps create mode 100644 .topmsg diff --git a/.topdeps b/.topdeps new file mode 100644 index 0000000000..1f7391f92b --- /dev/null +++ b/.topdeps @@ -0,0 +1 @@ +master diff --git a/.topmsg b/.topmsg new file mode 100644 index 0000000000..7727ce8d3f --- /dev/null +++ b/.topmsg @@ -0,0 +1,6 @@ +From: Brian Behlendorf +Subject: [PATCH] feature zap cursor to key + +Add a ZAP API to move a ZAP cursor to a given key + +Signed-off-by: Brian Behlendorf diff --git a/zfs/lib/libzcommon/include/sys/zap.h b/zfs/lib/libzcommon/include/sys/zap.h index df1ef8c9d2..62403d451c 100644 --- a/zfs/lib/libzcommon/include/sys/zap.h +++ b/zfs/lib/libzcommon/include/sys/zap.h @@ -301,6 +301,11 @@ void zap_cursor_advance(zap_cursor_t *zc); */ uint64_t zap_cursor_serialize(zap_cursor_t *zc); +/* + * Advance the cursor to the attribute having the key. + */ +int zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt); + /* * Initialize a zap cursor pointing to the position recorded by * zap_cursor_serialize (in the "serialized" argument). You can also diff --git a/zfs/lib/libzcommon/include/sys/zap_impl.h b/zfs/lib/libzcommon/include/sys/zap_impl.h index 8517471984..7b9c8a2b77 100644 --- a/zfs/lib/libzcommon/include/sys/zap_impl.h +++ b/zfs/lib/libzcommon/include/sys/zap_impl.h @@ -210,6 +210,7 @@ int fzap_add_cd(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, const void *val, uint32_t cd, dmu_tx_t *tx); void fzap_upgrade(zap_t *zap, dmu_tx_t *tx); +int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn); #ifdef __cplusplus } diff --git a/zfs/lib/libzpool/zap.c b/zfs/lib/libzpool/zap.c index f4f456ce8b..0484a29ab5 100644 --- a/zfs/lib/libzpool/zap.c +++ b/zfs/lib/libzpool/zap.c @@ -1029,6 +1029,30 @@ zap_stats_ptrtbl(zap_t *zap, uint64_t *tbl, int len, zap_stats_t *zs) } } +int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn) +{ + int err; + zap_leaf_t *l; + zap_entry_handle_t zeh; + uint64_t hash; + + if (zn->zn_name_orij && strlen(zn->zn_name_orij) > ZAP_MAXNAMELEN) + return (E2BIG); + + err = zap_deref_leaf(zc->zc_zap, zn->zn_hash, NULL, RW_READER, &l); + if (err != 0) + return (err); + + err = zap_leaf_lookup(l, zn, &zeh); + if (err != 0) + return (err); + + zc->zc_leaf = l; + zc->zc_hash = zeh.zeh_hash; + zc->zc_cd = zeh.zeh_cd; + return 0; +} + void fzap_get_stats(zap_t *zap, zap_stats_t *zs) { diff --git a/zfs/lib/libzpool/zap_micro.c b/zfs/lib/libzpool/zap_micro.c index 7aea76b311..c633be4035 100644 --- a/zfs/lib/libzpool/zap_micro.c +++ b/zfs/lib/libzpool/zap_micro.c @@ -1045,6 +1045,45 @@ zap_cursor_advance(zap_cursor_t *zc) } } +int zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt) +{ + int err = 0; + mzap_ent_t *mze; + zap_name_t *zn; + + if (zc->zc_zap == NULL) { + err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL, + RW_READER, TRUE, FALSE, &zc->zc_zap); + if (err) + return (err); + } else { + rw_enter(&zc->zc_zap->zap_rwlock, RW_READER); + } + + zn = zap_name_alloc(zc->zc_zap, name, mt); + if (zn == NULL) { + rw_exit(&zc->zc_zap->zap_rwlock); + return (ENOTSUP); + } + + if (!zc->zc_zap->zap_ismicro) { + err = fzap_cursor_move_to_key(zc, zn); + } else { + mze = mze_find(zn); + if (mze == NULL) { + err = (ENOENT); + goto out; + } + zc->zc_hash = mze->mze_hash; + zc->zc_cd = mze->mze_phys.mze_cd; + } + +out: + zap_name_free(zn); + rw_exit(&zc->zc_zap->zap_rwlock); + return (err); +} + int zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs) { From 4b67af72f4f5e9b1d1b0601e8212588d31e5d59c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 24 Nov 2008 14:33:02 -0800 Subject: [PATCH 3/7] Resolve C99 complience issue introduce by patch --- zfs/lib/libzpool/txg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zfs/lib/libzpool/txg.c b/zfs/lib/libzpool/txg.c index a745d3a56c..0b9ad1f701 100644 --- a/zfs/lib/libzpool/txg.c +++ b/zfs/lib/libzpool/txg.c @@ -250,7 +250,7 @@ txg_rele_commit_cb(txg_handle_t *th, list_t *tx_callbacks) int g = th->th_txg & TXG_MASK; mutex_enter(&tc->tc_lock); - while (dcb = list_head(tx_callbacks)) { + while ((dcb = list_head(tx_callbacks))) { list_remove(tx_callbacks, dcb); list_insert_tail(&tc->tc_callbacks[g], dcb); } @@ -298,7 +298,7 @@ txg_sync_thread(dsl_pool_t *dp) tx_state_t *tx = &dp->dp_tx; callb_cpr_t cpr; uint64_t timeout, start, delta, timer; - int target; + int c, target; txg_thread_enter(tx, &cpr); @@ -361,12 +361,13 @@ txg_sync_thread(dsl_pool_t *dp) * Call all the callbacks for this txg. The callbacks must * call dmu_tx_callback_data_destroy to free memory. */ - for (int c = 0; c < max_ncpus; c++) { - int g = txg & TXG_MASK; + for (c = 0; c < max_ncpus; c++) { + dmu_callback_t *dcb; tx_cpu_t *tc = &tx->tx_cpu[c]; + int g = txg & TXG_MASK; /* No need to lock tx_cpu_t */ - while (dcb = list_head(&tc->tc_callbacks[g])) { + while ((dcb = list_head(&tc->tc_callbacks[g]))) { list_remove(&tc->tc_callbacks[g], dcb); dcb->dcb_func(dcb->dcb_data, 0); } @@ -427,7 +428,6 @@ txg_quiesce_thread(dsl_pool_t *dp) { tx_state_t *tx = &dp->dp_tx; callb_cpr_t cpr; - dmu_callback_t *dcb; txg_thread_enter(tx, &cpr); From 572b26ddc3d0ba0ee202a56f16d57fca5ee5bb06 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 24 Nov 2008 14:45:56 -0800 Subject: [PATCH 4/7] Resolve 'suggest parentheses' warning which was introduced --- zfs/lib/libzpool/dmu_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zfs/lib/libzpool/dmu_tx.c b/zfs/lib/libzpool/dmu_tx.c index 6a28a19243..93eb58851c 100644 --- a/zfs/lib/libzpool/dmu_tx.c +++ b/zfs/lib/libzpool/dmu_tx.c @@ -1025,7 +1025,7 @@ dmu_tx_abort(dmu_tx_t *tx) dnode_rele(dn, tx); } - while (dcb = list_head(&tx->tx_callbacks)) { + while ((dcb = list_head(&tx->tx_callbacks))) { list_remove(&tx->tx_callbacks, dcb); /* From 578cd5b14fef912972d2d768b949fca9818b101a Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 24 Nov 2008 14:52:12 -0800 Subject: [PATCH 5/7] Remove unused variable hash --- zfs/lib/libzpool/zap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zfs/lib/libzpool/zap.c b/zfs/lib/libzpool/zap.c index 0484a29ab5..da8f312617 100644 --- a/zfs/lib/libzpool/zap.c +++ b/zfs/lib/libzpool/zap.c @@ -1034,7 +1034,6 @@ int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn) int err; zap_leaf_t *l; zap_entry_handle_t zeh; - uint64_t hash; if (zn->zn_name_orij && strlen(zn->zn_name_orij) > ZAP_MAXNAMELEN) return (E2BIG); From e24f5be337e3e0e2ec9289bb5c8119a9870965b6 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 3 Dec 2008 12:47:38 -0800 Subject: [PATCH 6/7] Recreate feature-branch to simply feature merge --- .topdeps | 2 +- .topmsg | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.topdeps b/.topdeps index 1f7391f92b..9fdb648b9d 100644 --- a/.topdeps +++ b/.topdeps @@ -1 +1 @@ -master +feature-commit-cb diff --git a/.topmsg b/.topmsg index c3cc0c8de8..56485000ad 100644 --- a/.topmsg +++ b/.topmsg @@ -1,12 +1,6 @@ From: Brian Behlendorf -Subject: [PATCH] feature commit cb +Subject: [PATCH] feature branch -ZFS commit callbacks (v3) some version of this support is expected -to appear in an official release from the core ZFS team. - -NOTE: The ztest test case was dropped because it assumed userspace -pthreads support. We should certainly keep the test case but the -user space modification should be properly written to handle and -kernel space build as well. +Merged result of all expected upstream ZFS features Signed-off-by: Brian Behlendorf From 04cd3d24f9c169343c0b933f9edef890837fd22b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 3 Dec 2008 12:47:52 -0800 Subject: [PATCH 7/7] New TopGit dependency: feature-zap-cursor-to-key --- .topdeps | 1 + 1 file changed, 1 insertion(+) diff --git a/.topdeps b/.topdeps index 9fdb648b9d..2594b30f5e 100644 --- a/.topdeps +++ b/.topdeps @@ -1 +1,2 @@ feature-commit-cb +feature-zap-cursor-to-key