* [PATCH v3 1/3] Btrfs-progs: move open_file_or_dir() to utils.c
2012-05-16 16:50 [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl Stefan Behrens
@ 2012-05-16 16:50 ` Stefan Behrens
2012-05-16 16:50 ` [PATCH v3 2/3] Btrfs-progs: make two utility functions globally available Stefan Behrens
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Stefan Behrens @ 2012-05-16 16:50 UTC (permalink / raw)
To: linux-btrfs
This is a preparation step to add support for device stats. The definition
of the function open_file_or_dir() is moved from common.c to utils.c in
order to be able to share some common code between scrub and the device
stats in the following step. That common code uses open_file_or_dir().
Since open_file_or_dir() makes use of the function dirfd(3), the required
XOPEN version was raised from 6 to 7.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
Makefile | 4 ++--
btrfsctl.c | 28 ----------------------------
cmds-balance.c | 1 +
cmds-inspect.c | 1 +
cmds-subvolume.c | 1 +
commands.h | 3 ---
common.c | 46 ----------------------------------------------
utils.c | 31 +++++++++++++++++++++++++++++--
utils.h | 3 +++
9 files changed, 37 insertions(+), 81 deletions(-)
diff --git a/Makefile b/Makefile
index 79818e6..fe2b432 100644
--- a/Makefile
+++ b/Makefile
@@ -39,8 +39,8 @@ all: version $(progs) manpages
version:
bash version.sh
-btrfs: $(objects) btrfs.o help.o common.o $(cmds_objects)
- $(CC) $(CFLAGS) -o btrfs btrfs.o help.o common.o $(cmds_objects) \
+btrfs: $(objects) btrfs.o help.o $(cmds_objects)
+ $(CC) $(CFLAGS) -o btrfs btrfs.o help.o $(cmds_objects) \
$(objects) $(LDFLAGS) $(LIBS) -lpthread
calc-size: $(objects) calc-size.o
diff --git a/btrfsctl.c b/btrfsctl.c
index d45e2a7..f0584f3 100644
--- a/btrfsctl.c
+++ b/btrfsctl.c
@@ -63,34 +63,6 @@ static void print_usage(void)
exit(1);
}
-static int open_file_or_dir(const char *fname)
-{
- int ret;
- struct stat st;
- DIR *dirstream;
- int fd;
-
- ret = stat(fname, &st);
- if (ret < 0) {
- perror("stat:");
- exit(1);
- }
- if (S_ISDIR(st.st_mode)) {
- dirstream = opendir(fname);
- if (!dirstream) {
- perror("opendir");
- exit(1);
- }
- fd = dirfd(dirstream);
- } else {
- fd = open(fname, O_RDWR);
- }
- if (fd < 0) {
- perror("open");
- exit(1);
- }
- return fd;
-}
int main(int ac, char **av)
{
char *fname = NULL;
diff --git a/cmds-balance.c b/cmds-balance.c
index 38a7426..5793b5c 100644
--- a/cmds-balance.c
+++ b/cmds-balance.c
@@ -26,6 +26,7 @@
#include "ctree.h"
#include "ioctl.h"
#include "volumes.h"
+#include "utils.h"
#include "commands.h"
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 2f0228f..7a8785b 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -22,6 +22,7 @@
#include "kerncompat.h"
#include "ioctl.h"
+#include "utils.h"
#include "commands.h"
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 950fa8f..8ecd3f4 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -26,6 +26,7 @@
#include "kerncompat.h"
#include "ioctl.h"
+#include "utils.h"
#include "commands.h"
diff --git a/commands.h b/commands.h
index a303a50..aea4cb1 100644
--- a/commands.h
+++ b/commands.h
@@ -79,9 +79,6 @@ void help_ambiguous_token(const char *arg, const struct cmd_group *grp);
void help_command_group(const struct cmd_group *grp, int argc, char **argv);
-/* common.c */
-int open_file_or_dir(const char *fname);
-
extern const struct cmd_group subvolume_cmd_group;
extern const struct cmd_group filesystem_cmd_group;
extern const struct cmd_group balance_cmd_group;
diff --git a/common.c b/common.c
deleted file mode 100644
index 03f6570..0000000
--- a/common.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-int open_file_or_dir(const char *fname)
-{
- int ret;
- struct stat st;
- DIR *dirstream;
- int fd;
-
- ret = stat(fname, &st);
- if (ret < 0) {
- return -1;
- }
- if (S_ISDIR(st.st_mode)) {
- dirstream = opendir(fname);
- if (!dirstream) {
- return -2;
- }
- fd = dirfd(dirstream);
- } else {
- fd = open(fname, O_RDWR);
- }
- if (fd < 0) {
- return -3;
- }
- return fd;
-}
diff --git a/utils.c b/utils.c
index ee7fa1b..6157115 100644
--- a/utils.c
+++ b/utils.c
@@ -16,8 +16,9 @@
* Boston, MA 021110-1307, USA.
*/
-#define _XOPEN_SOURCE 600
-#define __USE_XOPEN2K
+#define _XOPEN_SOURCE 700
+#define __USE_XOPEN2K8
+#define __XOPEN2K8 /* due to an error in dirent.h, to get dirfd() */
#include <stdio.h>
#include <stdlib.h>
#ifndef __CHECKER__
@@ -1206,3 +1207,29 @@ scan_again:
return 0;
}
+int open_file_or_dir(const char *fname)
+{
+ int ret;
+ struct stat st;
+ DIR *dirstream;
+ int fd;
+
+ ret = stat(fname, &st);
+ if (ret < 0) {
+ return -1;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ dirstream = opendir(fname);
+ if (!dirstream) {
+ return -2;
+ }
+ fd = dirfd(dirstream);
+ } else {
+ fd = open(fname, O_RDWR);
+ }
+ if (fd < 0) {
+ return -3;
+ }
+ return fd;
+}
+
diff --git a/utils.h b/utils.h
index c5f55e1..e281002 100644
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,8 @@
#ifndef __UTILS__
#define __UTILS__
+#include "ctree.h"
+
#define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
int make_btrfs(int fd, const char *device, const char *label,
@@ -46,4 +48,5 @@ int check_label(char *input);
int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
+int open_file_or_dir(const char *fname);
#endif
--
1.7.10.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/3] Btrfs-progs: make two utility functions globally available
2012-05-16 16:50 [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl Stefan Behrens
2012-05-16 16:50 ` [PATCH v3 1/3] Btrfs-progs: move open_file_or_dir() to utils.c Stefan Behrens
@ 2012-05-16 16:50 ` Stefan Behrens
2012-05-16 16:50 ` [PATCH v3 3/3] Btrfs-progs: add command to get/reset device stats via ioctl Stefan Behrens
2012-05-16 17:03 ` [PATCH v3 0/3] Btrfs-progs: support " Andrei Popa
3 siblings, 0 replies; 7+ messages in thread
From: Stefan Behrens @ 2012-05-16 16:50 UTC (permalink / raw)
To: linux-btrfs
Two convenient utility functions that have so far been local to scrub are
moved to utils.c.
They will be used in the device stats code in a following commit.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
cmds-scrub.c | 72 ++--------------------------------------------------------
utils.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
utils.h | 4 ++++
3 files changed, 72 insertions(+), 70 deletions(-)
diff --git a/cmds-scrub.c b/cmds-scrub.c
index c4503f4..37a9890 100644
--- a/cmds-scrub.c
+++ b/cmds-scrub.c
@@ -967,74 +967,6 @@ static struct scrub_file_record *last_dev_scrub(
return NULL;
}
-static int scrub_device_info(int fd, u64 devid,
- struct btrfs_ioctl_dev_info_args *di_args)
-{
- int ret;
-
- di_args->devid = devid;
- memset(&di_args->uuid, '\0', sizeof(di_args->uuid));
-
- ret = ioctl(fd, BTRFS_IOC_DEV_INFO, di_args);
- return ret ? -errno : 0;
-}
-
-static int scrub_fs_info(int fd, char *path,
- struct btrfs_ioctl_fs_info_args *fi_args,
- struct btrfs_ioctl_dev_info_args **di_ret)
-{
- int ret = 0;
- int ndevs = 0;
- int i = 1;
- struct btrfs_fs_devices *fs_devices_mnt = NULL;
- struct btrfs_ioctl_dev_info_args *di_args;
- char mp[BTRFS_PATH_NAME_MAX + 1];
-
- memset(fi_args, 0, sizeof(*fi_args));
-
- ret = ioctl(fd, BTRFS_IOC_FS_INFO, fi_args);
- if (ret && errno == EINVAL) {
- /* path is no mounted btrfs. try if it's a device */
- ret = check_mounted_where(fd, path, mp, sizeof(mp),
- &fs_devices_mnt);
- if (!ret)
- return -EINVAL;
- if (ret < 0)
- return ret;
- fi_args->num_devices = 1;
- fi_args->max_id = fs_devices_mnt->latest_devid;
- i = fs_devices_mnt->latest_devid;
- memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE);
- close(fd);
- fd = open_file_or_dir(mp);
- if (fd < 0)
- return -errno;
- } else if (ret) {
- return -errno;
- }
-
- if (!fi_args->num_devices)
- return 0;
-
- di_args = *di_ret = malloc(fi_args->num_devices * sizeof(*di_args));
- if (!di_args)
- return -errno;
-
- for (; i <= fi_args->max_id; ++i) {
- BUG_ON(ndevs >= fi_args->num_devices);
- ret = scrub_device_info(fd, i, &di_args[ndevs]);
- if (ret == -ENODEV)
- continue;
- if (ret)
- return ret;
- ++ndevs;
- }
-
- BUG_ON(ndevs == 0);
-
- return 0;
-}
-
int mkdir_p(char *path)
{
int i;
@@ -1155,7 +1087,7 @@ static int scrub_start(int argc, char **argv, int resume)
return 12;
}
- ret = scrub_fs_info(fdmnt, path, &fi_args, &di_args);
+ ret = get_fs_info(fdmnt, path, &fi_args, &di_args);
if (ret) {
ERR(!do_quiet, "ERROR: getting dev info for scrub failed: "
"%s\n", strerror(-ret));
@@ -1621,7 +1553,7 @@ static int cmd_scrub_status(int argc, char **argv)
return 12;
}
- ret = scrub_fs_info(fdmnt, path, &fi_args, &di_args);
+ ret = get_fs_info(fdmnt, path, &fi_args, &di_args);
if (ret) {
fprintf(stderr, "ERROR: getting dev info for scrub failed: "
"%s\n", strerror(-ret));
diff --git a/utils.c b/utils.c
index 6157115..037f64b 100644
--- a/utils.c
+++ b/utils.c
@@ -1233,3 +1233,69 @@ int open_file_or_dir(const char *fname)
return fd;
}
+int get_device_info(int fd, u64 devid,
+ struct btrfs_ioctl_dev_info_args *di_args)
+{
+ int ret;
+
+ di_args->devid = devid;
+ memset(&di_args->uuid, '\0', sizeof(di_args->uuid));
+
+ ret = ioctl(fd, BTRFS_IOC_DEV_INFO, di_args);
+ return ret ? -errno : 0;
+}
+
+int get_fs_info(int fd, char *path, struct btrfs_ioctl_fs_info_args *fi_args,
+ struct btrfs_ioctl_dev_info_args **di_ret)
+{
+ int ret = 0;
+ int ndevs = 0;
+ int i = 1;
+ struct btrfs_fs_devices *fs_devices_mnt = NULL;
+ struct btrfs_ioctl_dev_info_args *di_args;
+ char mp[BTRFS_PATH_NAME_MAX + 1];
+
+ memset(fi_args, 0, sizeof(*fi_args));
+
+ ret = ioctl(fd, BTRFS_IOC_FS_INFO, fi_args);
+ if (ret && (errno == EINVAL || errno == ENOTTY)) {
+ /* path is not a mounted btrfs. Try if it's a device */
+ ret = check_mounted_where(fd, path, mp, sizeof(mp),
+ &fs_devices_mnt);
+ if (!ret)
+ return -EINVAL;
+ if (ret < 0)
+ return ret;
+ fi_args->num_devices = 1;
+ fi_args->max_id = fs_devices_mnt->latest_devid;
+ i = fs_devices_mnt->latest_devid;
+ memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE);
+ close(fd);
+ fd = open_file_or_dir(mp);
+ if (fd < 0)
+ return -errno;
+ } else if (ret) {
+ return -errno;
+ }
+
+ if (!fi_args->num_devices)
+ return 0;
+
+ di_args = *di_ret = malloc(fi_args->num_devices * sizeof(*di_args));
+ if (!di_args)
+ return -errno;
+
+ for (; i <= fi_args->max_id; ++i) {
+ BUG_ON(ndevs >= fi_args->num_devices);
+ ret = get_device_info(fd, i, &di_args[ndevs]);
+ if (ret == -ENODEV)
+ continue;
+ if (ret)
+ return ret;
+ ndevs++;
+ }
+
+ BUG_ON(ndevs == 0);
+
+ return 0;
+}
diff --git a/utils.h b/utils.h
index e281002..e33c231 100644
--- a/utils.h
+++ b/utils.h
@@ -49,4 +49,8 @@ int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
int open_file_or_dir(const char *fname);
+int get_device_info(int fd, u64 devid,
+ struct btrfs_ioctl_dev_info_args *di_args);
+int get_fs_info(int fd, char *path, struct btrfs_ioctl_fs_info_args *fi_args,
+ struct btrfs_ioctl_dev_info_args **di_ret);
#endif
--
1.7.10.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 3/3] Btrfs-progs: add command to get/reset device stats via ioctl
2012-05-16 16:50 [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl Stefan Behrens
2012-05-16 16:50 ` [PATCH v3 1/3] Btrfs-progs: move open_file_or_dir() to utils.c Stefan Behrens
2012-05-16 16:50 ` [PATCH v3 2/3] Btrfs-progs: make two utility functions globally available Stefan Behrens
@ 2012-05-16 16:50 ` Stefan Behrens
2012-05-16 17:03 ` [PATCH v3 0/3] Btrfs-progs: support " Andrei Popa
3 siblings, 0 replies; 7+ messages in thread
From: Stefan Behrens @ 2012-05-16 16:50 UTC (permalink / raw)
To: linux-btrfs
"btrfs device stats" is used to retrieve and print the device stats.
"btrfs device stats -z" is used to atomically retrieve, reset and
print the stats.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
---
cmds-device.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ctree.h | 6 +++
ioctl.h | 27 ++++++++++++++
man/btrfs.8.in | 14 +++++++
print-tree.c | 6 +++
5 files changed, 166 insertions(+)
diff --git a/cmds-device.c b/cmds-device.c
index db625a6..3417f03 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -246,11 +246,124 @@ static int cmd_scan_dev(int argc, char **argv)
return 0;
}
+static const char * const cmd_dev_stats_usage[] = {
+ "btrfs device stats [-z] <path>|<device>",
+ "Show current device IO stats. -z to reset stats afterwards.",
+ NULL
+};
+
+static int cmd_dev_stats(int argc, char **argv)
+{
+ char *path;
+ struct btrfs_ioctl_fs_info_args fi_args;
+ struct btrfs_ioctl_dev_info_args *di_args = NULL;
+ int ret;
+ int fdmnt;
+ int i;
+ char c;
+ int fdres = -1;
+ int err = 0;
+ int cmd = BTRFS_IOC_GET_DEVICE_STATS;
+
+ optind = 1;
+ while ((c = getopt(argc, argv, "z")) != -1) {
+ switch (c) {
+ case 'z':
+ cmd = BTRFS_IOC_GET_AND_RESET_DEVICE_STATS;
+ break;
+ case '?':
+ default:
+ fprintf(stderr, "ERROR: device stat args invalid.\n"
+ " device stat [-z] <path>|<device>\n"
+ " -z to reset stats after reading.\n");
+ return 1;
+ }
+ }
+
+ if (optind + 1 != argc) {
+ fprintf(stderr, "ERROR: device stat needs path|device as single"
+ " argument\n");
+ return 1;
+ }
+
+ path = argv[optind];
+
+ fdmnt = open_file_or_dir(path);
+ if (fdmnt < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", path);
+ return 12;
+ }
+
+ ret = get_fs_info(fdmnt, path, &fi_args, &di_args);
+ if (ret) {
+ fprintf(stderr, "ERROR: getting dev info for devstats failed: "
+ "%s\n", strerror(-ret));
+ err = 1;
+ goto out;
+ }
+ if (!fi_args.num_devices) {
+ fprintf(stderr, "ERROR: no devices found\n");
+ err = 1;
+ goto out;
+ }
+
+ for (i = 0; i < fi_args.num_devices; i++) {
+ struct btrfs_ioctl_get_device_stats args = {0};
+ __u8 path[BTRFS_DEVICE_PATH_NAME_MAX + 1];
+
+ strncpy((char *)path, (char *)di_args[i].path,
+ BTRFS_DEVICE_PATH_NAME_MAX);
+ path[BTRFS_DEVICE_PATH_NAME_MAX] = '\0';
+
+ args.devid = di_args[i].devid;
+ args.nr_items = BTRFS_IOCTL_GET_DEVICE_STATS_MAX_NR_ITEMS;
+
+ if (ioctl(fdmnt, cmd, &args) < 0) {
+ fprintf(stderr, "ERROR: ioctl(%s) on %s failed: %s\n",
+ BTRFS_IOC_GET_AND_RESET_DEVICE_STATS == cmd ?
+ "BTRFS_IOC_GET_AND_RESET_DEVICE_STATS" :
+ "BTRFS_IOC_GET_DEVICE_STATS",
+ path, strerror(errno));
+ err = 1;
+ } else {
+ if (args.nr_items >= 1)
+ printf("[%s].cnt_write_io_errs %llu\n",
+ path, (unsigned long long)
+ args.cnt_write_io_errs);
+ if (args.nr_items >= 2)
+ printf("[%s].cnt_read_io_errs %llu\n",
+ path, (unsigned long long)
+ args.cnt_read_io_errs);
+ if (args.nr_items >= 3)
+ printf("[%s].cnt_flush_io_errs %llu\n",
+ path, (unsigned long long)
+ args.cnt_flush_io_errs);
+ if (args.nr_items >= 4)
+ printf("[%s].cnt_corruption_errs %llu\n",
+ path, (unsigned long long)
+ args.cnt_corruption_errs);
+ if (args.nr_items >= 5)
+ printf("[%s].cnt_generation_errs %llu\n",
+ path, (unsigned long long)
+ args.cnt_generation_errs);
+ }
+ }
+
+out:
+ free(di_args);
+ close(fdmnt);
+ if (fdres > -1)
+ close(fdres);
+
+ return err;
+}
+
const struct cmd_group device_cmd_group = {
device_cmd_group_usage, NULL, {
{ "add", cmd_add_dev, cmd_add_dev_usage, NULL, 0 },
{ "delete", cmd_rm_dev, cmd_rm_dev_usage, NULL, 0 },
{ "scan", cmd_scan_dev, cmd_scan_dev_usage, NULL, 0 },
+ { "stats", cmd_dev_stats, cmd_dev_stats_usage, NULL, 0 },
{ 0, 0, 0, 0, 0 }
}
};
diff --git a/ctree.h b/ctree.h
index 6545c50..db0de5e 100644
--- a/ctree.h
+++ b/ctree.h
@@ -943,6 +943,12 @@ struct btrfs_root {
#define BTRFS_BALANCE_ITEM_KEY 248
/*
+ * Persistantly stores the io stats in the device tree.
+ * One key for all stats, (0, BTRFS_DEVICE_STATS_KEY, devid).
+ */
+#define BTRFS_DEVICE_STATS_KEY 249
+
+/*
* string items are for debugging. They just store a short string of
* data in the FS
*/
diff --git a/ioctl.h b/ioctl.h
index f2e5d8d..f7b58dd 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -272,6 +272,29 @@ struct btrfs_ioctl_logical_ino_args {
__u64 inodes;
};
+#define BTRFS_IOCTL_GET_DEVICE_STATS_MAX_NR_ITEMS 5
+struct btrfs_ioctl_get_device_stats {
+ __u64 devid; /* in */
+ __u64 nr_items; /* in/out */
+
+ /* out values: */
+
+ /* disk I/O failure stats */
+ __u64 cnt_write_io_errs; /* EIO or EREMOTEIO from lower layers */
+ __u64 cnt_read_io_errs; /* EIO or EREMOTEIO from lower layers */
+ __u64 cnt_flush_io_errs; /* EIO or EREMOTEIO from lower layers */
+
+ /* stats for indirect indications for I/O failures */
+ __u64 cnt_corruption_errs; /* checksum error, bytenr error or
+ * contents is illegal: this is an
+ * indication that the block was damaged
+ * during read or write, or written to
+ * wrong location or read from wrong
+ * location */
+ __u64 cnt_generation_errs; /* an indication that blocks have not
+ * been written */
+};
+
/* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
@@ -330,5 +353,9 @@ struct btrfs_ioctl_logical_ino_args {
struct btrfs_ioctl_ino_path_args)
#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
struct btrfs_ioctl_ino_path_args)
+#define BTRFS_IOC_GET_DEVICE_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
+ struct btrfs_ioctl_get_device_stats)
+#define BTRFS_IOC_GET_AND_RESET_DEVICE_STATS _IOWR(BTRFS_IOCTL_MAGIC, 53, \
+ struct btrfs_ioctl_get_device_stats)
#endif
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index be478e0..c903fee 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -35,6 +35,8 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBdevice show\fP\fI [--all-devices|<uuid>|<label>]\fP
.PP
+\fBbtrfs\fP \fBdevice stats\fP [-z] {\fI<path>\fP|\fI<device>\fP}
+.PP
\fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP
.PP
\fBbtrfs\fP \fBdevice delete\fP\fI <device> [<device>...] <path> \fP
@@ -214,6 +216,18 @@ Balance the chunks of the filesystem identified by \fI<path>\fR
across the devices.
.TP
+\fBdevice stats\fP [-z] {\fI<path>\fP|\fI<device>\fP}
+Read and print the device IO stats for all devices of the filesystem
+identified by \fI<path>\fR or for a single \fI<device>\fR.
+
+.RS
+\fIOptions\fR
+.TP
+.B -z
+Reset stats to zero after reading them.
+.RE
+.TP
+
\fBdevice add\fR\fI <dev> [<dev>..] <path>\fR
Add device(s) to the filesystem identified by \fI<path>\fR.
.TP
diff --git a/print-tree.c b/print-tree.c
index fc134c0..7520601 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -357,6 +357,9 @@ static void print_key_type(u8 type)
case BTRFS_STRING_ITEM_KEY:
printf("STRING_ITEM");
break;
+ case BTRFS_DEVICE_STATS_KEY:
+ printf("DEVICE_STATS_ITEM");
+ break;
default:
printf("UNKNOWN");
};
@@ -609,6 +612,9 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
str = l->data + btrfs_item_ptr_offset(l, i);
printf("\t\titem data %.*s\n", btrfs_item_size(l, item), str);
break;
+ case BTRFS_DEVICE_STATS_KEY:
+ printf("\t\tdevice stats\n");
+ break;
};
fflush(stdout);
}
--
1.7.10.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl
2012-05-16 16:50 [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl Stefan Behrens
` (2 preceding siblings ...)
2012-05-16 16:50 ` [PATCH v3 3/3] Btrfs-progs: add command to get/reset device stats via ioctl Stefan Behrens
@ 2012-05-16 17:03 ` Andrei Popa
2012-05-17 8:44 ` Stefan Behrens
3 siblings, 1 reply; 7+ messages in thread
From: Andrei Popa @ 2012-05-16 17:03 UTC (permalink / raw)
To: Stefan Behrens; +Cc: linux-btrfs
Hi,
It would be nice if this function could show the file names affected by
errors, in case of a single, non-redundant drive, btrfs-progs should
show what files are affected by errors.
Then, an admin could restore only those files from backup.
On Wed, 2012-05-16 at 18:50 +0200, Stefan Behrens wrote:
> "btrfs device stats" is used to retrieve and print the device stats.
> "btrfs device stats -z" is used to atomically retrieve, reset and
> print the stats.
>
> In order to share two utility functions between scrub and the dev stats
> code, these two functions are moved to utils.c and renamed.
> Since these functions are using open_file_or_dir(), and since the linking
> against utils.o and common.o was different, open_file_or_dir() was moved
> from common.c to utils.c. And since that function makes use of the
> function dirfd(3), the required XOPEN version was raised from 6 to 7.
>
> Changes v1->v2:
> - Remove a verbose printf()
> - Cast u64 to unsigned long long for printf()
> - Update the man page
>
> Changes v2->v3:
> - Rebase on Chris' current master branch
> - Split the patch into three seperate patches because after rebasing,
> open_file_or_dir() was moved and additional changes had been necessary
>
> Stefan Behrens (3):
> Btrfs-progs: move open_file_or_dir() to utils.c
> Btrfs-progs: make two utility functions globally available
> Btrfs-progs: add command to get/reset device stats via ioctl
>
> Makefile | 4 +-
> btrfsctl.c | 28 --------------
> cmds-balance.c | 1 +
> cmds-device.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> cmds-inspect.c | 1 +
> cmds-scrub.c | 72 +---------------------------------
> cmds-subvolume.c | 1 +
> commands.h | 3 --
> common.c | 46 ----------------------
> ctree.h | 6 +++
> ioctl.h | 27 +++++++++++++
> man/btrfs.8.in | 14 +++++++
> print-tree.c | 6 +++
> utils.c | 97 +++++++++++++++++++++++++++++++++++++++++++++-
> utils.h | 7 ++++
> 15 files changed, 275 insertions(+), 151 deletions(-)
> delete mode 100644 common.c
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl
2012-05-16 17:03 ` [PATCH v3 0/3] Btrfs-progs: support " Andrei Popa
@ 2012-05-17 8:44 ` Stefan Behrens
2012-05-17 9:18 ` Andrei Popa
0 siblings, 1 reply; 7+ messages in thread
From: Stefan Behrens @ 2012-05-17 8:44 UTC (permalink / raw)
To: ierdnah; +Cc: linux-btrfs
On 05/16/2012 19:03, Andrei Popa wrote:
> It would be nice if this function could show the file names affected by
> errors, in case of a single, non-redundant drive, btrfs-progs should
> show what files are affected by errors.
> Then, an admin could restore only those files from backup.
>
> On Wed, 2012-05-16 at 18:50 +0200, Stefan Behrens wrote:
>> "btrfs device stats" is used to retrieve and print the device stats.
>> "btrfs device stats -z" is used to atomically retrieve, reset and
>> print the stats.
In case of disk errors, it is recommended to run scrub on that disk. It
checks the in-use disk contents for errors, repairs errors where
possible, and the scrub tool does print the paths and filenames of
errored files into the kernel log.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 0/3] Btrfs-progs: support get/reset device stats via ioctl
2012-05-17 8:44 ` Stefan Behrens
@ 2012-05-17 9:18 ` Andrei Popa
0 siblings, 0 replies; 7+ messages in thread
From: Andrei Popa @ 2012-05-17 9:18 UTC (permalink / raw)
To: Stefan Behrens; +Cc: linux-btrfs
On Thu, 2012-05-17 at 10:44 +0200, Stefan Behrens wrote:
> On 05/16/2012 19:03, Andrei Popa wrote:
> > It would be nice if this function could show the file names affected by
> > errors, in case of a single, non-redundant drive, btrfs-progs should
> > show what files are affected by errors.
> > Then, an admin could restore only those files from backup.
> >
> > On Wed, 2012-05-16 at 18:50 +0200, Stefan Behrens wrote:
> >> "btrfs device stats" is used to retrieve and print the device stats.
> >> "btrfs device stats -z" is used to atomically retrieve, reset and
> >> print the stats.
>
>
> In case of disk errors, it is recommended to run scrub on that disk. It
> checks the in-use disk contents for errors, repairs errors where
> possible, and the scrub tool does print the paths and filenames of
> errored files into the kernel log.
In an automated script or for the usual user it would be easier to get
the output from btrfs-progs scrub command with the affected files,
instead from kernel log.
^ permalink raw reply [flat|nested] 7+ messages in thread