@@ -635,18 +635,11 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
635635{
636636 char * subvol , * dst ;
637637 int res , retval ;
638- int fd = -1 , fddst = -1 ;
639- int len ;
640- bool readonly = false;
641- char * dupname = NULL ;
642- char * dupdir = NULL ;
643- const char * newname ;
644- char * dstdir ;
638+ char * dstdir = NULL ;
645639 enum btrfs_util_error err ;
646- struct btrfs_ioctl_vol_args_v2 args ;
647- struct btrfs_qgroup_inherit * inherit = NULL ;
640+ struct btrfs_util_qgroup_inherit * inherit = NULL ;
641+ int flags = 0 ;
648642
649- memset (& args , 0 , sizeof (args ));
650643 optind = 0 ;
651644 while (1 ) {
652645 int c = getopt (argc , argv , "i:r" );
@@ -655,14 +648,14 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
655648
656649 switch (c ) {
657650 case 'i' :
658- res = btrfs_qgroup_inherit_add_group (& inherit , optarg );
651+ res = qgroup_inherit_add_group (& inherit , optarg );
659652 if (res ) {
660653 retval = res ;
661654 goto out ;
662655 }
663656 break ;
664657 case 'r' :
665- readonly = true ;
658+ flags |= BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY ;
666659 break ;
667660 default :
668661 usage_unknown_option (cmd , argv );
@@ -696,72 +689,49 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
696689 }
697690
698691 if (res > 0 ) {
692+ char * dupname ;
693+ const char * newname ;
694+
699695 dupname = strdup (subvol );
700696 newname = path_basename (dupname );
701- dstdir = dst ;
702- } else {
703- dupname = strdup (dst );
704- newname = path_basename (dupname );
705- dupdir = strdup (dst );
706- dstdir = path_dirname (dupdir );
707- }
708-
709- if (!test_issubvolname (newname )) {
710- error ("invalid snapshot name '%s'" , newname );
711- goto out ;
712- }
713-
714- len = strlen (newname );
715- if (len > BTRFS_VOL_NAME_MAX ) {
716- error ("snapshot name too long '%s'" , newname );
717- goto out ;
718- }
719697
720- fddst = btrfs_open_dir (dstdir );
721- if (fddst < 0 )
722- goto out ;
723-
724- fd = btrfs_open_dir (subvol );
725- if (fd < 0 )
726- goto out ;
698+ dstdir = malloc (strlen (dst ) + 1 + strlen (newname ) + 1 );
699+ if (!dstdir ) {
700+ error_msg (ERROR_MSG_MEMORY , NULL );
701+ free (dupname );
702+ goto out ;
703+ }
727704
728- if (readonly )
729- args .flags |= BTRFS_SUBVOL_RDONLY ;
705+ dstdir [0 ] = 0 ;
706+ strcpy (dstdir , dst );
707+ strcat (dstdir , "/" );
708+ strcat (dstdir , newname );
730709
731- args .fd = fd ;
732- if (inherit ) {
733- args .flags |= BTRFS_SUBVOL_QGROUP_INHERIT ;
734- args .size = btrfs_qgroup_inherit_size (inherit );
735- args .qgroup_inherit = inherit ;
710+ free (dupname );
711+ } else {
712+ dstdir = strdup (dst );
736713 }
737- strncpy_null (args .name , newname , sizeof (args .name ));
738714
739- res = ioctl (fddst , BTRFS_IOC_SNAP_CREATE_V2 , & args );
740- if (res < 0 ) {
741- if (errno == ETXTBSY )
742- error ("cannot snapshot '%s': source subvolume contains an active swapfile (%m)" , subvol );
743- else
744- error ("cannot snapshot '%s': %m" , subvol );
715+ err = btrfs_util_subvolume_snapshot (subvol , dstdir , flags , NULL , inherit );
716+ if (err ) {
717+ error_btrfs_util (err );
745718 goto out ;
746719 }
747720
748721 retval = 0 ; /* success */
749722
750- if (readonly )
723+ if (flags & BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY )
751724 pr_verbose (LOG_DEFAULT ,
752- "Create readonly snapshot of '%s' in '%s/%s '\n" ,
753- subvol , dstdir , newname );
725+ "Create readonly snapshot of '%s' in '%s'\n" ,
726+ subvol , dstdir );
754727 else
755728 pr_verbose (LOG_DEFAULT ,
756- "Create snapshot of '%s' in '%s/%s '\n" ,
757- subvol , dstdir , newname );
729+ "Create snapshot of '%s' in '%s'\n" ,
730+ subvol , dstdir );
758731
759732out :
760- close (fddst );
761- close (fd );
762- free (inherit );
763- free (dupname );
764- free (dupdir );
733+ free (dstdir );
734+ btrfs_util_qgroup_inherit_destroy (inherit );
765735
766736 return retval ;
767737}
0 commit comments