diff options
Diffstat (limited to 'fs/gfs2/ops_file.c')
| -rw-r--r-- | fs/gfs2/ops_file.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 3064f133bf3c..b3f1e0349ae0 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/ext2_fs.h> | 22 | #include <linux/ext2_fs.h> |
| 23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
| 24 | #include <linux/lm_interface.h> | 24 | #include <linux/lm_interface.h> |
| 25 | #include <linux/writeback.h> | ||
| 25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
| 26 | 27 | ||
| 27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
| @@ -71,7 +72,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, | |||
| 71 | size = count; | 72 | size = count; |
| 72 | 73 | ||
| 73 | kaddr = kmap(page); | 74 | kaddr = kmap(page); |
| 74 | memcpy(desc->arg.buf, kaddr + offset, size); | 75 | memcpy(desc->arg.data, kaddr + offset, size); |
| 75 | kunmap(page); | 76 | kunmap(page); |
| 76 | 77 | ||
| 77 | desc->count = count - size; | 78 | desc->count = count - size; |
| @@ -86,7 +87,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, | |||
| 86 | struct inode *inode = &ip->i_inode; | 87 | struct inode *inode = &ip->i_inode; |
| 87 | read_descriptor_t desc; | 88 | read_descriptor_t desc; |
| 88 | desc.written = 0; | 89 | desc.written = 0; |
| 89 | desc.arg.buf = buf; | 90 | desc.arg.data = buf; |
| 90 | desc.count = size; | 91 | desc.count = size; |
| 91 | desc.error = 0; | 92 | desc.error = 0; |
| 92 | do_generic_mapping_read(inode->i_mapping, ra_state, | 93 | do_generic_mapping_read(inode->i_mapping, ra_state, |
| @@ -139,7 +140,7 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) | |||
| 139 | */ | 140 | */ |
| 140 | 141 | ||
| 141 | static int filldir_func(void *opaque, const char *name, unsigned int length, | 142 | static int filldir_func(void *opaque, const char *name, unsigned int length, |
| 142 | u64 offset, struct gfs2_inum *inum, | 143 | u64 offset, struct gfs2_inum_host *inum, |
| 143 | unsigned int type) | 144 | unsigned int type) |
| 144 | { | 145 | { |
| 145 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; | 146 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; |
| @@ -253,7 +254,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
| 253 | u32 fsflags; | 254 | u32 fsflags; |
| 254 | 255 | ||
| 255 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 256 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
| 256 | error = gfs2_glock_nq_m_atime(1, &gh); | 257 | error = gfs2_glock_nq_atime(&gh); |
| 257 | if (error) | 258 | if (error) |
| 258 | return error; | 259 | return error; |
| 259 | 260 | ||
| @@ -266,6 +267,24 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
| 266 | return error; | 267 | return error; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 270 | void gfs2_set_inode_flags(struct inode *inode) | ||
| 271 | { | ||
| 272 | struct gfs2_inode *ip = GFS2_I(inode); | ||
| 273 | struct gfs2_dinode_host *di = &ip->i_di; | ||
| 274 | unsigned int flags = inode->i_flags; | ||
| 275 | |||
| 276 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
| 277 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
| 278 | flags |= S_IMMUTABLE; | ||
| 279 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
| 280 | flags |= S_APPEND; | ||
| 281 | if (di->di_flags & GFS2_DIF_NOATIME) | ||
| 282 | flags |= S_NOATIME; | ||
| 283 | if (di->di_flags & GFS2_DIF_SYNC) | ||
| 284 | flags |= S_SYNC; | ||
| 285 | inode->i_flags = flags; | ||
| 286 | } | ||
| 287 | |||
| 269 | /* Flags that can be set by user space */ | 288 | /* Flags that can be set by user space */ |
| 270 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 289 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
| 271 | GFS2_DIF_DIRECTIO| \ | 290 | GFS2_DIF_DIRECTIO| \ |
| @@ -336,8 +355,9 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
| 336 | goto out_trans_end; | 355 | goto out_trans_end; |
| 337 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 356 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
| 338 | ip->i_di.di_flags = new_flags; | 357 | ip->i_di.di_flags = new_flags; |
| 339 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 358 | gfs2_dinode_out(ip, bh->b_data); |
| 340 | brelse(bh); | 359 | brelse(bh); |
| 360 | gfs2_set_inode_flags(inode); | ||
| 341 | out_trans_end: | 361 | out_trans_end: |
| 342 | gfs2_trans_end(sdp); | 362 | gfs2_trans_end(sdp); |
| 343 | out: | 363 | out: |
| @@ -425,7 +445,7 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
| 425 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 445 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
| 426 | file->private_data = fp; | 446 | file->private_data = fp; |
| 427 | 447 | ||
| 428 | if (S_ISREG(ip->i_di.di_mode)) { | 448 | if (S_ISREG(ip->i_inode.i_mode)) { |
| 429 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 449 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
| 430 | &i_gh); | 450 | &i_gh); |
| 431 | if (error) | 451 | if (error) |
| @@ -484,16 +504,40 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
| 484 | * @file: the file that points to the dentry (we ignore this) | 504 | * @file: the file that points to the dentry (we ignore this) |
| 485 | * @dentry: the dentry that points to the inode to sync | 505 | * @dentry: the dentry that points to the inode to sync |
| 486 | * | 506 | * |
| 507 | * The VFS will flush "normal" data for us. We only need to worry | ||
| 508 | * about metadata here. For journaled data, we just do a log flush | ||
| 509 | * as we can't avoid it. Otherwise we can just bale out if datasync | ||
| 510 | * is set. For stuffed inodes we must flush the log in order to | ||
| 511 | * ensure that all data is on disk. | ||
| 512 | * | ||
| 513 | * The call to write_inode_now() is there to write back metadata and | ||
| 514 | * the inode itself. It does also try and write the data, but thats | ||
| 515 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | ||
| 516 | * for us. | ||
| 517 | * | ||
| 487 | * Returns: errno | 518 | * Returns: errno |
| 488 | */ | 519 | */ |
| 489 | 520 | ||
| 490 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 521 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
| 491 | { | 522 | { |
| 492 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 523 | struct inode *inode = dentry->d_inode; |
| 524 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | ||
| 525 | int ret = 0; | ||
| 493 | 526 | ||
| 494 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 527 | if (gfs2_is_jdata(GFS2_I(inode))) { |
| 528 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
| 529 | return 0; | ||
| 530 | } | ||
| 495 | 531 | ||
| 496 | return 0; | 532 | if (sync_state != 0) { |
| 533 | if (!datasync) | ||
| 534 | ret = write_inode_now(inode, 0); | ||
| 535 | |||
| 536 | if (gfs2_is_stuffed(GFS2_I(inode))) | ||
| 537 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
| 538 | } | ||
| 539 | |||
| 540 | return ret; | ||
| 497 | } | 541 | } |
| 498 | 542 | ||
| 499 | /** | 543 | /** |
| @@ -515,7 +559,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
| 515 | 559 | ||
| 516 | if (!(fl->fl_flags & FL_POSIX)) | 560 | if (!(fl->fl_flags & FL_POSIX)) |
| 517 | return -ENOLCK; | 561 | return -ENOLCK; |
| 518 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 562 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
| 519 | return -ENOLCK; | 563 | return -ENOLCK; |
| 520 | 564 | ||
| 521 | if (sdp->sd_args.ar_localflocks) { | 565 | if (sdp->sd_args.ar_localflocks) { |
| @@ -617,7 +661,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
| 617 | 661 | ||
| 618 | if (!(fl->fl_flags & FL_FLOCK)) | 662 | if (!(fl->fl_flags & FL_FLOCK)) |
| 619 | return -ENOLCK; | 663 | return -ENOLCK; |
| 620 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 664 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
| 621 | return -ENOLCK; | 665 | return -ENOLCK; |
| 622 | 666 | ||
| 623 | if (sdp->sd_args.ar_localflocks) | 667 | if (sdp->sd_args.ar_localflocks) |
