rename bug patch]
PATCH 1/1 rename bug patch]
Others besides Marcelo are likely to be interested in this. I think this might be the fix to a longtime eluding us bug.
Hans
Quoted 1 line
From - Fri Jan 18 14:41:10 2002
X-Mozilla-Status2: 00000000
Message-ID: <[email protected]>
Date: Fri, 18 Jan 2002 14:41:10 +0300
From: Hans Reiser <[email protected]>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.7) Gecko/20011221
X-Accept-Language: en-us
MIME-Version: 1.0
To: Marcelo Tosatti <[email protected]>
Subject: [PATCH] rename bug patch
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Please apply and credit Oleg. It is tested by three persons and read/reviewed by Saveliev, so it should be good.
Hans
Hello!
A-rename_stale_item_bug-1.diff
This patch fixes 2 bugs in reiserfs_rename(). First one being attempt to access item before verifying it was not moved since last access. Second is a window, where old filename may be written to disk with 'visible' flag unset without these changes be journaled.
Bye,
Oleg
fs/reiserfs/namei.c renamed from fs/reiserfs/namei.c.orig +2 -1
@@ -1057,7 +1057,7 @@INITIALIZE_PATH (old_entry_path);INITIALIZE_PATH (new_entry_path);INITIALIZE_PATH (dot_dot_entry_path); -struct item_head new_entry_ih, old_entry_ih ; +struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;struct reiserfs_dir_entry old_de, new_de, dot_dot_de;struct inode * old_inode, * new_inode;int windex ;
@@ -1151,6 +1151,8 @@copy_item_head (&old_entry_ih,get_ih (&old_entry_path)) ; +
reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1) ;
+
// look for new name by reiserfs_find_entry
new_de.de_gen_number_bit_string = 0;
retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len,
@@ -1167,6 +1169,7 @@
if (S_ISDIR(old_inode->i_mode)) {
if (search_by_entry_key (new_dir->i_sb, &dot_dot_de.de_entry_key, &dot_dot_entry_path, &dot_dot_de) != NAME_FOUND)
BUG ();
+
copy_item_head(&dot_dot_ih, get_ih(&dot_dot_entry_path)) ;
// node containing ".." gets into transaction reiserfs_prepare_for_journal(old_inode->i_sb, dot_dot_de.de_bh, 1) ;
}
@@ -1183,23 +1186,33 @@
** of the above checks could have scheduled. We have to be ** sure our items haven't been shifted by another process. */
-
if (!entry_points_to_object(new_dentry->d_name.name,
+
if (item_moved(&new_entry_ih, &new_entry_path) ||
+
!entry_points_to_object(new_dentry->d_name.name,
new_dentry->d_name.len,
&new_de, new_inode) ||
-
item_moved(&new_entry_ih, &new_entry_path) || item_moved(&old_entry_ih, &old_entry_path) || !entry_points_to_object (old_dentry->d_name.name,
old_dentry->d_name.len,
&old_de, old_inode)) {
reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
+
reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh); if (S_ISDIR(old_inode->i_mode))
reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
continue;
}
+
if (S_ISDIR(old_inode->i_mode)) {
+
if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
+
!entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
+
reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
+
reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
+
reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
+
continue;
+
}+
}
+
RFALSE( S_ISDIR(old_inode->i_mode) &&
-
(!entry_points_to_object ("..", 2, &dot_dot_de, old_dir) ||
-
!reiserfs_buffer_prepared(dot_dot_de.de_bh)), "" );
+
!reiserfs_buffer_prepared(dot_dot_de.de_bh), "" ); break;
}
@@ -1212,6 +1225,7 @@
journal_mark_dirty (&th, old_dir->i_sb, new_de.de_bh);
mark_de_hidden (old_de.de_deh + old_de.de_entry_num);
+ journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;