Skip to contentSkip to conversation

reiserfs highmem bug on tail reads

PATCH New Chris Mason 1 participant 1 message Apr 26, 2001

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 reiserfs highmem bug on tail reads

Ok, so all the reiserfs tail bugs weren't quite fixed yet, the last tail fix can cause problems with highmem turned on. Both bugs are in fs/reiserfs/inode.c:_get_block_create_0

When reading the tail in, if the buffer was already up to date, we skip the disk i/o and return. But the cleanup code assumes the page was kmap'd, which isn't right.

Also, there was a chance to double kmap the page if kmap scheduled a nd the tree balanced while we slept. This bug has been there for a long time.

Anyway, this was tested with Andrea's HIGHMEM_DEBUG_MERE_MORTALS patch to force highmem on my 128MB machine. It works for me, but more testers are always good.

-chris

against 2.4.4-pre6, should work against 2.4.3 or higher.

fs/reiserfs/inode.c +8 -5
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
@@ -374,9 +374,11 @@
     ** sure we need to.  But, this means the item might move if
     ** kmap schedules
     */
-    p = (char *)kmap(bh_result->b_page) ;
-    if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-        goto research;
+    if (!p) {
+	p = (char *)kmap(bh_result->b_page) ;
+	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
+	    goto research;
+	}
     }
     p += offset ;
     memset (p, 0, inode->i_sb->s_blocksize);
@@ -420,14 +422,15 @@
 	ih = get_ih (&path);
     } while (1);
 
+    flush_dcache_page(bh_result->b_page) ;
+    kunmap(bh_result->b_page) ;
+
 finished:
     pathrelse (&path);
     bh_result->b_blocknr = 0 ;
     bh_result->b_dev = inode->i_dev;
     mark_buffer_uptodate (bh_result, 1);
     bh_result->b_state |= (1UL << BH_Mapped);
-    flush_dcache_page(bh_result->b_page) ;
-    kunmap(bh_result->b_page) ;
     return 0;
 }