summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2010-09-27 09:05:51 +0000
committermm <mm@FreeBSD.org>2010-09-27 09:05:51 +0000
commit06d7ad088338844d37a5a4328b1c4bb5de1a68a2 (patch)
tree51bc74c1fcdcb6583ce0325e215ee1938ced28f3 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
parent776968f31350da9df36c96599691f3e375ccfba4 (diff)
downloadFreeBSD-src-06d7ad088338844d37a5a4328b1c4bb5de1a68a2.zip
FreeBSD-src-06d7ad088338844d37a5a4328b1c4bb5de1a68a2.tar.gz
Enable offlining of log devices.
OpenSolaris revision and Bug IDs: 9701:cc5b64682e64 6803605 should be able to offline log devices 6726045 vdev_deflate_ratio is not set when offlining a log device 6599442 zpool import has faults in the display Approved by: delphij (mentor) Obtained from: OpenSolaris (Bug ID 6803605, 6726045, 6599442) MFC after: 3 weeks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
index 7839713..1dd8ea0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
@@ -25,6 +25,7 @@
#include <sys/zfs_context.h>
#include <sys/spa.h>
+#include <sys/spa_impl.h>
#include <sys/dmu.h>
#include <sys/zap.h>
#include <sys/arc.h>
@@ -515,6 +516,13 @@ zil_claim(char *osname, void *txarg)
zilog = dmu_objset_zil(os);
zh = zil_header_in_syncing_context(zilog);
+ if (zilog->zl_spa->spa_log_state == SPA_LOG_CLEAR) {
+ if (!BP_IS_HOLE(&zh->zh_log))
+ zio_free_blk(zilog->zl_spa, &zh->zh_log, first_txg);
+ BP_ZERO(&zh->zh_log);
+ dsl_dataset_dirty(dmu_objset_ds(os), tx);
+ }
+
/*
* Record here whether the zil has any records to replay.
* If the header block pointer is null or the block points
@@ -527,8 +535,10 @@ zil_claim(char *osname, void *txarg)
* Note, the intent log can be empty but still need the
* stubby to be claimed.
*/
- if (!zil_empty(zilog))
+ if (!zil_empty(zilog)) {
zh->zh_flags |= ZIL_REPLAY_NEEDED;
+ dsl_dataset_dirty(dmu_objset_ds(os), tx);
+ }
/*
* Claim all log blocks if we haven't already done so, and remember
@@ -597,36 +607,6 @@ zil_check_log_chain(char *osname, void *txarg)
return (error);
}
-/*
- * Clear a log chain
- */
-/* ARGSUSED */
-int
-zil_clear_log_chain(char *osname, void *txarg)
-{
- zilog_t *zilog;
- zil_header_t *zh;
- objset_t *os;
- dmu_tx_t *tx;
- int error;
-
- error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os);
- if (error) {
- cmn_err(CE_WARN, "can't open objset for %s", osname);
- return (0);
- }
-
- zilog = dmu_objset_zil(os);
- tx = dmu_tx_create(zilog->zl_os);
- (void) dmu_tx_assign(tx, TXG_WAIT);
- zh = zil_header_in_syncing_context(zilog);
- BP_ZERO(&zh->zh_log);
- dsl_dataset_dirty(dmu_objset_ds(os), tx);
- dmu_tx_commit(tx);
- dmu_objset_close(os);
- return (0);
-}
-
static int
zil_vdev_compare(const void *x1, const void *x2)
{
@@ -771,9 +751,9 @@ zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb)
}
if (lwb->lwb_zio == NULL) {
lwb->lwb_zio = zio_rewrite(zilog->zl_root_zio, zilog->zl_spa,
- 0, &lwb->lwb_blk, lwb->lwb_buf,
- lwb->lwb_sz, zil_lwb_write_done, lwb,
- ZIO_PRIORITY_LOG_WRITE, ZIO_FLAG_CANFAIL, &zb);
+ 0, &lwb->lwb_blk, lwb->lwb_buf, lwb->lwb_sz,
+ zil_lwb_write_done, lwb, ZIO_PRIORITY_LOG_WRITE,
+ ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE, &zb);
}
}
@@ -1270,12 +1250,7 @@ zil_sync(zilog_t *zilog, dmu_tx_t *tx)
}
}
- for (;;) {
- lwb = list_head(&zilog->zl_lwb_list);
- if (lwb == NULL) {
- mutex_exit(&zilog->zl_lock);
- return;
- }
+ while ((lwb = list_head(&zilog->zl_lwb_list)) != NULL) {
zh->zh_log = lwb->lwb_blk;
if (lwb->lwb_buf != NULL || lwb->lwb_max_txg > txg)
break;
@@ -1692,3 +1667,24 @@ out:
mutex_exit(&zilog->zl_lock);
return (ret);
}
+
+/* ARGSUSED */
+int
+zil_vdev_offline(char *osname, void *arg)
+{
+ objset_t *os;
+ zilog_t *zilog;
+ int error;
+
+ error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os);
+ if (error)
+ return (error);
+
+ zilog = dmu_objset_zil(os);
+ if (zil_suspend(zilog) != 0)
+ error = EEXIST;
+ else
+ zil_resume(zilog);
+ dmu_objset_close(os);
+ return (error);
+}
OpenPOWER on IntegriCloud