aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jfs/file.c5
-rw-r--r--fs/jfs/ioctl.c31
-rw-r--r--fs/jfs/jfs_dinode.h2
-rw-r--r--fs/jfs/jfs_inode.h4
-rw-r--r--fs/jfs/namei.c5
5 files changed, 40 insertions, 7 deletions
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 87eb93694af7..7f6063acaa3b 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -112,5 +112,8 @@ const struct file_operations jfs_file_operations = {
112 .splice_write = generic_file_splice_write, 112 .splice_write = generic_file_splice_write,
113 .fsync = jfs_fsync, 113 .fsync = jfs_fsync,
114 .release = jfs_release, 114 .release = jfs_release,
115 .ioctl = jfs_ioctl, 115 .unlocked_ioctl = jfs_ioctl,
116#ifdef CONFIG_COMPAT
117 .compat_ioctl = jfs_compat_ioctl,
118#endif
116}; 119};
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index dfda12a073e1..a1f8e375ad21 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)
51} 51}
52 52
53 53
54int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, 54long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
55 unsigned long arg)
56{ 55{
56 struct inode *inode = filp->f_dentry->d_inode;
57 struct jfs_inode_info *jfs_inode = JFS_IP(inode); 57 struct jfs_inode_info *jfs_inode = JFS_IP(inode);
58 unsigned int flags; 58 unsigned int flags;
59 59
@@ -82,6 +82,10 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
82 /* Is it quota file? Do not allow user to mess with it */ 82 /* Is it quota file? Do not allow user to mess with it */
83 if (IS_NOQUOTA(inode)) 83 if (IS_NOQUOTA(inode))
84 return -EPERM; 84 return -EPERM;
85
86 /* Lock against other parallel changes of flags */
87 mutex_lock(&inode->i_mutex);
88
85 jfs_get_inode_flags(jfs_inode); 89 jfs_get_inode_flags(jfs_inode);
86 oldflags = jfs_inode->mode2; 90 oldflags = jfs_inode->mode2;
87 91
@@ -92,8 +96,10 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
92 if ((oldflags & JFS_IMMUTABLE_FL) || 96 if ((oldflags & JFS_IMMUTABLE_FL) ||
93 ((flags ^ oldflags) & 97 ((flags ^ oldflags) &
94 (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { 98 (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
95 if (!capable(CAP_LINUX_IMMUTABLE)) 99 if (!capable(CAP_LINUX_IMMUTABLE)) {
100 mutex_unlock(&inode->i_mutex);
96 return -EPERM; 101 return -EPERM;
102 }
97 } 103 }
98 104
99 flags = flags & JFS_FL_USER_MODIFIABLE; 105 flags = flags & JFS_FL_USER_MODIFIABLE;
@@ -101,6 +107,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
101 jfs_inode->mode2 = flags; 107 jfs_inode->mode2 = flags;
102 108
103 jfs_set_inode_flags(inode); 109 jfs_set_inode_flags(inode);
110 mutex_unlock(&inode->i_mutex);
104 inode->i_ctime = CURRENT_TIME_SEC; 111 inode->i_ctime = CURRENT_TIME_SEC;
105 mark_inode_dirty(inode); 112 mark_inode_dirty(inode);
106 return 0; 113 return 0;
@@ -110,3 +117,21 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
110 } 117 }
111} 118}
112 119
120#ifdef CONFIG_COMPAT
121long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
122{
123 /* While these ioctl numbers defined with 'long' and have different
124 * numbers than the 64bit ABI,
125 * the actual implementation only deals with ints and is compatible.
126 */
127 switch (cmd) {
128 case JFS_IOC_GETFLAGS32:
129 cmd = JFS_IOC_GETFLAGS;
130 break;
131 case JFS_IOC_SETFLAGS32:
132 cmd = JFS_IOC_SETFLAGS;
133 break;
134 }
135 return jfs_ioctl(filp, cmd, arg);
136}
137#endif
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index c387540d3425..395c4c0d0f06 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -170,5 +170,7 @@ struct dinode {
170#define JFS_IOC_GETFLAGS _IOR('f', 1, long) 170#define JFS_IOC_GETFLAGS _IOR('f', 1, long)
171#define JFS_IOC_SETFLAGS _IOW('f', 2, long) 171#define JFS_IOC_SETFLAGS _IOW('f', 2, long)
172 172
173#define JFS_IOC_GETFLAGS32 _IOR('f', 1, int)
174#define JFS_IOC_SETFLAGS32 _IOW('f', 2, int)
173 175
174#endif /*_H_JFS_DINODE */ 176#endif /*_H_JFS_DINODE */
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 95a6a11425e5..adb2fafcc544 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -22,8 +22,8 @@ struct fid;
22 22
23extern struct inode *ialloc(struct inode *, umode_t); 23extern struct inode *ialloc(struct inode *, umode_t);
24extern int jfs_fsync(struct file *, struct dentry *, int); 24extern int jfs_fsync(struct file *, struct dentry *, int);
25extern int jfs_ioctl(struct inode *, struct file *, 25extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
26 unsigned int, unsigned long); 26extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
27extern struct inode *jfs_iget(struct super_block *, unsigned long); 27extern struct inode *jfs_iget(struct super_block *, unsigned long);
28extern int jfs_commit_inode(struct inode *, int); 28extern int jfs_commit_inode(struct inode *, int);
29extern int jfs_write_inode(struct inode*, int); 29extern int jfs_write_inode(struct inode*, int);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 403cfc24c6fe..0ba6778edaa2 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1556,7 +1556,10 @@ const struct file_operations jfs_dir_operations = {
1556 .read = generic_read_dir, 1556 .read = generic_read_dir,
1557 .readdir = jfs_readdir, 1557 .readdir = jfs_readdir,
1558 .fsync = jfs_fsync, 1558 .fsync = jfs_fsync,
1559 .ioctl = jfs_ioctl, 1559 .unlocked_ioctl = jfs_ioctl,
1560#ifdef CONFIG_COMPAT
1561 .compat_ioctl = jfs_compat_ioctl,
1562#endif
1560}; 1563};
1561 1564
1562static int jfs_ci_hash(struct dentry *dir, struct qstr *this) 1565static int jfs_ci_hash(struct dentry *dir, struct qstr *this)