Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / fs / ioctl.c
index a59635e..29167be 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/security.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>
@@ -42,7 +42,7 @@ static long vfs_ioctl(struct file *filp, unsigned int cmd,
 
        error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
        if (error == -ENOIOCTLCMD)
-               error = -EINVAL;
+               error = -ENOTTY;
  out:
        return error;
 }
@@ -273,6 +273,13 @@ int __generic_block_fiemap(struct inode *inode,
                len = isize;
        }
 
+       /*
+        * Some filesystems can't deal with being asked to map less than
+        * blocksize, so make sure our len is at least block length.
+        */
+       if (logical_to_blk(inode, len) == 0)
+               len = blk_to_logical(inode, 1);
+
        start_blk = logical_to_blk(inode, start);
        last_blk = logical_to_blk(inode, start + len - 1);
 
@@ -541,6 +548,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 {
        int error = 0;
        int __user *argp = (int __user *)arg;
+       struct inode *inode = filp->f_path.dentry->d_inode;
 
        switch (cmd) {
        case FIOCLEX:
@@ -560,13 +568,11 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                break;
 
        case FIOQSIZE:
-               if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
-                   S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
-                   S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
-                       loff_t res =
-                               inode_get_bytes(filp->f_path.dentry->d_inode);
-                       error = copy_to_user((loff_t __user *)arg, &res,
-                                            sizeof(res)) ? -EFAULT : 0;
+               if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
+                   S_ISLNK(inode->i_mode)) {
+                       loff_t res = inode_get_bytes(inode);
+                       error = copy_to_user(argp, &res, sizeof(res)) ?
+                                       -EFAULT : 0;
                } else
                        error = -ENOTTY;
                break;
@@ -583,14 +589,10 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                return ioctl_fiemap(filp, arg);
 
        case FIGETBSZ:
-       {
-               struct inode *inode = filp->f_path.dentry->d_inode;
-               int __user *p = (int __user *)arg;
-               return put_user(inode->i_sb->s_blocksize, p);
-       }
+               return put_user(inode->i_sb->s_blocksize, argp);
 
        default:
-               if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
+               if (S_ISREG(inode->i_mode))
                        error = file_ioctl(filp, cmd, arg);
                else
                        error = vfs_ioctl(filp, cmd, arg);