(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/