From patchwork Tue Sep 28 20:53:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 215912 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8SL0qXd016328 for ; Tue, 28 Sep 2010 21:00:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752929Ab0I1VAu (ORCPT ); Tue, 28 Sep 2010 17:00:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:12914 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752017Ab0I1VAt (ORCPT ); Tue, 28 Sep 2010 17:00:49 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8SL0ntU013265 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 28 Sep 2010 17:00:49 -0400 Received: from localhost.localdomain (test1244.test.redhat.com [10.10.10.244]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8SL0mmM017097 for ; Tue, 28 Sep 2010 17:00:48 -0400 From: Josef Bacik 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 Message-Id: <1285707196-16268-1-git-send-email-josef@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 28 Sep 2010 21:00:52 +0000 (UTC) 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