Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Jun 2005 16:40:29 +0300
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        Seb <sebastien.b@swissinfo.org>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Accessing filesystem from a KLD
Message-ID:  <20050629134029.GA220@pm514-9.comsys.ntu-kpi.kiev.ua>
In-Reply-To: <200506291155.50929.sebastien.b@swissinfo.org>
References:  <200506251203.13569.sebastien.b@swissinfo.org> <200506291051.01760.sebastien.b@swissinfo.org> <20050629091211.GA438@pm514-9.comsys.ntu-kpi.kiev.ua> <200506291155.50929.sebastien.b@swissinfo.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Jun 29, 2005 at 11:55:50AM +0200, Seb wrote:
> > Why not to use VOP_READ?  See how it is called in dev/md.c:mdstart_vnode,
> > check kern/vfs_vnops.c:vn_open_cred for information how to lookup a file
> > name and open it.
> 
> That's what I do, however I use the wrapper functions vn_open(), vn_rdwr() and 
> so.
> 
> But I have a problem, when I call this code :
> 
> void *request_firmware(const char *name, size_t *size)
> {
> int flags;
> char filename[40];
> struct nameidata nd;
> struct thread *td = curthread;
> [...]
> NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, &filename[0], td);
> flags = FREAD;
> vn_open(&nd, &flags, 0, -1);
> [...]
> }
> 
> from the KLD handler function (for testing) it works. But when I call it from 
> a thread created by kthread_create() in another KLD, I have a page fault.
> A few printfs show that the call to vn_open() is responsible for the fault.
> I have not forgotten to lock Giant in my kernel thread.
> Any ideas ?

You got page fault from namei(), which is called from vn_open() to lookup
a path name.  namei() tries to obtain a reference on current directory for
the current thread.  This current directory (fd_cdir field) is NULL in
your kthread.  At this point a page fault in kernel address space is
generated.

More detail:  Check in kthread_create() how new kthread is created,
check flag RFFDG in fork1().  Since new kthread is created from thread0
and RFFDG is on, then new kthread will copy descriptor table from proc0.
proc0 has descriptor table created by fdinit() in proc0_init().  fdinit()
sets fd_cdir (current directory) to 0 (the same as NULL in /sys).

Can you change fd_cdir in kthread to rootvnode I don't know, haven't
checked this yet.  But you can open a file in syscall and then use
obtained vp in your kthread for VOP_READ call.

It would be better to see backtrace of above mentioned page fault.
But I guess that everything happened as I described.

Hope this can help.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050629134029.GA220>