Skip to contentSkip to conversation

Patch "ubifs: Correctly evict xattr inodes" has been added to the 4.12-stable tree

PATCH [email protected] 1 participant 1 message Jul 25, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ubifs: Correctly evict xattr inodes

to the 4.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ubifs-correctly-evict-xattr-inodes.patch
and it can be found in the queue-4.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 272eda8298dc82eb411ece82bbb2c62911087b24 Mon Sep 17 00:00:00 2001

From: Richard Weinberger <[email protected]>
Date: Wed, 17 May 2017 00:20:27 +0200
Subject: ubifs: Correctly evict xattr inodes

From: Richard Weinberger <[email protected]>

commit 272eda8298dc82eb411ece82bbb2c62911087b24 upstream.

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")
---
 fs/ubifs/tnc.c   |    2 ++
 fs/ubifs/ubifs.h |    1 +
 fs/ubifs/xattr.c |   22 ++++++++++++++++++++++
 3 files changed, 25 insertions(+)
fs/ubifs/tnc.c +2 -0
@@ -2802,6 +2802,8 @@ int ubifs_tnc_remove_ino(struct ubifs_in
 		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);
fs/ubifs/ubifs.h +1 -0
@@ -1757,6 +1757,7 @@ int ubifs_xattr_set(struct inode *host,
 		    size_t size, int flags);
 ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
 			size_t size);
+void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);
 
 #ifdef CONFIG_UBIFS_FS_SECURITY
 extern int ubifs_init_security(struct inode *dentry, struct inode *inode,
fs/ubifs/xattr.c +22 -0
@@ -513,6 +513,28 @@ out_cancel:
 	return err;
 }
 
+/**
+ * ubifs_evict_xattr_inode - Evict an xattr inode.
+ * @c: UBIFS file-system description object
+ * @xattr_inum: xattr inode number
+ *
+ * When an inode that hosts xattrs is being removed we have to make sure
+ * that cached inodes of the xattrs also get removed from the inode cache
+ * otherwise we'd waste memory. This function looks up an inode from the
+ * inode cache and clears the link counter such that iput() will evict
+ * the inode.
+ */
+void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum)
+{
+	struct inode *inode;
+
+	inode = ilookup(c->vfs_sb, xattr_inum);
+	if (inode) {
+		clear_nlink(inode);
+		iput(inode);
+	}
+}
+
 static int ubifs_xattr_remove(struct inode *host, const char *name)
 {
 	struct inode *inode;

Patches currently in stable-queue which might be from [email protected] are

queue-4.12/ubifs-don-t-leak-kernel-memory-to-the-mtd.patch queue-4.12/ubifs-don-t-encrypt-special-files-on-creation.patch queue-4.12/ubifs-correctly-evict-xattr-inodes.patch queue-4.12/ubifs-set-double-hash-cookie-also-for-rename_exchange.patch