mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-26 04:07:45 +03:00
Illumos 5911 - ZFS "hangs" while deleting file
5911 ZFS "hangs" while deleting file Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com> Reviewed by: Alek Pinchuk <alek@nexenta.com> Reviewed by: Simon Klinkert <simon.klinkert@gmail.com> Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Richard Lowe <richlowe@richlowe.net> References: https://www.illumos.org/issues/5911 https://github.com/illumos/illumos-gate/commit/46e1baa Porting notes: Resolved ISO C90 forbids mixed declarations and code wanting in the dnode_free_range() function. Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3554
This commit is contained in:
committed by
Brian Behlendorf
parent
5e8cd5d17f
commit
4bda3bd0e7
+20
-14
@@ -21,7 +21,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
*/
|
||||
@@ -1455,6 +1455,16 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
dbuf_dirty_record_t *dr, **drp;
|
||||
|
||||
ASSERT(txg != 0);
|
||||
|
||||
/*
|
||||
* Due to our use of dn_nlevels below, this can only be called
|
||||
* in open context, unless we are operating on the MOS.
|
||||
* From syncing context, dn_nlevels may be different from the
|
||||
* dn_nlevels used when dbuf was dirtied.
|
||||
*/
|
||||
ASSERT(db->db_objset ==
|
||||
dmu_objset_pool(db->db_objset)->dp_meta_objset ||
|
||||
txg != spa_syncing_txg(dmu_objset_spa(db->db_objset)));
|
||||
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
|
||||
ASSERT0(db->db_level);
|
||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||
@@ -1477,11 +1487,8 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
|
||||
ASSERT(db->db.db_size != 0);
|
||||
|
||||
/*
|
||||
* Any space we accounted for in dp_dirty_* will be cleaned up by
|
||||
* dsl_pool_sync(). This is relatively rare so the discrepancy
|
||||
* is not a big deal.
|
||||
*/
|
||||
dsl_pool_undirty_space(dmu_objset_pool(dn->dn_objset),
|
||||
dr->dr_accounted, txg);
|
||||
|
||||
*drp = dr->dr_next;
|
||||
|
||||
@@ -1496,7 +1503,7 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
list_remove(&dr->dr_parent->dt.di.dr_children, dr);
|
||||
mutex_exit(&dr->dr_parent->dt.di.dr_mtx);
|
||||
} else if (db->db_blkid == DMU_SPILL_BLKID ||
|
||||
db->db_level+1 == dn->dn_nlevels) {
|
||||
db->db_level + 1 == dn->dn_nlevels) {
|
||||
ASSERT(db->db_blkptr == NULL || db->db_parent == dn->dn_dbuf);
|
||||
mutex_enter(&dn->dn_mtx);
|
||||
list_remove(&dn->dn_dirty_records[txg & TXG_MASK], dr);
|
||||
@@ -1513,11 +1520,6 @@ dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
VERIFY(arc_buf_remove_ref(dr->dt.dl.dr_data, db));
|
||||
}
|
||||
|
||||
if (db->db_level != 0) {
|
||||
mutex_destroy(&dr->dt.di.dr_mtx);
|
||||
list_destroy(&dr->dt.di.dr_children);
|
||||
}
|
||||
|
||||
kmem_free(dr, sizeof (dbuf_dirty_record_t));
|
||||
|
||||
ASSERT(db->db_dirtycnt > 0);
|
||||
@@ -2603,7 +2605,7 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||
|
||||
zio = dr->dr_zio;
|
||||
mutex_enter(&dr->dt.di.dr_mtx);
|
||||
dbuf_sync_list(&dr->dt.di.dr_children, tx);
|
||||
dbuf_sync_list(&dr->dt.di.dr_children, db->db_level - 1, tx);
|
||||
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
|
||||
mutex_exit(&dr->dt.di.dr_mtx);
|
||||
zio_nowait(zio);
|
||||
@@ -2754,7 +2756,7 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
void
|
||||
dbuf_sync_list(list_t *list, dmu_tx_t *tx)
|
||||
dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx)
|
||||
{
|
||||
dbuf_dirty_record_t *dr;
|
||||
|
||||
@@ -2771,6 +2773,10 @@ dbuf_sync_list(list_t *list, dmu_tx_t *tx)
|
||||
DMU_META_DNODE_OBJECT);
|
||||
break;
|
||||
}
|
||||
if (dr->dr_dbuf->db_blkid != DMU_BONUS_BLKID &&
|
||||
dr->dr_dbuf->db_blkid != DMU_SPILL_BLKID) {
|
||||
VERIFY3U(dr->dr_dbuf->db_level, ==, level);
|
||||
}
|
||||
list_remove(list, dr);
|
||||
if (dr->dr_dbuf->db_level > 0)
|
||||
dbuf_sync_indirect(dr, tx);
|
||||
|
||||
Reference in New Issue
Block a user