make sure that freeing shmem fast symlinks is RCU-delayed
Cc: stable@vger.kernel.org # v4.2+ Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
5955102c99
commit
3ed47db34f
|
@ -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 */
|
||||
|
|
|
@ -701,8 +701,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);
|
||||
|
@ -2549,13 +2548,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 {
|
||||
inode_nohighmem(inode);
|
||||
error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
|
||||
|
@ -3132,6 +3130,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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue