summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zfs_vnops.c
diff options
context:
space:
mode:
authorNeil Perrin <Neil.Perrin@Sun.COM>2009-10-15 11:39:49 -0600
committerNeil Perrin <Neil.Perrin@Sun.COM>2009-10-15 11:39:49 -0600
commit975c32a05c38c6fa808592dd35fa6dba183ca077 (patch)
tree12a92c3406b435c65e688afb076dc7a14c6b84bb /usr/src/uts/common/fs/zfs/zfs_vnops.c
parentc4cbca4f3a766d8c662ce2e0e36a6f1e41ff0a80 (diff)
downloadillumos-gate-975c32a05c38c6fa808592dd35fa6dba183ca077.tar.gz
6880764 fsync on zfs is broken if writes are greater than 32kb on a hard crash and no log attached
6793430 zdb -ivvvv assertion failure: bp->blk_cksum.zc_word[2] == dmu_objset_id(zilog->zl_os)
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zfs_vnops.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index 6513640437..08bd0d378b 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -961,16 +961,28 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
lr->lr_common.lrc_txg, zfs_get_done, zgd);
ASSERT((error && error != EINPROGRESS) ||
lr->lr_length <= zp->z_blksz);
- if (error == 0)
+ if (error == 0) {
+ /*
+ * dmu_sync() can compress a block of zeros to a null
+ * blkptr but the block size still needs to be passed
+ * through to replay.
+ */
+ BP_SET_LSIZE(&lr->lr_blkptr, db->db_size);
zil_add_block(zfsvfs->z_log, &lr->lr_blkptr);
+ }
+
/*
* If we get EINPROGRESS, then we need to wait for a
* write IO initiated by dmu_sync() to complete before
* we can release this dbuf. We will finish everything
* up in the zfs_get_done() callback.
*/
- if (error == EINPROGRESS)
+ if (error == EINPROGRESS) {
return (0);
+ } else if (error == EALREADY) {
+ lr->lr_common.lrc_txtype = TX_WRITE2;
+ error = 0;
+ }
dmu_buf_rele(db, zgd);
kmem_free(zgd, sizeof (zgd_t));
}