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
5 changed files with 15 additions and 23 deletions
|
@ -306,17 +306,18 @@ void fput(struct file *file)
|
|||
{
|
||||
if (atomic_long_dec_and_test(&file->f_count)) {
|
||||
struct task_struct *task = current;
|
||||
file_sb_list_del(file);
|
||||
if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) {
|
||||
unsigned long flags;
|
||||
|
||||
file_sb_list_del(file);
|
||||
if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
|
||||
init_task_work(&file->f_u.fu_rcuhead, ____fput);
|
||||
if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&delayed_fput_lock, flags);
|
||||
list_add(&file->f_u.fu_list, &delayed_fput_list);
|
||||
schedule_work(&delayed_fput_work);
|
||||
spin_unlock_irqrestore(&delayed_fput_lock, flags);
|
||||
return;
|
||||
}
|
||||
init_task_work(&file->f_u.fu_rcuhead, ____fput);
|
||||
task_work_add(task, &file->f_u.fu_rcuhead, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1976,7 +1976,7 @@ static int path_lookupat(int dfd, const char *name,
|
|||
err = complete_walk(nd);
|
||||
|
||||
if (!err && nd->flags & LOOKUP_DIRECTORY) {
|
||||
if (!nd->inode->i_op->lookup) {
|
||||
if (!can_lookup(nd->inode)) {
|
||||
path_put(&nd->path);
|
||||
err = -ENOTDIR;
|
||||
}
|
||||
|
@ -2850,7 +2850,7 @@ finish_lookup:
|
|||
if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
|
||||
goto out;
|
||||
error = -ENOTDIR;
|
||||
if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup)
|
||||
if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
|
||||
goto out;
|
||||
audit_inode(name, nd->path.dentry, 0);
|
||||
finish_open:
|
||||
|
|
|
@ -1029,15 +1029,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
DPRINTK("ncp_rmdir: removing %s/%s\n",
|
||||
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);
|
||||
error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
|
||||
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)
|
||||
*/
|
||||
forget_original_parent(tsk);
|
||||
exit_task_namespaces(tsk);
|
||||
|
||||
write_lock_irq(&tasklist_lock);
|
||||
if (group_dead)
|
||||
|
@ -795,6 +794,7 @@ void do_exit(long code)
|
|||
exit_shm(tsk);
|
||||
exit_files(tsk);
|
||||
exit_fs(tsk);
|
||||
exit_task_namespaces(tsk);
|
||||
exit_task_work(tsk);
|
||||
check_stack_usage();
|
||||
exit_thread();
|
||||
|
|
|
@ -1649,6 +1649,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||
}
|
||||
if (!snd_pcm_stream_linked(substream)) {
|
||||
substream->group = group;
|
||||
group = NULL;
|
||||
spin_lock_init(&substream->group->lock);
|
||||
INIT_LIST_HEAD(&substream->group->substreams);
|
||||
list_add_tail(&substream->link_list, &substream->group->substreams);
|
||||
|
@ -1663,7 +1664,6 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||
_nolock:
|
||||
snd_card_unref(substream1->pcm->card);
|
||||
fput_light(file, fput_needed);
|
||||
if (res < 0)
|
||||
kfree(group);
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue