summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/tnc.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2017-05-17 00:20:27 +0200
committerRichard Weinberger <richard@nod.at>2017-07-14 22:49:04 +0200
commit272eda8298dc82eb411ece82bbb2c62911087b24 (patch)
tree5772eeddfafe6006785b13774dc221f92403b4b1 /fs/ubifs/tnc.c
parentubifs: Unexport ubifs_inode_slab (diff)
downloadlinux-272eda8298dc82eb411ece82bbb2c62911087b24.tar.xz
linux-272eda8298dc82eb411ece82bbb2c62911087b24.zip
ubifs: Correctly evict xattr inodes
UBIFS handles extended attributes just like files, as consequence of that, they also have inodes. Therefore UBIFS does all the inode machinery also for xattrs. Since new inodes have i_nlink of 1, a file or xattr inode will be evicted if i_nlink goes down to 0 after an unlink. UBIFS assumes this model also for xattrs, which is not correct. One can create a file "foo" with xattr "user.test". By reading "user.test" an inode will be created, and by deleting "user.test" it will get evicted later. The assumption breaks if the file "foo", which hosts the xattrs, will be removed. VFS nor UBIFS does not remove each xattr via ubifs_xattr_remove(), it just removes the host inode from the TNC and all underlying xattr nodes too and the inode will remain in the cache and wastes memory. To solve this problem, remove xattr inodes from the VFS inode cache in ubifs_xattr_remove() to make sure that they get evicted. Fixes: 1e51764a3c2ac05a ("UBIFS: add new flash file system") Cc: <stable@vger.kernel.org> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/tnc.c')
-rw-r--r--fs/ubifs/tnc.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 709aa098dd46..96374a39ffba 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -2802,6 +2802,8 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
dbg_tnc("xent '%s', ino %lu", xent->name,
(unsigned long)xattr_inum);
+ ubifs_evict_xattr_inode(c, xattr_inum);
+
fname_name(&nm) = xent->name;
fname_len(&nm) = le16_to_cpu(xent->nlen);
err = ubifs_tnc_remove_nm(c, &key1, &nm);