aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/aops.c
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2013-09-03 17:59:42 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2013-09-05 04:04:24 -0400
commit0c9018097fe2966d80fe39e5c9ca94bb436ec369 (patch)
treea3a30053c83e22f30e3e7d3fc595ea68fbdc7afa /fs/gfs2/aops.c
parent1d12d175ea3b56fdf2573bf6f168cce8f39b19e3 (diff)
GFS2: dirty inode correctly in gfs2_write_end
GFS2 was only setting I_DIRTY_DATASYNC on files that it wrote to, when it actually increased the file size. If gfs2_fsync was called without I_DIRTY_DATASYNC set, it didn't flush the incore data to the log before returning, so any metadata or journaled data changes were not getting fsynced. This meant that writes to the middle of files were not always getting fsynced properly. This patch makes gfs2 set I_DIRTY_DATASYNC whenever metadata has been updated during a write. It also make gfs2_sync flush the incore log if I_DIRTY_PAGES is set, and the file is using data journalling. This will make sure that all incore logged data gets written to disk before returning from a fsync. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r--fs/gfs2/aops.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index a9ea6f07774b..1f7d8057ea68 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -815,6 +815,8 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
815 unsigned int from = pos & (PAGE_CACHE_SIZE - 1); 815 unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
816 unsigned int to = from + len; 816 unsigned int to = from + len;
817 int ret; 817 int ret;
818 struct gfs2_trans *tr = current->journal_info;
819 BUG_ON(!tr);
818 820
819 BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == NULL); 821 BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == NULL);
820 822
@@ -825,8 +827,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
825 goto failed; 827 goto failed;
826 } 828 }
827 829
828 gfs2_trans_add_meta(ip->i_gl, dibh);
829
830 if (gfs2_is_stuffed(ip)) 830 if (gfs2_is_stuffed(ip))
831 return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page); 831 return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page);
832 832
@@ -834,6 +834,11 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
834 gfs2_page_add_databufs(ip, page, from, to); 834 gfs2_page_add_databufs(ip, page, from, to);
835 835
836 ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); 836 ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
837 if (tr->tr_num_buf_new)
838 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
839 else
840 gfs2_trans_add_meta(ip->i_gl, dibh);
841
837 842
838 if (inode == sdp->sd_rindex) { 843 if (inode == sdp->sd_rindex) {
839 adjust_fs_space(inode); 844 adjust_fs_space(inode);