Re: [patch-2.4.0-test5-pre1] nullfs and forced umount

From: Manfred Spraul (manfred@colorfullife.com)
Date: Tue Jul 18 2000 - 15:13:30 EST


Tigran Aivazian wrote:
>
> On Tue, 18 Jul 2000, Tigran Aivazian wrote:
> > repeat:
> > read_lock(&tasklist_lock);
> > for_each_task(p) {
> > blabla, need to block next
> > task_lock(p);
> > get_task_struct(p);
> > task_unlock(p);
> > read_unlock(&tasklist_lock);
> > block and manipulate p
> > goto repeat;
> > }
>
> actually, the above is wrong - there is no need for task_lock/unlock
> around get_task_struct because the count is atomic. Also, where is
> put_task_struct() (which should atomic_dec() the same count).
>

Ok, my mail was a bit too short.
The task_lock is required around reading tsk->mm, ->fs and ->files,
otherwise you can race with concurrent do_exit's or do_execve calls.

<<<<<<<<<<
repeat:
read_lock(&task_lock);
for_each_task(p) {
        task_lock(p);
        /* Now dereferencing p->mm, p->fs and p->files is safe,
           they won't be destroyed while we look at them.
         */
        tsk_mm = p->mm;
        tsk_fs = p->fs;
        atomic_inc(&tsk_mm->mm_users);
        atomic_inc(&tsk_fs->count);
        task_unlock(p);
        if(I_must_block) {
                read_unlock(&task_lock);
                /* you cannot touch tsk from this line on,
                   but tsk_fs and tsk_mm are safe */
                put_fs_struct(tsk_fs);
                mmput(tsk_mm);
                goto repeat;
        }
}
>>>>>>>>>>>

You can find sample code in kernel/ptrace.c + arch/i386/kernel/ptrace.c
or fs/proc/{base,array}.c.
If you must access a field in tsk after the read_unlock(task_lock), then
you must use get_task_struct() + free_task_struct().

--
	Manfred

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jul 23 2000 - 21:00:11 EST