nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / fs / ioctl.c
index cc3f1aa..240ec63 100644 (file)
@@ -439,6 +439,43 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp,
        return error;
 }
 
+static int ioctl_fsfreeze(struct file *filp)
+{
+       struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       /* If filesystem doesn't support freeze feature, return. */
+       if (sb->s_op->freeze_fs == NULL)
+               return -EOPNOTSUPP;
+
+       /* If a blockdevice-backed filesystem isn't specified, return. */
+       if (sb->s_bdev == NULL)
+               return -EINVAL;
+
+       /* Freeze */
+       sb = freeze_bdev(sb->s_bdev);
+       if (IS_ERR(sb))
+               return PTR_ERR(sb);
+       return 0;
+}
+
+static int ioctl_fsthaw(struct file *filp)
+{
+       struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */
+       if (sb->s_bdev == NULL)
+               return -EINVAL;
+
+       /* Thaw */
+       return thaw_bdev(sb->s_bdev, sb);
+}
+
 /*
  * When you add any new common ioctls to the switches above and below
  * please update compat_sys_ioctl() too.
@@ -486,6 +523,15 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                } else
                        error = -ENOTTY;
                break;
+
+       case FIFREEZE:
+               error = ioctl_fsfreeze(filp);
+               break;
+
+       case FITHAW:
+               error = ioctl_fsthaw(filp);
+               break;
+
        default:
                if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
                        error = file_ioctl(filp, cmd, arg);
@@ -496,7 +542,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
        return error;
 }
 
-asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
 {
        struct file *filp;
        int error = -EBADF;