Add a command to show all of the btrfs filesystems on the box (btrfs-show)
This commit is contained in:
parent
b569dafbf2
commit
358564890a
5
Makefile
5
Makefile
|
@ -15,7 +15,7 @@ prefix ?= /usr/local
|
||||||
bindir = $(prefix)/bin
|
bindir = $(prefix)/bin
|
||||||
LIBS=-luuid
|
LIBS=-luuid
|
||||||
|
|
||||||
progs = btrfsctl btrfsck mkfs.btrfs debug-tree quick-test
|
progs = btrfsctl btrfsck mkfs.btrfs debug-tree quick-test btrfs-show
|
||||||
|
|
||||||
# make C=1 to enable sparse
|
# make C=1 to enable sparse
|
||||||
ifdef C
|
ifdef C
|
||||||
|
@ -34,6 +34,9 @@ all: $(progs)
|
||||||
btrfsctl: $(objects) btrfsctl.o
|
btrfsctl: $(objects) btrfsctl.o
|
||||||
gcc $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS)
|
gcc $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
btrfs-show: $(objects) btrfs-show.o
|
||||||
|
gcc $(CFLAGS) -o btrfs-show btrfs-show.o $(objects) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
btrfsck: $(objects) btrfsck.o bit-radix.o
|
btrfsck: $(objects) btrfsck.o bit-radix.o
|
||||||
gcc $(CFLAGS) -o btrfsck btrfsck.o $(objects) bit-radix.o $(LDFLAGS) $(LIBS)
|
gcc $(CFLAGS) -o btrfsck btrfsck.o $(objects) bit-radix.o $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007 Oracle. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public
|
||||||
|
* License v2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 021110-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#ifndef __CHECKER__
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include "ioctl.h"
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
#include "kerncompat.h"
|
||||||
|
#include "ctree.h"
|
||||||
|
#include "transaction.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "volumes.h"
|
||||||
|
|
||||||
|
static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search)
|
||||||
|
{
|
||||||
|
struct list_head *cur;
|
||||||
|
struct btrfs_device *device;
|
||||||
|
|
||||||
|
list_for_each(cur, &fs_devices->devices) {
|
||||||
|
device = list_entry(cur, struct btrfs_device, dev_list);
|
||||||
|
if ((device->label && strcmp(device->label, search) == 0) ||
|
||||||
|
strcmp(device->name, search) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
|
||||||
|
{
|
||||||
|
char uuidbuf[37];
|
||||||
|
struct list_head *cur;
|
||||||
|
struct btrfs_device *device;
|
||||||
|
char *super_bytes_used;
|
||||||
|
u64 devs_found = 0;
|
||||||
|
u64 total;
|
||||||
|
|
||||||
|
uuid_unparse(fs_devices->fsid, uuidbuf);
|
||||||
|
device = list_entry(fs_devices->devices.next, struct btrfs_device,
|
||||||
|
dev_list);
|
||||||
|
if (device->label && device->label[0])
|
||||||
|
printf("Label: %s ", device->label);
|
||||||
|
else
|
||||||
|
printf("Label: none ");
|
||||||
|
|
||||||
|
super_bytes_used = pretty_sizes(device->super_bytes_used);
|
||||||
|
|
||||||
|
total = device->total_devs;
|
||||||
|
printf(" uuid: %s\n\tTotal devices %llu FS bytes used %s\n", uuidbuf,
|
||||||
|
(unsigned long long)total, super_bytes_used);
|
||||||
|
|
||||||
|
free(super_bytes_used);
|
||||||
|
|
||||||
|
list_for_each(cur, &fs_devices->devices) {
|
||||||
|
char *total_bytes;
|
||||||
|
char *bytes_used;
|
||||||
|
device = list_entry(cur, struct btrfs_device, dev_list);
|
||||||
|
total_bytes = pretty_sizes(device->total_bytes);
|
||||||
|
bytes_used = pretty_sizes(device->bytes_used);
|
||||||
|
printf("\tdevid %4llu size %s used %s path %s\n",
|
||||||
|
(unsigned long long)device->devid,
|
||||||
|
total_bytes, bytes_used, device->name);
|
||||||
|
free(total_bytes);
|
||||||
|
free(bytes_used);
|
||||||
|
devs_found++;
|
||||||
|
}
|
||||||
|
if (devs_found < total) {
|
||||||
|
printf("\t*** Some devices missing\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: btrfs-show [search label or device]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
/* { "byte-count", 1, NULL, 'b' }, */
|
||||||
|
{ 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
struct list_head *all_uuids;
|
||||||
|
struct btrfs_fs_devices *fs_devices;
|
||||||
|
struct list_head *cur_uuid;
|
||||||
|
char *search = NULL;
|
||||||
|
int ret;
|
||||||
|
int option_index = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
int c;
|
||||||
|
c = getopt_long(ac, av, "", long_options,
|
||||||
|
&option_index);
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
switch(c) {
|
||||||
|
default:
|
||||||
|
print_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ac = ac - optind;
|
||||||
|
if (ac != 0) {
|
||||||
|
search = av[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = btrfs_scan_one_dir("/dev", 0);
|
||||||
|
if (ret)
|
||||||
|
fprintf(stderr, "error %d while scanning\n", ret);
|
||||||
|
|
||||||
|
all_uuids = btrfs_scanned_uuids();
|
||||||
|
list_for_each(cur_uuid, all_uuids) {
|
||||||
|
fs_devices = list_entry(cur_uuid, struct btrfs_fs_devices,
|
||||||
|
list);
|
||||||
|
if (search && uuid_search(fs_devices, search) == 0)
|
||||||
|
continue;
|
||||||
|
print_one_uuid(fs_devices);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -493,8 +493,6 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr)
|
||||||
fprintf(stderr, "No valid Btrfs found on %s\n", path);
|
fprintf(stderr, "No valid Btrfs found on %s\n", path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "found Btrfs on %s with %lu devices\n", path,
|
|
||||||
(unsigned long)total_devs);
|
|
||||||
|
|
||||||
if (total_devs != 1) {
|
if (total_devs != 1) {
|
||||||
ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1);
|
ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1);
|
||||||
|
|
16
mkfs.c
16
mkfs.c
|
@ -296,6 +296,7 @@ int main(int ac, char **av)
|
||||||
struct btrfs_root *root;
|
struct btrfs_root *root;
|
||||||
struct btrfs_trans_handle *trans;
|
struct btrfs_trans_handle *trans;
|
||||||
char *label = NULL;
|
char *label = NULL;
|
||||||
|
char *first_file;
|
||||||
u64 block_count = 0;
|
u64 block_count = 0;
|
||||||
u64 dev_block_count = 0;
|
u64 dev_block_count = 0;
|
||||||
u64 blocks[6];
|
u64 blocks[6];
|
||||||
|
@ -375,6 +376,7 @@ int main(int ac, char **av)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
first_fd = fd;
|
first_fd = fd;
|
||||||
|
first_file = file;
|
||||||
ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count);
|
ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count);
|
||||||
if (block_count == 0)
|
if (block_count == 0)
|
||||||
block_count = dev_block_count;
|
block_count = dev_block_count;
|
||||||
|
@ -394,12 +396,6 @@ int main(int ac, char **av)
|
||||||
fprintf(stderr, "failed to setup the root directory\n");
|
fprintf(stderr, "failed to setup the root directory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
|
|
||||||
"sectorsize %u bytes %llu\n",
|
|
||||||
label, file, nodesize, leafsize, sectorsize,
|
|
||||||
(unsigned long long)block_count);
|
|
||||||
|
|
||||||
free(label);
|
|
||||||
root = open_ctree(file, 0);
|
root = open_ctree(file, 0);
|
||||||
trans = btrfs_start_transaction(root, 1);
|
trans = btrfs_start_transaction(root, 1);
|
||||||
|
|
||||||
|
@ -452,9 +448,17 @@ int main(int ac, char **av)
|
||||||
raid_groups:
|
raid_groups:
|
||||||
ret = create_raid_groups(trans, root, data_profile,
|
ret = create_raid_groups(trans, root, data_profile,
|
||||||
metadata_profile);
|
metadata_profile);
|
||||||
|
|
||||||
|
printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
|
||||||
|
"sectorsize %u size %s\n",
|
||||||
|
label, first_file, nodesize, leafsize, sectorsize,
|
||||||
|
pretty_sizes(btrfs_super_total_bytes(&root->fs_info->super_copy)));
|
||||||
|
|
||||||
btrfs_commit_transaction(trans, root);
|
btrfs_commit_transaction(trans, root);
|
||||||
ret = close_ctree(root);
|
ret = close_ctree(root);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
|
|
||||||
|
free(label);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
utils.c
26
utils.c
|
@ -774,3 +774,29 @@ brelse:
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *size_strs[] = { "", "KB", "MB", "GB", "TB",
|
||||||
|
"PB", "EB", "ZB", "YB"};
|
||||||
|
char *pretty_sizes(u64 size)
|
||||||
|
{
|
||||||
|
int num_divs = 0;
|
||||||
|
u64 last_size = size;
|
||||||
|
u64 fract_size = size;
|
||||||
|
float fraction;
|
||||||
|
char *pretty;
|
||||||
|
|
||||||
|
while(size > 0) {
|
||||||
|
fract_size = last_size;
|
||||||
|
last_size = size;
|
||||||
|
size /= 1024;
|
||||||
|
num_divs++;
|
||||||
|
}
|
||||||
|
if (num_divs > ARRAY_SIZE(size_strs))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fraction = (float)fract_size / 1024;
|
||||||
|
pretty = malloc(16);
|
||||||
|
sprintf(pretty, "%.2f%s", fraction, size_strs[num_divs-1]);
|
||||||
|
return pretty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1
utils.h
1
utils.h
|
@ -39,4 +39,5 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl);
|
||||||
int check_mounted(char *devicename);
|
int check_mounted(char *devicename);
|
||||||
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
|
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
|
||||||
int super_offset);
|
int super_offset);
|
||||||
|
char *pretty_sizes(u64 size);
|
||||||
#endif
|
#endif
|
||||||
|
|
27
volumes.c
27
volumes.c
|
@ -119,6 +119,13 @@ static int device_list_add(const char *path,
|
||||||
kfree(device);
|
kfree(device);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
device->label = kstrdup(disk_super->label, GFP_NOFS);
|
||||||
|
device->total_devs = btrfs_super_num_devices(disk_super);
|
||||||
|
device->super_bytes_used = btrfs_super_bytes_used(disk_super);
|
||||||
|
device->total_bytes =
|
||||||
|
btrfs_stack_device_total_bytes(&disk_super->dev_item);
|
||||||
|
device->bytes_used =
|
||||||
|
btrfs_stack_device_bytes_used(&disk_super->dev_item);
|
||||||
list_add(&device->dev_list, &fs_devices->devices);
|
list_add(&device->dev_list, &fs_devices->devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,13 +163,13 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags)
|
||||||
|
|
||||||
list_for_each(cur, head) {
|
list_for_each(cur, head) {
|
||||||
device = list_entry(cur, struct btrfs_device, dev_list);
|
device = list_entry(cur, struct btrfs_device, dev_list);
|
||||||
|
|
||||||
fd = open(device->name, flags);
|
fd = open(device->name, flags);
|
||||||
printk("opening %s devid %llu fd %d\n", device->name,
|
|
||||||
(unsigned long long)device->devid, fd);
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->devid == fs_devices->latest_devid)
|
if (device->devid == fs_devices->latest_devid)
|
||||||
fs_devices->latest_bdev = fd;
|
fs_devices->latest_bdev = fd;
|
||||||
if (device->devid == fs_devices->lowest_devid)
|
if (device->devid == fs_devices->lowest_devid)
|
||||||
|
@ -205,12 +212,6 @@ int btrfs_scan_one_device(int fd, const char *path,
|
||||||
*total_devs = btrfs_super_num_devices(disk_super);
|
*total_devs = btrfs_super_num_devices(disk_super);
|
||||||
uuid_unparse(disk_super->fsid, uuidbuf);
|
uuid_unparse(disk_super->fsid, uuidbuf);
|
||||||
|
|
||||||
printf("device ");
|
|
||||||
if (disk_super->label[0])
|
|
||||||
printf("label %s ", disk_super->label);
|
|
||||||
else
|
|
||||||
printf("fsuuid %s ", uuidbuf);
|
|
||||||
printf("devid %llu %s\n", (unsigned long long)devid, path);
|
|
||||||
ret = device_list_add(path, disk_super, devid, fs_devices_ret);
|
ret = device_list_add(path, disk_super, devid, fs_devices_ret);
|
||||||
|
|
||||||
error_brelse:
|
error_brelse:
|
||||||
|
@ -764,7 +765,6 @@ again:
|
||||||
*num_bytes = chunk_bytes_by_type(type, calc_size,
|
*num_bytes = chunk_bytes_by_type(type, calc_size,
|
||||||
num_stripes, sub_stripes);
|
num_stripes, sub_stripes);
|
||||||
index = 0;
|
index = 0;
|
||||||
printk("new chunk type %Lu start %Lu size %Lu\n", type, key.offset, *num_bytes);
|
|
||||||
while(index < num_stripes) {
|
while(index < num_stripes) {
|
||||||
struct btrfs_stripe *stripe;
|
struct btrfs_stripe *stripe;
|
||||||
BUG_ON(list_empty(&private_devs));
|
BUG_ON(list_empty(&private_devs));
|
||||||
|
@ -781,10 +781,7 @@ printk("new chunk type %Lu start %Lu size %Lu\n", type, key.offset, *num_bytes);
|
||||||
BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset,
|
BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset,
|
||||||
calc_size, &dev_offset);
|
calc_size, &dev_offset);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
printk("\talloc chunk size %llu from dev %llu phys %llu\n",
|
|
||||||
(unsigned long long)calc_size,
|
|
||||||
(unsigned long long)device->devid,
|
|
||||||
(unsigned long long)dev_offset);
|
|
||||||
device->bytes_used += calc_size;
|
device->bytes_used += calc_size;
|
||||||
ret = btrfs_update_device(trans, device);
|
ret = btrfs_update_device(trans, device);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
|
@ -1297,3 +1294,7 @@ error:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct list_head *btrfs_scanned_uuids(void)
|
||||||
|
{
|
||||||
|
return &fs_uuids;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ struct btrfs_device {
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
/* these are read off the super block, only in the progs */
|
||||||
|
char *label;
|
||||||
|
u64 total_devs;
|
||||||
|
u64 super_bytes_used;
|
||||||
|
|
||||||
/* the internal btrfs device id */
|
/* the internal btrfs device id */
|
||||||
u64 devid;
|
u64 devid;
|
||||||
|
|
||||||
|
@ -109,4 +114,5 @@ int btrfs_scan_one_device(int fd, const char *path,
|
||||||
int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
|
int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
|
||||||
int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree,
|
int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree,
|
||||||
struct btrfs_fs_devices *fs_devices);
|
struct btrfs_fs_devices *fs_devices);
|
||||||
|
struct list_head *btrfs_scanned_uuids(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue