Merge tag 'for-linus-merge-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / fs / jfs / ioctl.c
index f19d1e0..bc555ff 100644 (file)
 #include <linux/mount.h>
 #include <linux/time.h>
 #include <linux/sched.h>
+#include <linux/blkdev.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 
+#include "jfs_filsys.h"
+#include "jfs_debug.h"
 #include "jfs_incore.h"
 #include "jfs_dinode.h"
 #include "jfs_inode.h"
-
+#include "jfs_dmap.h"
+#include "jfs_discard.h"
 
 static struct {
        long jfs_flag;
@@ -123,6 +127,40 @@ setflags_out:
                mnt_drop_write_file(filp);
                return err;
        }
+
+       case FITRIM:
+       {
+               struct super_block *sb = inode->i_sb;
+               struct request_queue *q = bdev_get_queue(sb->s_bdev);
+               struct fstrim_range range;
+               s64 ret = 0;
+
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               if (!blk_queue_discard(q)) {
+                       jfs_warn("FITRIM not supported on device");
+                       return -EOPNOTSUPP;
+               }
+
+               if (copy_from_user(&range, (struct fstrim_range __user *)arg,
+                   sizeof(range)))
+                       return -EFAULT;
+
+               range.minlen = max_t(unsigned int, range.minlen,
+                       q->limits.discard_granularity);
+
+               ret = jfs_ioc_trim(inode, &range);
+               if (ret < 0)
+                       return ret;
+
+               if (copy_to_user((struct fstrim_range __user *)arg, &range,
+                   sizeof(range)))
+                       return -EFAULT;
+
+               return 0;
+       }
+
        default:
                return -ENOTTY;
        }
@@ -142,6 +180,9 @@ long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case JFS_IOC_SETFLAGS32:
                cmd = JFS_IOC_SETFLAGS;
                break;
+       case FITRIM:
+               cmd = FITRIM;
+               break;
        }
        return jfs_ioctl(filp, cmd, arg);
 }