Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

GFS2: Make ->write_inode() really write

The GFS2 ->write_inode function should be more aggressive at writing
back to the filesystem. This adopts the XFS system of returning
-EAGAIN when the writeback has not been completely done. Also, we
now kick off in-place writeback when called with WB_SYNC_NONE,
but we only wait for it and flush the log when WB_SYNC_ALL is
requested.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

+13 -6
+13 -6
fs/gfs2/super.c
··· 704 704 /** 705 705 * gfs2_write_inode - Make sure the inode is stable on the disk 706 706 * @inode: The inode 707 - * @sync: synchronous write flag 707 + * @wbc: The writeback control structure 708 708 * 709 709 * Returns: errno 710 710 */ ··· 713 713 { 714 714 struct gfs2_inode *ip = GFS2_I(inode); 715 715 struct gfs2_sbd *sdp = GFS2_SB(inode); 716 + struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); 716 717 struct gfs2_holder gh; 717 718 struct buffer_head *bh; 718 719 struct timespec atime; 719 720 struct gfs2_dinode *di; 720 - int ret = 0; 721 + int ret = -EAGAIN; 721 722 722 - /* Check this is a "normal" inode, etc */ 723 + /* Skip timestamp update, if this is from a memalloc */ 723 724 if (current->flags & PF_MEMALLOC) 724 - return 0; 725 + goto do_flush; 725 726 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 726 727 if (ret) 727 728 goto do_flush; ··· 746 745 do_flush: 747 746 if (wbc->sync_mode == WB_SYNC_ALL) 748 747 gfs2_log_flush(GFS2_SB(inode), ip->i_gl); 748 + filemap_fdatawrite(metamapping); 749 + if (!ret && (wbc->sync_mode == WB_SYNC_ALL)) 750 + ret = filemap_fdatawait(metamapping); 751 + if (ret) 752 + mark_inode_dirty_sync(inode); 749 753 return ret; 750 754 } 751 755 ··· 880 874 881 875 static int gfs2_sync_fs(struct super_block *sb, int wait) 882 876 { 883 - if (wait && sb->s_fs_info) 884 - gfs2_log_flush(sb->s_fs_info, NULL); 877 + struct gfs2_sbd *sdp = sb->s_fs_info; 878 + if (wait && sdp) 879 + gfs2_log_flush(sdp, NULL); 885 880 return 0; 886 881 } 887 882