aboutsummaryrefslogtreecommitdiff
path: root/fs/reiserfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/super.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index edfd74f9f7e..b82897ae090 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -145,7 +145,7 @@ static int finish_unfinished(struct super_block *s)
{
INITIALIZE_PATH(path);
struct cpu_key max_cpu_key, obj_key;
- struct reiserfs_key save_link_key;
+ struct reiserfs_key save_link_key, last_inode_key;
int retval = 0;
struct item_head *ih;
struct buffer_head *bh;
@@ -166,6 +166,8 @@ static int finish_unfinished(struct super_block *s)
set_cpu_key_k_offset(&max_cpu_key, ~0U);
max_cpu_key.key_length = 3;
+ memset(&last_inode_key, 0, sizeof(last_inode_key));
+
#ifdef CONFIG_QUOTA
/* Needed for iput() to work correctly and not trash data */
if (s->s_flags & MS_ACTIVE) {
@@ -278,8 +280,18 @@ static int finish_unfinished(struct super_block *s)
REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
/* not completed unlink (rmdir) found */
reiserfs_info(s, "Removing %k..", INODE_PKEY(inode));
- /* removal gets completed in iput */
- retval = 0;
+ if (memcmp(&last_inode_key, INODE_PKEY(inode),
+ sizeof(last_inode_key))){
+ last_inode_key = *INODE_PKEY(inode);
+ /* removal gets completed in iput */
+ retval = 0;
+ } else {
+ reiserfs_warning(s, "Dead loop in "
+ "finish_unfinished detected, "
+ "just remove save link\n");
+ retval = remove_save_link_only(s,
+ &save_link_key, 0);
+ }
}
iput(inode);