Implement SA based xattrs
[zfs.git] / module / zfs / sa.c
index 4278ed7..bcef7d1 100644 (file)
@@ -201,6 +201,7 @@ sa_attr_type_t sa_dummy_zpl_layout[] = { 0 };
 
 static int sa_legacy_attr_count = 16;
 static kmem_cache_t *sa_cache = NULL;
+static kmem_cache_t *spill_cache = NULL;
 
 /*ARGSUSED*/
 static int
@@ -232,6 +233,8 @@ sa_cache_init(void)
        sa_cache = kmem_cache_create("sa_cache",
            sizeof (sa_handle_t), 0, sa_cache_constructor,
            sa_cache_destructor, NULL, NULL, NULL, 0);
+       spill_cache = kmem_cache_create("spill_cache",
+           SPA_MAXBLOCKSIZE, 0, NULL, NULL, NULL, NULL, NULL, 0);
 }
 
 void
@@ -239,6 +242,21 @@ sa_cache_fini(void)
 {
        if (sa_cache)
                kmem_cache_destroy(sa_cache);
+
+       if (spill_cache)
+               kmem_cache_destroy(spill_cache);
+}
+
+void *
+sa_spill_alloc(int flags)
+{
+       return kmem_cache_alloc(spill_cache, flags);
+}
+
+void
+sa_spill_free(void *obj)
+{
+       kmem_cache_free(spill_cache, obj);
 }
 
 static int
@@ -1618,7 +1636,7 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
        sa_bulk_attr_t *attr_desc;
        void *old_data[2];
        int bonus_attr_count = 0;
-       int bonus_data_size = 0, spill_data_size = 0;
+       int bonus_data_size = 0;
        int spill_attr_count = 0;
        int error;
        uint16_t length;
@@ -1648,8 +1666,8 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
        /* Bring spill buffer online if it isn't currently */
 
        if ((error = sa_get_spill(hdl)) == 0) {
-               spill_data_size = hdl->sa_spill->db_size;
-               old_data[1] = kmem_alloc(spill_data_size, KM_SLEEP);
+               ASSERT3U(hdl->sa_spill->db_size, <=, SPA_MAXBLOCKSIZE);
+               old_data[1] = sa_spill_alloc(KM_SLEEP);
                bcopy(hdl->sa_spill->db_data, old_data[1],
                    hdl->sa_spill->db_size);
                spill_attr_count =
@@ -1729,7 +1747,7 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
        if (old_data[0])
                kmem_free(old_data[0], bonus_data_size);
        if (old_data[1])
-               kmem_free(old_data[1], spill_data_size);
+               sa_spill_free(old_data[1]);
        kmem_free(attr_desc, sizeof (sa_bulk_attr_t) * attr_count);
 
        return (error);
@@ -1998,6 +2016,8 @@ EXPORT_SYMBOL(sa_replace_all_by_template_locked);
 EXPORT_SYMBOL(sa_enabled);
 EXPORT_SYMBOL(sa_cache_init);
 EXPORT_SYMBOL(sa_cache_fini);
+EXPORT_SYMBOL(sa_spill_alloc);
+EXPORT_SYMBOL(sa_spill_free);
 EXPORT_SYMBOL(sa_set_sa_object);
 EXPORT_SYMBOL(sa_hdrsize);
 EXPORT_SYMBOL(sa_handle_lock);