aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorLi Dongyang <lidongyang@novell.com>2011-03-24 06:24:28 -0400
committerroot <Chris Mason chris.mason@oracle.com>2011-03-28 05:37:47 -0400
commitf7039b1d5c32241f87a513e33120db36bf30264d (patch)
treee911bc79c795fceb3e9a618d8f18571c2a776307 /fs/btrfs/ioctl.c
parent5378e60734f5b7bfe1b43dc191aaf6131c1befe7 (diff)
Btrfs: add btrfs_trim_fs() to handle FITRIM
We take an free extent out from allocator, trim it, then put it back, but before we trim the block group, we should make sure the block group is cached, so plus a little change to make cache_block_group() run without a transaction. Signed-off-by: Li Dongyang <lidongyang@novell.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 32c980ae0f1c..649f47d2afb4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -40,6 +40,7 @@
40#include <linux/xattr.h> 40#include <linux/xattr.h>
41#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/blkdev.h>
43#include "compat.h" 44#include "compat.h"
44#include "ctree.h" 45#include "ctree.h"
45#include "disk-io.h" 46#include "disk-io.h"
@@ -258,6 +259,49 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
258 return put_user(inode->i_generation, arg); 259 return put_user(inode->i_generation, arg);
259} 260}
260 261
262static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
263{
264 struct btrfs_root *root = fdentry(file)->d_sb->s_fs_info;
265 struct btrfs_fs_info *fs_info = root->fs_info;
266 struct btrfs_device *device;
267 struct request_queue *q;
268 struct fstrim_range range;
269 u64 minlen = ULLONG_MAX;
270 u64 num_devices = 0;
271 int ret;
272
273 if (!capable(CAP_SYS_ADMIN))
274 return -EPERM;
275
276 mutex_lock(&fs_info->fs_devices->device_list_mutex);
277 list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
278 if (!device->bdev)
279 continue;
280 q = bdev_get_queue(device->bdev);
281 if (blk_queue_discard(q)) {
282 num_devices++;
283 minlen = min((u64)q->limits.discard_granularity,
284 minlen);
285 }
286 }
287 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
288 if (!num_devices)
289 return -EOPNOTSUPP;
290
291 if (copy_from_user(&range, arg, sizeof(range)))
292 return -EFAULT;
293
294 range.minlen = max(range.minlen, minlen);
295 ret = btrfs_trim_fs(root, &range);
296 if (ret < 0)
297 return ret;
298
299 if (copy_to_user(arg, &range, sizeof(range)))
300 return -EFAULT;
301
302 return 0;
303}
304
261static noinline int create_subvol(struct btrfs_root *root, 305static noinline int create_subvol(struct btrfs_root *root,
262 struct dentry *dentry, 306 struct dentry *dentry,
263 char *name, int namelen, 307 char *name, int namelen,
@@ -2426,6 +2470,8 @@ long btrfs_ioctl(struct file *file, unsigned int
2426 return btrfs_ioctl_setflags(file, argp); 2470 return btrfs_ioctl_setflags(file, argp);
2427 case FS_IOC_GETVERSION: 2471 case FS_IOC_GETVERSION:
2428 return btrfs_ioctl_getversion(file, argp); 2472 return btrfs_ioctl_getversion(file, argp);
2473 case FITRIM:
2474 return btrfs_ioctl_fitrim(file, argp);
2429 case BTRFS_IOC_SNAP_CREATE: 2475 case BTRFS_IOC_SNAP_CREATE:
2430 return btrfs_ioctl_snap_create(file, argp, 0); 2476 return btrfs_ioctl_snap_create(file, argp, 0);
2431 case BTRFS_IOC_SNAP_CREATE_V2: 2477 case BTRFS_IOC_SNAP_CREATE_V2: