Reiser4 bug fixes
PATCH 1/1 Reiser4 bug fixes
Hopefully this will make reiser4 stable code again. Or at least, a lot more stable than v3 (or other FSes) was when it went in....
From: Vladimir Saveliev <[email protected]>
This patch contains 4 reiser4 bug fixes:
- missing long term lock unlock on read' error handling code path is added
- truncate_inode_pages is now called with embedded mapping.
It is needed to deal properly with block device special files.
- copy_to_user might be called for more bytes than was prefaulted with fault_in_pages_writeable. That caused undesirable major page faults.
- readdir bug similar to the previous one:
call to filldir might lead to deadlock due to major page fault.
fs/reiser4/super_ops.c renamed from fs/reiser4/super_ops.c~reiser4-one-line-fixes +1 -1
@@ -202,7 +202,7 @@ static void reiser4_delete_inode(struct fplug->delete_object (inode); } -truncate_inode_pages (inode->i_mapping,0 ); +truncate_inode_pages (&inode->i_data,0 ); inode->i_blocks =0 ;clear_inode (inode);reiser4_exit_context (ctx);
fs/reiser4/plugin/file/file.c renamed from fs/reiser4/plugin/file/file.c~reiser4-one-line-fixes +16 -5
@@ -781,9 +781,12 @@ int find_or_create_extent(struct page *plock_page (page); node =jnode_of_page (page); -unlock_page (page); -if (IS_ERR (node)) +if (IS_ERR (node)) { +unlock_page (page);return PTR_ERR (node); + } +JF_SET (node,JNODE_WRITE_PREPARED ); +unlock_page (page);if (node->blocknr ==0 ) { plugged_hole =0 ;
@@ -791,6 +794,7 @@ int find_or_create_extent(struct page *p (loff_t )page->index <<PAGE_CACHE_SHIFT , &plugged_hole);if (result) { +JF_CLR (node,JNODE_WRITE_PREPARED );jput (node);warning ("" ,"update_extent failed: %d" , result);return result;
@@ -806,6 +810,7 @@ int find_or_create_extent(struct page *p }BUG_ON (node->atom ==NULL ); +JF_CLR (node,JNODE_WRITE_PREPARED );jput (node);if (get_current_context ()->entd) {
@@ -1631,14 +1636,18 @@ static size_t read_file(hint_t * hint, s/* error happened */ break ; -if (coord->between !=AT_UNIT ) +if (coord->between !=AT_UNIT ) {/* there were no items corresponding to given offset */ +done_lh (hint->ext_coord.lh);break ; + } loaded = coord->node; result =zload (loaded); -if (unlikely (result)) +if (unlikely (result)) { +done_lh (hint->ext_coord.lh);break ; + }if (hint->ext_coord.valid ==0 ) validate_extended_coord(&hint->ext_coord,
@@ -1729,7 +1738,9 @@ ssize_t read_unix_file(struct file *filereturn RETERR (-EFAULT ); } - read =read_file (hint, file, buf, left, off); + read =read_file (hint, file, buf, + left >PAGE_CACHE_SIZE ?PAGE_CACHE_SIZE : left, + off);drop_nonexclusive_access (uf_info);
fs/reiser4/plugin/file_ops_readdir.c renamed from fs/reiser4/plugin/file_ops_readdir.c~reiser4-one-line-fixes +2 -1
@@ -349,6 +349,7 @@ feed_entry(struct file *f,*/ assert ("nikita-3436" ,lock_stack_isclean (get_current_lock_stack ())); +txn_restart_current (); result = filldir(dirent, name, (int)strlen(name), /* offset of this entry */ f->f_pos,
@@ -630,7 +631,7 @@ int readdir_common(struct file *f /* dirdetach_fsdata (f);/* try to update directory's atime */ -if (reiser4_grab_space (inode_file_plugin (inode)->estimate.update (inode), +if (reiser4_grab_space_force (inode_file_plugin (inode)->estimate.update (inode),BA_CAN_COMMIT ) !=0 )warning ("" ,"failed to update atime on readdir: %llu" ,get_inode_oid (inode));
_
Quoted 24 lines · Hans Reiser
Hopefully this will make reiser4 stable code again. Or at least, a lot more stable than v3 (or other FSes) was when it went in....
Signed-off-by Hans ReiserFrom: Vladimir Saveliev <[email protected]>
This patch contains 4 reiser4 bug fixes:
- missing long term lock unlock on read' error handling code path is added
-truncate_inode_pagesis now called with embedded mapping.
It is needed to deal properly with block device special files.
-copy_to_usermight be called for more bytes than was prefaulted withfault_in_pages_writeable. That caused undesirable major page faults.
- readdir bug similar to the previous one:
call to filldir might lead to deadlock due to major page fault.Signed-off-by Vladimir Saveliev <[email protected]>diff -puN
fs/reiser4/super_ops.c~reiser4-one-line-fixesfs/reiser4/super_ops.c
fs/reiser4/super_ops.c static void reiser4_delete_inode(struct · line 205
Quoted 5 lines
fs/reiser4/super_ops.c renamed from fs/reiser4/super_ops.c~reiser4-one-line-fixes +1
-1@@ -202,7 +202,7 @@ static void reiser4_delete_inode(struct fplug->delete_object (inode); } -truncate_inode_pages (inode->i_mapping,0 ); +truncate_inode_pages (&inode->i_data,0 );
Where do you reset i_mapping to be different from i_data? It is a valid thing to do in theory (that's why we have those different fields), but in practice most usages I've seen are bogus.
(And yes, this is not a personal attack again you, just a normal review)