From 8ae5d31263c746f1680d005b33a82d167cdb9eb6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 5 May 2007 17:50:25 +0100 Subject: [JFFS2] Fix BUG() caused by failing to discard xattrs on deleted files. When we cannot mark nodes as obsolete, such as on NAND flash, we end up having to delete inodes with !nlink in jffs2_build_remove_unlinked_inode(). However, jffs2_build_xattr_subsystem() runs later than this, and will attach an xref to the dead inode. Then later when the last nodes of that dead inode are erased we hit a BUG() in jffs2_del_ino_cache() because we're not supposed to get there with an xattr still attached to the inode which is being killed. The simple fix is to refrain from attaching xattrs to inodes with zero nlink, in jffs2_build_xattr_subsystem(). It's it's OK to trust nlink here because the file system isn't actually mounted yet, so there's no chance that a zero-nlink file could actually be alive still because it's open. Signed-off-by: David Woodhouse --- fs/jffs2/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/jffs2/xattr.c') diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 78fc08893a6c..073469856d4e 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -825,7 +825,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ref->xd and ref->ic are not valid yet. */ xd = jffs2_find_xattr_datum(c, ref->xid); ic = jffs2_get_ino_cache(c, ref->ino); - if (!xd || !ic) { + if (!xd || !ic || !ic->nlink) { dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n", ref->ino, ref->xid, ref->xseqno); ref->xseqno |= XREF_DELETE_MARKER; -- cgit v1.2.3 From 2ad8ee713566671875216ebcec64f2eda47bd19d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 8 May 2007 00:12:58 +0100 Subject: [JFFS2] Fix potential memory leak of dead xattrs on unmount. An xattr_datum which ends up orphaned should be freed by the GC thread. But if we umount before the GC thread is finished, or if we mount read-only and the GC thread never runs, they might never be freed. Clean them up during unmount, if there are any left. Signed-off-by: David Woodhouse --- fs/jffs2/xattr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/jffs2/xattr.c') diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 073469856d4e..e48665984cb3 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -754,6 +754,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c) list_del(&xd->xindex); jffs2_free_xattr_datum(xd); } + list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { + list_del(&xd->xindex); + jffs2_free_xattr_datum(xd); + } } #define XREF_TMPHASH_SIZE (128) -- cgit v1.2.3