aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorColy Li <coyli@suse.de>2008-06-30 06:45:45 -0400
committerMark Fasheh <mfasheh@suse.com>2008-07-16 19:13:04 -0400
commitc0420ad2ca514551ca086510b0e7d17a05c70492 (patch)
treed0c66f31d3ca100ad2bc0ac1dcd0e293865fd894 /fs/ocfs2/aops.c
parente75206517504461778c283b942440ef312e437d5 (diff)
[PATCH] ocfs2: fix oops in mmap_truncate testing
This patch fixes a mmap_truncate bug which was found by ocfs2 test suite. In an ocfs2 cluster more than 1 node, run program mmap_truncate, which races mmap writes and truncates from multiple processes. While the test is running, a stat from another node forces writeout, causing an oops in ocfs2_get_block() because it sees a buffer to write which isn't allocated. This patch fixed the bug by clear dirty and uptodate bits in buffer, leave the buffer unmapped and return. Fix is suggested by Mark Fasheh, and I code up the patch. Signed-off-by: Coly Li <coyli@suse.de> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 17964c0505a9..1db080135c6d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -174,10 +174,17 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
174 * need to use BH_New is when we're extending i_size on a file 174 * need to use BH_New is when we're extending i_size on a file
175 * system which doesn't support holes, in which case BH_New 175 * system which doesn't support holes, in which case BH_New
176 * allows block_prepare_write() to zero. 176 * allows block_prepare_write() to zero.
177 *
178 * If we see this on a sparse file system, then a truncate has
179 * raced us and removed the cluster. In this case, we clear
180 * the buffers dirty and uptodate bits and let the buffer code
181 * ignore it as a hole.
177 */ 182 */
178 mlog_bug_on_msg(create && p_blkno == 0 && ocfs2_sparse_alloc(osb), 183 if (create && p_blkno == 0 && ocfs2_sparse_alloc(osb)) {
179 "ino %lu, iblock %llu\n", inode->i_ino, 184 clear_buffer_dirty(bh_result);
180 (unsigned long long)iblock); 185 clear_buffer_uptodate(bh_result);
186 goto bail;
187 }
181 188
182 /* Treat the unwritten extent as a hole for zeroing purposes. */ 189 /* Treat the unwritten extent as a hole for zeroing purposes. */
183 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN)) 190 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))