|
@@ -15,12 +15,11 @@
|
|
#include <linux/mount.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/time.h>
|
|
#include <linux/time.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/compat.h>
|
|
-#include <linux/smp_lock.h>
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
|
|
-int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
|
|
|
|
- unsigned long arg)
|
|
|
|
|
|
+long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
{
|
|
|
|
+ struct inode *inode = filp->f_dentry->d_inode;
|
|
struct ext3_inode_info *ei = EXT3_I(inode);
|
|
struct ext3_inode_info *ei = EXT3_I(inode);
|
|
unsigned int flags;
|
|
unsigned int flags;
|
|
unsigned short rsv_window_size;
|
|
unsigned short rsv_window_size;
|
|
@@ -39,29 +38,25 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
|
|
unsigned int oldflags;
|
|
unsigned int oldflags;
|
|
unsigned int jflag;
|
|
unsigned int jflag;
|
|
|
|
|
|
|
|
+ if (!is_owner_or_cap(inode))
|
|
|
|
+ return -EACCES;
|
|
|
|
+
|
|
|
|
+ if (get_user(flags, (int __user *) arg))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
err = mnt_want_write(filp->f_path.mnt);
|
|
err = mnt_want_write(filp->f_path.mnt);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
- if (!is_owner_or_cap(inode)) {
|
|
|
|
- err = -EACCES;
|
|
|
|
- goto flags_out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (get_user(flags, (int __user *) arg)) {
|
|
|
|
- err = -EFAULT;
|
|
|
|
- goto flags_out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
flags = ext3_mask_flags(inode->i_mode, flags);
|
|
flags = ext3_mask_flags(inode->i_mode, flags);
|
|
|
|
|
|
mutex_lock(&inode->i_mutex);
|
|
mutex_lock(&inode->i_mutex);
|
|
|
|
+
|
|
/* Is it quota file? Do not allow user to mess with it */
|
|
/* Is it quota file? Do not allow user to mess with it */
|
|
- if (IS_NOQUOTA(inode)) {
|
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
- err = -EPERM;
|
|
|
|
|
|
+ err = -EPERM;
|
|
|
|
+ if (IS_NOQUOTA(inode))
|
|
goto flags_out;
|
|
goto flags_out;
|
|
- }
|
|
|
|
|
|
+
|
|
oldflags = ei->i_flags;
|
|
oldflags = ei->i_flags;
|
|
|
|
|
|
/* The JOURNAL_DATA flag is modifiable only by root */
|
|
/* The JOURNAL_DATA flag is modifiable only by root */
|
|
@@ -74,11 +69,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
|
|
* This test looks nicer. Thanks to Pauline Middelink
|
|
* This test looks nicer. Thanks to Pauline Middelink
|
|
*/
|
|
*/
|
|
if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
|
|
if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
|
|
- if (!capable(CAP_LINUX_IMMUTABLE)) {
|
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
- err = -EPERM;
|
|
|
|
|
|
+ if (!capable(CAP_LINUX_IMMUTABLE))
|
|
goto flags_out;
|
|
goto flags_out;
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -86,17 +78,12 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
|
|
* the relevant capability.
|
|
* the relevant capability.
|
|
*/
|
|
*/
|
|
if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
|
|
if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
|
|
- if (!capable(CAP_SYS_RESOURCE)) {
|
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
- err = -EPERM;
|
|
|
|
|
|
+ if (!capable(CAP_SYS_RESOURCE))
|
|
goto flags_out;
|
|
goto flags_out;
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
handle = ext3_journal_start(inode, 1);
|
|
handle = ext3_journal_start(inode, 1);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
err = PTR_ERR(handle);
|
|
err = PTR_ERR(handle);
|
|
goto flags_out;
|
|
goto flags_out;
|
|
}
|
|
}
|
|
@@ -116,15 +103,13 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
|
|
err = ext3_mark_iloc_dirty(handle, inode, &iloc);
|
|
err = ext3_mark_iloc_dirty(handle, inode, &iloc);
|
|
flags_err:
|
|
flags_err:
|
|
ext3_journal_stop(handle);
|
|
ext3_journal_stop(handle);
|
|
- if (err) {
|
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
- return err;
|
|
|
|
- }
|
|
|
|
|
|
+ if (err)
|
|
|
|
+ goto flags_out;
|
|
|
|
|
|
if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
|
|
if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
|
|
err = ext3_change_inode_journal_flag(inode, jflag);
|
|
err = ext3_change_inode_journal_flag(inode, jflag);
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
|
flags_out:
|
|
flags_out:
|
|
|
|
+ mutex_unlock(&inode->i_mutex);
|
|
mnt_drop_write(filp->f_path.mnt);
|
|
mnt_drop_write(filp->f_path.mnt);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
@@ -140,6 +125,7 @@ flags_out:
|
|
|
|
|
|
if (!is_owner_or_cap(inode))
|
|
if (!is_owner_or_cap(inode))
|
|
return -EPERM;
|
|
return -EPERM;
|
|
|
|
+
|
|
err = mnt_want_write(filp->f_path.mnt);
|
|
err = mnt_want_write(filp->f_path.mnt);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
@@ -147,6 +133,7 @@ flags_out:
|
|
err = -EFAULT;
|
|
err = -EFAULT;
|
|
goto setversion_out;
|
|
goto setversion_out;
|
|
}
|
|
}
|
|
|
|
+
|
|
handle = ext3_journal_start(inode, 1);
|
|
handle = ext3_journal_start(inode, 1);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
err = PTR_ERR(handle);
|
|
err = PTR_ERR(handle);
|
|
@@ -299,9 +286,6 @@ group_add_out:
|
|
#ifdef CONFIG_COMPAT
|
|
#ifdef CONFIG_COMPAT
|
|
long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
{
|
|
{
|
|
- struct inode *inode = file->f_path.dentry->d_inode;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
/* These are just misnamed, they actually get/put from/to user an int */
|
|
/* These are just misnamed, they actually get/put from/to user an int */
|
|
switch (cmd) {
|
|
switch (cmd) {
|
|
case EXT3_IOC32_GETFLAGS:
|
|
case EXT3_IOC32_GETFLAGS:
|
|
@@ -341,9 +325,6 @@ long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
default:
|
|
default:
|
|
return -ENOIOCTLCMD;
|
|
return -ENOIOCTLCMD;
|
|
}
|
|
}
|
|
- lock_kernel();
|
|
|
|
- ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
|
|
|
|
- unlock_kernel();
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return ext3_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|