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); |
