diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-11-30 10:14:32 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-11-30 10:37:44 -0500 |
commit | 33c3de32872ef3c075e4dac04c0de8f86ac39f6f (patch) | |
tree | 32b8d14e4de17e78918ba8794c47781c1b069e2f /fs/gfs2 | |
parent | aac1a3c77a46c2d06f297641760dd740ac2a84af (diff) |
[GFS2] Don't flush everything on fdatasync
The gfs2_fsync() function was doing a journal flush on each
and every call. While this is correct, its also a lot of
overhead. This patch means that on fdatasync flushes we
rely on the VFS to flush the data for us and we don't do
a journal flush unless we really need to.
We have to do a journal flush for stuffed files though because
they have the data and the inode metadata in the same block.
Journaled files also need a journal flush too of course.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/ops_file.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index c2be216eb928..7bd971bf7cdd 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" |
@@ -503,16 +504,39 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
503 | * @file: the file that points to the dentry (we ignore this) | 504 | * @file: the file that points to the dentry (we ignore this) |
504 | * @dentry: the dentry that points to the inode to sync | 505 | * @dentry: the dentry that points to the inode to sync |
505 | * | 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 | * | ||
506 | * Returns: errno | 513 | * Returns: errno |
507 | */ | 514 | */ |
508 | 515 | ||
509 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 516 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
510 | { | 517 | { |
511 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 518 | struct inode *inode = dentry->d_inode; |
519 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | ||
520 | int ret = 0; | ||
521 | struct writeback_control wbc = { | ||
522 | .sync_mode = WB_SYNC_ALL, | ||
523 | .nr_to_write = 0, | ||
524 | }; | ||
525 | |||
526 | if (gfs2_is_jdata(GFS2_I(inode))) { | ||
527 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
528 | return 0; | ||
529 | } | ||
512 | 530 | ||
513 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 531 | if (sync_state != 0) { |
532 | if (!datasync) | ||
533 | ret = sync_inode(inode, &wbc); | ||
514 | 534 | ||
515 | return 0; | 535 | if (gfs2_is_stuffed(GFS2_I(inode))) |
536 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
537 | } | ||
538 | |||
539 | return ret; | ||
516 | } | 540 | } |
517 | 541 | ||
518 | /** | 542 | /** |