linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Josef Bacik <josef@redhat.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH] Btrfs: add a disk info ioctl to get the disks attached to a filesystem
Date: Tue, 28 Sep 2010 16:53:16 -0400	[thread overview]
Message-ID: <1285707196-16268-1-git-send-email-josef@redhat.com> (raw)

This was a request from the systemd guys.  They need a quick and easy way to get
all devices attached to a Btrfs filesystem in order to check if any of the disks
are SSD for...something, I didn't ask :).   I've tested this with the
btrfs-progs patch that accompanies this patch.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
---
 fs/btrfs/ioctl.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    7 ++++++
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 9254b3d..f59b0bc 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1957,6 +1957,68 @@ out:
 	return ret;
 }
 
+static noinline long btrfs_ioctl_disk_info(struct btrfs_root *root,
+					   void __user *arg)
+{
+	struct btrfs_ioctl_disk_info_args di_args;
+	u64 *user_dest;
+	u64 *dest = NULL;
+	struct btrfs_device *device;
+	struct list_head *devices;
+	int alloc_size = 0;
+	int ret = 0;
+
+	if (copy_from_user(&di_args,
+			   (struct btrfs_ioctl_disk_info_args __user *)arg,
+			   sizeof(di_args)))
+		return -EFAULT;
+
+	mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
+	if (!di_args.num_devices) {
+		di_args.num_devices = root->fs_info->fs_devices->num_devices;
+		goto out;
+	}
+	alloc_size = sizeof(u64) * di_args.num_devices;
+
+	di_args.num_devices = 0;
+
+	/*
+	 * If we have more than 4k worth of space to hold a bunch of u64's,
+	 * somebody is misbehaving.
+	 */
+	if (alloc_size > PAGE_CACHE_SIZE) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	dest = kzalloc(alloc_size, GFP_NOFS);
+	if (!dest) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	devices = &root->fs_info->fs_devices->devices;
+
+	list_for_each_entry(device, devices, dev_list) {
+		dest[di_args.num_devices] =
+			huge_encode_dev(device->bdev->bd_dev);
+		di_args.num_devices++;
+	}
+
+	user_dest = (u64 *)
+		(arg + sizeof(struct btrfs_ioctl_disk_info_args));
+
+	if (copy_to_user(user_dest, dest, alloc_size))
+		ret = -EFAULT;
+out:
+	mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+	if (ret == 0 && copy_to_user(arg, &di_args, sizeof(di_args)))
+		ret = -EFAULT;
+	kfree(dest);
+
+	return ret;
+}
+
 /*
  * there are many ways the trans_start and trans_end ioctls can lead
  * to deadlocks.  They should only be used by applications that
@@ -2031,6 +2093,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_ino_lookup(file, argp);
 	case BTRFS_IOC_SPACE_INFO:
 		return btrfs_ioctl_space_info(root, argp);
+	case BTRFS_IOC_DISK_INFO:
+		return btrfs_ioctl_disk_info(root, argp);
 	case BTRFS_IOC_SYNC:
 		btrfs_sync_fs(file->f_dentry->d_sb, 1);
 		return 0;
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 424694a..294e8c3 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -138,6 +138,11 @@ struct btrfs_ioctl_space_args {
 	struct btrfs_ioctl_space_info spaces[0];
 };
 
+struct btrfs_ioctl_disk_info_args {
+	__u32 num_devices;
+	__u64 devices[0];
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -178,4 +183,6 @@ struct btrfs_ioctl_space_args {
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
 				    struct btrfs_ioctl_space_args)
+#define BTRFS_IOC_DISK_INFO _IOWR(BTRFS_IOCTL_MAGIC, 21, \
+				  struct btrfs_ioctl_disk_info_args)
 #endif
-- 
1.6.6.1


             reply	other threads:[~2010-09-28 20:53 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-28 20:53 Josef Bacik [this message]
2010-09-28 22:28 ` [PATCH] Btrfs: add a disk info ioctl to get the disks attached to a filesystem Goffredo Baroncelli
2010-09-29  0:24   ` Josef Bacik
2010-09-28 23:25 ` Christoph Hellwig
2010-09-29  0:08   ` Josef Bacik
2010-09-29  0:19     ` Lennart Poettering
2010-09-29  7:25       ` Ric Wheeler
2010-09-29  8:04         ` Kay Sievers
2010-09-29 23:43           ` Christoph Hellwig
2010-09-30  0:32             ` Josef Bacik
2010-09-30  7:43             ` Kay Sievers
2010-09-30 12:38               ` Josef Bacik
2010-09-30 13:47               ` Andi Kleen
2010-09-30 19:48             ` Josef Bacik
2010-09-30 19:59               ` Kay Sievers
2010-09-30 20:37                 ` Lennart Poettering
2010-09-29 11:59         ` Lennart Poettering
2010-09-29 12:08           ` Ric Wheeler
2010-09-29 12:19   ` Kay Sievers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1285707196-16268-1-git-send-email-josef@redhat.com \
    --to=josef@redhat.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).