Skip to contentSkip to conversation

reiserfs leak in errors paths

PATCH New Chris Mason 1 participant 1 message Jun 5, 2001

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 reiserfs leak in errors paths

Hi guys,

A few of the reiserfs errors paths for i/o error neglect to release buffer heads. This patch makes sure things get released properly and if dirty buffers were prepared for the log, also makes sure the dirty bits are reset (by using unfix_nodes intead of pathrelse).

Vladimir Saveliev helped out with this one, it was against 2.4.4, but I just retested under 2.4.5.

Alan, please apply.

-chris

fs/reiserfs/fix_node.c +2 -7
diff -urN linux-2.4.4.tmp/fs/reiserfs/fix_node.c linux-2.4.4/fs/reiserfs/fix_node.c
@@ -2719,12 +2719,6 @@
 {
     int	i;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! tb->vn_buf )
-	reiserfs_panic (tb->tb_sb,
-			"PAP-16050: unfix_nodes: pointer to the virtual node is NULL");
-#endif
-
     /* Release path buffers. */
     pathrelse_and_restore (tb->tb_sb, tb->tb_path);
 
@@ -2781,7 +2775,8 @@
 	    }
 	}
 #endif /* 0 */
-    reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+    if (tb->vn_buf) 
+	reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
 
 } 
 
fs/reiserfs/stree.c +21 -13
diff -urN linux-2.4.4.tmp/fs/reiserfs/stree.c linux-2.4.4/fs/reiserfs/stree.c
@@ -1724,7 +1724,7 @@
 	    continue;
 
 	reiserfs_warning ("PAP-5610: reiserfs_cut_from_item: item %K not found\n", p_s_item_key);
-	pathrelse (p_s_path);
+	unfix_nodes (&s_cut_balance);
 	return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
     } /* while */
   
@@ -1994,12 +1994,14 @@
     while ( (retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) == REPEAT_SEARCH ) {
 	/* file system changed while we were in the fix_nodes */
 	retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
-	if (retval == IO_ERROR)
-	    return -EIO;
+	if (retval == IO_ERROR) {
+	    retval = -EIO ;
+	    goto error_out ;
+	}
 	if (retval == POSITION_FOUND) {
 	    reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", p_s_key);
-	    pathrelse (p_s_search_path);
-	    return -EEXIST;
+	    retval = -EEXIST ;
+	    goto error_out ;
 	}
 	
 #ifdef CONFIG_REISERFS_CHECK
@@ -2013,9 +2015,11 @@
 	do_balance(&s_paste_balance, NULL/*ih*/, p_c_body, M_PASTE);
 	return 0;
     }
-
+    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+error_out:
+    /* this also releases the path */
     unfix_nodes(&s_paste_balance);
-    return (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+    return retval ;
 }
 
 
@@ -2040,14 +2044,15 @@
     while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
 	/* file system changed while we were in the fix_nodes */
 	retval = search_item (th->t_super, key, p_s_path);
-	if (retval == IO_ERROR)
-	    return -EIO;
-
+	if (retval == IO_ERROR) {
+	    retval = -EIO;
+	    goto error_out ;
+	}
 	if (retval == ITEM_FOUND) {
 	    reiserfs_warning ("PAP-5760: reiserfs_insert_item: "
 			      "key %K already exists in the tree\n", key);
-	    pathrelse (p_s_path);
-	    return -EEXIST;
+	    retval = -EEXIST ;
+	    goto error_out; 
 	}
     }
 
@@ -2057,8 +2062,11 @@
 	return 0;
     }
 
+    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+error_out:
+    /* also releases the path */
     unfix_nodes(&s_ins_balance);
-    return (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+    return retval; 
 }