+
+int
+zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
+ uint64_t *towrite, uint64_t *tooverwrite)
+{
+ zap_t *zap;
+ int err = 0;
+
+
+ /*
+ * Since, we don't have a name, we cannot figure out which blocks will
+ * be affected in this operation. So, account for the worst case :
+ * - 3 blocks overwritten: target leaf, ptrtbl block, header block
+ * - 4 new blocks written if adding:
+ * - 2 blocks for possibly split leaves,
+ * - 2 grown ptrtbl blocks
+ *
+ * This also accomodates the case where an add operation to a fairly
+ * large microzap results in a promotion to fatzap.
+ */
+ if (name == NULL) {
+ *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
+ return (err);
+ }
+
+ /*
+ * We lock the zap with adding == FALSE. Because, if we pass
+ * the actual value of add, it could trigger a mzap_upgrade().
+ * At present we are just evaluating the possibility of this operation
+ * and hence we donot want to trigger an upgrade.
+ */
+ err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
+ if (err)
+ return (err);
+
+ if (!zap->zap_ismicro) {
+ zap_name_t *zn = zap_name_alloc(zap, name, MT_EXACT);
+ if (zn) {
+ err = fzap_count_write(zn, add, towrite,
+ tooverwrite);
+ zap_name_free(zn);
+ } else {
+ /*
+ * We treat this case as similar to (name == NULL)
+ */
+ *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
+ }
+ } else {
+ /*
+ * We are here if (name != NULL) and this is a micro-zap.
+ * We account for the header block depending on whether it
+ * is freeable.
+ *
+ * Incase of an add-operation it is hard to find out
+ * if this add will promote this microzap to fatzap.
+ * Hence, we consider the worst case and account for the
+ * blocks assuming this microzap would be promoted to a
+ * fatzap.
+ *
+ * 1 block overwritten : header block
+ * 4 new blocks written : 2 new split leaf, 2 grown
+ * ptrtbl blocks
+ */
+ if (dmu_buf_freeable(zap->zap_dbuf))
+ *tooverwrite += SPA_MAXBLOCKSIZE;
+ else
+ *towrite += SPA_MAXBLOCKSIZE;
+
+ if (add) {
+ *towrite += 4 * SPA_MAXBLOCKSIZE;
+ }
+ }
+
+ zap_unlockdir(zap);
+ return (err);
+}
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(zap_add);
+EXPORT_SYMBOL(zap_create);
+EXPORT_SYMBOL(zap_cursor_advance);
+EXPORT_SYMBOL(zap_cursor_fini);
+EXPORT_SYMBOL(zap_cursor_init);
+EXPORT_SYMBOL(zap_cursor_init_serialized);
+EXPORT_SYMBOL(zap_cursor_move_to_key);
+EXPORT_SYMBOL(zap_cursor_retrieve);
+EXPORT_SYMBOL(zap_cursor_serialize);
+EXPORT_SYMBOL(zap_lookup);
+EXPORT_SYMBOL(zap_lookup_norm);
+EXPORT_SYMBOL(zap_remove);
+EXPORT_SYMBOL(zap_update);
+#endif