* [PATCH 0/1 not for integration] btrfs-devlist
@ 2014-05-16 14:03 Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs: introduce BTRFS_IOC_GET_DEVS Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs-progs: introduce btrfs-devlist Anand Jain
0 siblings, 2 replies; 3+ messages in thread
From: Anand Jain @ 2014-05-16 14:03 UTC (permalink / raw)
To: linux-btrfs
btrfs-devlist: Dumps kernel fs_devices for debug purpose
(This is not for integration, use it until we have a
replacement tool)
Anand Jain (1):
btrfs: introduce BTRFS_IOC_GET_DEVS
fs/btrfs/super.c | 86 ++++++++++++++++++++++++++
fs/btrfs/volumes.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/volumes.h | 2 +
include/uapi/linux/btrfs.h | 51 ++++++++++++++++
4 files changed, 281 insertions(+), 0 deletions(-)
Anand Jain (1):
btrfs-progs: introduce btrfs-devlist
.gitignore | 1 +
Makefile | 4 +-
btrfs-devlist.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
ioctl.h | 51 +++++++++++
4 files changed, 320 insertions(+), 2 deletions(-)
create mode 100644 btrfs-devlist.c
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] btrfs: introduce BTRFS_IOC_GET_DEVS
2014-05-16 14:03 [PATCH 0/1 not for integration] btrfs-devlist Anand Jain
@ 2014-05-16 14:03 ` Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs-progs: introduce btrfs-devlist Anand Jain
1 sibling, 0 replies; 3+ messages in thread
From: Anand Jain @ 2014-05-16 14:03 UTC (permalink / raw)
To: linux-btrfs
The user land progs needs a simple way to see
the raw list of disks and its parameters as seen
by the btrfs kernel.
As of now btrfs-devlist uses this ioctl.
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
fs/btrfs/super.c | 86 ++++++++++++++++++++++++++
fs/btrfs/volumes.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/volumes.h | 2 +
include/uapi/linux/btrfs.h | 51 ++++++++++++++++
4 files changed, 281 insertions(+), 0 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index ac5886b..f43327d 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1717,6 +1717,89 @@ static struct file_system_type btrfs_fs_type = {
};
MODULE_ALIAS_FS("btrfs");
+static int btrfs_ioc_get_devlist(void __user *arg)
+{
+ int ret = 0;
+ u64 sz_devlist_arg;
+ u64 sz_devlist;
+ u64 u_sz_devlist_arg;
+ u64 u_sz_devlist;
+ u64 sz_out;
+
+ struct btrfs_ioctl_devlist_args *devlist_arg;
+ struct btrfs_ioctl_devlist_args *tmp_devlist_arg;
+ struct btrfs_ioctl_devlist *devlist;
+
+ u64 cnt = 0, ucnt;
+
+ sz_devlist_arg = sizeof(*devlist_arg);
+ sz_devlist = sizeof(*devlist);
+
+ /* Check if the user land and kernel ioctl struct match */
+ if (copy_from_user(&u_sz_devlist_arg,
+ (struct btrfs_ioctl_devlist_args __user *)(arg +
+ offsetof(struct btrfs_ioctl_devlist_args, sz_self)),
+ sizeof(u_sz_devlist_arg)))
+ return -EFAULT;
+
+ if (copy_from_user(&u_sz_devlist,
+ (struct btrfs_ioctl_devlist_args __user *)(arg +
+ sz_devlist_arg +
+ offsetof(struct btrfs_ioctl_devlist, sz_self)),
+ sizeof(u_sz_devlist)))
+ return -EFAULT;
+
+ if (u_sz_devlist_arg != sz_devlist_arg ||
+ u_sz_devlist != sz_devlist) {
+ if (copy_to_user(arg +
+ offsetof(struct btrfs_ioctl_devlist_args, sz_self),
+ &sz_devlist_arg, sizeof(sz_devlist_arg)))
+ return -EFAULT;
+ if (copy_to_user(arg +
+ sz_devlist_arg +
+ offsetof(struct btrfs_ioctl_devlist, sz_self),
+ &sz_devlist, sizeof(sz_devlist)))
+ return -EFAULT;
+ return 2;
+ }
+
+ if (copy_from_user(&ucnt,
+ (struct btrfs_ioctl_devlist_args __user *)(arg +
+ offsetof(struct btrfs_ioctl_devlist_args, count)),
+ sizeof(ucnt)))
+ return -EFAULT;
+
+ cnt = btrfs_get_devlist_cnt();
+
+ if (cnt > ucnt) {
+ if (copy_to_user(arg +
+ offsetof(struct btrfs_ioctl_devlist_args, count),
+ &cnt, sizeof(cnt)))
+ return -EFAULT;
+ return 1;
+ }
+
+ sz_out = sz_devlist_arg + sz_devlist * cnt;
+
+ tmp_devlist_arg = devlist_arg = memdup_user(arg, sz_out);
+ if (IS_ERR(devlist_arg))
+ return PTR_ERR(devlist_arg);
+
+ devlist = (struct btrfs_ioctl_devlist *) (++tmp_devlist_arg);
+ cnt = btrfs_get_devlist(devlist, cnt);
+ devlist_arg->count = cnt;
+
+ if (copy_to_user(arg, devlist_arg, sz_out)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = 0;
+out:
+ kfree(devlist_arg);
+ return ret;
+
+}
+
static int btrfs_ioc_get_fslist(void __user *arg)
{
int ret = 0;
@@ -1801,6 +1884,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
case BTRFS_IOC_GET_FSLIST:
ret = btrfs_ioc_get_fslist(argp);
break;
+ case BTRFS_IOC_GET_DEVS:
+ ret = btrfs_ioc_get_devlist(argp);
+ break;
}
return ret;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e22ac22..012aed7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6380,3 +6380,145 @@ u64 btrfs_get_fslist(struct btrfs_ioctl_fslist *fslist, u64 ucnt)
return cnt;
}
+
+int btrfs_get_devlist_cnt(void)
+{
+ int cnt = 0;
+ struct btrfs_device *device;
+ struct btrfs_fs_devices *fs_devices;
+ struct btrfs_fs_devices *cur_fs_devices;
+
+ mutex_lock(&uuid_mutex);
+ list_for_each_entry(cur_fs_devices, &fs_uuids, list) {
+
+ fs_devices = cur_fs_devices;
+again_dev_cnt:
+ list_for_each_entry(device, &fs_devices->devices, dev_list)
+ cnt++;
+
+ fs_devices = fs_devices->seed;
+ if (fs_devices)
+ goto again_dev_cnt;
+ }
+
+ mutex_unlock(&uuid_mutex);
+
+ return cnt;
+}
+
+u64 btrfs_get_devlist(struct btrfs_ioctl_devlist *dev, u64 alloc_cnt)
+{
+ u64 cnt = 0;
+
+ struct btrfs_device *device;
+ struct btrfs_fs_devices *fs_devices;
+ struct btrfs_fs_devices *cur_fs_devices;
+ struct btrfs_fs_devices *sprout_fs_devices;
+
+ mutex_lock(&uuid_mutex);
+ /* Todo: there must be better way of doing this */
+ list_for_each_entry(cur_fs_devices, &fs_uuids, list) {
+
+ mutex_lock(&cur_fs_devices->device_list_mutex);
+
+ fs_devices = cur_fs_devices;
+ sprout_fs_devices = NULL;
+
+again_dev:
+ list_for_each_entry(device, &fs_devices->devices, dev_list) {
+
+ if (!(cnt < alloc_cnt))
+ break;
+
+ dev->fs_addr = (u64)fs_devices;
+ dev->dev_addr = (u64)device;
+ memcpy(dev->fsid, fs_devices->fsid, BTRFS_FSID_SIZE);
+
+ if (fs_devices->seed)
+ memcpy(dev->seed_fsid, fs_devices->seed->fsid,
+ BTRFS_FSID_SIZE);
+ else
+ memset(dev->seed_fsid, 0, BTRFS_FSID_SIZE);
+
+ if (sprout_fs_devices)
+ memcpy(dev->sprout_fsid, sprout_fs_devices->fsid,
+ BTRFS_FSID_SIZE);
+ else
+ memset(dev->sprout_fsid, 0, BTRFS_FSID_SIZE);
+
+ dev->fs_latest_devid = fs_devices->latest_devid;
+ dev->fs_latest_trans = fs_devices->latest_trans;
+ dev->fs_num_devices = fs_devices->num_devices;
+ dev->fs_open_devices = fs_devices->open_devices;
+ dev->fs_rw_devices = fs_devices->rw_devices;
+ dev->fs_missing_devices = fs_devices->missing_devices;
+ dev->fs_total_rw_bytes = fs_devices->total_rw_bytes;
+ dev->fs_num_can_discard = fs_devices->num_can_discard;
+ dev->fs_total_devices = fs_devices->total_devices;
+
+ dev->flags = 0;
+
+ if (fs_devices->opened)
+ dev->flags |= BTRFS_FS_MOUNTED;
+ if (fs_devices->seeding)
+ dev->flags |= BTRFS_FS_SEEDING;
+ if (fs_devices->rotating)
+ dev->flags |= BTRFS_FS_ROTATING;
+
+ dev->gen = device->generation;
+ dev->devid = device->devid;
+ dev->total_bytes = device->total_bytes;
+ dev->disk_total_bytes = device->disk_total_bytes;
+ dev->bytes_used = device->bytes_used;
+ dev->type = device->type;
+ dev->io_align = device->io_align;
+ dev->io_width = device->io_width;
+ dev->sector_size = device->sector_size;
+ dev->fmode = device->mode;
+
+ if (device->writeable)
+ dev->flags |= BTRFS_DEV_WRITEABLE;
+ if (device->in_fs_metadata)
+ dev->flags |= BTRFS_DEV_IN_FS_MD;
+ if (device->missing)
+ dev->flags |= BTRFS_DEV_MISSING;
+ if (device->can_discard)
+ dev->flags |= BTRFS_DEV_CAN_DISCARD;
+ if (device->is_tgtdev_for_dev_replace)
+ dev->flags |= BTRFS_DEV_REPLACE_TGT;
+ if (device->running_pending)
+ dev->flags |= BTRFS_DEV_RUN_PENDING;
+ if (device->nobarriers)
+ dev->flags |= BTRFS_DEV_NOBARRIERS;
+ if (device->dev_stats_valid)
+ dev->flags |= BTRFS_DEV_STATS_VALID;
+ if (device->dev_stats_dirty)
+ dev->flags |= BTRFS_DEV_STATS_DIRTY;
+ if (device->bdev)
+ dev->flags |= BTRFS_DEV_BDEV;
+
+ memcpy(dev->uuid, device->uuid, BTRFS_UUID_SIZE);
+ if (device->name) {
+ rcu_read_lock();
+ memcpy(dev->name, rcu_str_deref(device->name),
+ BTRFS_PATH_NAME_MAX);
+ rcu_read_unlock();
+ } else {
+ memset(dev->name, 0, BTRFS_PATH_NAME_MAX);
+ }
+ dev++;
+ cnt++;
+ }
+
+ if (fs_devices->seed) {
+ sprout_fs_devices = fs_devices;
+ fs_devices = fs_devices->seed;
+ goto again_dev;
+ }
+
+ mutex_unlock(&cur_fs_devices->device_list_mutex);
+ }
+ mutex_unlock(&uuid_mutex);
+
+ return cnt;
+}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 0b97fcf..91b7596 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -393,4 +393,6 @@ static inline void btrfs_dev_stat_reset(struct btrfs_device *dev,
}
int btrfs_get_fslist_cnt(void);
u64 btrfs_get_fslist(struct btrfs_ioctl_fslist *fslist, u64 ucnt);
+int btrfs_get_devlist_cnt(void);
+u64 btrfs_get_devlist(struct btrfs_ioctl_devlist *devlist, u64 ucnt);
#endif
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 76b91d6..1c12b7f 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -520,6 +520,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
/* fs flags */
#define BTRFS_FS_MOUNTED (1LLU << 0)
+#define BTRFS_FS_SEEDING (1LLU << 1)
+#define BTRFS_FS_ROTATING (1LLU << 2)
struct btrfs_ioctl_fslist {
__u64 self_sz; /* in/out */
@@ -535,6 +537,53 @@ struct btrfs_ioctl_fslist_args {
__u64 count; /* out */
};
+#define BTRFS_DEV_WRITEABLE (1LLU << 8)
+#define BTRFS_DEV_IN_FS_MD (1LLU << 9)
+#define BTRFS_DEV_MISSING (1LLU << 10)
+#define BTRFS_DEV_CAN_DISCARD (1LLU << 11)
+#define BTRFS_DEV_REPLACE_TGT (1LLU << 12)
+#define BTRFS_DEV_RUN_PENDING (1LLU << 13)
+#define BTRFS_DEV_NOBARRIERS (1LLU << 14)
+#define BTRFS_DEV_STATS_VALID (1LLU << 15)
+#define BTRFS_DEV_STATS_DIRTY (1LLU << 16)
+#define BTRFS_DEV_BDEV (1LLU << 17)
+
+struct btrfs_ioctl_devlist {
+ __u64 sz_self;
+ __u64 fs_addr;
+ __u64 dev_addr;
+ __u64 fs_latest_devid;
+ __u64 fs_latest_trans;
+ __u64 fs_num_devices;
+ __u64 fs_open_devices;
+ __u64 fs_rw_devices;
+ __u64 fs_missing_devices;
+ __u64 fs_total_rw_bytes;
+ __u64 fs_num_can_discard;
+ __u64 fs_total_devices;
+ __u64 gen;
+ __u64 flags;
+ __u64 devid;
+ __u64 total_bytes;
+ __u64 disk_total_bytes;
+ __u64 bytes_used;
+ __u64 type;
+ __u64 fmode;
+ __u32 io_align;
+ __u32 io_width;
+ __u32 sector_size;
+ __u8 fsid[BTRFS_FSID_SIZE];
+ __u8 uuid[BTRFS_UUID_SIZE];
+ __u8 seed_fsid[BTRFS_FSID_SIZE];
+ __u8 sprout_fsid[BTRFS_UUID_SIZE];
+ __u8 name[BTRFS_PATH_NAME_MAX];
+}__attribute__ ((__packed__));
+
+struct btrfs_ioctl_devlist_args {
+ __u64 sz_self; /* in/out */
+ __u64 count; /* in/out */
+};
+
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -637,5 +686,7 @@ struct btrfs_ioctl_fslist_args {
struct btrfs_ioctl_feature_flags[2])
#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
struct btrfs_ioctl_feature_flags[3])
+#define BTRFS_IOC_GET_DEVS _IOWR(BTRFS_IOCTL_MAGIC, 58, \
+ struct btrfs_ioctl_devlist_args)
#endif /* _UAPI_LINUX_BTRFS_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 1/1] btrfs-progs: introduce btrfs-devlist
2014-05-16 14:03 [PATCH 0/1 not for integration] btrfs-devlist Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs: introduce BTRFS_IOC_GET_DEVS Anand Jain
@ 2014-05-16 14:03 ` Anand Jain
1 sibling, 0 replies; 3+ messages in thread
From: Anand Jain @ 2014-05-16 14:03 UTC (permalink / raw)
To: linux-btrfs
This is a small (debug) program to dump the device list
in the raw format from the btrfs kernel.
here I use ioctl which was introduced in the below kernel
patch
btrfs: introduce BTRFS_IOC_GET_DEVS
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
.gitignore | 1 +
Makefile | 4 +-
btrfs-devlist.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
ioctl.h | 51 +++++++++++
4 files changed, 320 insertions(+), 2 deletions(-)
create mode 100644 btrfs-devlist.c
diff --git a/.gitignore b/.gitignore
index fc8c07a..760eaeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@ libbtrfs.a
libbtrfs.so
libbtrfs.so.0
libbtrfs.so.0.1
+btrfs-devlist
diff --git a/Makefile b/Makefile
index c861d61..a91cf8b 100644
--- a/Makefile
+++ b/Makefile
@@ -48,7 +48,7 @@ MAKEOPTS = --no-print-directory Q=$(Q)
progs = mkfs.btrfs btrfs-debug-tree btrfsck \
btrfs btrfs-map-logical btrfs-image btrfs-zero-log btrfs-convert \
- btrfs-find-root btrfstune btrfs-show-super
+ btrfs-find-root btrfstune btrfs-show-super btrfs-devlist
# external libs required by various binaries; for btrfs-foo,
# specify btrfs_foo_libs = <list of libs>; see $($(subst...)) rules below
@@ -229,7 +229,7 @@ clean: $(CLEANDIRS)
@echo "Cleaning"
$(Q)rm -f $(progs) cscope.out *.o *.o.d btrfs-convert btrfs-image btrfs-select-super \
btrfs-zero-log btrfstune dir-test ioctl-test quick-test send-test btrfsck \
- btrfs.static mkfs.btrfs.static btrfs-calc-size \
+ btrfs.static mkfs.btrfs.static btrfs-calc-size btrfs-devlist\
version.h $(check_defs) \
$(libs) $(lib_links)
diff --git a/btrfs-devlist.c b/btrfs-devlist.c
new file mode 100644
index 0000000..332a171
--- /dev/null
+++ b/btrfs-devlist.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <unistd.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <uuid/uuid.h>
+
+#include "ctree.h"
+#include "ioctl.h"
+#include "commands.h"
+#include "utils.h"
+
+void print_header(void)
+{
+ printf(
+ "fs_address dev_address\n"\
+ "fsid "\
+ "name "\
+ "uuid "\
+ "(seed_fsid "\
+ "sprout_fsid) \n"\
+ "\t(fs_latest_devid "\
+ "fs_num_devices "\
+ "fs_open_devices "\
+ "fs_rw_devices "\
+ "fs_missing_devices "\
+ "fs_total_devices) "\
+ "fs_total_rw_bytes "\
+ "fs_num_can_discard "\
+ "fs_latest_trans \n"\
+ "\tdevid "\
+ "gen "\
+ "total_bytes "\
+ "disk_total_bytes "\
+ "bytes_used "\
+ "type "\
+ "io_align "\
+ "io_width "\
+ "sector_size "\
+ "fmode \n"\
+ "\tfs_flags\n"\
+ "\tdev_flags\n");
+}
+
+void print_dev(struct btrfs_ioctl_devlist *dev)
+{
+ char uuid[BTRFS_UUID_UNPARSED_SIZE];
+ char fsid[BTRFS_UUID_UNPARSED_SIZE];
+ char seed_fsid[BTRFS_UUID_UNPARSED_SIZE];
+ char sprout_fsid[BTRFS_UUID_UNPARSED_SIZE];
+
+ memset(seed_fsid, '0', BTRFS_UUID_UNPARSED_SIZE);
+ strcpy(seed_fsid, "null");
+ memset(sprout_fsid, '0', BTRFS_UUID_UNPARSED_SIZE);
+ strcpy(sprout_fsid, "null");
+
+ uuid_unparse(dev->uuid, uuid);
+ uuid_unparse(dev->fsid, fsid);
+ if (! uuid_is_null(dev->seed_fsid))
+ uuid_unparse(dev->seed_fsid, seed_fsid);
+ if (! uuid_is_null(dev->sprout_fsid))
+ uuid_unparse(dev->sprout_fsid, sprout_fsid);
+
+ printf("\n%llX %llX\n"\
+ "%s %s %s (%s %s)\n"\
+ "\t(%llu %llu %llu %llu %llu %llu) %llu %llu %llu\n"\
+ "\t%llu %llu %llu %llu %llu %llu %u %u %u 0x%llX\n"\
+ "\t%s|%s|%s\n"\
+ "\t%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n",
+ dev->fs_addr,
+ dev->dev_addr,
+ fsid,
+ dev->name,
+ uuid,
+ seed_fsid,
+ sprout_fsid,
+ dev->fs_latest_devid,
+ dev->fs_num_devices,
+ dev->fs_open_devices,
+ dev->fs_rw_devices,
+ dev->fs_missing_devices,
+ dev->fs_total_devices,
+ dev->fs_total_rw_bytes,
+ dev->fs_num_can_discard,
+ dev->fs_latest_trans,
+ dev->devid,
+ dev->gen,
+ dev->total_bytes,
+ dev->disk_total_bytes,
+ dev->bytes_used,
+ dev->type,
+ dev->io_align,
+ dev->io_width,
+ dev->sector_size,
+ dev->fmode,
+ dev->flags & BTRFS_FS_MOUNTED ? "fs_Mounted":"not_fs_Mounted",
+ dev->flags & BTRFS_FS_SEEDING ? "fs_Seeding":"not_fs_Seeding",
+ dev->flags & BTRFS_FS_ROTATING ? "fs_Rotating":"not_fs_Rotating",
+ dev->flags & BTRFS_DEV_WRITEABLE ? "Writable":"not_Writable",
+ dev->flags & BTRFS_DEV_IN_FS_MD ? "MD":"not_MD",
+ dev->flags & BTRFS_DEV_MISSING ? "Missing":"not_Missing",
+ dev->flags & BTRFS_DEV_CAN_DISCARD ? "Discard":"not_Discard",
+ dev->flags & BTRFS_DEV_REPLACE_TGT ? "Replace_tgt":"not_Replace_tgt",
+ dev->flags & BTRFS_DEV_RUN_PENDING ? "Run_pending":"not_Run_pending",
+ dev->flags & BTRFS_DEV_NOBARRIERS ? "Nobarriers":"not_Nobarriers",
+ dev->flags & BTRFS_DEV_STATS_VALID ? "Stat_valid":"not_Stat_valid",
+ dev->flags & BTRFS_DEV_STATS_DIRTY ? "Stat_dirty":"not_Stat_dirty",
+ dev->flags & BTRFS_DEV_BDEV ? "Bdev":"not_Bdev");
+}
+
+int get_devlist(struct btrfs_ioctl_devlist **out_devlist, u64 *out_count)
+{
+ int ret, fd, e;
+ struct btrfs_ioctl_devlist_args *devargs;
+ struct btrfs_ioctl_devlist_args *devargs_saved = NULL;
+ struct btrfs_ioctl_devlist *devlist;
+ u64 sz;
+ int count;
+
+ fd = open("/dev/btrfs-control", O_RDWR);
+ e = errno;
+ if (fd < 0) {
+ perror("failed to open /dev/btrfs-control");
+ return -e;
+ }
+
+ /* space to hold 512 fsids, doesn't matter if small
+ * it would fail and return count so then we try again
+ */
+ count = 512;
+again:
+ sz = sizeof(*devargs) + sizeof(*devlist) * count;
+
+ devargs_saved = devargs = malloc(sz);
+ if (!devargs) {
+ close(fd);
+ return -ENOMEM;
+ }
+
+ memset(devargs, 0, sz);
+ devlist = (struct btrfs_ioctl_devlist *) (++devargs);
+ devargs = devargs_saved;
+
+ devargs->count = count;
+ devargs->sz_self = (u64) sizeof(*devargs);
+ devlist->sz_self = (u64) sizeof(*devlist);
+
+ ret = ioctl(fd, BTRFS_IOC_GET_DEVS, devargs);
+ e = errno;
+ if (ret == 1) {
+ /* out of size so reallocate */
+ count = devargs->count;
+ free(devargs);
+ goto again;
+ } else if (ret < 0) {
+ printf("ERROR: scan_fsid ioctl failed - %s\n",
+ strerror(e));
+ ret = -e;
+ goto out;
+ }
+
+ /* Check if the kernel has the same struct as this */
+ if (devargs->sz_self != sizeof(*devargs) ||
+ devlist->sz_self != sizeof(*devlist)) {
+ fprintf(stderr,
+ "ERROR: version mismatch udevarg %lu udevlist %lu kdevarg %llu kdevlist %llu\n",
+ sizeof(*devargs), sizeof(*devlist), devargs->sz_self, devlist->sz_self);
+ goto out;
+ }
+
+ /* ioctl returns devs count in count parameter*/
+
+ *out_count = devargs->count;
+ if (*out_count == 0) {
+ *out_devlist = NULL;
+ ret = 0;
+ goto out;
+ }
+
+
+ sz = sizeof(*devlist) * *out_count;
+ *out_devlist = malloc(sz);
+ if (*out_devlist == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(*out_devlist, devlist, sz);
+ ret = 0;
+
+out:
+ free(devargs_saved);
+ close(fd);
+ return ret;
+}
+
+static void local_usage(void)
+{
+ printf("btrfs_devlist [options]\n"\
+ " Dumps the device list from the btrfs kernel "\
+ "without altering at the user level\n"\
+ " options:\n"\
+ " -h|--help prints this usage\n");
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ u64 cnt;
+ struct btrfs_ioctl_devlist *devlist;
+ struct btrfs_ioctl_devlist *tmp_devlist;
+
+ while(1) {
+ int long_index;
+ static struct option long_options[] = {
+ {"help", no_argument, NULL, 'h'},
+ { NULL, no_argument, NULL, 0 }
+ };
+
+ int c = getopt_long(argc, argv, "h", long_options,
+ &long_index);
+
+ if(c < 0)
+ break;
+
+ switch(c) {
+ case 'h':
+ default:
+ local_usage();
+ }
+ }
+
+ ret = get_devlist(&devlist, &cnt);
+ if (ret) {
+ fprintf(stderr, "get devlist failed %d\n", ret);
+ return 1;
+ }
+
+ tmp_devlist = devlist;
+
+ print_header();
+ while (cnt--) {
+ print_dev(devlist);
+ devlist++;
+ }
+ kfree(tmp_devlist);
+ return ret;
+}
diff --git a/ioctl.h b/ioctl.h
index d4e54f9..a2320fc 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -528,6 +528,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
/* fs flags */
#define BTRFS_FS_MOUNTED (1LLU << 0)
+#define BTRFS_FS_SEEDING (1LLU << 1)
+#define BTRFS_FS_ROTATING (1LLU << 2)
struct btrfs_ioctl_fslist {
__u64 self_sz; /* in/out */
@@ -543,6 +545,53 @@ struct btrfs_ioctl_fslist_args {
__u64 count; /* out */
};
+#define BTRFS_DEV_WRITEABLE (1LLU << 8)
+#define BTRFS_DEV_IN_FS_MD (1LLU << 9)
+#define BTRFS_DEV_MISSING (1LLU << 10)
+#define BTRFS_DEV_CAN_DISCARD (1LLU << 11)
+#define BTRFS_DEV_REPLACE_TGT (1LLU << 12)
+#define BTRFS_DEV_RUN_PENDING (1LLU << 13)
+#define BTRFS_DEV_NOBARRIERS (1LLU << 14)
+#define BTRFS_DEV_STATS_VALID (1LLU << 15)
+#define BTRFS_DEV_STATS_DIRTY (1LLU << 16)
+#define BTRFS_DEV_BDEV (1LLU << 17)
+
+struct btrfs_ioctl_devlist {
+ __u64 sz_self;
+ __u64 fs_addr;
+ __u64 dev_addr;
+ __u64 fs_latest_devid;
+ __u64 fs_latest_trans;
+ __u64 fs_num_devices;
+ __u64 fs_open_devices;
+ __u64 fs_rw_devices;
+ __u64 fs_missing_devices;
+ __u64 fs_total_rw_bytes;
+ __u64 fs_num_can_discard;
+ __u64 fs_total_devices;
+ __u64 gen;
+ __u64 flags;
+ __u64 devid;
+ __u64 total_bytes;
+ __u64 disk_total_bytes;
+ __u64 bytes_used;
+ __u64 type;
+ __u64 fmode;
+ __u32 io_align;
+ __u32 io_width;
+ __u32 sector_size;
+ __u8 fsid[BTRFS_FSID_SIZE];
+ __u8 uuid[BTRFS_UUID_SIZE];
+ __u8 seed_fsid[BTRFS_FSID_SIZE];
+ __u8 sprout_fsid[BTRFS_UUID_SIZE];
+ __u8 name[BTRFS_PATH_NAME_MAX];
+}__attribute__ ((__packed__));
+
+struct btrfs_ioctl_devlist_args {
+ __u64 sz_self; /* in/out */
+ __u64 count; /* in/out */
+};
+
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -652,6 +701,8 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_feature_flags[2])
#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
struct btrfs_ioctl_feature_flags[3])
+#define BTRFS_IOC_GET_DEVS _IOWR(BTRFS_IOCTL_MAGIC, 58, \
+ struct btrfs_ioctl_devlist_args)
#ifdef __cplusplus
}
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-16 14:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-16 14:03 [PATCH 0/1 not for integration] btrfs-devlist Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs: introduce BTRFS_IOC_GET_DEVS Anand Jain
2014-05-16 14:03 ` [PATCH 1/1] btrfs-progs: introduce btrfs-devlist Anand Jain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).