summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPrasad Joshi <prasadjoshi.linux@gmail.com>2012-07-23 09:18:14 +0530
committerPrasad Joshi <prasadjoshi.linux@gmail.com>2012-07-23 09:18:14 +0530
commitddb24bbac3681b87ae0638aacb702d9273e3c025 (patch)
tree44355f9781051e2aca826c87c86c74a4b1d1cdd4 /fs
parentcd8bfa9c8a13cf3facc5731da17e10188b3795d1 (diff)
logfs: create a pagecache page if it is not present
While writing the partial journal entries we assumed that the page associated with the journal would always in locatable. This incorrect assumption resulted in the following BUG kernel BUG at /home/benixon/WD_SMR/kernels/linux-3.3.7-logfs/fs/logfs/journal.c:569! EIP is at logfs_write_area+0xb6/0x109 [logfs] EAX: 00000000 EBX: 00000000 ECX: ef6efea4 EDX: 00000000 ESI: 001b9000 EDI: f009e000 EBP: c3c13f14 ESP: c3c13ef0 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process sync (pid: 1799, ti=c3c12000 task=f07825b0 task.ti=c3c12000) Stack: 01001000 c3c13f26 781b9000 00000000 f009e000 f7286000 f1f83400 f8445071 f1f83400 c3c13f30 f8445ae9 c3c13f20 0000100a 000ee000 f009e000 00000001 c3c13f5c f8445d17 c05eb0ee 00000000 f1f83400 ef718000 f009e25c ea9c3d80 Call Trace: [<f8445071>] ? account_shadow+0x16d/0x16d [logfs] [<f8445ae9>] logfs_write_je+0x2a/0x44 [logfs] [<f8445d17>] logfs_write_anchor+0x114/0x228 [logfs] [<c05eb0ee>] ? empty+0x5/0x5 [<f8444522>] logfs_sync_fs+0x1e/0x31 [logfs] [<c051be66>] __sync_filesystem+0x5d/0x6f [<c051be8d>] sync_one_sb+0x15/0x17 [<c04ff8b0>] iterate_supers+0x59/0x9a [<c051be78>] ? __sync_filesystem+0x6f/0x6f [<c051befc>] sys_sync+0x29/0x4f [<c084285f>] sysenter_do_call+0x12/0x28 EIP: [<f8445127>] logfs_write_area+0xb6/0x109 [logfs] SS:ESP 0068:c3c13ef0 ---[ end trace ef6e9ef52601a945 ]--- The fix is to create the pagecache page if it is not locatable. Reported-and-tested-by: Benixon Dhas <Benixon.Dhas@wdc.com> Signed-off-by: Prasad Joshi <prasadjoshi.linux@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/logfs/journal.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
index 1e1c369df22..2a09b8d7398 100644
--- a/fs/logfs/journal.c
+++ b/fs/logfs/journal.c
@@ -565,7 +565,7 @@ static void write_wbuf(struct super_block *sb, struct logfs_area *area,
index = ofs >> PAGE_SHIFT;
page_ofs = ofs & (PAGE_SIZE - 1);
- page = find_lock_page(mapping, index);
+ page = find_or_create_page(mapping, index, GFP_NOFS);
BUG_ON(!page);
memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);
unlock_page(page);