summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-11-12 23:58:07 +0000
committermav <mav@FreeBSD.org>2016-11-12 23:58:07 +0000
commit5e20e71666b91f6a7ebc59077e4315736bfb1a28 (patch)
tree0a782ec3bdea3521923c04be31918a513228b72b /sys/cddl/contrib/opensolaris/uts/common
parentdd9903d50b424e07ad2f044b60101cb465d9baa1 (diff)
downloadFreeBSD-src-5e20e71666b91f6a7ebc59077e4315736bfb1a28.zip
FreeBSD-src-5e20e71666b91f6a7ebc59077e4315736bfb1a28.tar.gz
MFC r308173:
Fix ZIL records ordering when ZVOL opened both with and without FSYNC. Before this an earlier writes to a ZVOL opened without FSYNC could get to ZIL after later writes to the same ZVOL opened with FSYNC. Fix this by replicating functionality of ZPL (zv_sync_cnt equivalent to z_sync_cnt), marking all log records sync if anybody opened the ZVOL with FSYNC.
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c14
3 files changed, 14 insertions, 5 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
index 1642da0..8887aa8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
@@ -405,6 +405,7 @@ extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
extern void zil_itx_destroy(itx_t *itx);
extern void zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
+extern void zil_async_to_sync(zilog_t *zilog, uint64_t oid);
extern void zil_commit(zilog_t *zilog, uint64_t oid);
extern int zil_vdev_offline(const char *osname, void *txarg);
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 29cf371..799df31 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
@@ -93,8 +93,6 @@ SYSCTL_INT(_vfs_zfs_trim, OID_AUTO, enabled, CTLFLAG_RDTUN, &zfs_trim_enabled, 0
static kmem_cache_t *zil_lwb_cache;
-static void zil_async_to_sync(zilog_t *zilog, uint64_t foid);
-
#define LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \
sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused))
@@ -1415,7 +1413,7 @@ zil_get_commit_list(zilog_t *zilog)
/*
* Move the async itxs for a specified object to commit into sync lists.
*/
-static void
+void
zil_async_to_sync(zilog_t *zilog, uint64_t foid)
{
uint64_t otxg, txg;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index 693de88..a5d516f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -167,6 +167,7 @@ typedef struct zvol_state {
uint32_t zv_open_count[OTYPCNT]; /* open counts */
#endif
uint32_t zv_total_opens; /* total open count */
+ uint32_t zv_sync_cnt; /* synchronous open count */
zilog_t *zv_zilog; /* ZIL handle */
list_t zv_extents; /* List of extents for dump */
znode_t zv_znode; /* for range locking */
@@ -1416,7 +1417,9 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid,
BP_ZERO(&lr->lr_blkptr);
itx->itx_private = zv;
- itx->itx_sync = sync;
+
+ if (!sync && (zv->zv_sync_cnt == 0))
+ itx->itx_sync = B_FALSE;
zil_itx_assign(zilog, itx, tx);
@@ -2058,7 +2061,7 @@ zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, uint64_t len,
lr->lr_offset = off;
lr->lr_length = len;
- itx->itx_sync = sync;
+ itx->itx_sync = (sync || zv->zv_sync_cnt != 0);
zil_itx_assign(zilog, itx, tx);
}
@@ -3050,6 +3053,11 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td)
#endif
zv->zv_total_opens++;
+ if (flags & (FSYNC | FDSYNC)) {
+ zv->zv_sync_cnt++;
+ if (zv->zv_sync_cnt == 1)
+ zil_async_to_sync(zv->zv_zilog, ZVOL_OBJ);
+ }
mutex_exit(&zfsdev_state_lock);
return (err);
out:
@@ -3080,6 +3088,8 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td)
* You may get multiple opens, but only one close.
*/
zv->zv_total_opens--;
+ if (flags & (FSYNC | FDSYNC))
+ zv->zv_sync_cnt--;
if (zv->zv_total_opens == 0)
zvol_last_close(zv);
OpenPOWER on IntegriCloud