diff options
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r-- | fs/ioctl.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index cc3f1aa1cf7b..20b0a8a24c6b 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -439,6 +439,43 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp, | |||
439 | return error; | 439 | return error; |
440 | } | 440 | } |
441 | 441 | ||
442 | static int ioctl_fsfreeze(struct file *filp) | ||
443 | { | ||
444 | struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; | ||
445 | |||
446 | if (!capable(CAP_SYS_ADMIN)) | ||
447 | return -EPERM; | ||
448 | |||
449 | /* If filesystem doesn't support freeze feature, return. */ | ||
450 | if (sb->s_op->freeze_fs == NULL) | ||
451 | return -EOPNOTSUPP; | ||
452 | |||
453 | /* If a blockdevice-backed filesystem isn't specified, return. */ | ||
454 | if (sb->s_bdev == NULL) | ||
455 | return -EINVAL; | ||
456 | |||
457 | /* Freeze */ | ||
458 | sb = freeze_bdev(sb->s_bdev); | ||
459 | if (IS_ERR(sb)) | ||
460 | return PTR_ERR(sb); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int ioctl_fsthaw(struct file *filp) | ||
465 | { | ||
466 | struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; | ||
467 | |||
468 | if (!capable(CAP_SYS_ADMIN)) | ||
469 | return -EPERM; | ||
470 | |||
471 | /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */ | ||
472 | if (sb->s_bdev == NULL) | ||
473 | return -EINVAL; | ||
474 | |||
475 | /* Thaw */ | ||
476 | return thaw_bdev(sb->s_bdev, sb); | ||
477 | } | ||
478 | |||
442 | /* | 479 | /* |
443 | * When you add any new common ioctls to the switches above and below | 480 | * When you add any new common ioctls to the switches above and below |
444 | * please update compat_sys_ioctl() too. | 481 | * please update compat_sys_ioctl() too. |
@@ -486,6 +523,15 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, | |||
486 | } else | 523 | } else |
487 | error = -ENOTTY; | 524 | error = -ENOTTY; |
488 | break; | 525 | break; |
526 | |||
527 | case FIFREEZE: | ||
528 | error = ioctl_fsfreeze(filp); | ||
529 | break; | ||
530 | |||
531 | case FITHAW: | ||
532 | error = ioctl_fsthaw(filp); | ||
533 | break; | ||
534 | |||
489 | default: | 535 | default: |
490 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | 536 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) |
491 | error = file_ioctl(filp, cmd, arg); | 537 | error = file_ioctl(filp, cmd, arg); |