aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-10-18 17:14:45 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2007-11-06 18:32:00 -0500
commit9ea2d32f40434589ea0e136373f7d1545afb411f (patch)
tree2bc258fcaae4769a7b41ae71725eb073de33aded
parent9f70968af3e6e21612e06e153aa71c62dee5a09b (diff)
ocfs2: Commit journal on sync writes
We're missing a meta data commit for extending sync writes. In thoery, write could return with the meta data required to read the data uncommitted to disk. Fix that by detecting an allocating write and forcing a journal commit in the sync case. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
-rw-r--r--fs/ocfs2/file.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f92fe91ff260..bbac7cd33e0b 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1891,9 +1891,11 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1891 ssize_t written = 0; 1891 ssize_t written = 0;
1892 size_t ocount; /* original count */ 1892 size_t ocount; /* original count */
1893 size_t count; /* after file limit checks */ 1893 size_t count; /* after file limit checks */
1894 loff_t *ppos = &iocb->ki_pos; 1894 loff_t old_size, *ppos = &iocb->ki_pos;
1895 u32 old_clusters;
1895 struct file *file = iocb->ki_filp; 1896 struct file *file = iocb->ki_filp;
1896 struct inode *inode = file->f_path.dentry->d_inode; 1897 struct inode *inode = file->f_path.dentry->d_inode;
1898 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1897 1899
1898 mlog_entry("(0x%p, %u, '%.*s')\n", file, 1900 mlog_entry("(0x%p, %u, '%.*s')\n", file,
1899 (unsigned int)nr_segs, 1901 (unsigned int)nr_segs,
@@ -1949,6 +1951,13 @@ relock:
1949 goto relock; 1951 goto relock;
1950 } 1952 }
1951 1953
1954 /*
1955 * To later detect whether a journal commit for sync writes is
1956 * necessary, we sample i_size, and cluster count here.
1957 */
1958 old_size = i_size_read(inode);
1959 old_clusters = OCFS2_I(inode)->ip_clusters;
1960
1952 /* communicate with ocfs2_dio_end_io */ 1961 /* communicate with ocfs2_dio_end_io */
1953 ocfs2_iocb_set_rw_locked(iocb, rw_level); 1962 ocfs2_iocb_set_rw_locked(iocb, rw_level);
1954 1963
@@ -1978,6 +1987,21 @@ out_dio:
1978 /* buffered aio wouldn't have proper lock coverage today */ 1987 /* buffered aio wouldn't have proper lock coverage today */
1979 BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); 1988 BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
1980 1989
1990 if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) {
1991 /*
1992 * The generic write paths have handled getting data
1993 * to disk, but since we don't make use of the dirty
1994 * inode list, a manual journal commit is necessary
1995 * here.
1996 */
1997 if (old_size != i_size_read(inode) ||
1998 old_clusters != OCFS2_I(inode)->ip_clusters) {
1999 ret = journal_force_commit(osb->journal->j_journal);
2000 if (ret < 0)
2001 written = ret;
2002 }
2003 }
2004
1981 /* 2005 /*
1982 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io 2006 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
1983 * function pointer which is called when o_direct io completes so that 2007 * function pointer which is called when o_direct io completes so that