Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcb1875a authored by Al Viro's avatar Al Viro Committed by Greg Kroah-Hartman
Browse files

make sure that freeing shmem fast symlinks is RCU-delayed



commit 3ed47db34f480df7caf44436e3e63e555351ae9a upstream.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a83b3498
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -15,10 +15,7 @@ struct shmem_inode_info {
	unsigned int		seals;		/* shmem seals */
	unsigned long		flags;
	unsigned long		alloced;	/* data pages alloced to file */
	union {
	unsigned long		swapped;	/* subtotal assigned to swap */
		char		*symlink;	/* unswappable short symlink */
	};
	struct shared_policy	policy;		/* NUMA memory alloc policy */
	struct list_head	swaplist;	/* chain of maybes on swap */
	struct simple_xattrs	xattrs;		/* list of xattrs */
+4 −5
Original line number Diff line number Diff line
@@ -620,8 +620,7 @@ static void shmem_evict_inode(struct inode *inode)
			list_del_init(&info->swaplist);
			mutex_unlock(&shmem_swaplist_mutex);
		}
	} else
		kfree(info->symlink);
	}

	simple_xattrs_free(&info->xattrs);
	WARN_ON(inode->i_blocks);
@@ -2462,13 +2461,12 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
	info = SHMEM_I(inode);
	inode->i_size = len-1;
	if (len <= SHORT_SYMLINK_LEN) {
		info->symlink = kmemdup(symname, len, GFP_KERNEL);
		if (!info->symlink) {
		inode->i_link = kmemdup(symname, len, GFP_KERNEL);
		if (!inode->i_link) {
			iput(inode);
			return -ENOMEM;
		}
		inode->i_op = &shmem_short_symlink_operations;
		inode->i_link = info->symlink;
	} else {
		error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
		if (error) {
@@ -3083,6 +3081,7 @@ static struct inode *shmem_alloc_inode(struct super_block *sb)
static void shmem_destroy_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kfree(inode->i_link);
	kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
}