Skip to content

Commit 8009ce9

Browse files
ubifs: Don't leak orphans on memory during commit
If an orphan has child orphans (xattrs), and due to a commit the parent orpahn cannot get free()'ed immediately, put also all child orphans on the erase list. Otherwise UBIFS will free() them only upon unmount and we waste memory. Fixes: 988bec4 ("ubifs: orphan: Handle xattrs like files") Signed-off-by: Richard Weinberger <[email protected]>
1 parent ee1438c commit 8009ce9

File tree

1 file changed

+24
-26
lines changed

1 file changed

+24
-26
lines changed

fs/ubifs/orphan.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,25 +126,11 @@ static void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o)
126126
kfree(o);
127127
}
128128

129-
static void orphan_delete(struct ubifs_info *c, ino_t inum)
129+
static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
130130
{
131-
struct ubifs_orphan *orph, *child_orph, *tmp_o;
132-
133-
spin_lock(&c->orphan_lock);
134-
135-
orph = lookup_orphan(c, inum);
136-
if (!orph) {
137-
spin_unlock(&c->orphan_lock);
138-
ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum);
139-
dump_stack();
140-
141-
return;
142-
}
143-
144131
if (orph->del) {
145132
spin_unlock(&c->orphan_lock);
146-
dbg_gen("deleted twice ino %lu",
147-
(unsigned long)inum);
133+
dbg_gen("deleted twice ino %lu", orph->inum);
148134
return;
149135
}
150136

@@ -153,19 +139,11 @@ static void orphan_delete(struct ubifs_info *c, ino_t inum)
153139
orph->dnext = c->orph_dnext;
154140
c->orph_dnext = orph;
155141
spin_unlock(&c->orphan_lock);
156-
dbg_gen("delete later ino %lu",
157-
(unsigned long)inum);
142+
dbg_gen("delete later ino %lu", orph->inum);
158143
return;
159144
}
160145

161-
list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) {
162-
list_del(&child_orph->child_list);
163-
__orphan_drop(c, child_orph);
164-
}
165-
166146
__orphan_drop(c, orph);
167-
168-
spin_unlock(&c->orphan_lock);
169147
}
170148

171149
/**
@@ -223,7 +201,27 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
223201
*/
224202
void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
225203
{
226-
orphan_delete(c, inum);
204+
struct ubifs_orphan *orph, *child_orph, *tmp_o;
205+
206+
spin_lock(&c->orphan_lock);
207+
208+
orph = lookup_orphan(c, inum);
209+
if (!orph) {
210+
spin_unlock(&c->orphan_lock);
211+
ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum);
212+
dump_stack();
213+
214+
return;
215+
}
216+
217+
list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) {
218+
list_del(&child_orph->child_list);
219+
orphan_delete(c, child_orph);
220+
}
221+
222+
orphan_delete(c, orph);
223+
224+
spin_unlock(&c->orphan_lock);
227225
}
228226

229227
/**

0 commit comments

Comments
 (0)