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  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  27  * Copyright (c) 2011 by Delphix. All rights reserved.
  28  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #include <sys/dmu.h>
  32 #include <sys/dmu_impl.h>
  33 #include <sys/dmu_tx.h>
  34 #include <sys/dbuf.h>
  35 #include <sys/dnode.h>
  36 #include <sys/zfs_context.h>
  37 #include <sys/dmu_objset.h>
  38 #include <sys/dmu_traverse.h>
  39 #include <sys/dsl_dataset.h>
  40 #include <sys/dsl_dir.h>
  41 #include <sys/dsl_prop.h>
  42 #include <sys/dsl_pool.h>
  43 #include <sys/dsl_synctask.h>
  44 #include <sys/zfs_ioctl.h>
  45 #include <sys/zap.h>
  46 #include <sys/zio_checksum.h>
  47 #include <sys/zfs_znode.h>
 
 
1058         case DRR_END:
1059                 DO64(drr_end.drr_checksum.zc_word[0]);
1060                 DO64(drr_end.drr_checksum.zc_word[1]);
1061                 DO64(drr_end.drr_checksum.zc_word[2]);
1062                 DO64(drr_end.drr_checksum.zc_word[3]);
1063                 DO64(drr_end.drr_toguid);
1064                 break;
1065         }
1066 #undef DO64
1067 #undef DO32
1068 }
1069 
1070 static int
1071 restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
1072 {
1073         int err;
1074         dmu_tx_t *tx;
1075         void *data = NULL;
1076 
1077         if (drro->drr_type == DMU_OT_NONE ||
1078             drro->drr_type >= DMU_OT_NUMTYPES ||
1079             drro->drr_bonustype >= DMU_OT_NUMTYPES ||
1080             drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS ||
1081             drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
1082             P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
1083             drro->drr_blksz < SPA_MINBLOCKSIZE ||
1084             drro->drr_blksz > SPA_MAXBLOCKSIZE ||
1085             drro->drr_bonuslen > DN_MAX_BONUSLEN) {
1086                 return (EINVAL);
1087         }
1088 
1089         err = dmu_object_info(os, drro->drr_object, NULL);
1090 
1091         if (err != 0 && err != ENOENT)
1092                 return (EINVAL);
1093 
1094         if (drro->drr_bonuslen) {
1095                 data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
1096                 if (ra->err)
1097                         return (ra->err);
1098         }
1099 
 
1124         dmu_tx_hold_bonus(tx, drro->drr_object);
1125         err = dmu_tx_assign(tx, TXG_WAIT);
1126         if (err) {
1127                 dmu_tx_abort(tx);
1128                 return (err);
1129         }
1130 
1131         dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksumtype,
1132             tx);
1133         dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
1134 
1135         if (data != NULL) {
1136                 dmu_buf_t *db;
1137 
1138                 VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
1139                 dmu_buf_will_dirty(db, tx);
1140 
1141                 ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
1142                 bcopy(data, db->db_data, drro->drr_bonuslen);
1143                 if (ra->byteswap) {
1144                         dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,
1145                             drro->drr_bonuslen);
1146                 }
1147                 dmu_buf_rele(db, FTAG);
1148         }
1149         dmu_tx_commit(tx);
1150         return (0);
1151 }
1152 
1153 /* ARGSUSED */
1154 static int
1155 restore_freeobjects(struct restorearg *ra, objset_t *os,
1156     struct drr_freeobjects *drrfo)
1157 {
1158         uint64_t obj;
1159 
1160         if (drrfo->drr_firstobj + drrfo->drr_numobjs < drrfo->drr_firstobj)
1161                 return (EINVAL);
1162 
1163         for (obj = drrfo->drr_firstobj;
1164             obj < drrfo->drr_firstobj + drrfo->drr_numobjs;
 
1167 
1168                 if (dmu_object_info(os, obj, NULL) != 0)
1169                         continue;
1170 
1171                 err = dmu_free_object(os, obj);
1172                 if (err)
1173                         return (err);
1174         }
1175         return (0);
1176 }
1177 
1178 static int
1179 restore_write(struct restorearg *ra, objset_t *os,
1180     struct drr_write *drrw)
1181 {
1182         dmu_tx_t *tx;
1183         void *data;
1184         int err;
1185 
1186         if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset ||
1187             drrw->drr_type >= DMU_OT_NUMTYPES)
1188                 return (EINVAL);
1189 
1190         data = restore_read(ra, drrw->drr_length);
1191         if (data == NULL)
1192                 return (ra->err);
1193 
1194         if (dmu_object_info(os, drrw->drr_object, NULL) != 0)
1195                 return (EINVAL);
1196 
1197         tx = dmu_tx_create(os);
1198 
1199         dmu_tx_hold_write(tx, drrw->drr_object,
1200             drrw->drr_offset, drrw->drr_length);
1201         err = dmu_tx_assign(tx, TXG_WAIT);
1202         if (err) {
1203                 dmu_tx_abort(tx);
1204                 return (err);
1205         }
1206         if (ra->byteswap)
1207                 dmu_ot[drrw->drr_type].ot_byteswap(data, drrw->drr_length);
1208         dmu_write(os, drrw->drr_object,
1209             drrw->drr_offset, drrw->drr_length, data, tx);
1210         dmu_tx_commit(tx);
1211         return (0);
1212 }
1213 
1214 /*
1215  * Handle a DRR_WRITE_BYREF record.  This record is used in dedup'ed
1216  * streams to refer to a copy of the data that is already on the
1217  * system because it came in earlier in the stream.  This function
1218  * finds the earlier copy of the data, and uses that copy instead of
1219  * data from the stream to fulfill this write.
1220  */
1221 static int
1222 restore_write_byref(struct restorearg *ra, objset_t *os,
1223     struct drr_write_byref *drrwbr)
1224 {
1225         dmu_tx_t *tx;
1226         int err;
1227         guid_map_entry_t gmesrch;
 
 | 
 
 
   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 2011 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright (c) 2012 by Delphix. All rights reserved.
  25  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  26  */
  27 
  28 #include <sys/dmu.h>
  29 #include <sys/dmu_impl.h>
  30 #include <sys/dmu_tx.h>
  31 #include <sys/dbuf.h>
  32 #include <sys/dnode.h>
  33 #include <sys/zfs_context.h>
  34 #include <sys/dmu_objset.h>
  35 #include <sys/dmu_traverse.h>
  36 #include <sys/dsl_dataset.h>
  37 #include <sys/dsl_dir.h>
  38 #include <sys/dsl_prop.h>
  39 #include <sys/dsl_pool.h>
  40 #include <sys/dsl_synctask.h>
  41 #include <sys/zfs_ioctl.h>
  42 #include <sys/zap.h>
  43 #include <sys/zio_checksum.h>
  44 #include <sys/zfs_znode.h>
 
 
1055         case DRR_END:
1056                 DO64(drr_end.drr_checksum.zc_word[0]);
1057                 DO64(drr_end.drr_checksum.zc_word[1]);
1058                 DO64(drr_end.drr_checksum.zc_word[2]);
1059                 DO64(drr_end.drr_checksum.zc_word[3]);
1060                 DO64(drr_end.drr_toguid);
1061                 break;
1062         }
1063 #undef DO64
1064 #undef DO32
1065 }
1066 
1067 static int
1068 restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
1069 {
1070         int err;
1071         dmu_tx_t *tx;
1072         void *data = NULL;
1073 
1074         if (drro->drr_type == DMU_OT_NONE ||
1075             !DMU_OT_IS_VALID(drro->drr_type) ||
1076             !DMU_OT_IS_VALID(drro->drr_bonustype) ||
1077             drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS ||
1078             drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
1079             P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
1080             drro->drr_blksz < SPA_MINBLOCKSIZE ||
1081             drro->drr_blksz > SPA_MAXBLOCKSIZE ||
1082             drro->drr_bonuslen > DN_MAX_BONUSLEN) {
1083                 return (EINVAL);
1084         }
1085 
1086         err = dmu_object_info(os, drro->drr_object, NULL);
1087 
1088         if (err != 0 && err != ENOENT)
1089                 return (EINVAL);
1090 
1091         if (drro->drr_bonuslen) {
1092                 data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
1093                 if (ra->err)
1094                         return (ra->err);
1095         }
1096 
 
1121         dmu_tx_hold_bonus(tx, drro->drr_object);
1122         err = dmu_tx_assign(tx, TXG_WAIT);
1123         if (err) {
1124                 dmu_tx_abort(tx);
1125                 return (err);
1126         }
1127 
1128         dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksumtype,
1129             tx);
1130         dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
1131 
1132         if (data != NULL) {
1133                 dmu_buf_t *db;
1134 
1135                 VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
1136                 dmu_buf_will_dirty(db, tx);
1137 
1138                 ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
1139                 bcopy(data, db->db_data, drro->drr_bonuslen);
1140                 if (ra->byteswap) {
1141                         dmu_object_byteswap_t byteswap =
1142                             DMU_OT_BYTESWAP(drro->drr_bonustype);
1143                         dmu_ot_byteswap[byteswap].ob_func(db->db_data,
1144                             drro->drr_bonuslen);
1145                 }
1146                 dmu_buf_rele(db, FTAG);
1147         }
1148         dmu_tx_commit(tx);
1149         return (0);
1150 }
1151 
1152 /* ARGSUSED */
1153 static int
1154 restore_freeobjects(struct restorearg *ra, objset_t *os,
1155     struct drr_freeobjects *drrfo)
1156 {
1157         uint64_t obj;
1158 
1159         if (drrfo->drr_firstobj + drrfo->drr_numobjs < drrfo->drr_firstobj)
1160                 return (EINVAL);
1161 
1162         for (obj = drrfo->drr_firstobj;
1163             obj < drrfo->drr_firstobj + drrfo->drr_numobjs;
 
1166 
1167                 if (dmu_object_info(os, obj, NULL) != 0)
1168                         continue;
1169 
1170                 err = dmu_free_object(os, obj);
1171                 if (err)
1172                         return (err);
1173         }
1174         return (0);
1175 }
1176 
1177 static int
1178 restore_write(struct restorearg *ra, objset_t *os,
1179     struct drr_write *drrw)
1180 {
1181         dmu_tx_t *tx;
1182         void *data;
1183         int err;
1184 
1185         if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset ||
1186             !DMU_OT_IS_VALID(drrw->drr_type))
1187                 return (EINVAL);
1188 
1189         data = restore_read(ra, drrw->drr_length);
1190         if (data == NULL)
1191                 return (ra->err);
1192 
1193         if (dmu_object_info(os, drrw->drr_object, NULL) != 0)
1194                 return (EINVAL);
1195 
1196         tx = dmu_tx_create(os);
1197 
1198         dmu_tx_hold_write(tx, drrw->drr_object,
1199             drrw->drr_offset, drrw->drr_length);
1200         err = dmu_tx_assign(tx, TXG_WAIT);
1201         if (err) {
1202                 dmu_tx_abort(tx);
1203                 return (err);
1204         }
1205         if (ra->byteswap) {
1206                 dmu_object_byteswap_t byteswap =
1207                     DMU_OT_BYTESWAP(drrw->drr_type);
1208                 dmu_ot_byteswap[byteswap].ob_func(data, drrw->drr_length);
1209         }
1210         dmu_write(os, drrw->drr_object,
1211             drrw->drr_offset, drrw->drr_length, data, tx);
1212         dmu_tx_commit(tx);
1213         return (0);
1214 }
1215 
1216 /*
1217  * Handle a DRR_WRITE_BYREF record.  This record is used in dedup'ed
1218  * streams to refer to a copy of the data that is already on the
1219  * system because it came in earlier in the stream.  This function
1220  * finds the earlier copy of the data, and uses that copy instead of
1221  * data from the stream to fulfill this write.
1222  */
1223 static int
1224 restore_write_byref(struct restorearg *ra, objset_t *os,
1225     struct drr_write_byref *drrwbr)
1226 {
1227         dmu_tx_t *tx;
1228         int err;
1229         guid_map_entry_t gmesrch;
 
 |