diff options
author | Li Dongyang <lidongyang@novell.com> | 2010-04-17 05:49:10 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-04-30 16:45:13 -0400 |
commit | 6b933c8e6f1a2f3118082c455eef25f9b1ac7b45 (patch) | |
tree | bf31f4067a95aa23a354edfa89810c9eaaf71aaa | |
parent | f9221fd80343285514568da6c5dbda0f87109de8 (diff) |
ocfs2: Avoid direct write if we fall back to buffered I/O
when we fall back to buffered write from direct write, we call
__generic_file_aio_write() but that will end up doing direct write
even we are only prepared to do buffered write because the file
has the O_DIRECT flag set. This is a fix for
https://bugzilla.novell.com/show_bug.cgi?id=591039
revised with Joel's comments.
Signed-off-by: Li Dongyang <lidongyang@novell.com>
Acked-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r-- | fs/ocfs2/file.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 20e0ee58dd39..a5fbd9cea968 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1982,18 +1982,18 @@ relock: | |||
1982 | /* communicate with ocfs2_dio_end_io */ | 1982 | /* communicate with ocfs2_dio_end_io */ |
1983 | ocfs2_iocb_set_rw_locked(iocb, rw_level); | 1983 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
1984 | 1984 | ||
1985 | if (direct_io) { | 1985 | ret = generic_segment_checks(iov, &nr_segs, &ocount, |
1986 | ret = generic_segment_checks(iov, &nr_segs, &ocount, | 1986 | VERIFY_READ); |
1987 | VERIFY_READ); | 1987 | if (ret) |
1988 | if (ret) | 1988 | goto out_dio; |
1989 | goto out_dio; | ||
1990 | 1989 | ||
1991 | count = ocount; | 1990 | count = ocount; |
1992 | ret = generic_write_checks(file, ppos, &count, | 1991 | ret = generic_write_checks(file, ppos, &count, |
1993 | S_ISBLK(inode->i_mode)); | 1992 | S_ISBLK(inode->i_mode)); |
1994 | if (ret) | 1993 | if (ret) |
1995 | goto out_dio; | 1994 | goto out_dio; |
1996 | 1995 | ||
1996 | if (direct_io) { | ||
1997 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 1997 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, |
1998 | ppos, count, ocount); | 1998 | ppos, count, ocount); |
1999 | if (written < 0) { | 1999 | if (written < 0) { |
@@ -2008,7 +2008,10 @@ relock: | |||
2008 | goto out_dio; | 2008 | goto out_dio; |
2009 | } | 2009 | } |
2010 | } else { | 2010 | } else { |
2011 | written = __generic_file_aio_write(iocb, iov, nr_segs, ppos); | 2011 | current->backing_dev_info = file->f_mapping->backing_dev_info; |
2012 | written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos, | ||
2013 | ppos, count, 0); | ||
2014 | current->backing_dev_info = NULL; | ||
2012 | } | 2015 | } |
2013 | 2016 | ||
2014 | out_dio: | 2017 | out_dio: |