4646#include "common/units.h"
4747#include "common/format-output.h"
4848#include "common/tree-search.h"
49+ #include "common/parse-utils.h"
4950#include "cmds/commands.h"
5051#include "cmds/qgroup.h"
5152
@@ -140,28 +141,15 @@ static const char * const cmd_subvolume_create_usage[] = {
140141 NULL
141142};
142143
143- static int create_one_subvolume (const char * dst , struct btrfs_qgroup_inherit * inherit ,
144+ static int create_one_subvolume (const char * dst , struct btrfs_util_qgroup_inherit * inherit ,
144145 bool create_parents )
145146{
146147 int ret ;
147- int len ;
148- int fddst = -1 ;
149148 char * dupname = NULL ;
150149 char * dupdir = NULL ;
151150 const char * newname ;
152151 char * dstdir ;
153-
154- ret = path_is_dir (dst );
155- if (ret < 0 && ret != - ENOENT ) {
156- errno = - ret ;
157- error ("cannot access %s: %m" , dst );
158- goto out ;
159- }
160- if (ret >= 0 ) {
161- error ("target path already exists: %s" , dst );
162- ret = - EEXIST ;
163- goto out ;
164- }
152+ enum btrfs_util_error err ;
165153
166154 dupname = strdup (dst );
167155 if (!dupname ) {
@@ -179,19 +167,6 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
179167 }
180168 dstdir = path_dirname (dupdir );
181169
182- if (!test_issubvolname (newname )) {
183- error ("invalid subvolume name: %s" , newname );
184- ret = - EINVAL ;
185- goto out ;
186- }
187-
188- len = strlen (newname );
189- if (len > BTRFS_VOL_NAME_MAX ) {
190- error ("subvolume name too long: %s" , newname );
191- ret = - EINVAL ;
192- goto out ;
193- }
194-
195170 if (create_parents ) {
196171 char p [PATH_MAX ] = { 0 };
197172 char dstdir_dup [PATH_MAX ];
@@ -223,47 +198,57 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
223198 }
224199 }
225200
226- fddst = btrfs_open_dir (dstdir );
227- if (fddst < 0 ) {
228- ret = fddst ;
201+ err = btrfs_util_subvolume_create (dst , 0 , NULL , inherit );
202+ if (err ) {
203+ error_btrfs_util (err );
204+ ret = - errno ;
229205 goto out ;
230206 }
231207
232- if (inherit ) {
233- struct btrfs_ioctl_vol_args_v2 args ;
208+ pr_verbose (LOG_DEFAULT , "Create subvolume '%s/%s'\n" , dstdir , newname );
234209
235- memset (& args , 0 , sizeof (args ));
236- strncpy_null (args .name , newname , sizeof (args .name ));
237- args .flags |= BTRFS_SUBVOL_QGROUP_INHERIT ;
238- args .size = btrfs_qgroup_inherit_size (inherit );
239- args .qgroup_inherit = inherit ;
210+ ret = 0 ;
240211
241- ret = ioctl ( fddst , BTRFS_IOC_SUBVOL_CREATE_V2 , & args );
242- } else {
243- struct btrfs_ioctl_vol_args args ;
212+ out :
213+ free ( dupname );
214+ free ( dupdir ) ;
244215
245- memset (& args , 0 , sizeof (args ));
246- strncpy_null (args .name , newname , sizeof (args .name ));
247- ret = ioctl (fddst , BTRFS_IOC_SUBVOL_CREATE , & args );
216+ return ret ;
217+ }
218+
219+ static int qgroup_inherit_add_group (struct btrfs_util_qgroup_inherit * * inherit ,
220+ const char * arg )
221+ {
222+ enum btrfs_util_error err ;
223+ u64 qgroupid ;
224+
225+ if (!* inherit ) {
226+ err = btrfs_util_qgroup_inherit_create (0 , inherit );
227+ if (err ) {
228+ error_btrfs_util (err );
229+ return - errno ;
230+ }
248231 }
249232
250- if (ret < 0 ) {
251- error ("cannot create subvolume: %m" );
252- goto out ;
233+ qgroupid = parse_qgroupid_or_path (optarg );
234+ if (qgroupid == 0 ) {
235+ error ("invalid qgroup specification, qgroupid must not be 0" );
236+ return - EINVAL ;
253237 }
254- pr_verbose (LOG_DEFAULT , "Create subvolume '%s/%s'\n" , dstdir , newname );
255238
256- out :
257- close (fddst );
258- free (dupname );
259- free (dupdir );
239+ err = btrfs_util_qgroup_inherit_add_group (inherit , qgroupid );
240+ if (err ) {
241+ error_btrfs_util (err );
242+ return - errno ;
243+ }
260244
261- return ret ;
245+ return 0 ;
262246}
247+
263248static int cmd_subvolume_create (const struct cmd_struct * cmd , int argc , char * * argv )
264249{
265250 int retval , ret ;
266- struct btrfs_qgroup_inherit * inherit = NULL ;
251+ struct btrfs_util_qgroup_inherit * inherit = NULL ;
267252 bool has_error = false;
268253 bool create_parents = false;
269254
@@ -281,7 +266,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
281266
282267 switch (c ) {
283268 case 'i' :
284- ret = btrfs_qgroup_inherit_add_group (& inherit , optarg );
269+ ret = qgroup_inherit_add_group (& inherit , optarg );
285270 if (ret ) {
286271 retval = ret ;
287272 goto out ;
@@ -310,7 +295,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
310295 if (!has_error )
311296 retval = 0 ;
312297out :
313- free (inherit );
298+ btrfs_util_qgroup_inherit_destroy (inherit );
314299
315300 return retval ;
316301}
0 commit comments