mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 15:58:47 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS fixes from Al Viro: "Several fixes + obvious cleanup (you've missed a couple of open-coded can_lookup() back then)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: snd_pcm_link(): fix a leak... use can_lookup() instead of direct checks of ->i_op->lookup move exit_task_namespaces() outside of exit_notify() fput: task_work_add() can fail if the caller has passed exit_task_work() ncpfs: fix rmdir returns Device or resource busy
This commit is contained in:
commit
d0ff934881
@ -306,17 +306,18 @@ void fput(struct file *file)
|
|||||||
{
|
{
|
||||||
if (atomic_long_dec_and_test(&file->f_count)) {
|
if (atomic_long_dec_and_test(&file->f_count)) {
|
||||||
struct task_struct *task = current;
|
struct task_struct *task = current;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
file_sb_list_del(file);
|
file_sb_list_del(file);
|
||||||
if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) {
|
if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
|
||||||
unsigned long flags;
|
init_task_work(&file->f_u.fu_rcuhead, ____fput);
|
||||||
spin_lock_irqsave(&delayed_fput_lock, flags);
|
if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
|
||||||
list_add(&file->f_u.fu_list, &delayed_fput_list);
|
return;
|
||||||
schedule_work(&delayed_fput_work);
|
|
||||||
spin_unlock_irqrestore(&delayed_fput_lock, flags);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
init_task_work(&file->f_u.fu_rcuhead, ____fput);
|
spin_lock_irqsave(&delayed_fput_lock, flags);
|
||||||
task_work_add(task, &file->f_u.fu_rcuhead, true);
|
list_add(&file->f_u.fu_list, &delayed_fput_list);
|
||||||
|
schedule_work(&delayed_fput_work);
|
||||||
|
spin_unlock_irqrestore(&delayed_fput_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1976,7 +1976,7 @@ static int path_lookupat(int dfd, const char *name,
|
|||||||
err = complete_walk(nd);
|
err = complete_walk(nd);
|
||||||
|
|
||||||
if (!err && nd->flags & LOOKUP_DIRECTORY) {
|
if (!err && nd->flags & LOOKUP_DIRECTORY) {
|
||||||
if (!nd->inode->i_op->lookup) {
|
if (!can_lookup(nd->inode)) {
|
||||||
path_put(&nd->path);
|
path_put(&nd->path);
|
||||||
err = -ENOTDIR;
|
err = -ENOTDIR;
|
||||||
}
|
}
|
||||||
@ -2850,7 +2850,7 @@ finish_lookup:
|
|||||||
if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
|
if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
|
||||||
goto out;
|
goto out;
|
||||||
error = -ENOTDIR;
|
error = -ENOTDIR;
|
||||||
if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup)
|
if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
|
||||||
goto out;
|
goto out;
|
||||||
audit_inode(name, nd->path.dentry, 0);
|
audit_inode(name, nd->path.dentry, 0);
|
||||||
finish_open:
|
finish_open:
|
||||||
|
@ -1029,15 +1029,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
DPRINTK("ncp_rmdir: removing %s/%s\n",
|
DPRINTK("ncp_rmdir: removing %s/%s\n",
|
||||||
dentry->d_parent->d_name.name, dentry->d_name.name);
|
dentry->d_parent->d_name.name, dentry->d_name.name);
|
||||||
|
|
||||||
/*
|
|
||||||
* fail with EBUSY if there are still references to this
|
|
||||||
* directory.
|
|
||||||
*/
|
|
||||||
dentry_unhash(dentry);
|
|
||||||
error = -EBUSY;
|
|
||||||
if (!d_unhashed(dentry))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
len = sizeof(__name);
|
len = sizeof(__name);
|
||||||
error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
|
error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
|
||||||
dentry->d_name.len, !ncp_preserve_case(dir));
|
dentry->d_name.len, !ncp_preserve_case(dir));
|
||||||
|
@ -649,7 +649,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
|
|||||||
* jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
* jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
||||||
*/
|
*/
|
||||||
forget_original_parent(tsk);
|
forget_original_parent(tsk);
|
||||||
exit_task_namespaces(tsk);
|
|
||||||
|
|
||||||
write_lock_irq(&tasklist_lock);
|
write_lock_irq(&tasklist_lock);
|
||||||
if (group_dead)
|
if (group_dead)
|
||||||
@ -795,6 +794,7 @@ void do_exit(long code)
|
|||||||
exit_shm(tsk);
|
exit_shm(tsk);
|
||||||
exit_files(tsk);
|
exit_files(tsk);
|
||||||
exit_fs(tsk);
|
exit_fs(tsk);
|
||||||
|
exit_task_namespaces(tsk);
|
||||||
exit_task_work(tsk);
|
exit_task_work(tsk);
|
||||||
check_stack_usage();
|
check_stack_usage();
|
||||||
exit_thread();
|
exit_thread();
|
||||||
|
@ -1649,6 +1649,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||||||
}
|
}
|
||||||
if (!snd_pcm_stream_linked(substream)) {
|
if (!snd_pcm_stream_linked(substream)) {
|
||||||
substream->group = group;
|
substream->group = group;
|
||||||
|
group = NULL;
|
||||||
spin_lock_init(&substream->group->lock);
|
spin_lock_init(&substream->group->lock);
|
||||||
INIT_LIST_HEAD(&substream->group->substreams);
|
INIT_LIST_HEAD(&substream->group->substreams);
|
||||||
list_add_tail(&substream->link_list, &substream->group->substreams);
|
list_add_tail(&substream->link_list, &substream->group->substreams);
|
||||||
@ -1663,8 +1664,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||||||
_nolock:
|
_nolock:
|
||||||
snd_card_unref(substream1->pcm->card);
|
snd_card_unref(substream1->pcm->card);
|
||||||
fput_light(file, fput_needed);
|
fput_light(file, fput_needed);
|
||||||
if (res < 0)
|
kfree(group);
|
||||||
kfree(group);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user