155 #include <sys/dsl_deleg.h>
156 #include <sys/dmu_objset.h>
157 #include <sys/dmu_impl.h>
158 #include <sys/ddi.h>
159 #include <sys/sunddi.h>
160 #include <sys/sunldi.h>
161 #include <sys/policy.h>
162 #include <sys/zone.h>
163 #include <sys/nvpair.h>
164 #include <sys/pathname.h>
165 #include <sys/mount.h>
166 #include <sys/sdt.h>
167 #include <sys/fs/zfs.h>
168 #include <sys/zfs_ctldir.h>
169 #include <sys/zfs_dir.h>
170 #include <sys/zfs_onexit.h>
171 #include <sys/zvol.h>
172 #include <sys/dsl_scan.h>
173 #include <sharefs/share.h>
174 #include <sys/dmu_objset.h>
175
176 #include "zfs_namecheck.h"
177 #include "zfs_prop.h"
178 #include "zfs_deleg.h"
179 #include "zfs_comutil.h"
180
181 extern struct modlfs zfs_modlfs;
182
183 extern void zfs_init(void);
184 extern void zfs_fini(void);
185
186 ldi_ident_t zfs_li = NULL;
187 dev_info_t *zfs_dip;
188
189 uint_t zfs_fsyncer_key;
190 extern uint_t rrw_tsd_key;
191 static uint_t zfs_allow_log_key;
192
193 typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
194 typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
4025 }
4026 out:
4027 nvlist_free(props);
4028 nvlist_free(origprops);
4029 nvlist_free(errors);
4030 releasef(fd);
4031
4032 if (error == 0)
4033 error = props_error;
4034
4035 return (error);
4036 }
4037
4038 /*
4039 * inputs:
4040 * zc_name name of snapshot to send
4041 * zc_cookie file descriptor to send stream to
4042 * zc_obj fromorigin flag (mutually exclusive with zc_fromobj)
4043 * zc_sendobj objsetid of snapshot to send
4044 * zc_fromobj objsetid of incremental fromsnap (may be zero)
4045 * zc_guid if set, estimate size of stream only. zc_cookie is ignored.
4046 * output size in zc_objset_type.
4047 *
4048 * outputs: none
4049 */
4050 static int
4051 zfs_ioc_send(zfs_cmd_t *zc)
4052 {
4053 objset_t *fromsnap = NULL;
4054 objset_t *tosnap;
4055 int error;
4056 offset_t off;
4057 dsl_dataset_t *ds;
4058 dsl_dataset_t *dsfrom = NULL;
4059 spa_t *spa;
4060 dsl_pool_t *dp;
4061 boolean_t estimate = (zc->zc_guid != 0);
4062
4063 error = spa_open(zc->zc_name, &spa, FTAG);
4064 if (error)
4065 return (error);
4066
4067 dp = spa_get_dsl(spa);
4068 rw_enter(&dp->dp_config_rwlock, RW_READER);
4069 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
4070 rw_exit(&dp->dp_config_rwlock);
4071 spa_close(spa, FTAG);
4072 if (error)
4073 return (error);
4074
4075 error = dmu_objset_from_ds(ds, &tosnap);
4076 if (error) {
4077 dsl_dataset_rele(ds, FTAG);
4078 return (error);
4079 }
4080
4081 if (zc->zc_fromobj != 0) {
4117 dsl_dataset_rele(dsfrom, FTAG);
4118 dsl_dataset_rele(ds, FTAG);
4119 return (error);
4120 }
4121 }
4122 }
4123
4124 if (estimate) {
4125 error = dmu_send_estimate(tosnap, fromsnap,
4126 &zc->zc_objset_type);
4127 } else {
4128 file_t *fp = getf(zc->zc_cookie);
4129 if (fp == NULL) {
4130 dsl_dataset_rele(ds, FTAG);
4131 if (dsfrom)
4132 dsl_dataset_rele(dsfrom, FTAG);
4133 return (EBADF);
4134 }
4135
4136 off = fp->f_offset;
4137 error = dmu_send(tosnap, fromsnap,
4138 zc->zc_cookie, fp->f_vnode, &off);
4139
4140 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4141 fp->f_offset = off;
4142 releasef(zc->zc_cookie);
4143 }
4144 if (dsfrom)
4145 dsl_dataset_rele(dsfrom, FTAG);
4146 dsl_dataset_rele(ds, FTAG);
4147 return (error);
4148 }
4149
4150 /*
4151 * inputs:
4152 * zc_name name of snapshot on which to report progress
4153 * zc_cookie file descriptor of send stream
4154 *
4155 * outputs:
4156 * zc_cookie number of bytes written in send stream thus far
4157 */
4158 static int
5075 }
5076
5077 /*
5078 * innvl: {
5079 * "fd" -> file descriptor to write stream to (int32)
5080 * (optional) "fromsnap" -> full snap name to send an incremental from
5081 * }
5082 *
5083 * outnvl is unused
5084 */
5085 /* ARGSUSED */
5086 static int
5087 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5088 {
5089 objset_t *fromsnap = NULL;
5090 objset_t *tosnap;
5091 int error;
5092 offset_t off;
5093 char *fromname;
5094 int fd;
5095
5096 error = nvlist_lookup_int32(innvl, "fd", &fd);
5097 if (error != 0)
5098 return (EINVAL);
5099
5100 error = dmu_objset_hold(snapname, FTAG, &tosnap);
5101 if (error)
5102 return (error);
5103
5104 error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5105 if (error == 0) {
5106 error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5107 if (error) {
5108 dmu_objset_rele(tosnap, FTAG);
5109 return (error);
5110 }
5111 }
5112
5113 file_t *fp = getf(fd);
5114 if (fp == NULL) {
5115 dmu_objset_rele(tosnap, FTAG);
5116 if (fromsnap != NULL)
5117 dmu_objset_rele(fromsnap, FTAG);
5118 return (EBADF);
5119 }
5120
5121 off = fp->f_offset;
5122 error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5123
5124 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5125 fp->f_offset = off;
5126 releasef(fd);
5127 if (fromsnap != NULL)
5128 dmu_objset_rele(fromsnap, FTAG);
5129 dmu_objset_rele(tosnap, FTAG);
5130 return (error);
5131 }
5132
5133 /*
5134 * Determine approximately how large a zfs send stream will be -- the number
5135 * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5136 *
5137 * innvl: {
5138 * (optional) "fromsnap" -> full snap name to send an incremental from
5139 * }
5140 *
5141 * outnvl: {
5142 * "space" -> bytes of space (uint64)
|
155 #include <sys/dsl_deleg.h>
156 #include <sys/dmu_objset.h>
157 #include <sys/dmu_impl.h>
158 #include <sys/ddi.h>
159 #include <sys/sunddi.h>
160 #include <sys/sunldi.h>
161 #include <sys/policy.h>
162 #include <sys/zone.h>
163 #include <sys/nvpair.h>
164 #include <sys/pathname.h>
165 #include <sys/mount.h>
166 #include <sys/sdt.h>
167 #include <sys/fs/zfs.h>
168 #include <sys/zfs_ctldir.h>
169 #include <sys/zfs_dir.h>
170 #include <sys/zfs_onexit.h>
171 #include <sys/zvol.h>
172 #include <sys/dsl_scan.h>
173 #include <sharefs/share.h>
174 #include <sys/dmu_objset.h>
175 #include <sys/far.h>
176
177 #include "zfs_namecheck.h"
178 #include "zfs_prop.h"
179 #include "zfs_deleg.h"
180 #include "zfs_comutil.h"
181
182 extern struct modlfs zfs_modlfs;
183
184 extern void zfs_init(void);
185 extern void zfs_fini(void);
186
187 ldi_ident_t zfs_li = NULL;
188 dev_info_t *zfs_dip;
189
190 uint_t zfs_fsyncer_key;
191 extern uint_t rrw_tsd_key;
192 static uint_t zfs_allow_log_key;
193
194 typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
195 typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
4026 }
4027 out:
4028 nvlist_free(props);
4029 nvlist_free(origprops);
4030 nvlist_free(errors);
4031 releasef(fd);
4032
4033 if (error == 0)
4034 error = props_error;
4035
4036 return (error);
4037 }
4038
4039 /*
4040 * inputs:
4041 * zc_name name of snapshot to send
4042 * zc_cookie file descriptor to send stream to
4043 * zc_obj fromorigin flag (mutually exclusive with zc_fromobj)
4044 * zc_sendobj objsetid of snapshot to send
4045 * zc_fromobj objsetid of incremental fromsnap (may be zero)
4046 * zc_guid bit 0: if set, estimate size of stream only. zc_cookie is
4047 * ignored. output size in zc_objset_type.
4048 * zc_guid bit 1: if set, send output in FAR-format
4049 *
4050 * outputs: none
4051 */
4052 static int
4053 zfs_ioc_send(zfs_cmd_t *zc)
4054 {
4055 objset_t *fromsnap = NULL;
4056 objset_t *tosnap;
4057 int error;
4058 offset_t off;
4059 dsl_dataset_t *ds;
4060 dsl_dataset_t *dsfrom = NULL;
4061 spa_t *spa;
4062 dsl_pool_t *dp;
4063 boolean_t estimate = ((zc->zc_guid & 1) != 0);
4064 boolean_t far = ((zc->zc_guid & 2) != 0);
4065
4066 error = spa_open(zc->zc_name, &spa, FTAG);
4067 if (error)
4068 return (error);
4069
4070 dp = spa_get_dsl(spa);
4071 rw_enter(&dp->dp_config_rwlock, RW_READER);
4072 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
4073 rw_exit(&dp->dp_config_rwlock);
4074 spa_close(spa, FTAG);
4075 if (error)
4076 return (error);
4077
4078 error = dmu_objset_from_ds(ds, &tosnap);
4079 if (error) {
4080 dsl_dataset_rele(ds, FTAG);
4081 return (error);
4082 }
4083
4084 if (zc->zc_fromobj != 0) {
4120 dsl_dataset_rele(dsfrom, FTAG);
4121 dsl_dataset_rele(ds, FTAG);
4122 return (error);
4123 }
4124 }
4125 }
4126
4127 if (estimate) {
4128 error = dmu_send_estimate(tosnap, fromsnap,
4129 &zc->zc_objset_type);
4130 } else {
4131 file_t *fp = getf(zc->zc_cookie);
4132 if (fp == NULL) {
4133 dsl_dataset_rele(ds, FTAG);
4134 if (dsfrom)
4135 dsl_dataset_rele(dsfrom, FTAG);
4136 return (EBADF);
4137 }
4138
4139 off = fp->f_offset;
4140 if (!far)
4141 error = dmu_send(tosnap, fromsnap,
4142 zc->zc_cookie, fp->f_vnode, &off);
4143 else
4144 error = far_send(tosnap, fromsnap,
4145 zc->zc_cookie, fp->f_vnode, &off);
4146
4147 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4148 fp->f_offset = off;
4149 releasef(zc->zc_cookie);
4150 }
4151 if (dsfrom)
4152 dsl_dataset_rele(dsfrom, FTAG);
4153 dsl_dataset_rele(ds, FTAG);
4154 return (error);
4155 }
4156
4157 /*
4158 * inputs:
4159 * zc_name name of snapshot on which to report progress
4160 * zc_cookie file descriptor of send stream
4161 *
4162 * outputs:
4163 * zc_cookie number of bytes written in send stream thus far
4164 */
4165 static int
5082 }
5083
5084 /*
5085 * innvl: {
5086 * "fd" -> file descriptor to write stream to (int32)
5087 * (optional) "fromsnap" -> full snap name to send an incremental from
5088 * }
5089 *
5090 * outnvl is unused
5091 */
5092 /* ARGSUSED */
5093 static int
5094 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5095 {
5096 objset_t *fromsnap = NULL;
5097 objset_t *tosnap;
5098 int error;
5099 offset_t off;
5100 char *fromname;
5101 int fd;
5102 int far;
5103
5104 error = nvlist_lookup_int32(innvl, "fd", &fd);
5105 if (error != 0)
5106 return (EINVAL);
5107
5108 error = nvlist_lookup_int32(innvl, "far", &far);
5109 if (error != 0 && error != ENOENT)
5110 return (EINVAL);
5111
5112 error = dmu_objset_hold(snapname, FTAG, &tosnap);
5113 if (error)
5114 return (error);
5115
5116 error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5117 if (error == 0) {
5118 error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5119 if (error) {
5120 dmu_objset_rele(tosnap, FTAG);
5121 return (error);
5122 }
5123 }
5124
5125 file_t *fp = getf(fd);
5126 if (fp == NULL) {
5127 dmu_objset_rele(tosnap, FTAG);
5128 if (fromsnap != NULL)
5129 dmu_objset_rele(fromsnap, FTAG);
5130 return (EBADF);
5131 }
5132
5133 off = fp->f_offset;
5134 if (!far)
5135 error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5136 else
5137 error = far_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5138
5139 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5140 fp->f_offset = off;
5141 releasef(fd);
5142 if (fromsnap != NULL)
5143 dmu_objset_rele(fromsnap, FTAG);
5144 dmu_objset_rele(tosnap, FTAG);
5145 return (error);
5146 }
5147
5148 /*
5149 * Determine approximately how large a zfs send stream will be -- the number
5150 * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5151 *
5152 * innvl: {
5153 * (optional) "fromsnap" -> full snap name to send an incremental from
5154 * }
5155 *
5156 * outnvl: {
5157 * "space" -> bytes of space (uint64)
|