diff options
author | Christoph Hellwig <hch@lst.de> | 2010-09-30 23:41:35 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2010-09-30 23:41:35 -0400 |
commit | 6333816ade7e04a96ec0a34a8378c455e4f7c4dd (patch) | |
tree | bd6f3fc3d929b44cffea4319f6bda828b6704269 /fs/hfsplus/ioctl.c | |
parent | 94744567fef9602c3d8218a1d8f58c04cce354f6 (diff) |
hfsplus: protect setflags using i_mutex
Use i_mutex for protecting against concurrent setflags ioctls like in
other filesystems and get rid of the BKL in hfsplus_ioctl.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs/hfsplus/ioctl.c')
-rw-r--r-- | fs/hfsplus/ioctl.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 0e359c3b55ee..906bd3dd3145 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/mount.h> | 17 | #include <linux/mount.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/xattr.h> | 19 | #include <linux/xattr.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
22 | #include "hfsplus_fs.h" | 21 | #include "hfsplus_fs.h" |
23 | 22 | ||
@@ -42,10 +41,9 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) | |||
42 | unsigned int flags; | 41 | unsigned int flags; |
43 | int err = 0; | 42 | int err = 0; |
44 | 43 | ||
45 | lock_kernel(); | ||
46 | err = mnt_want_write(file->f_path.mnt); | 44 | err = mnt_want_write(file->f_path.mnt); |
47 | if (err) | 45 | if (err) |
48 | goto out_unlock_kernel; | 46 | goto out; |
49 | 47 | ||
50 | if (!is_owner_or_cap(inode)) { | 48 | if (!is_owner_or_cap(inode)) { |
51 | err = -EACCES; | 49 | err = -EACCES; |
@@ -57,18 +55,20 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) | |||
57 | goto out_drop_write; | 55 | goto out_drop_write; |
58 | } | 56 | } |
59 | 57 | ||
58 | mutex_lock(&inode->i_mutex); | ||
59 | |||
60 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || | 60 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || |
61 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { | 61 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { |
62 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 62 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
63 | err = -EPERM; | 63 | err = -EPERM; |
64 | goto out_drop_write; | 64 | goto out_unlock_inode; |
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | /* don't silently ignore unsupported ext2 flags */ | 68 | /* don't silently ignore unsupported ext2 flags */ |
69 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { | 69 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { |
70 | err = -EOPNOTSUPP; | 70 | err = -EOPNOTSUPP; |
71 | goto out_drop_write; | 71 | goto out_unlock_inode; |
72 | } | 72 | } |
73 | if (flags & FS_IMMUTABLE_FL) { | 73 | if (flags & FS_IMMUTABLE_FL) { |
74 | inode->i_flags |= S_IMMUTABLE; | 74 | inode->i_flags |= S_IMMUTABLE; |
@@ -92,10 +92,11 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) | |||
92 | inode->i_ctime = CURRENT_TIME_SEC; | 92 | inode->i_ctime = CURRENT_TIME_SEC; |
93 | mark_inode_dirty(inode); | 93 | mark_inode_dirty(inode); |
94 | 94 | ||
95 | out_unlock_inode: | ||
96 | mutex_lock(&inode->i_mutex); | ||
95 | out_drop_write: | 97 | out_drop_write: |
96 | mnt_drop_write(file->f_path.mnt); | 98 | mnt_drop_write(file->f_path.mnt); |
97 | out_unlock_kernel: | 99 | out: |
98 | unlock_kernel(); | ||
99 | return err; | 100 | return err; |
100 | } | 101 | } |
101 | 102 | ||