Skip to content

Instantly share code, notes, and snippets.

@pcd1193182
Last active August 23, 2016 16:38
Show Gist options
  • Save pcd1193182/f91e950925d8edc0648ff4a69d00b08e to your computer and use it in GitHub Desktop.
Save pcd1193182/f91e950925d8edc0648ff4a69d00b08e to your computer and use it in GitHub Desktop.
alternate 4996 patch, now compiles, boots, passes 3.sh
diff --git a/usr/src/uts/common/fs/zfs/dnode_sync.c b/usr/src/uts/common/fs/zfs/dnode_sync.c
index d4e6502..c8c8240 100644
--- a/usr/src/uts/common/fs/zfs/dnode_sync.c
+++ b/usr/src/uts/common/fs/zfs/dnode_sync.c
@@ -111,7 +111,7 @@ dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
}
static void
-free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx)
+free_blocks(dnode_t *dn, blkptr_t *bp, int num, uint64_t birth, dmu_tx_t *tx)
{
dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset;
uint64_t bytesfreed = 0;
@@ -150,7 +150,8 @@ free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx)
BP_SET_LSIZE(bp, lsize);
BP_SET_TYPE(bp, type);
BP_SET_LEVEL(bp, lvl);
- BP_SET_BIRTH(bp, dmu_tx_get_txg(tx), 0);
+ BP_SET_BIRTH(bp,
+ (birth == 0 ? dmu_tx_get_txg(tx) : birth), 0);
}
}
dnode_diduse_space(dn, -bytesfreed);
@@ -237,7 +238,7 @@ free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx)
static void
free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
- dmu_tx_t *tx)
+ boolean_t force_free, dmu_tx_t *tx)
{
dnode_t *dn;
blkptr_t *bp;
@@ -278,7 +279,7 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
if (db->db_level == 1) {
FREE_VERIFY(db, start, end, tx);
- free_blocks(dn, bp, end-start+1, tx);
+ free_blocks(dn, bp, end-start+1, 0, tx);
} else {
for (uint64_t id = start; id <= end; id++, bp++) {
if (BP_IS_HOLE(bp))
@@ -289,14 +290,16 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
rw_exit(&dn->dn_struct_rwlock);
ASSERT3P(bp, ==, subdb->db_blkptr);
- free_children(subdb, blkid, nblks, tx);
+ free_children(subdb, blkid, nblks, force_free, tx);
dbuf_rele(subdb, FTAG);
}
}
+ uint64_t first_birth = ((blkptr_t *)db->db.db_data)->blk_birth;
/* If this whole block is free, free ourself too. */
for (i = 0, bp = db->db.db_data; i < 1 << epbs; i++, bp++) {
- if (!BP_IS_HOLE(bp))
+ if (!BP_IS_HOLE(bp) ||
+ (!force_free && bp->blk_birth != first_birth))
break;
}
if (i == 1 << epbs) {
@@ -308,7 +311,8 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
bzero(db->db.db_data, db->db.db_size);
rw_exit(&dn->dn_struct_rwlock);
- free_blocks(dn, db->db_blkptr, 1, tx);
+ free_blocks(dn, db->db_blkptr, 1,
+ (force_free ? 0 : first_birth), tx);
} else {
/*
* Partial block free; must be marked dirty so that it
@@ -327,7 +331,7 @@ free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
*/
static void
dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
- dmu_tx_t *tx)
+ boolean_t force_free, dmu_tx_t *tx)
{
blkptr_t *bp = dn->dn_phys->dn_blkptr;
int dnlevel = dn->dn_phys->dn_nlevels;
@@ -349,7 +353,7 @@ dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
return;
}
ASSERT3U(blkid + nblks, <=, dn->dn_phys->dn_nblkptr);
- free_blocks(dn, bp + blkid, nblks, tx);
+ free_blocks(dn, bp + blkid, nblks, 0, tx);
} else {
int shift = (dnlevel - 1) *
(dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT);
@@ -367,7 +371,7 @@ dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
TRUE, FALSE, FTAG, &db));
rw_exit(&dn->dn_struct_rwlock);
- free_children(db, blkid, nblks, tx);
+ free_children(db, blkid, nblks, force_free, tx);
dbuf_rele(db, FTAG);
}
}
@@ -386,6 +390,7 @@ dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
typedef struct dnode_sync_free_range_arg {
dnode_t *dsfra_dnode;
dmu_tx_t *dsfra_tx;
+ boolean_t dsfra_force_free;
} dnode_sync_free_range_arg_t;
static void
@@ -395,7 +400,8 @@ dnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks)
dnode_t *dn = dsfra->dsfra_dnode;
mutex_exit(&dn->dn_mtx);
- dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_tx);
+ dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_force_free,
+ dsfra->dsfra_tx);
mutex_enter(&dn->dn_mtx);
}
@@ -661,7 +667,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
mutex_exit(&dn->dn_mtx);
if (kill_spill) {
- free_blocks(dn, &dn->dn_phys->dn_spill, 1, tx);
+ free_blocks(dn, &dn->dn_phys->dn_spill, 1, 0, tx);
mutex_enter(&dn->dn_mtx);
dnp->dn_flags &= ~DNODE_FLAG_SPILL_BLKPTR;
mutex_exit(&dn->dn_mtx);
@@ -672,6 +678,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
dnode_sync_free_range_arg_t dsfra;
dsfra.dsfra_dnode = dn;
dsfra.dsfra_tx = tx;
+ dsfra.dsfra_force_free = freeing_dnode;
mutex_enter(&dn->dn_mtx);
range_tree_vacate(dn->dn_free_ranges[txgoff],
dnode_sync_free_range, &dsfra);
diff --git a/usr/src/uts/common/fs/zfs/zfs_znode.c b/usr/src/uts/common/fs/zfs/zfs_znode.c
index 6304ec8..dd2cc1d 100644
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c
+++ b/usr/src/uts/common/fs/zfs/zfs_znode.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
/* Portions Copyright 2007 Jeremy Teo */
@@ -1590,7 +1590,8 @@ zfs_trunc(znode_t *zp, uint64_t end)
return (0);
}
- error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end, -1);
+ error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end,
+ DMU_OBJECT_END);
if (error) {
zfs_range_unlock(rl);
return (error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment