~ubuntu-branches/debian/sid/btrfs-tools/sid

« back to all changes in this revision

Viewing changes to cmds-subvolume.c

  • Committer: Package Import Robot
  • Author(s): Dimitri John Ledkov
  • Date: 2014-04-19 12:12:11 UTC
  • mfrom: (1.3.4)
  • Revision ID: package-import@ubuntu.com-20140419121211-0jeuu83zmf9nowmu
Tags: 3.14.1-1
* New upstream release.
* Switch to git-dpm.
* Rebase and cleanup patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
142
142
 
143
143
        fddst = open_file_or_dir(dstdir, &dirstream);
144
144
        if (fddst < 0) {
145
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", dstdir);
 
145
                fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
146
146
                goto out;
147
147
        }
148
148
 
201
201
        return (st.st_ino == 256) && S_ISDIR(st.st_mode);
202
202
}
203
203
 
 
204
static int wait_for_commit(int fd)
 
205
{
 
206
        int ret;
 
207
 
 
208
        ret = ioctl(fd, BTRFS_IOC_START_SYNC, NULL);
 
209
        if (ret < 0)
 
210
                return ret;
 
211
        return ioctl(fd, BTRFS_IOC_WAIT_SYNC, NULL);
 
212
}
 
213
 
204
214
static const char * const cmd_subvol_delete_usage[] = {
205
 
        "btrfs subvolume delete <subvolume> [<subvolume>...]",
 
215
        "btrfs subvolume delete [options] <subvolume> [<subvolume>...]",
206
216
        "Delete subvolume(s)",
 
217
        "Delete subvolumes from the filesystem. The corresponding directory",
 
218
        "is removed instantly but the data blocks are removed later.",
 
219
        "The deletion does not involve full commit by default due to",
 
220
        "performance reasons (as a consequence, the subvolume may appear again",
 
221
        "after a crash). Use one of the --commit options to wait until the",
 
222
        "operation is safely stored on the media.",
 
223
        "",
 
224
        "-c|--commit-after      wait for transaction commit at the end of the operation",
 
225
        "-C|--commit-each       wait for transaction commit after deleting each subvolume",
207
226
        NULL
208
227
};
209
228
 
210
229
static int cmd_subvol_delete(int argc, char **argv)
211
230
{
212
 
        int     res, fd, len, e, cnt = 1, ret = 0;
 
231
        int     res, len, e, ret = 0;
 
232
        int cnt;
 
233
        int fd = -1;
213
234
        struct btrfs_ioctl_vol_args     args;
214
235
        char    *dname, *vname, *cpath;
215
236
        char    *dupdname = NULL;
216
237
        char    *dupvname = NULL;
217
238
        char    *path;
218
239
        DIR     *dirstream = NULL;
219
 
 
220
 
        if (argc < 2)
 
240
        int sync_mode = 0;
 
241
        struct option long_options[] = {
 
242
                {"commit-after", no_argument, NULL, 'c'},  /* sync mode 1 */
 
243
                {"commit-each", no_argument, NULL, 'C'},  /* sync mode 2 */
 
244
                {NULL, 0, NULL, 0}
 
245
        };
 
246
 
 
247
        optind = 1;
 
248
        while (1) {
 
249
                int c;
 
250
 
 
251
                c = getopt_long(argc, argv, "cC", long_options, NULL);
 
252
                if (c < 0)
 
253
                        break;
 
254
 
 
255
                switch(c) {
 
256
                case 'c':
 
257
                        sync_mode = 1;
 
258
                        break;
 
259
                case 'C':
 
260
                        sync_mode = 2;
 
261
                        break;
 
262
                default:
 
263
                        usage(cmd_subvol_delete_usage);
 
264
                }
 
265
        }
 
266
 
 
267
        if (check_argc_min(argc - optind, 1))
221
268
                usage(cmd_subvol_delete_usage);
222
269
 
 
270
        printf("Transaction commit: %s\n",
 
271
                !sync_mode ? "none (default)" :
 
272
                sync_mode == 1 ? "at the end" : "after each");
 
273
 
 
274
        cnt = optind;
 
275
 
223
276
again:
224
277
        path = argv[cnt];
225
278
 
266
319
 
267
320
        fd = open_file_or_dir(dname, &dirstream);
268
321
        if (fd < 0) {
269
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", dname);
 
322
                fprintf(stderr, "ERROR: can't access '%s'\n", dname);
270
323
                ret = 1;
271
324
                goto out;
272
325
        }
276
329
        res = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
277
330
        e = errno;
278
331
 
279
 
        close_file_or_dir(fd, dirstream);
280
 
 
281
332
        if(res < 0 ){
282
333
                fprintf( stderr, "ERROR: cannot delete '%s/%s' - %s\n",
283
334
                        dname, vname, strerror(e));
285
336
                goto out;
286
337
        }
287
338
 
 
339
        if (sync_mode == 1) {
 
340
                res = wait_for_commit(fd);
 
341
                if (res < 0) {
 
342
                        fprintf(stderr,
 
343
                                "ERROR: unable to wait for commit after '%s': %s\n",
 
344
                                path, strerror(errno));
 
345
                        ret = 1;
 
346
                }
 
347
        }
 
348
 
288
349
out:
289
350
        free(dupdname);
290
351
        free(dupvname);
291
352
        dupdname = NULL;
292
353
        dupvname = NULL;
293
354
        cnt++;
294
 
        if (cnt < argc)
 
355
        if (cnt < argc) {
 
356
                close_file_or_dir(fd, dirstream);
 
357
                /* avoid double free */
 
358
                fd = -1;
 
359
                dirstream = NULL;
295
360
                goto again;
 
361
        }
 
362
 
 
363
        if (sync_mode == 2 && fd != -1) {
 
364
                res = wait_for_commit(fd);
 
365
                if (res < 0) {
 
366
                        fprintf(stderr,
 
367
                                "ERROR: unable to do final sync: %s\n",
 
368
                                strerror(errno));
 
369
                        ret = 1;
 
370
                }
 
371
        }
 
372
        close_file_or_dir(fd, dirstream);
296
373
 
297
374
        return ret;
298
375
}
611
688
 
612
689
        fddst = open_file_or_dir(dstdir, &dirstream1);
613
690
        if (fddst < 0) {
614
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", dstdir);
 
691
                fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
615
692
                goto out;
616
693
        }
617
694
 
618
695
        fd = open_file_or_dir(subvol, &dirstream2);
619
696
        if (fd < 0) {
620
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", dstdir);
 
697
                fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
621
698
                goto out;
622
699
        }
623
700
 
743
820
        subvolid = argv[1];
744
821
        path = argv[2];
745
822
 
746
 
        objectid = (unsigned long long)strtoll(subvolid, NULL, 0);
747
 
        if (errno == ERANGE) {
748
 
                fprintf(stderr, "ERROR: invalid tree id (%s)\n", subvolid);
749
 
                return 1;
750
 
        }
 
823
        objectid = arg_strtou64(subvolid);
751
824
 
752
825
        fd = open_file_or_dir(path, &dirstream);
753
826
        if (fd < 0) {
754
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", path);
 
827
                fprintf(stderr, "ERROR: can't access '%s'\n", path);
755
828
                return 1;
756
829
        }
757
830
 
784
857
                usage(cmd_find_new_usage);
785
858
 
786
859
        subvol = argv[1];
787
 
        last_gen = atoll(argv[2]);
 
860
        last_gen = arg_strtou64(argv[2]);
788
861
 
789
862
        ret = test_issubvolume(subvol);
790
863
        if (ret < 0) {
826
899
        struct root_info get_ri;
827
900
        struct btrfs_list_filter_set *filter_set;
828
901
        char tstr[256];
829
 
        char uuidparse[37];
 
902
        char uuidparse[BTRFS_UUID_UNPARSED_SIZE];
830
903
        char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
831
904
        char raw_prefix[] = "\t\t\t\t";
832
905
        u64 sv_id, mntid;
949
1022
                        1, raw_prefix);
950
1023
 
951
1024
        /* clean up */
952
 
        if (get_ri.path)
953
 
                free(get_ri.path);
954
 
        if (get_ri.name)
955
 
                free(get_ri.name);
956
 
        if (get_ri.full_path)
957
 
                free(get_ri.full_path);
958
 
        if (filter_set)
959
 
                btrfs_list_free_filter_set(filter_set);
 
1025
        free(get_ri.path);
 
1026
        free(get_ri.name);
 
1027
        free(get_ri.full_path);
 
1028
        btrfs_list_free_filter_set(filter_set);
960
1029
 
961
1030
out:
962
1031
        close_file_or_dir(fd, dirstream1);
963
1032
        close_file_or_dir(mntfd, dirstream2);
964
 
        if (mnt)
965
 
                free(mnt);
966
 
        if (fullpath)
967
 
                free(fullpath);
 
1033
        free(mnt);
 
1034
        free(fullpath);
968
1035
        return !!ret;
969
1036
}
970
1037