diff options
author | Neil Perrin <Neil.Perrin@Sun.COM> | 2009-10-15 11:39:49 -0600 |
---|---|---|
committer | Neil Perrin <Neil.Perrin@Sun.COM> | 2009-10-15 11:39:49 -0600 |
commit | 975c32a05c38c6fa808592dd35fa6dba183ca077 (patch) | |
tree | 12a92c3406b435c65e688afb076dc7a14c6b84bb /usr/src/uts/common/fs/zfs/zfs_vnops.c | |
parent | c4cbca4f3a766d8c662ce2e0e36a6f1e41ff0a80 (diff) | |
download | illumos-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.c | 16 |
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)); } |