summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/super.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2006-02-23 02:35:08 +0100
committerMark Fasheh <mark.fasheh@oracle.com>2006-03-01 20:32:41 +0100
commitb4df6ed8db0c387d38292e31f00adc4cd297ed5a (patch)
treed7dcaeecfa55b3fd9d6c4844d90e07759182f845 /fs/ocfs2/super.c
parent[PATCH] ocfs2: complete failure recovery for nodemanager init (diff)
downloadlinux-b4df6ed8db0c387d38292e31f00adc4cd297ed5a.tar.xz
linux-b4df6ed8db0c387d38292e31f00adc4cd297ed5a.zip
[PATCH] ocfs2: fix orphan recovery deadlock
Orphan dir recovery can deadlock with another process in ocfs2_delete_inode() in some corner cases. Fix this by tracking recovery state more closely and allowing it to handle inode wipes which might deadlock. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r--fs/ocfs2/super.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 046824b6b625..8dd3aafec499 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1325,6 +1325,16 @@ static int ocfs2_initialize_super(struct super_block *sb,
}
mlog(ML_NOTICE, "max_slots for this device: %u\n", osb->max_slots);
+ init_waitqueue_head(&osb->osb_wipe_event);
+ osb->osb_orphan_wipes = kcalloc(osb->max_slots,
+ sizeof(*osb->osb_orphan_wipes),
+ GFP_KERNEL);
+ if (!osb->osb_orphan_wipes) {
+ status = -ENOMEM;
+ mlog_errno(status);
+ goto bail;
+ }
+
osb->s_feature_compat =
le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_compat);
osb->s_feature_ro_compat =
@@ -1638,6 +1648,7 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb)
if (osb->slot_info)
ocfs2_free_slot_info(osb->slot_info);
+ kfree(osb->osb_orphan_wipes);
/* FIXME
* This belongs in journal shutdown, but because we have to
* allocate osb->journal at the start of ocfs2_initalize_osb(),