1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Portions Copyright 2011 iXsystems, Inc
  24  */
  25 
  26 #include <sys/zfs_context.h>
  27 #include <sys/types.h>
  28 #include <sys/param.h>
  29 #include <sys/systm.h>
  30 #include <sys/sysmacros.h>
  31 #include <sys/dmu.h>
  32 #include <sys/dmu_impl.h>
  33 #include <sys/dmu_objset.h>
  34 #include <sys/dbuf.h>
  35 #include <sys/dnode.h>
  36 #include <sys/zap.h>
  37 #include <sys/sa.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/sa_impl.h>
  40 #include <sys/dnode.h>
  41 #include <sys/errno.h>
  42 #include <sys/zfs_context.h>
  43 
 
 
 410 {
 411         sa_os_t *sa = os->os_sa;
 412         sa_lot_t *tb, *findtb;
 413         int i;
 414         avl_index_t loc;
 415 
 416         ASSERT(MUTEX_HELD(&sa->sa_lock));
 417         tb = kmem_zalloc(sizeof (sa_lot_t), KM_SLEEP);
 418         tb->lot_attr_count = attr_count;
 419         tb->lot_attrs = kmem_alloc(sizeof (sa_attr_type_t) * attr_count,
 420             KM_SLEEP);
 421         bcopy(attrs, tb->lot_attrs, sizeof (sa_attr_type_t) * attr_count);
 422         tb->lot_num = lot_num;
 423         tb->lot_hash = hash;
 424         tb->lot_instance = 0;
 425 
 426         if (zapadd) {
 427                 char attr_name[8];
 428 
 429                 if (sa->sa_layout_attr_obj == 0) {
 430                         sa->sa_layout_attr_obj = zap_create(os,
 431                             DMU_OT_SA_ATTR_LAYOUTS, DMU_OT_NONE, 0, tx);
 432                         VERIFY(zap_add(os, sa->sa_master_obj, SA_LAYOUTS, 8, 1,
 433                             &sa->sa_layout_attr_obj, tx) == 0);
 434                 }
 435 
 436                 (void) snprintf(attr_name, sizeof (attr_name),
 437                     "%d", (int)lot_num);
 438                 VERIFY(0 == zap_update(os, os->os_sa->sa_layout_attr_obj,
 439                     attr_name, 2, attr_count, attrs, tx));
 440         }
 441 
 442         list_create(&tb->lot_idx_tab, sizeof (sa_idx_tab_t),
 443             offsetof(sa_idx_tab_t, sa_next));
 444 
 445         for (i = 0; i != attr_count; i++) {
 446                 if (sa->sa_attr_table[tb->lot_attrs[i]].sa_length == 0)
 447                         tb->lot_var_sizes++;
 448         }
 449 
 450         avl_add(&sa->sa_layout_num_tree, tb);
 451 
 452         /* verify we don't have a hash collision */
 453         if ((findtb = avl_find(&sa->sa_layout_hash_tree, tb, &loc)) != NULL) {
 
1535         *dataptr = userdata;
1536         *len = total_len;
1537 }
1538 
1539 static void
1540 sa_attr_register_sync(sa_handle_t *hdl, dmu_tx_t *tx)
1541 {
1542         uint64_t attr_value = 0;
1543         sa_os_t *sa = hdl->sa_os->os_sa;
1544         sa_attr_table_t *tb = sa->sa_attr_table;
1545         int i;
1546 
1547         mutex_enter(&sa->sa_lock);
1548 
1549         if (!sa->sa_need_attr_registration || sa->sa_master_obj == NULL) {
1550                 mutex_exit(&sa->sa_lock);
1551                 return;
1552         }
1553 
1554         if (sa->sa_reg_attr_obj == NULL) {
1555                 sa->sa_reg_attr_obj = zap_create(hdl->sa_os,
1556                     DMU_OT_SA_ATTR_REGISTRATION, DMU_OT_NONE, 0, tx);
1557                 VERIFY(zap_add(hdl->sa_os, sa->sa_master_obj,
1558                     SA_REGISTRY, 8, 1, &sa->sa_reg_attr_obj, tx) == 0);
1559         }
1560         for (i = 0; i != sa->sa_num_attrs; i++) {
1561                 if (sa->sa_attr_table[i].sa_registered)
1562                         continue;
1563                 ATTR_ENCODE(attr_value, tb[i].sa_attr, tb[i].sa_length,
1564                     tb[i].sa_byteswap);
1565                 VERIFY(0 == zap_update(hdl->sa_os, sa->sa_reg_attr_obj,
1566                     tb[i].sa_name, 8, 1, &attr_value, tx));
1567                 tb[i].sa_registered = B_TRUE;
1568         }
1569         sa->sa_need_attr_registration = B_FALSE;
1570         mutex_exit(&sa->sa_lock);
1571 }
1572 
1573 /*
1574  * Replace all attributes with attributes specified in template.
1575  * If dnode had a spill buffer then those attributes will be
1576  * also be replaced, possibly with just an empty spill block
1577  *
1578  * This interface is intended to only be used for bulk adding of
 
 | 
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Portions Copyright 2011 iXsystems, Inc
  25  * Copyright (c) 2012 by Delphix. All rights reserved.
  26  */
  27 
  28 #include <sys/zfs_context.h>
  29 #include <sys/types.h>
  30 #include <sys/param.h>
  31 #include <sys/systm.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/dmu.h>
  34 #include <sys/dmu_impl.h>
  35 #include <sys/dmu_objset.h>
  36 #include <sys/dbuf.h>
  37 #include <sys/dnode.h>
  38 #include <sys/zap.h>
  39 #include <sys/sa.h>
  40 #include <sys/sunddi.h>
  41 #include <sys/sa_impl.h>
  42 #include <sys/dnode.h>
  43 #include <sys/errno.h>
  44 #include <sys/zfs_context.h>
  45 
 
 
 412 {
 413         sa_os_t *sa = os->os_sa;
 414         sa_lot_t *tb, *findtb;
 415         int i;
 416         avl_index_t loc;
 417 
 418         ASSERT(MUTEX_HELD(&sa->sa_lock));
 419         tb = kmem_zalloc(sizeof (sa_lot_t), KM_SLEEP);
 420         tb->lot_attr_count = attr_count;
 421         tb->lot_attrs = kmem_alloc(sizeof (sa_attr_type_t) * attr_count,
 422             KM_SLEEP);
 423         bcopy(attrs, tb->lot_attrs, sizeof (sa_attr_type_t) * attr_count);
 424         tb->lot_num = lot_num;
 425         tb->lot_hash = hash;
 426         tb->lot_instance = 0;
 427 
 428         if (zapadd) {
 429                 char attr_name[8];
 430 
 431                 if (sa->sa_layout_attr_obj == 0) {
 432                         sa->sa_layout_attr_obj = zap_create_link(os,
 433                             DMU_OT_SA_ATTR_LAYOUTS,
 434                             sa->sa_master_obj, SA_LAYOUTS, tx);
 435                 }
 436 
 437                 (void) snprintf(attr_name, sizeof (attr_name),
 438                     "%d", (int)lot_num);
 439                 VERIFY(0 == zap_update(os, os->os_sa->sa_layout_attr_obj,
 440                     attr_name, 2, attr_count, attrs, tx));
 441         }
 442 
 443         list_create(&tb->lot_idx_tab, sizeof (sa_idx_tab_t),
 444             offsetof(sa_idx_tab_t, sa_next));
 445 
 446         for (i = 0; i != attr_count; i++) {
 447                 if (sa->sa_attr_table[tb->lot_attrs[i]].sa_length == 0)
 448                         tb->lot_var_sizes++;
 449         }
 450 
 451         avl_add(&sa->sa_layout_num_tree, tb);
 452 
 453         /* verify we don't have a hash collision */
 454         if ((findtb = avl_find(&sa->sa_layout_hash_tree, tb, &loc)) != NULL) {
 
1536         *dataptr = userdata;
1537         *len = total_len;
1538 }
1539 
1540 static void
1541 sa_attr_register_sync(sa_handle_t *hdl, dmu_tx_t *tx)
1542 {
1543         uint64_t attr_value = 0;
1544         sa_os_t *sa = hdl->sa_os->os_sa;
1545         sa_attr_table_t *tb = sa->sa_attr_table;
1546         int i;
1547 
1548         mutex_enter(&sa->sa_lock);
1549 
1550         if (!sa->sa_need_attr_registration || sa->sa_master_obj == NULL) {
1551                 mutex_exit(&sa->sa_lock);
1552                 return;
1553         }
1554 
1555         if (sa->sa_reg_attr_obj == NULL) {
1556                 sa->sa_reg_attr_obj = zap_create_link(hdl->sa_os,
1557                     DMU_OT_SA_ATTR_REGISTRATION,
1558                     sa->sa_master_obj, SA_REGISTRY, tx);
1559         }
1560         for (i = 0; i != sa->sa_num_attrs; i++) {
1561                 if (sa->sa_attr_table[i].sa_registered)
1562                         continue;
1563                 ATTR_ENCODE(attr_value, tb[i].sa_attr, tb[i].sa_length,
1564                     tb[i].sa_byteswap);
1565                 VERIFY(0 == zap_update(hdl->sa_os, sa->sa_reg_attr_obj,
1566                     tb[i].sa_name, 8, 1, &attr_value, tx));
1567                 tb[i].sa_registered = B_TRUE;
1568         }
1569         sa->sa_need_attr_registration = B_FALSE;
1570         mutex_exit(&sa->sa_lock);
1571 }
1572 
1573 /*
1574  * Replace all attributes with attributes specified in template.
1575  * If dnode had a spill buffer then those attributes will be
1576  * also be replaced, possibly with just an empty spill block
1577  *
1578  * This interface is intended to only be used for bulk adding of
 
 |