(2.4 question) open_namei hangs
From: Shan Sinha
Date: Sun Nov 09 2003 - 20:50:37 EST
Hi everyone-
I know everyone is probably focused on 2.6 right now, but I hope someone
will have the time to answer this question about 2.4.20! I'm extremely
confused, and am not sure what work-around I could employ.
I am trying to read the contents of a file from a kernel thread, spawned
when an LKM is insmod'ed. open_namei appears to hang. The LKM is
something that I created. When I call filp_open("/mydirectory",
O_RDONLY, 0), and then subsequently call vfs_readdir on the returned
file *, it traverses the files in the directory correctly.
However, in the call back passed to vfs_readdir, if I try to do a
filp_open("/mydirectory/file1"), where "file1" is the string passed to
the call back, filp_open appears to hang somewhere inside open_namei (I
verified this by modifying filp_open).
But! if I do "touch /mydirectory/*" in user space before I insert the
module and spawn my thread, the open and subsequent read for any files
in /mydirectory work fine.
I suspect this is something to do with the files being loaded into the
buffer cache and my doing something incorrectly with respect to being in
a kernel thread. Does anyone have any ideas of what may be happening?
I have included snips of the relevant code below. I guessing my thread
is getting deadlocked somehow when the kernel has to go to disk to fetch
the file. However, I created the code using khttpd as a sample (not
sure if this was a mistake).
Cheers-
Shan Sinha
Network and Mobile Systems
MIT CSAIL
ssinha@xxxxxxxxxxx
------------------------------------------------------------
int my_callback(void * buf, const char * name, int namlen, loff_t
offset,
ino_t ino, unsigned int d_type)
{
// for each file
if (d_type == DT_REG) {
struct file * f;
read_descriptor_t read_desc;
char * file_name = make_file_name("/mydirectory/", name, namlen);
printk(KERN_INFO "loading file: %s\n", file_name);
// WE HANG IN HERE (IF FILES HAVE NOT BEEN LOADED INTO BUFFER
CACHE??)!!!
f = filp_open(file_name, O_RDONLY, 0);
printk(KERN_INFO "opened file: %s\n", file_name);
// Code snipped - set up code for call to do_generic_file_read
// Code snipped - call to do_generic_file_read
kfree(file_name);
}
return 0;
}
// Main daemon thread
int pm_daemon(void * data)
{
DECLARE_WAIT_QUEUE_HEAD(WQ);
sigset_t tmpsig;
daemon_running = 1;
leave_daemon_running = 1;
sprintf(current->comm, "mythread");
daemonize();
/* Code snipped that blocks all signals except SIGKILL and SIGTERM */
/* main loop */
while (leave_daemon_running) {
int signal_counter = 0;
// count the number of files
int num_files = 0;
struct file * f = filp_open("/mydirectory/", O_RDONLY, 0);
vfs_readdir(f, file_counter, &num_files);
// loop through all files
fput(f);
printk(KERN_INFO "Counted files: %d\n", num_files );
f = filp_open("/mydirectory/", O_RDONLY, 0);
vfs_readdir(f, my_callback, NULL);
// code snipped sleep and respond to signals
}
leave_daemon_running = 0;
daemon_running = 0;
return 0;
}
// called on module init
void pm_init(void)
{
if (!daemon_running)
kernel_thread(pm_daemon, NULL, CLONE_FS | CLONE_FILES |
CLONE_SIGHAND);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/