diff options
author | mav <mav@FreeBSD.org> | 2016-11-12 23:58:07 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2016-11-12 23:58:07 +0000 |
commit | 5e20e71666b91f6a7ebc59077e4315736bfb1a28 (patch) | |
tree | 0a782ec3bdea3521923c04be31918a513228b72b /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | |
parent | dd9903d50b424e07ad2f044b60101cb465d9baa1 (diff) | |
download | FreeBSD-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/fs/zfs/zvol.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | 14 |
1 files changed, 12 insertions, 2 deletions
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); |