From 77124e4ca8beabd786f7768a64b850c04e9892ef Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 18 May 2004 17:18:07 -0700 Subject: [PATCH] [PATCH] Fix reiserfs inode size update race reiserfs_file_write unlocks the pages it operated on before updating i_size. This can lead to races with writepage, who checks i_size when deciding how much of the file to zero out. This patch also replaces SetPageReferenced with mark_page_accessed() in reiserfs_file_write This was verified to fix the BitKeeper data corruption problems that Steven Cole has been debugging, where concurrent writes to a file and writebacks to disk would cause zeroes in the file when CONFIG_PREEMPT was enabled. --- fs/reiserfs/file.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 32135c0292cb6..bf10173d5d9e0 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -655,10 +656,6 @@ int reiserfs_submit_file_region_for_write( // we only remember error status to report it on // exit. write_bytes-=count; - SetPageReferenced(page); - unlock_page(page); // We unlock the page as it was locked by earlier call - // to grab_cache_page - page_cache_release(page); } /* now that we've gotten all the ordered buffers marked dirty, * we can safely update i_size and close any running transaction @@ -695,6 +692,17 @@ int reiserfs_submit_file_region_for_write( reiserfs_write_unlock(inode->i_sb); } th->t_trans_id = 0; + + /* + * we have to unlock the pages after updating i_size, otherwise + * we race with writepage + */ + for ( i = 0; i < num_pages ; i++) { + struct page *page=prepared_pages[i]; + unlock_page(page); + mark_page_accessed(page); + page_cache_release(page); + } return retval; } -- 2.53.0