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
|