diff options
Diffstat (limited to 'fs/jfs/ioctl.c')
-rw-r--r-- | fs/jfs/ioctl.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index dfda12a073e..fc82eccf408 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c @@ -51,9 +51,9 @@ static long jfs_map_ext2(unsigned long flags, int from) } -int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, - unsigned long arg) +long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + struct inode *inode = filp->f_dentry->d_inode; struct jfs_inode_info *jfs_inode = JFS_IP(inode); unsigned int flags; @@ -82,6 +82,10 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, /* Is it quota file? Do not allow user to mess with it */ if (IS_NOQUOTA(inode)) return -EPERM; + + /* Lock against other parallel changes of flags */ + mutex_lock(&inode->i_mutex); + jfs_get_inode_flags(jfs_inode); oldflags = jfs_inode->mode2; @@ -92,8 +96,10 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, if ((oldflags & JFS_IMMUTABLE_FL) || ((flags ^ oldflags) & (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { - if (!capable(CAP_LINUX_IMMUTABLE)) + if (!capable(CAP_LINUX_IMMUTABLE)) { + mutex_unlock(&inode->i_mutex); return -EPERM; + } } flags = flags & JFS_FL_USER_MODIFIABLE; @@ -101,6 +107,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, jfs_inode->mode2 = flags; jfs_set_inode_flags(inode); + mutex_unlock(&inode->i_mutex); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); return 0; |