Last active
August 23, 2016 16:38
-
-
Save pcd1193182/f91e950925d8edc0648ff4a69d00b08e to your computer and use it in GitHub Desktop.
alternate 4996 patch, now compiles, boots, passes 3.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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