diff options
Diffstat (limited to 'fs/gfs2/ops_file.c')
-rw-r--r-- | fs/gfs2/ops_file.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 24dd59450088..e9a366d4411c 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/uio.h> | 15 | #include <linux/uio.h> |
16 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/mount.h> | ||
18 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
19 | #include <linux/gfs2_ondisk.h> | 20 | #include <linux/gfs2_ondisk.h> |
20 | #include <linux/ext2_fs.h> | 21 | #include <linux/ext2_fs.h> |
@@ -133,7 +134,6 @@ static const u32 fsflags_to_gfs2[32] = { | |||
133 | [7] = GFS2_DIF_NOATIME, | 134 | [7] = GFS2_DIF_NOATIME, |
134 | [12] = GFS2_DIF_EXHASH, | 135 | [12] = GFS2_DIF_EXHASH, |
135 | [14] = GFS2_DIF_INHERIT_JDATA, | 136 | [14] = GFS2_DIF_INHERIT_JDATA, |
136 | [20] = GFS2_DIF_INHERIT_DIRECTIO, | ||
137 | }; | 137 | }; |
138 | 138 | ||
139 | static const u32 gfs2_to_fsflags[32] = { | 139 | static const u32 gfs2_to_fsflags[32] = { |
@@ -142,7 +142,6 @@ static const u32 gfs2_to_fsflags[32] = { | |||
142 | [gfs2fl_AppendOnly] = FS_APPEND_FL, | 142 | [gfs2fl_AppendOnly] = FS_APPEND_FL, |
143 | [gfs2fl_NoAtime] = FS_NOATIME_FL, | 143 | [gfs2fl_NoAtime] = FS_NOATIME_FL, |
144 | [gfs2fl_ExHash] = FS_INDEX_FL, | 144 | [gfs2fl_ExHash] = FS_INDEX_FL, |
145 | [gfs2fl_InheritDirectio] = FS_DIRECTIO_FL, | ||
146 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, | 145 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, |
147 | }; | 146 | }; |
148 | 147 | ||
@@ -160,12 +159,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
160 | return error; | 159 | return error; |
161 | 160 | ||
162 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); | 161 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); |
163 | if (!S_ISDIR(inode->i_mode)) { | 162 | if (!S_ISDIR(inode->i_mode) && ip->i_di.di_flags & GFS2_DIF_JDATA) |
164 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | 163 | fsflags |= FS_JOURNAL_DATA_FL; |
165 | fsflags |= FS_JOURNAL_DATA_FL; | ||
166 | if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) | ||
167 | fsflags |= FS_DIRECTIO_FL; | ||
168 | } | ||
169 | if (put_user(fsflags, ptr)) | 164 | if (put_user(fsflags, ptr)) |
170 | error = -EFAULT; | 165 | error = -EFAULT; |
171 | 166 | ||
@@ -194,13 +189,11 @@ void gfs2_set_inode_flags(struct inode *inode) | |||
194 | 189 | ||
195 | /* Flags that can be set by user space */ | 190 | /* Flags that can be set by user space */ |
196 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 191 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
197 | GFS2_DIF_DIRECTIO| \ | ||
198 | GFS2_DIF_IMMUTABLE| \ | 192 | GFS2_DIF_IMMUTABLE| \ |
199 | GFS2_DIF_APPENDONLY| \ | 193 | GFS2_DIF_APPENDONLY| \ |
200 | GFS2_DIF_NOATIME| \ | 194 | GFS2_DIF_NOATIME| \ |
201 | GFS2_DIF_SYNC| \ | 195 | GFS2_DIF_SYNC| \ |
202 | GFS2_DIF_SYSTEM| \ | 196 | GFS2_DIF_SYSTEM| \ |
203 | GFS2_DIF_INHERIT_DIRECTIO| \ | ||
204 | GFS2_DIF_INHERIT_JDATA) | 197 | GFS2_DIF_INHERIT_JDATA) |
205 | 198 | ||
206 | /** | 199 | /** |
@@ -220,10 +213,14 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
220 | int error; | 213 | int error; |
221 | u32 new_flags, flags; | 214 | u32 new_flags, flags; |
222 | 215 | ||
223 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 216 | error = mnt_want_write(filp->f_path.mnt); |
224 | if (error) | 217 | if (error) |
225 | return error; | 218 | return error; |
226 | 219 | ||
220 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
221 | if (error) | ||
222 | goto out_drop_write; | ||
223 | |||
227 | flags = ip->i_di.di_flags; | 224 | flags = ip->i_di.di_flags; |
228 | new_flags = (flags & ~mask) | (reqflags & mask); | 225 | new_flags = (flags & ~mask) | (reqflags & mask); |
229 | if ((new_flags ^ flags) == 0) | 226 | if ((new_flags ^ flags) == 0) |
@@ -242,7 +239,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
242 | !capable(CAP_LINUX_IMMUTABLE)) | 239 | !capable(CAP_LINUX_IMMUTABLE)) |
243 | goto out; | 240 | goto out; |
244 | if (!IS_IMMUTABLE(inode)) { | 241 | if (!IS_IMMUTABLE(inode)) { |
245 | error = permission(inode, MAY_WRITE, NULL); | 242 | error = gfs2_permission(inode, MAY_WRITE); |
246 | if (error) | 243 | if (error) |
247 | goto out; | 244 | goto out; |
248 | } | 245 | } |
@@ -272,6 +269,8 @@ out_trans_end: | |||
272 | gfs2_trans_end(sdp); | 269 | gfs2_trans_end(sdp); |
273 | out: | 270 | out: |
274 | gfs2_glock_dq_uninit(&gh); | 271 | gfs2_glock_dq_uninit(&gh); |
272 | out_drop_write: | ||
273 | mnt_drop_write(filp->f_path.mnt); | ||
275 | return error; | 274 | return error; |
276 | } | 275 | } |
277 | 276 | ||
@@ -285,8 +284,6 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | |||
285 | if (!S_ISDIR(inode->i_mode)) { | 284 | if (!S_ISDIR(inode->i_mode)) { |
286 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | 285 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) |
287 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | 286 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); |
288 | if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO) | ||
289 | gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO); | ||
290 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 287 | return do_gfs2_set_flags(filp, gfsflags, ~0); |
291 | } | 288 | } |
292 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); | 289 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); |
@@ -487,11 +484,6 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
487 | goto fail_gunlock; | 484 | goto fail_gunlock; |
488 | } | 485 | } |
489 | 486 | ||
490 | /* Listen to the Direct I/O flag */ | ||
491 | |||
492 | if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) | ||
493 | file->f_flags |= O_DIRECT; | ||
494 | |||
495 | gfs2_glock_dq_uninit(&i_gh); | 487 | gfs2_glock_dq_uninit(&i_gh); |
496 | } | 488 | } |
497 | 489 | ||
@@ -669,8 +661,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
669 | int error = 0; | 661 | int error = 0; |
670 | 662 | ||
671 | state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; | 663 | state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; |
672 | flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE | 664 | flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; |
673 | | GL_FLOCK; | ||
674 | 665 | ||
675 | mutex_lock(&fp->f_fl_mutex); | 666 | mutex_lock(&fp->f_fl_mutex); |
676 | 667 | ||
@@ -683,9 +674,8 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
683 | gfs2_glock_dq_wait(fl_gh); | 674 | gfs2_glock_dq_wait(fl_gh); |
684 | gfs2_holder_reinit(state, flags, fl_gh); | 675 | gfs2_holder_reinit(state, flags, fl_gh); |
685 | } else { | 676 | } else { |
686 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), | 677 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), ip->i_no_addr, |
687 | ip->i_no_addr, &gfs2_flock_glops, | 678 | &gfs2_flock_glops, CREATE, &gl); |
688 | CREATE, &gl); | ||
689 | if (error) | 679 | if (error) |
690 | goto out; | 680 | goto out; |
691 | gfs2_holder_init(gl, state, flags, fl_gh); | 681 | gfs2_holder_init(gl, state, flags, fl_gh); |