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;
|