diff options
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r-- | fs/ioctl.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index 286f38dfc6c0..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 | */ | ||
414 | int 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 | |||
408 | static int file_ioctl(struct file *filp, unsigned int cmd, | 438 | static int file_ioctl(struct file *filp, unsigned int cmd, |
409 | unsigned long arg) | 439 | unsigned long arg) |
410 | { | 440 | { |
@@ -416,6 +446,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd, | |||
416 | return ioctl_fibmap(filp, p); | 446 | return ioctl_fibmap(filp, p); |
417 | case FIONREAD: | 447 | case FIONREAD: |
418 | 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); | ||
419 | } | 452 | } |
420 | 453 | ||
421 | return vfs_ioctl(filp, cmd, arg); | 454 | return vfs_ioctl(filp, cmd, arg); |