/*
* Convert a string to a err_phys.
*/
-static void
+void
name_to_errphys(char *buf, zbookmark_err_phys_t *zep)
{
zep->zb_object = zfs_strtonum(buf, &buf);
ASSERT(*buf == '\0');
}
-#ifdef _KERNEL
-static void
+void
zep_to_zb(uint64_t dataset, zbookmark_err_phys_t *zep, zbookmark_phys_t *zb)
{
zb->zb_objset = dataset;
zb->zb_level = zep->zb_level;
zb->zb_blkid = zep->zb_blkid;
}
-#endif
static void
name_to_object(char *buf, uint64_t *obj)
mutex_exit(&spa->spa_errlist_lock);
}
-#ifdef _KERNEL
-static int
+int
find_birth_txg(dsl_dataset_t *ds, zbookmark_err_phys_t *zep,
uint64_t *birth_txg)
{
return (error);
}
+/*
+ * This function finds the oldest affected filesystem containing an error
+ * block.
+ */
+int
+find_top_affected_fs(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
+ uint64_t *top_affected_fs)
+{
+ uint64_t oldest_dsobj;
+ int error = dsl_dataset_oldest_snapshot(spa, head_ds, zep->zb_birth,
+ &oldest_dsobj);
+ if (error != 0)
+ return (error);
+
+ dsl_dataset_t *ds;
+ error = dsl_dataset_hold_obj_flags(spa->spa_dsl_pool, oldest_dsobj,
+ DS_HOLD_FLAG_DECRYPT, FTAG, &ds);
+ if (error != 0)
+ return (error);
+
+ *top_affected_fs =
+ dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj;
+ dsl_dataset_rele_flags(ds, DS_HOLD_FLAG_DECRYPT, FTAG);
+ return (0);
+}
+
+
+#ifdef _KERNEL
/*
* Copy the bookmark to the end of the user-space buffer which starts at
* uaddr and has *count unused entries, and decrement *count by 1.
* Each time the error block is referenced by a snapshot or clone, add a
* zbookmark_phys_t entry to the userspace array at uaddr. The array is
* filled from the back and the in-out parameter *count is modified to be the
- * number of unused entries at the beginning of the array.
+ * number of unused entries at the beginning of the array. The function
+ * scrub_filesystem() is modelled after this one.
*/
static int
check_filesystem(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
return (error);
}
-static int
-find_top_affected_fs(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
- uint64_t *top_affected_fs)
-{
- uint64_t oldest_dsobj;
- int error = dsl_dataset_oldest_snapshot(spa, head_ds, zep->zb_birth,
- &oldest_dsobj);
- if (error != 0)
- return (error);
-
- dsl_dataset_t *ds;
- error = dsl_dataset_hold_obj_flags(spa->spa_dsl_pool, oldest_dsobj,
- DS_HOLD_FLAG_DECRYPT, FTAG, &ds);
- if (error != 0)
- return (error);
-
- *top_affected_fs =
- dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj;
- dsl_dataset_rele_flags(ds, DS_HOLD_FLAG_DECRYPT, FTAG);
- return (0);
-}
-
static int
process_error_block(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
void *uaddr, uint64_t *count)
}
#endif
+/* Return the number of errors in the error log */
+uint64_t
+spa_get_last_errlog_size(spa_t *spa)
+{
+ uint64_t total = 0, count;
+ mutex_enter(&spa->spa_errlog_lock);
+
+ if (spa->spa_errlog_last != 0 &&
+ zap_count(spa->spa_meta_objset, spa->spa_errlog_last,
+ &count) == 0)
+ total += count;
+ mutex_exit(&spa->spa_errlog_lock);
+ return (total);
+}
+
/*
* If a healed bookmark matches an entry in the error log we stash it in a tree
* so that we can later remove the related log entries in sync context.
/* error handling */
EXPORT_SYMBOL(spa_log_error);
EXPORT_SYMBOL(spa_approx_errlog_size);
+EXPORT_SYMBOL(spa_get_last_errlog_size);
EXPORT_SYMBOL(spa_get_errlog);
EXPORT_SYMBOL(spa_errlog_rotate);
EXPORT_SYMBOL(spa_errlog_drain);
EXPORT_SYMBOL(spa_swap_errlog);
EXPORT_SYMBOL(sync_error_list);
EXPORT_SYMBOL(spa_upgrade_errlog);
+EXPORT_SYMBOL(find_top_affected_fs);
+EXPORT_SYMBOL(find_birth_txg);
+EXPORT_SYMBOL(zep_to_zb);
+EXPORT_SYMBOL(name_to_errphys);
#endif
/* BEGIN CSTYLED */