diff options
author | Mark J Musante <Mark.Musante@Sun.COM> | 2010-05-03 09:07:08 -0600 |
---|---|---|
committer | Mark J Musante <Mark.Musante@Sun.COM> | 2010-05-03 09:07:08 -0600 |
commit | 55da60b91d96984f12de050ce428373ea25c7f35 (patch) | |
tree | a7ed1a951a706f3fa3bd793cbdaf4b753f62e12c | |
parent | d94ffb286aba68edc813c6eda61754891db7f7a1 (diff) | |
download | illumos-joyent-55da60b91d96984f12de050ce428373ea25c7f35.tar.gz |
PSARC/2010/108 zil synchronicity
6280630 zil synchronicity
Contributed by Robert Milkowski <milek@task.gda.pl>
-rw-r--r-- | usr/src/cmd/mdb/common/modules/zfs/zfs.c | 7 | ||||
-rw-r--r-- | usr/src/cmd/ztest/ztest.c | 21 | ||||
-rw-r--r-- | usr/src/common/zfs/zfs_prop.c | 13 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dmu_objset.c | 30 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/dmu.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/dmu_objset.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zil.h | 9 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zil_impl.h | 6 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vfsops.c | 67 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vnops.c | 49 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zil.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zvol.c | 19 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fs/zfs.h | 9 |
13 files changed, 189 insertions, 65 deletions
diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c index 13733d6834..e722007d72 100644 --- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c @@ -19,10 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <mdb/mdb_ctf.h> #include <sys/zfs_context.h> #include <sys/mdb_modapi.h> @@ -329,8 +330,8 @@ zfs_params(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) "fzap_default_block_shift", "zfs_immediate_write_sz", "zfs_read_chunk_size", - "zil_disable", "zfs_nocacheflush", + "zil_replay_disable", "metaslab_gang_bang", "metaslab_df_alloc_threshold", "metaslab_df_free_pct", diff --git a/usr/src/cmd/ztest/ztest.c b/usr/src/cmd/ztest/ztest.c index 063d1478ca..eea3aa0d39 100644 --- a/usr/src/cmd/ztest/ztest.c +++ b/usr/src/cmd/ztest/ztest.c @@ -2820,6 +2820,21 @@ ztest_objset_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx) DMU_OT_ZAP_OTHER, DMU_OT_NONE, 0, tx) == 0); } +static int +ztest_dataset_create(char *dsname) +{ + uint64_t zilset = ztest_random(100); + int err = dmu_objset_create(dsname, DMU_OST_OTHER, 0, + ztest_objset_create_cb, NULL); + + if (err || zilset < 80) + return (err); + + (void) printf("Setting dataset %s to sync always\n", dsname); + return (ztest_dsl_prop_set_uint64(dsname, ZFS_PROP_SYNC, + ZFS_SYNC_ALWAYS, B_FALSE)); +} + /* ARGSUSED */ static int ztest_objset_destroy_cb(const char *name, void *arg) @@ -2929,8 +2944,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id) /* * Verify that we can create a new dataset. */ - error = dmu_objset_create(name, DMU_OST_OTHER, 0, - ztest_objset_create_cb, NULL); + error = ztest_dataset_create(name); if (error) { if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -5019,8 +5033,7 @@ ztest_dataset_open(ztest_shared_t *zs, int d) (void) rw_rdlock(&zs->zs_name_lock); - error = dmu_objset_create(name, DMU_OST_OTHER, 0, - ztest_objset_create_cb, NULL); + error = ztest_dataset_create(name); if (error == ENOSPC) { (void) rw_unlock(&zs->zs_name_lock); ztest_record_enospc(FTAG); diff --git a/usr/src/common/zfs/zfs_prop.c b/usr/src/common/zfs/zfs_prop.c index 8c87292bc6..f29bcf6271 100644 --- a/usr/src/common/zfs/zfs_prop.c +++ b/usr/src/common/zfs/zfs_prop.c @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <sys/zio.h> #include <sys/spa.h> #include <sys/u8_textprep.h> @@ -176,7 +178,18 @@ zfs_prop_init(void) { NULL } }; + static zprop_index_t sync_table[] = { + { "standard", ZFS_SYNC_STANDARD }, + { "always", ZFS_SYNC_ALWAYS }, + { "disabled", ZFS_SYNC_DISABLED }, + { NULL } + }; + /* inherit index properties */ + zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + "standard | always | disabled", "SYNC", + sync_table); zprop_register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c index 3d25cab374..210d693051 100644 --- a/usr/src/uts/common/fs/zfs/dmu_objset.c +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <sys/cred.h> #include <sys/zfs_context.h> #include <sys/dmu_objset.h> @@ -92,6 +94,12 @@ dmu_objset_id(objset_t *os) } uint64_t +dmu_objset_syncprop(objset_t *os) +{ + return (os->os_sync); +} + +uint64_t dmu_objset_logbias(objset_t *os) { return (os->os_logbias); @@ -184,6 +192,22 @@ secondary_cache_changed_cb(void *arg, uint64_t newval) } static void +sync_changed_cb(void *arg, uint64_t newval) +{ + objset_t *os = arg; + + /* + * Inheritance and range checking should have been done by now. + */ + ASSERT(newval == ZFS_SYNC_STANDARD || newval == ZFS_SYNC_ALWAYS || + newval == ZFS_SYNC_DISABLED); + + os->os_sync = newval; + if (os->os_zil) + zil_set_sync(os->os_zil, newval); +} + +static void logbias_changed_cb(void *arg, uint64_t newval) { objset_t *os = arg; @@ -303,6 +327,9 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, if (err == 0) err = dsl_prop_register(ds, "logbias", logbias_changed_cb, os); + if (err == 0) + err = dsl_prop_register(ds, "sync", + sync_changed_cb, os); } if (err) { VERIFY(arc_buf_remove_ref(os->os_phys_buf, @@ -318,6 +345,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, os->os_dedup_checksum = ZIO_CHECKSUM_OFF; os->os_dedup_verify = 0; os->os_logbias = 0; + os->os_sync = 0; os->os_primary_cache = ZFS_CACHE_ALL; os->os_secondary_cache = ZFS_CACHE_ALL; } @@ -493,6 +521,8 @@ dmu_objset_evict(objset_t *os) dedup_changed_cb, os)); VERIFY(0 == dsl_prop_unregister(ds, "logbias", logbias_changed_cb, os)); + VERIFY(0 == dsl_prop_unregister(ds, "sync", + sync_changed_cb, os)); } VERIFY(0 == dsl_prop_unregister(ds, "primarycache", primary_cache_changed_cb, os)); diff --git a/usr/src/uts/common/fs/zfs/sys/dmu.h b/usr/src/uts/common/fs/zfs/sys/dmu.h index c28b8feca8..9c9369f8a7 100644 --- a/usr/src/uts/common/fs/zfs/sys/dmu.h +++ b/usr/src/uts/common/fs/zfs/sys/dmu.h @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #ifndef _SYS_DMU_H #define _SYS_DMU_H @@ -641,6 +643,7 @@ extern struct dsl_dataset *dmu_objset_ds(objset_t *os); extern void dmu_objset_name(objset_t *os, char *buf); extern dmu_objset_type_t dmu_objset_type(objset_t *os); extern uint64_t dmu_objset_id(objset_t *os); +extern uint64_t dmu_objset_syncprop(objset_t *os); extern uint64_t dmu_objset_logbias(objset_t *os); extern int dmu_snapshot_list_next(objset_t *os, int namelen, char *name, uint64_t *id, uint64_t *offp, boolean_t *case_conflict); diff --git a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h index 1da23009c2..ef1782b74d 100644 --- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h +++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #ifndef _SYS_DMU_OBJSET_H #define _SYS_DMU_OBJSET_H @@ -77,6 +79,7 @@ struct objset { uint8_t os_logbias; uint8_t os_primary_cache; uint8_t os_secondary_cache; + uint8_t os_sync; /* no lock needed: */ struct dmu_tx *os_synctx; /* XXX sketchy */ diff --git a/usr/src/uts/common/fs/zfs/sys/zil.h b/usr/src/uts/common/fs/zfs/sys/zil.h index b603241db7..2f01cf922e 100644 --- a/usr/src/uts/common/fs/zfs/sys/zil.h +++ b/usr/src/uts/common/fs/zfs/sys/zil.h @@ -19,10 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #ifndef _SYS_ZIL_H #define _SYS_ZIL_H @@ -417,9 +418,11 @@ extern void zil_resume(zilog_t *zilog); extern void zil_add_block(zilog_t *zilog, const blkptr_t *bp); extern int zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp); +extern void zil_set_sync(zilog_t *zilog, uint64_t syncval); + extern void zil_set_logbias(zilog_t *zilog, uint64_t slogval); -extern int zil_disable; +extern int zil_replay_disable; #ifdef __cplusplus } diff --git a/usr/src/uts/common/fs/zfs/sys/zil_impl.h b/usr/src/uts/common/fs/zfs/sys/zil_impl.h index c46063b052..6560a7942b 100644 --- a/usr/src/uts/common/fs/zfs/sys/zil_impl.h +++ b/usr/src/uts/common/fs/zfs/sys/zil_impl.h @@ -19,10 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #ifndef _SYS_ZIL_IMPL_H #define _SYS_ZIL_IMPL_H @@ -86,6 +87,7 @@ struct zilog { uint8_t zl_stop_sync; /* for debugging */ uint8_t zl_writer; /* boolean: write setup in progress */ uint8_t zl_logbias; /* latency or throughput */ + uint8_t zl_sync; /* synchronous or asynchronous */ int zl_parse_error; /* last zil_parse() error */ uint64_t zl_parse_blk_seq; /* highest blk seq on last parse */ uint64_t zl_parse_lr_seq; /* highest lr seq on last parse */ diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c index 237bff1285..da9163c963 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> @@ -165,8 +167,7 @@ zfs_sync(vfs_t *vfsp, short flag, cred_t *cr) if (zfsvfs->z_log != NULL) zil_commit(zfsvfs->z_log, UINT64_MAX, 0); - else - txg_wait_synced(dp, 0); + ZFS_EXIT(zfsvfs); } else { /* @@ -1024,10 +1025,6 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) mutex_exit(&zfsvfs->z_os->os_user_ptr_lock); zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data); - if (zil_disable) { - zil_destroy(zfsvfs->z_log, B_FALSE); - zfsvfs->z_log = NULL; - } /* * If we are not mounting (ie: online recv), then we don't @@ -1047,34 +1044,36 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting) else zfs_unlinked_drain(zfsvfs); - if (zfsvfs->z_log) { - /* - * Parse and replay the intent log. - * - * Because of ziltest, this must be done after - * zfs_unlinked_drain(). (Further note: ziltest - * doesn't use readonly mounts, where - * zfs_unlinked_drain() isn't called.) This is because - * ziltest causes spa_sync() to think it's committed, - * but actually it is not, so the intent log contains - * many txg's worth of changes. - * - * In particular, if object N is in the unlinked set in - * the last txg to actually sync, then it could be - * actually freed in a later txg and then reallocated - * in a yet later txg. This would write a "create - * object N" record to the intent log. Normally, this - * would be fine because the spa_sync() would have - * written out the fact that object N is free, before - * we could write the "create object N" intent log - * record. - * - * But when we are in ziltest mode, we advance the "open - * txg" without actually spa_sync()-ing the changes to - * disk. So we would see that object N is still - * allocated and in the unlinked set, and there is an - * intent log record saying to allocate it. - */ + /* + * Parse and replay the intent log. + * + * Because of ziltest, this must be done after + * zfs_unlinked_drain(). (Further note: ziltest + * doesn't use readonly mounts, where + * zfs_unlinked_drain() isn't called.) This is because + * ziltest causes spa_sync() to think it's committed, + * but actually it is not, so the intent log contains + * many txg's worth of changes. + * + * In particular, if object N is in the unlinked set in + * the last txg to actually sync, then it could be + * actually freed in a later txg and then reallocated + * in a yet later txg. This would write a "create + * object N" record to the intent log. Normally, this + * would be fine because the spa_sync() would have + * written out the fact that object N is free, before + * we could write the "create object N" intent log + * record. + * + * But when we are in ziltest mode, we advance the "open + * txg" without actually spa_sync()-ing the changes to + * disk. So we would see that object N is still + * allocated and in the unlinked set, and there is an + * intent log record saying to allocate it. + */ + if (zil_replay_disable) { + zil_destroy(zfsvfs->z_log, B_FALSE); + } else { zfsvfs->z_replay = B_TRUE; zil_replay(zfsvfs->z_os, zfsvfs, zfs_replay_vector); zfsvfs->z_replay = B_FALSE; diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 08c48cb99c..0addf84afb 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -23,6 +23,7 @@ */ /* Portions Copyright 2007 Jeremy Teo */ +/* Portions Copyright 2010 Robert Milkowski */ #include <sys/types.h> #include <sys/param.h> @@ -56,6 +57,7 @@ #include <sys/zfs_ioctl.h> #include <sys/fs/zfs.h> #include <sys/dmu.h> +#include <sys/dmu_objset.h> #include <sys/spa.h> #include <sys/txg.h> #include <sys/dbuf.h> @@ -487,7 +489,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) /* * If we're in FRSYNC mode, sync out this znode before reading it. */ - if (ioflag & FRSYNC) + if (ioflag & FRSYNC || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zfsvfs->z_log, zp->z_last_itx, zp->z_id); /* @@ -913,7 +915,8 @@ again: return (error); } - if (ioflag & (FSYNC | FDSYNC)) + if (ioflag & (FSYNC | FDSYNC) || + zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zilog, zp->z_last_itx, zp->z_id); ZFS_EXIT(zfsvfs); @@ -1489,6 +1492,9 @@ out: error = specvp_check(vpp, cr); } + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -1704,6 +1710,9 @@ out: if (xzp) VN_RELE(ZTOV(xzp)); + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -1877,6 +1886,9 @@ top: zfs_dirent_unlock(dl); + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (0); } @@ -2002,6 +2014,9 @@ out: VN_RELE(vp); + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -2316,10 +2331,12 @@ zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) (void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt); - ZFS_ENTER(zfsvfs); - ZFS_VERIFY_ZP(zp); - zil_commit(zfsvfs->z_log, zp->z_last_itx, zp->z_id); - ZFS_EXIT(zfsvfs); + if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) { + ZFS_ENTER(zfsvfs); + ZFS_VERIFY_ZP(zp); + zil_commit(zfsvfs->z_log, zp->z_last_itx, zp->z_id); + ZFS_EXIT(zfsvfs); + } return (0); } @@ -3117,6 +3134,9 @@ out: out2: + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (err); } @@ -3547,6 +3567,9 @@ out: if (tzp) VN_RELE(ZTOV(tzp)); + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -3687,6 +3710,9 @@ top: VN_RELE(ZTOV(zp)); + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -3877,6 +3903,9 @@ top: vnevent_link(svp, ct); } + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } @@ -4109,7 +4138,7 @@ zfs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr, } out: zfs_range_unlock(rl); - if ((flags & B_ASYNC) == 0) + if ((flags & B_ASYNC) == 0 || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zfsvfs->z_log, UINT64_MAX, zp->z_id); ZFS_EXIT(zfsvfs); return (error); @@ -4757,10 +4786,16 @@ zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, zfsvfs_t *zfsvfs = zp->z_zfsvfs; int error; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; + zilog_t *zilog = zfsvfs->z_log; ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); + error = zfs_setacl(zp, vsecp, skipaclchk, cr); + + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, UINT64_MAX, 0); + ZFS_EXIT(zfsvfs); return (error); } diff --git a/usr/src/uts/common/fs/zfs/zil.c b/usr/src/uts/common/fs/zfs/zil.c index 24789494ca..e4c435341f 100644 --- a/usr/src/uts/common/fs/zfs/zil.c +++ b/usr/src/uts/common/fs/zfs/zil.c @@ -19,10 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <sys/zfs_context.h> #include <sys/spa.h> #include <sys/dmu.h> @@ -65,7 +66,7 @@ /* * This global ZIL switch affects all pools */ -int zil_disable = 0; /* disable intent logging */ +int zil_replay_disable = 0; /* disable intent logging replay */ /* * Tunable parameter for debugging or performance analysis. Setting @@ -1266,7 +1267,7 @@ zil_commit_writer(zilog_t *zilog, uint64_t seq, uint64_t foid) void zil_commit(zilog_t *zilog, uint64_t seq, uint64_t foid) { - if (zilog == NULL || seq == 0) + if (zilog->zl_sync == ZFS_SYNC_DISABLED || seq == 0) return; mutex_enter(&zilog->zl_lock); @@ -1398,6 +1399,12 @@ zil_fini(void) } void +zil_set_sync(zilog_t *zilog, uint64_t sync) +{ + zilog->zl_sync = sync; +} + +void zil_set_logbias(zilog_t *zilog, uint64_t logbias) { zilog->zl_logbias = logbias; @@ -1416,6 +1423,7 @@ zil_alloc(objset_t *os, zil_header_t *zh_phys) zilog->zl_dmu_pool = dmu_objset_pool(os); zilog->zl_destroy_txg = TXG_INITIAL - 1; zilog->zl_logbias = dmu_objset_logbias(os); + zilog->zl_sync = dmu_objset_syncprop(os); mutex_init(&zilog->zl_lock, NULL, MUTEX_DEFAULT, NULL); @@ -1721,7 +1729,7 @@ zil_replay(objset_t *os, void *arg, zil_replay_func_t *replay_func[TX_MAX_TYPE]) boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx) { - if (zilog == NULL) + if (zilog->zl_sync == ZFS_SYNC_DISABLED) return (B_TRUE); if (zilog->zl_replay) { diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 20e9a3424a..3481fb0586 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -22,6 +22,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + /* * ZFS volume emulation driver. * @@ -525,7 +527,10 @@ zvol_create_minor(const char *name) ASSERT(error == 0); zv->zv_volblocksize = doi.doi_data_block_size; - zil_replay(os, zv, zvol_replay_vector); + if (zil_replay_disable) + zil_destroy(dmu_objset_zil(os), B_FALSE); + else + zil_replay(os, zv, zvol_replay_vector); dmu_objset_disown(os, zvol_tag); zv->zv_objset = NULL; @@ -988,9 +993,6 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid, boolean_t slogging; ssize_t immediate_write_sz; - if (zil_disable) - return; - if (zil_replaying(zilog, tx)) return; @@ -1182,8 +1184,10 @@ zvol_strategy(buf_t *bp) } is_dump = zv->zv_flags & ZVOL_DUMPIFIED; - sync = !(bp->b_flags & B_ASYNC) && !doread && !is_dump && - !(zv->zv_flags & ZVOL_WCE) && !zil_disable; + sync = ((!(bp->b_flags & B_ASYNC) && + !(zv->zv_flags & ZVOL_WCE)) || + (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)) && + !doread && !is_dump; /* * There must be no buffer changes when doing a dmu_sync() because @@ -1363,7 +1367,8 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) return (error); } - sync = !(zv->zv_flags & ZVOL_WCE) && !zil_disable; + sync = !(zv->zv_flags & ZVOL_WCE) || + (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS); rl = zfs_range_lock(&zv->zv_znode, uio->uio_loffset, uio->uio_resid, RL_WRITER); diff --git a/usr/src/uts/common/sys/fs/zfs.h b/usr/src/uts/common/sys/fs/zfs.h index ddf4db3e2f..a5d9122246 100644 --- a/usr/src/uts/common/sys/fs/zfs.h +++ b/usr/src/uts/common/sys/fs/zfs.h @@ -23,6 +23,8 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #ifndef _SYS_FS_ZFS_H #define _SYS_FS_ZFS_H @@ -119,6 +121,7 @@ typedef enum { ZFS_PROP_OBJSETID, /* not exposed to the user */ ZFS_PROP_DEDUP, ZFS_PROP_MLSLABEL, + ZFS_PROP_SYNC, ZFS_NUM_PROPS } zfs_prop_t; @@ -296,6 +299,12 @@ typedef enum zfs_cache_type { ZFS_CACHE_ALL = 2 } zfs_cache_type_t; +typedef enum { + ZFS_SYNC_STANDARD = 0, + ZFS_SYNC_ALWAYS = 1, + ZFS_SYNC_DISABLED = 2 +} zfs_sync_type_t; + /* * On-disk version number. |