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

« back to all changes in this revision

Viewing changes to cmds-filesystem.c

  • Committer: Package Import Robot
  • Author(s): Dimitri John Ledkov
  • Date: 2014-04-19 12:12:11 UTC
  • mfrom: (1.2.12) (6.1.37 sid)
  • Revision ID: package-import@ubuntu.com-20140419121211-mski0g757tsdv4x1
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:
37
37
#include "version.h"
38
38
#include "commands.h"
39
39
#include "list_sort.h"
 
40
#include "disk-io.h"
40
41
 
41
42
 
42
43
/*
187
188
        sargs = malloc(sizeof(struct btrfs_ioctl_space_args) +
188
189
                        (count * sizeof(struct btrfs_ioctl_space_info)));
189
190
        if (!sargs)
190
 
                ret = -ENOMEM;
 
191
                return -ENOMEM;
191
192
 
192
193
        sargs->space_slots = count;
193
194
        sargs->total_spaces = 0;
232
233
 
233
234
        fd = open_file_or_dir(path, &dirstream);
234
235
        if (fd < 0) {
235
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", path);
 
236
                fprintf(stderr, "ERROR: can't access '%s'\n", path);
236
237
                return 1;
237
238
        }
238
239
        ret = get_df(fd, &sargs);
248
249
        return !!ret;
249
250
}
250
251
 
 
252
static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
 
253
                                        char *search)
 
254
{
 
255
        char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
 
256
        int search_len = strlen(search);
 
257
 
 
258
        search_len = min(search_len, BTRFS_UUID_UNPARSED_SIZE);
 
259
        uuid_unparse(fsid, uuidbuf);
 
260
        if (!strncmp(uuidbuf, search, search_len))
 
261
                return 1;
 
262
 
 
263
        if (strlen(label) && strcmp(label, search) == 0)
 
264
                return 1;
 
265
 
 
266
        if (strcmp(mnt, search) == 0)
 
267
                return 1;
 
268
 
 
269
        return 0;
 
270
}
 
271
 
251
272
static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search)
252
273
{
253
 
        char uuidbuf[37];
 
274
        char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
254
275
        struct list_head *cur;
255
276
        struct btrfs_device *device;
256
277
        int search_len = strlen(search);
257
278
 
258
 
        search_len = min(search_len, 37);
 
279
        search_len = min(search_len, BTRFS_UUID_UNPARSED_SIZE);
259
280
        uuid_unparse(fs_devices->fsid, uuidbuf);
260
281
        if (!strncmp(uuidbuf, search, search_len))
261
282
                return 1;
286
307
 
287
308
static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
288
309
{
289
 
        char uuidbuf[37];
 
310
        char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
290
311
        struct list_head *cur;
291
312
        struct btrfs_device *device;
292
313
        u64 devs_found = 0;
343
364
                char *label, char *path)
344
365
{
345
366
        int i;
346
 
        char uuidbuf[37];
 
367
        int fd;
 
368
        int missing = 0;
 
369
        char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
347
370
        struct btrfs_ioctl_dev_info_args *tmp_dev_info;
348
371
        int ret;
349
372
 
354
377
                return ret;
355
378
 
356
379
        uuid_unparse(fs_info->fsid, uuidbuf);
357
 
        printf("Label: %s  uuid: %s\n",
358
 
                strlen(label) ? label : "none", uuidbuf);
 
380
        if (label && strlen(label))
 
381
                printf("Label: '%s' ", label);
 
382
        else
 
383
                printf("Label: none ");
359
384
 
360
 
        printf("\tTotal devices %llu FS bytes used %s\n",
361
 
                                fs_info->num_devices,
 
385
        printf(" uuid: %s\n\tTotal devices %llu FS bytes used %s\n", uuidbuf,
 
386
                        fs_info->num_devices,
362
387
                        pretty_size(calc_used_bytes(space_info)));
363
388
 
364
389
        for (i = 0; i < fs_info->num_devices; i++) {
365
390
                tmp_dev_info = (struct btrfs_ioctl_dev_info_args *)&dev_info[i];
366
 
                printf("\tdevid    %llu size %s used %s path %s\n",
 
391
 
 
392
                /* Add check for missing devices even mounted */
 
393
                fd = open((char *)tmp_dev_info->path, O_RDONLY);
 
394
                if (fd < 0) {
 
395
                        missing = 1;
 
396
                        continue;
 
397
                }
 
398
                close(fd);
 
399
                printf("\tdevid %4llu size %s used %s path %s\n",
367
400
                        tmp_dev_info->devid,
368
401
                        pretty_size(tmp_dev_info->total_bytes),
369
402
                        pretty_size(tmp_dev_info->bytes_used),
370
403
                        tmp_dev_info->path);
371
404
        }
372
405
 
 
406
        if (missing)
 
407
                printf("\t*** Some devices missing\n");
373
408
        printf("\n");
374
409
        return 0;
375
410
}
387
422
        char path[PATH_MAX];
388
423
 
389
424
        if (!input)
390
 
                return BTRFS_ARG_UNKNOWN;
 
425
                return -EINVAL;
391
426
 
392
427
        if (realpath(input, path)) {
393
 
                if (is_block_device(input) == 1)
 
428
                if (is_block_device(path) == 1)
394
429
                        return BTRFS_ARG_BLKDEV;
395
430
 
396
 
                if (is_mount_point(input) == 1)
 
431
                if (is_mount_point(path) == 1)
397
432
                        return BTRFS_ARG_MNTPOINT;
398
433
 
399
434
                return BTRFS_ARG_UNKNOWN;
400
435
        }
401
436
 
402
 
        if (!uuid_parse(input, out))
 
437
        if (strlen(input) == (BTRFS_UUID_UNPARSED_SIZE - 1) &&
 
438
                !uuid_parse(input, out))
403
439
                return BTRFS_ARG_UUID;
404
440
 
405
441
        return BTRFS_ARG_UNKNOWN;
407
443
 
408
444
static int btrfs_scan_kernel(void *search)
409
445
{
410
 
        int ret = 0, fd, type;
 
446
        int ret = 0, fd;
411
447
        FILE *f;
412
448
        struct mntent *mnt;
413
449
        struct btrfs_ioctl_fs_info_args fs_info_arg;
414
450
        struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
415
 
        struct btrfs_ioctl_space_args *space_info_arg;
 
451
        struct btrfs_ioctl_space_args *space_info_arg = NULL;
416
452
        char label[BTRFS_LABEL_SIZE];
417
 
        uuid_t uuid;
418
453
 
419
454
        f = setmntent("/proc/self/mounts", "r");
420
455
        if (f == NULL)
421
456
                return 1;
422
457
 
423
 
        type = check_arg_type(search);
424
 
        if (type == BTRFS_ARG_BLKDEV)
425
 
                return 1;
426
 
 
 
458
        memset(label, 0, sizeof(label));
427
459
        while ((mnt = getmntent(f)) != NULL) {
428
460
                if (strcmp(mnt->mnt_type, "btrfs"))
429
461
                        continue;
430
462
                ret = get_fs_info(mnt->mnt_dir, &fs_info_arg,
431
463
                                &dev_info_arg);
432
464
                if (ret)
433
 
                        return ret;
 
465
                        goto out;
434
466
 
435
 
                switch (type) {
436
 
                case BTRFS_ARG_UUID:
437
 
                        ret = uuid_parse(search, uuid);
438
 
                        if (ret)
439
 
                                return 1;
440
 
                        if (uuid_compare(fs_info_arg.fsid, uuid))
441
 
                                continue;
442
 
                        break;
443
 
                case BTRFS_ARG_MNTPOINT:
444
 
                        if (strcmp(search, mnt->mnt_dir))
445
 
                                continue;
446
 
                        break;
447
 
                case BTRFS_ARG_UNKNOWN:
448
 
                        break;
 
467
                if (get_label_mounted(mnt->mnt_dir, label)) {
 
468
                        kfree(dev_info_arg);
 
469
                        ret = 1;
 
470
                        goto out;
 
471
                }
 
472
                if (search && !match_search_item_kernel(fs_info_arg.fsid,
 
473
                                        mnt->mnt_dir, label, search)) {
 
474
                        kfree(dev_info_arg);
 
475
                        continue;
449
476
                }
450
477
 
451
478
                fd = open(mnt->mnt_dir, O_RDONLY);
452
479
                if ((fd != -1) && !get_df(fd, &space_info_arg)) {
453
 
                        get_label_mounted(mnt->mnt_dir, label);
454
480
                        print_one_fs(&fs_info_arg, dev_info_arg,
455
481
                                        space_info_arg, label, mnt->mnt_dir);
456
 
                        free(space_info_arg);
 
482
                        kfree(space_info_arg);
 
483
                        memset(label, 0, sizeof(label));
457
484
                }
458
485
                if (fd != -1)
459
486
                        close(fd);
460
 
                free(dev_info_arg);
461
 
        }
 
487
                kfree(dev_info_arg);
 
488
                if (search)
 
489
                        ret = 0;
 
490
        }
 
491
        if (search)
 
492
                ret = 1;
 
493
 
 
494
out:
 
495
        endmntent(f);
 
496
        return ret;
 
497
}
 
498
 
 
499
static int dev_to_fsid(char *dev, __u8 *fsid)
 
500
{
 
501
        struct btrfs_super_block *disk_super;
 
502
        char *buf;
 
503
        int ret;
 
504
        int fd;
 
505
 
 
506
        buf = malloc(4096);
 
507
        if (!buf)
 
508
                return -ENOMEM;
 
509
 
 
510
        fd = open(dev, O_RDONLY);
 
511
        if (fd < 0) {
 
512
                ret = -errno;
 
513
                free(buf);
 
514
                return ret;
 
515
        }
 
516
 
 
517
        disk_super = (struct btrfs_super_block *)buf;
 
518
        ret = btrfs_read_dev_super(fd, disk_super,
 
519
                        BTRFS_SUPER_INFO_OFFSET);
 
520
        if (ret)
 
521
                goto out;
 
522
 
 
523
        memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
 
524
        ret = 0;
 
525
 
 
526
out:
 
527
        close(fd);
 
528
        free(buf);
462
529
        return ret;
463
530
}
464
531
 
465
532
static const char * const cmd_show_usage[] = {
466
 
        "btrfs filesystem show [options|<path>|<uuid>]",
 
533
        "btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
467
534
        "Show the structure of a filesystem",
468
535
        "-d|--all-devices   show only disks under /dev containing btrfs filesystem",
469
536
        "-m|--mounted       show only mounted btrfs",
481
548
        int where = BTRFS_SCAN_LBLKID;
482
549
        int type = 0;
483
550
        char mp[BTRFS_PATH_NAME_MAX + 1];
 
551
        char path[PATH_MAX];
 
552
        __u8 fsid[BTRFS_FSID_SIZE];
 
553
        char uuid_buf[37];
 
554
        int found = 0;
484
555
 
485
556
        while (1) {
486
557
                int long_index;
505
576
                }
506
577
        }
507
578
 
508
 
        if (where == BTRFS_SCAN_LBLKID) {
509
 
                if (check_argc_max(argc, optind + 1))
510
 
                        usage(cmd_show_usage);
511
 
        } else {
512
 
                if (check_argc_max(argc, optind))
513
 
                        usage(cmd_show_usage);
514
 
        }
 
579
        if (check_argc_max(argc, optind + 1))
 
580
                usage(cmd_show_usage);
 
581
 
515
582
        if (argc > optind) {
516
583
                search = argv[optind];
 
584
                if (strlen(search) == 0)
 
585
                        usage(cmd_show_usage);
517
586
                type = check_arg_type(search);
518
 
                if (type == BTRFS_ARG_UNKNOWN) {
519
 
                        fprintf(stderr, "ERROR: arg type unknown\n");
520
 
                        usage(cmd_show_usage);
521
 
                }
 
587
                /*
 
588
                 * needs spl handling if input arg is block dev
 
589
                 * And if input arg is mount-point just print it
 
590
                 * right away
 
591
                 */
522
592
                if (type == BTRFS_ARG_BLKDEV) {
523
 
                        ret = get_btrfs_mount(search, mp, sizeof(mp));
524
 
                        if (ret == 0)
525
 
                                search = mp;
 
593
                        if (where == BTRFS_SCAN_DEV) {
 
594
                                /* we need to do this because
 
595
                                 * legacy BTRFS_SCAN_DEV
 
596
                                 * provides /dev/dm-x paths
 
597
                                 */
 
598
                                if (realpath(search, path))
 
599
                                        search = path;
 
600
                        } else {
 
601
                                ret = get_btrfs_mount(search,
 
602
                                                mp, sizeof(mp));
 
603
                                if (!ret) {
 
604
                                        /* given block dev is mounted*/
 
605
                                        search = mp;
 
606
                                        type = BTRFS_ARG_MNTPOINT;
 
607
                                } else {
 
608
                                        ret = dev_to_fsid(search, fsid);
 
609
                                        if (ret) {
 
610
                                                fprintf(stderr,
 
611
                                                        "ERROR: No btrfs on %s\n",
 
612
                                                        search);
 
613
                                                return 1;
 
614
                                        }
 
615
                                        uuid_unparse(fsid, uuid_buf);
 
616
                                        search = uuid_buf;
 
617
                                        type = BTRFS_ARG_UUID;
 
618
                                        goto devs_only;
 
619
                                }
 
620
                        }
526
621
                }
527
622
        }
528
623
 
530
625
                goto devs_only;
531
626
 
532
627
        /* show mounted btrfs */
533
 
        btrfs_scan_kernel(search);
 
628
        ret = btrfs_scan_kernel(search);
 
629
        if (search && !ret) {
 
630
                /* since search is found we are done */
 
631
                goto out;
 
632
        }
534
633
 
535
634
        /* shows mounted only */
536
635
        if (where == BTRFS_SCAN_MOUNTED)
552
651
                        continue;
553
652
 
554
653
                print_one_uuid(fs_devices);
 
654
                found = 1;
555
655
        }
 
656
        if (search && !found)
 
657
                ret = 1;
556
658
 
 
659
        while (!list_empty(all_uuids)) {
 
660
                fs_devices = list_entry(all_uuids->next,
 
661
                                        struct btrfs_fs_devices, list);
 
662
                list_del(&fs_devices->list);
 
663
                btrfs_close_devices(fs_devices);
 
664
        }
557
665
out:
558
666
        printf("%s\n", BTRFS_BUILD_VERSION);
559
667
        free_seen_fsid();
560
 
        return 0;
 
668
        return ret;
561
669
}
562
670
 
563
671
static const char * const cmd_sync_usage[] = {
579
687
 
580
688
        fd = open_file_or_dir(path, &dirstream);
581
689
        if (fd < 0) {
582
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", path);
 
690
                fprintf(stderr, "ERROR: can't access '%s'\n", path);
583
691
                return 1;
584
692
        }
585
693
 
646
754
        int e = 0;
647
755
        int fd = 0;
648
756
 
649
 
        if (typeflag == FTW_F) {
 
757
        if ((typeflag == FTW_F) && S_ISREG(sb->st_mode)) {
650
758
                if (defrag_global_verbose)
651
759
                        printf("%s\n", fpath);
652
760
                fd = open(fpath, O_RDWR);
656
764
                ret = do_defrag(fd, defrag_global_fancy_ioctl, &defrag_global_range);
657
765
                e = errno;
658
766
                close(fd);
659
 
                if (ret && e == ENOTTY) {
 
767
                if (ret && e == ENOTTY && defrag_global_fancy_ioctl) {
660
768
                        fprintf(stderr, "ERROR: defrag range ioctl not "
661
769
                                "supported in this kernel, please try "
662
770
                                "without any options.\n");
748
856
                defrag_global_range.flags |= BTRFS_DEFRAG_RANGE_START_IO;
749
857
 
750
858
        for (i = optind; i < argc; i++) {
 
859
                struct stat st;
 
860
 
751
861
                dirstream = NULL;
752
862
                fd = open_file_or_dir(argv[i], &dirstream);
753
863
                if (fd < 0) {
757
867
                        close_file_or_dir(fd, dirstream);
758
868
                        continue;
759
869
                }
 
870
                if (fstat(fd, &st)) {
 
871
                        fprintf(stderr, "ERROR: failed to stat %s - %s\n",
 
872
                                        argv[i], strerror(errno));
 
873
                        defrag_global_errors++;
 
874
                        close_file_or_dir(fd, dirstream);
 
875
                        continue;
 
876
                }
 
877
                if (!(S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
 
878
                        fprintf(stderr,
 
879
                            "ERROR: %s is not a directory or a regular file\n",
 
880
                            argv[i]);
 
881
                        defrag_global_errors++;
 
882
                        close_file_or_dir(fd, dirstream);
 
883
                        continue;
 
884
                }
760
885
                if (recursive) {
761
 
                        struct stat st;
762
 
 
763
 
                        if (fstat(fd, &st)) {
764
 
                                fprintf(stderr, "ERROR: failed to stat %s - %s\n",
765
 
                                                argv[i], strerror(errno));
766
 
                                defrag_global_errors++;
767
 
                                close_file_or_dir(fd, dirstream);
768
 
                                continue;
769
 
                        }
770
886
                        if (S_ISDIR(st.st_mode)) {
771
887
                                ret = nftw(argv[i], defrag_callback, 10,
772
888
                                                FTW_MOUNT | FTW_PHYS);
789
905
                        e = errno;
790
906
                }
791
907
                close_file_or_dir(fd, dirstream);
792
 
                if (ret && e == ENOTTY) {
 
908
                if (ret && e == ENOTTY && defrag_global_fancy_ioctl) {
793
909
                        fprintf(stderr, "ERROR: defrag range ioctl not "
794
910
                                "supported in this kernel, please try "
795
911
                                "without any options.\n");
840
956
 
841
957
        fd = open_file_or_dir(path, &dirstream);
842
958
        if (fd < 0) {
843
 
                fprintf(stderr, "ERROR: can't access to '%s'\n", path);
 
959
                fprintf(stderr, "ERROR: can't access '%s'\n", path);
844
960
                return 1;
845
961
        }
846
962
 
870
986
        if (check_argc_min(argc, 2) || check_argc_max(argc, 3))
871
987
                usage(cmd_label_usage);
872
988
 
873
 
        if (argc > 2)
 
989
        if (argc > 2) {
874
990
                return set_label(argv[1], argv[2]);
875
 
        else
876
 
                return get_label(argv[1]);
 
991
        } else {
 
992
                char label[BTRFS_LABEL_SIZE];
 
993
                int ret;
 
994
 
 
995
                ret = get_label(argv[1], label);
 
996
                if (!ret)
 
997
                        fprintf(stdout, "%s\n", label);
 
998
 
 
999
                return ret;
 
1000
        }
877
1001
}
878
1002
 
879
1003
const struct cmd_group filesystem_cmd_group = {