diff options
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c index 23313a9..8fdfa62 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -300,6 +300,7 @@ space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype, uint64_t *entry, *entry_map, *entry_map_end; uint64_t bufsize, size, offset, end, space; uint64_t mapstart = sm->sm_start; + int error = 0; ASSERT(MUTEX_HELD(sm->sm_lock)); @@ -337,9 +338,10 @@ space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype, smo->smo_object, offset, size); mutex_exit(sm->sm_lock); - VERIFY3U(dmu_read(os, smo->smo_object, offset, size, - entry_map), ==, 0); + error = dmu_read(os, smo->smo_object, offset, size, entry_map); mutex_enter(sm->sm_lock); + if (error != 0) + break; entry_map_end = entry_map + (size / sizeof (uint64_t)); for (entry = entry_map; entry < entry_map_end; entry++) { @@ -354,20 +356,25 @@ space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype, SM_RUN_DECODE(e) << sm->sm_shift); } } - VERIFY3U(sm->sm_space, ==, space); + + if (error == 0) { + VERIFY3U(sm->sm_space, ==, space); + + sm->sm_loaded = B_TRUE; + sm->sm_ops = ops; + if (ops != NULL) + ops->smop_load(sm); + } else { + space_map_vacate(sm, NULL, NULL); + } zio_buf_free(entry_map, bufsize); sm->sm_loading = B_FALSE; - sm->sm_loaded = B_TRUE; - sm->sm_ops = ops; cv_broadcast(&sm->sm_load_cv); - if (ops != NULL) - ops->smop_load(sm); - - return (0); + return (error); } void |