Print this page
FITS: generating send-streams in portable format
This commit adds the command 'zfs fits-send', analogous to zfs send. The
generated send stream is compatible with the stream generated with that
from 'btrfs send' and can in principle easily be received to any filesystem.


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


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)
5143  * }
5144  */
5145 static int
5146 zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5147 {
5148         objset_t *fromsnap = NULL;
5149         objset_t *tosnap;
5150         int error;
5151         char *fromname;
5152         uint64_t space;
5153 


5405             zfs_ioc_objset_zplprops);
5406         zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
5407             zfs_ioc_dataset_list_next);
5408         zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
5409             zfs_ioc_snapshot_list_next);
5410         zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
5411             zfs_ioc_send_progress);
5412 
5413         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
5414             zfs_ioc_diff, zfs_secpolicy_diff);
5415         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
5416             zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
5417         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
5418             zfs_ioc_obj_to_path, zfs_secpolicy_diff);
5419         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
5420             zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
5421         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
5422             zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
5423         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
5424             zfs_ioc_send, zfs_secpolicy_send);


5425 
5426         zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
5427             zfs_secpolicy_none);
5428         zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
5429             zfs_secpolicy_destroy);
5430         zfs_ioctl_register_dataset_modify(ZFS_IOC_ROLLBACK, zfs_ioc_rollback,
5431             zfs_secpolicy_rollback);
5432         zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
5433             zfs_secpolicy_rename);
5434         zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
5435             zfs_secpolicy_recv);
5436         zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
5437             zfs_secpolicy_promote);
5438         zfs_ioctl_register_dataset_modify(ZFS_IOC_HOLD, zfs_ioc_hold,
5439             zfs_secpolicy_hold);
5440         zfs_ioctl_register_dataset_modify(ZFS_IOC_RELEASE, zfs_ioc_release,
5441             zfs_secpolicy_release);
5442         zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
5443             zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
5444         zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,




 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/fits.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 *);


5115         if (fp == NULL) {
5116                 dmu_objset_rele(tosnap, FTAG);
5117                 if (fromsnap != NULL)
5118                         dmu_objset_rele(fromsnap, FTAG);
5119                 return (EBADF);
5120         }
5121 
5122         off = fp->f_offset;
5123         error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5124 
5125         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5126                 fp->f_offset = off;
5127         releasef(fd);
5128         if (fromsnap != NULL)
5129                 dmu_objset_rele(fromsnap, FTAG);
5130         dmu_objset_rele(tosnap, FTAG);
5131         return (error);
5132 }
5133 
5134 /*
5135  * inputs:
5136  * zc_name      name of snapshot to send
5137  * zc_cookie    file descriptor to send stream to
5138  * zc_obj       fromorigin flag (mutually exclusive with zc_fromobj)
5139  * zc_sendobj   objsetid of snapshot to send
5140  * zc_fromobj   objsetid of incremental fromsnap (may be zero)
5141  * zc_guid      if set, estimate size of stream only.  zc_cookie is ignored.
5142  *              output size in zc_objset_type.
5143  *
5144  * outputs: none
5145  */
5146 static int
5147 zfs_ioc_fits_send(zfs_cmd_t *zc)
5148 {
5149         objset_t *fromsnap = NULL;
5150         objset_t *tosnap;
5151         int error;
5152         offset_t off;
5153         dsl_dataset_t *ds;
5154         dsl_dataset_t *dsfrom = NULL;
5155         spa_t *spa;
5156         file_t *fp;
5157         dsl_pool_t *dp;
5158         boolean_t estimate = (zc->zc_guid != 0);
5159 
5160         error = spa_open(zc->zc_name, &spa, FTAG);
5161         if (error)
5162                 return (error);
5163 
5164         dp = spa_get_dsl(spa);
5165         rw_enter(&dp->dp_config_rwlock, RW_READER);
5166         error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
5167         rw_exit(&dp->dp_config_rwlock);
5168         spa_close(spa, FTAG);
5169         if (error)
5170                 return (error);
5171 
5172         error = dmu_objset_from_ds(ds, &tosnap);
5173         if (error) {
5174                 dsl_dataset_rele(ds, FTAG);
5175                 return (error);
5176         }
5177 
5178         if (zc->zc_fromobj != 0) {
5179                 rw_enter(&dp->dp_config_rwlock, RW_READER);
5180                 error = dsl_dataset_hold_obj(dp, zc->zc_fromobj, FTAG, &dsfrom);
5181                 rw_exit(&dp->dp_config_rwlock);
5182                 if (error) {
5183                         dsl_dataset_rele(ds, FTAG);
5184                         return (error);
5185                 }
5186                 error = dmu_objset_from_ds(dsfrom, &fromsnap);
5187                 if (error) {
5188                         dsl_dataset_rele(dsfrom, FTAG);
5189                         dsl_dataset_rele(ds, FTAG);
5190                         return (error);
5191                 }
5192         }
5193 
5194         if (zc->zc_obj) {
5195                 dsl_pool_t *dp = ds->ds_dir->dd_pool;
5196 
5197                 if (fromsnap != NULL) {
5198                         dsl_dataset_rele(dsfrom, FTAG);
5199                         dsl_dataset_rele(ds, FTAG);
5200                         return (EINVAL);
5201                 }
5202 
5203                 if (dsl_dir_is_clone(ds->ds_dir)) {
5204                         rw_enter(&dp->dp_config_rwlock, RW_READER);
5205                         error = dsl_dataset_hold_obj(dp,
5206                             ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &dsfrom);
5207                         rw_exit(&dp->dp_config_rwlock);
5208                         if (error) {
5209                                 dsl_dataset_rele(ds, FTAG);
5210                                 return (error);
5211                         }
5212                         error = dmu_objset_from_ds(dsfrom, &fromsnap);
5213                         if (error) {
5214                                 dsl_dataset_rele(dsfrom, FTAG);
5215                                 dsl_dataset_rele(ds, FTAG);
5216                                 return (error);
5217                         }
5218                 }
5219         }
5220 
5221         fp = getf(zc->zc_cookie);
5222         if (fp == NULL) {
5223                 dsl_dataset_rele(ds, FTAG);
5224                 if (dsfrom)
5225                         dsl_dataset_rele(dsfrom, FTAG);
5226                 return (EBADF);
5227         }
5228 
5229         off = fp->f_offset;
5230         error = fits_send(tosnap, fromsnap, zc->zc_cookie, fp->f_vnode, &off);
5231 
5232         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5233                 fp->f_offset = off;
5234         releasef(zc->zc_cookie);
5235 
5236         if (dsfrom)
5237                 dsl_dataset_rele(dsfrom, FTAG);
5238         dsl_dataset_rele(ds, FTAG);
5239         return (error);
5240 }
5241 
5242 /*
5243  * Determine approximately how large a zfs send stream will be -- the number
5244  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5245  *
5246  * innvl: {
5247  *     (optional) "fromsnap" -> full snap name to send an incremental from
5248  * }
5249  *
5250  * outnvl: {
5251  *     "space" -> bytes of space (uint64)
5252  * }
5253  */
5254 static int
5255 zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5256 {
5257         objset_t *fromsnap = NULL;
5258         objset_t *tosnap;
5259         int error;
5260         char *fromname;
5261         uint64_t space;
5262 


5514             zfs_ioc_objset_zplprops);
5515         zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
5516             zfs_ioc_dataset_list_next);
5517         zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
5518             zfs_ioc_snapshot_list_next);
5519         zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
5520             zfs_ioc_send_progress);
5521 
5522         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
5523             zfs_ioc_diff, zfs_secpolicy_diff);
5524         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
5525             zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
5526         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
5527             zfs_ioc_obj_to_path, zfs_secpolicy_diff);
5528         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
5529             zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
5530         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
5531             zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
5532         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
5533             zfs_ioc_send, zfs_secpolicy_send);
5534         zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_FITS_SEND,
5535             zfs_ioc_fits_send, zfs_secpolicy_send);
5536 
5537         zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
5538             zfs_secpolicy_none);
5539         zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
5540             zfs_secpolicy_destroy);
5541         zfs_ioctl_register_dataset_modify(ZFS_IOC_ROLLBACK, zfs_ioc_rollback,
5542             zfs_secpolicy_rollback);
5543         zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
5544             zfs_secpolicy_rename);
5545         zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
5546             zfs_secpolicy_recv);
5547         zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
5548             zfs_secpolicy_promote);
5549         zfs_ioctl_register_dataset_modify(ZFS_IOC_HOLD, zfs_ioc_hold,
5550             zfs_secpolicy_hold);
5551         zfs_ioctl_register_dataset_modify(ZFS_IOC_RELEASE, zfs_ioc_release,
5552             zfs_secpolicy_release);
5553         zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
5554             zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
5555         zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,