aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r--fs/ioctl.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 82d9c42b8bac..5612880fcbe7 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -15,6 +15,7 @@
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/writeback.h> 16#include <linux/writeback.h>
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/falloc.h>
18 19
19#include <asm/ioctls.h> 20#include <asm/ioctls.h>
20 21
@@ -70,9 +71,7 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
70 res = get_user(block, p); 71 res = get_user(block, p);
71 if (res) 72 if (res)
72 return res; 73 return res;
73 lock_kernel();
74 res = mapping->a_ops->bmap(mapping, block); 74 res = mapping->a_ops->bmap(mapping, block);
75 unlock_kernel();
76 return put_user(res, p); 75 return put_user(res, p);
77} 76}
78 77
@@ -405,6 +404,37 @@ EXPORT_SYMBOL(generic_block_fiemap);
405 404
406#endif /* CONFIG_BLOCK */ 405#endif /* CONFIG_BLOCK */
407 406
407/*
408 * This provides compatibility with legacy XFS pre-allocation ioctls
409 * which predate the fallocate syscall.
410 *
411 * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
412 * are used here, rest are ignored.
413 */
414int ioctl_preallocate(struct file *filp, void __user *argp)
415{
416 struct inode *inode = filp->f_path.dentry->d_inode;
417 struct space_resv sr;
418
419 if (copy_from_user(&sr, argp, sizeof(sr)))
420 return -EFAULT;
421
422 switch (sr.l_whence) {
423 case SEEK_SET:
424 break;
425 case SEEK_CUR:
426 sr.l_start += filp->f_pos;
427 break;
428 case SEEK_END:
429 sr.l_start += i_size_read(inode);
430 break;
431 default:
432 return -EINVAL;
433 }
434
435 return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
436}
437
408static int file_ioctl(struct file *filp, unsigned int cmd, 438static int file_ioctl(struct file *filp, unsigned int cmd,
409 unsigned long arg) 439 unsigned long arg)
410{ 440{
@@ -414,12 +444,11 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
414 switch (cmd) { 444 switch (cmd) {
415 case FIBMAP: 445 case FIBMAP:
416 return ioctl_fibmap(filp, p); 446 return ioctl_fibmap(filp, p);
417 case FS_IOC_FIEMAP:
418 return ioctl_fiemap(filp, arg);
419 case FIGETBSZ:
420 return put_user(inode->i_sb->s_blocksize, p);
421 case FIONREAD: 447 case FIONREAD:
422 return put_user(i_size_read(inode) - filp->f_pos, p); 448 return put_user(i_size_read(inode) - filp->f_pos, p);
449 case FS_IOC_RESVSP:
450 case FS_IOC_RESVSP64:
451 return ioctl_preallocate(filp, p);
423 } 452 }
424 453
425 return vfs_ioctl(filp, cmd, arg); 454 return vfs_ioctl(filp, cmd, arg);
@@ -557,6 +586,16 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
557 error = ioctl_fsthaw(filp); 586 error = ioctl_fsthaw(filp);
558 break; 587 break;
559 588
589 case FS_IOC_FIEMAP:
590 return ioctl_fiemap(filp, arg);
591
592 case FIGETBSZ:
593 {
594 struct inode *inode = filp->f_path.dentry->d_inode;
595 int __user *p = (int __user *)arg;
596 return put_user(inode->i_sb->s_blocksize, p);
597 }
598
560 default: 599 default:
561 if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) 600 if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
562 error = file_ioctl(filp, cmd, arg); 601 error = file_ioctl(filp, cmd, arg);