Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>


   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2011 by Delphix. All rights reserved.
  24  */
  25 
  26 #include <sys/zio.h>
  27 #include <sys/spa.h>
  28 #include <sys/dmu.h>
  29 #include <sys/zfs_context.h>
  30 #include <sys/zap.h>
  31 #include <sys/refcount.h>
  32 #include <sys/zap_impl.h>
  33 #include <sys/zap_leaf.h>
  34 #include <sys/avl.h>
  35 #include <sys/arc.h>
  36 
  37 #ifdef _KERNEL
  38 #include <sys/sunddi.h>
  39 #endif
  40 
  41 static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags);
  42 
  43 uint64_t


 444 
 445 int
 446 zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
 447     krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
 448 {
 449         zap_t *zap;
 450         dmu_buf_t *db;
 451         krw_t lt;
 452         int err;
 453 
 454         *zapp = NULL;
 455 
 456         err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
 457         if (err)
 458                 return (err);
 459 
 460 #ifdef ZFS_DEBUG
 461         {
 462                 dmu_object_info_t doi;
 463                 dmu_object_info_from_db(db, &doi);
 464                 ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
 465         }
 466 #endif
 467 
 468         zap = dmu_buf_get_user(db);
 469         if (zap == NULL)
 470                 zap = mzap_open(os, obj, db);
 471 
 472         /*
 473          * We're checking zap_ismicro without the lock held, in order to
 474          * tell what type of lock we want.  Once we have some sort of
 475          * lock, see if it really is the right type.  In practice this
 476          * can only be different if it was upgraded from micro to fat,
 477          * and micro wanted WRITER but fat only needs READER.
 478          */
 479         lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
 480         rw_enter(&zap->zap_rwlock, lt);
 481         if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
 482                 /* it was upgraded, now we only need reader */
 483                 ASSERT(lt == RW_WRITER);
 484                 ASSERT(RW_READER ==


 568                         break;
 569         }
 570         kmem_free(mzp, sz);
 571         *zapp = zap;
 572         return (err);
 573 }
 574 
 575 static void
 576 mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
 577     dmu_tx_t *tx)
 578 {
 579         dmu_buf_t *db;
 580         mzap_phys_t *zp;
 581 
 582         VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
 583 
 584 #ifdef ZFS_DEBUG
 585         {
 586                 dmu_object_info_t doi;
 587                 dmu_object_info_from_db(db, &doi);
 588                 ASSERT(dmu_ot[doi.doi_type].ot_byteswap == zap_byteswap);
 589         }
 590 #endif
 591 
 592         dmu_buf_will_dirty(db, tx);
 593         zp = db->db_data;
 594         zp->mz_block_type = ZBT_MICRO;
 595         zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
 596         zp->mz_normflags = normflags;
 597         dmu_buf_rele(db, FTAG);
 598 
 599         if (flags != 0) {
 600                 zap_t *zap;
 601                 /* Only fat zap supports flags; upgrade immediately. */
 602                 VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
 603                     B_FALSE, B_FALSE, &zap));
 604                 VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags));
 605                 zap_unlockdir(zap);
 606         }
 607 }
 608 




   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012 by Delphix. All rights reserved.
  24  */
  25 
  26 #include <sys/zio.h>
  27 #include <sys/spa.h>
  28 #include <sys/dmu.h>
  29 #include <sys/zfs_context.h>
  30 #include <sys/zap.h>
  31 #include <sys/refcount.h>
  32 #include <sys/zap_impl.h>
  33 #include <sys/zap_leaf.h>
  34 #include <sys/avl.h>
  35 #include <sys/arc.h>
  36 
  37 #ifdef _KERNEL
  38 #include <sys/sunddi.h>
  39 #endif
  40 
  41 static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags);
  42 
  43 uint64_t


 444 
 445 int
 446 zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
 447     krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
 448 {
 449         zap_t *zap;
 450         dmu_buf_t *db;
 451         krw_t lt;
 452         int err;
 453 
 454         *zapp = NULL;
 455 
 456         err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
 457         if (err)
 458                 return (err);
 459 
 460 #ifdef ZFS_DEBUG
 461         {
 462                 dmu_object_info_t doi;
 463                 dmu_object_info_from_db(db, &doi);
 464                 ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
 465         }
 466 #endif
 467 
 468         zap = dmu_buf_get_user(db);
 469         if (zap == NULL)
 470                 zap = mzap_open(os, obj, db);
 471 
 472         /*
 473          * We're checking zap_ismicro without the lock held, in order to
 474          * tell what type of lock we want.  Once we have some sort of
 475          * lock, see if it really is the right type.  In practice this
 476          * can only be different if it was upgraded from micro to fat,
 477          * and micro wanted WRITER but fat only needs READER.
 478          */
 479         lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
 480         rw_enter(&zap->zap_rwlock, lt);
 481         if (lt != ((!zap->zap_ismicro && fatreader) ? RW_READER : lti)) {
 482                 /* it was upgraded, now we only need reader */
 483                 ASSERT(lt == RW_WRITER);
 484                 ASSERT(RW_READER ==


 568                         break;
 569         }
 570         kmem_free(mzp, sz);
 571         *zapp = zap;
 572         return (err);
 573 }
 574 
 575 static void
 576 mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
 577     dmu_tx_t *tx)
 578 {
 579         dmu_buf_t *db;
 580         mzap_phys_t *zp;
 581 
 582         VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
 583 
 584 #ifdef ZFS_DEBUG
 585         {
 586                 dmu_object_info_t doi;
 587                 dmu_object_info_from_db(db, &doi);
 588                 ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
 589         }
 590 #endif
 591 
 592         dmu_buf_will_dirty(db, tx);
 593         zp = db->db_data;
 594         zp->mz_block_type = ZBT_MICRO;
 595         zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
 596         zp->mz_normflags = normflags;
 597         dmu_buf_rele(db, FTAG);
 598 
 599         if (flags != 0) {
 600                 zap_t *zap;
 601                 /* Only fat zap supports flags; upgrade immediately. */
 602                 VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
 603                     B_FALSE, B_FALSE, &zap));
 604                 VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags));
 605                 zap_unlockdir(zap);
 606         }
 607 }
 608