From: liaohua <
liaohua4@huawei.com>
list_for_each_safe was used in yaffs_del_dir_contents and when
traverse the list, the current list node and the next list node
was hold together. But if current list node was a file node,
and the next list node was the hardlink of this file, the next
list node will be deleted in yaffs_unlink_obj. So a list corruption
happened, and a infinite loop was happend in list_for_each_safe.
And search context may be too complicated for this problem, we just
traverse the list again to fix it.
Signed-off-by: liaohua <
liaohua4@huawei.com>
---
yaffs_guts.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/yaffs_guts.c b/yaffs_guts.c
index b83fa63..11ac7cb 100644
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -4168,8 +4168,15 @@ static void yaffs_del_dir_contents(struct yaffs_obj *dir)
if (dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
BUG();
+retry:
list_for_each_safe(lh, n, &dir->variant.dir_variant.children) {
obj = list_entry(lh, struct yaffs_obj, siblings);
+ if (obj->parent == NULL || obj->parent != dir) {
+ yaffs_trace(YAFFS_TRACE_ALWAYS, "List corruption happened in lost_found object %d",
+ dir->obj_id);
+ goto retry;
+ }
+
if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
yaffs_del_dir_contents(obj);
yaffs_trace(YAFFS_TRACE_SCAN,
--
2.12.3