Hi, Ingo We plan to add path_walk() to the end of generic_send_file in output.c since this is the best location for us to know which file is cache missed, but we found kernel always crashed after we add our code to output.c and rebuild TUX and restart TUX. Here I pasted the modified generic_send_file(), the codes between "--------------" are added by us. How can I do to avoid kernel crash. Thank you. Liang ---------------------------------the data structure we defined at the beginning of output.c----------------- tux_req_t my_req[50]; int current_p=0; ---------------------------------the data structure we defined at the beginning of output.c----------------- int generic_send_file (tux_req_t *req, struct socket *sock, int cachemiss) { sock_send_desc_t sock_desc; int len, want, nonblock = !cachemiss; int i, j,missed,err; //added by Victor struct nameidata base; char buf[10]; sock->sk->tp_pinfo.af_tcp.nonagle = 2; sock_desc.sock = sock; sock_desc.req = req; repeat: Dprintk("generic_send_file(%p,%d,%p) called, f_pos: %Ld, output_len: %Ld.\n", req, nonblock, sock, req->in_file.f_pos, req->output_len); if (req->proto->check_req_err(req, cachemiss)) return -1; if (connection_too_fast(req) == 2) { len = -5; goto out; } if (req->total_file_len < req->in_file.f_pos) TUX_BUG(); req->desc.written = 0; /* * Careful, output_len can be 64-bit, while 'want' can be 32-bit. */ if (req->output_len > SEND_BLOCKSIZE) want = SEND_BLOCKSIZE; else want = req->output_len; req->desc.count = want; req->desc.buf = (char *) &sock_desc; req->desc.error = 0; Dprintk("sendfile(), desc.count: %d.\n", req->desc.count); do_generic_file_read(&req->in_file, &req->in_file.f_pos, &req->desc, sock_send_actor, nonblock); if (req->desc.written > 0) { req->bytes_sent += req->desc.written; req->output_len -= req->desc.written; } if (!nonblock && (req->desc.error == -EWOULDBLOCKIO)) TUX_BUG(); Dprintk("sendfile() wrote: %d bytes.\n", req->desc.written); if (req->output_len && !req->desc.written && !req->desc.error) { #if CONFIG_TUX_DEBUG req->bytes_expected = 0; #endif req->in_file.f_pos = 0; req->error = TUX_ERROR_CONN_CLOSE; zap_request(req, cachemiss); return -1; } switch (req->desc.error) { case -EWOULDBLOCKIO: len = -3; break; case -EAGAIN: no_write_space: Dprintk("sk->wmem_queued: %d, sk->sndbuf: %d.\n", sock->sk->wmem_queued, sock->sk->sndbuf); len = -4; break; default: len = req->desc.written; #if CONFIG_TUX_DEBUG if (req->desc.error) TDprintk("TUX: sendfile() returned error %d (signals pending: %08lx)!\n", req->desc.error, current->pending.signal.sig[0]); #endif if (!req->desc.error) { if (req->output_len < 0) BUG(); if (req->output_len) { if (test_bit(SOCK_NOSPACE, &sock->flags)) goto no_write_space; goto repeat; } } #if CONFIG_TUX_DEBUG if (req->desc.written != want) TDprintk("TUX: sendfile() wrote %d bytes, wanted %d! (pos %Ld) (signals pending: %08lx).\n", req->desc.written, want, req->in_file.f_pos, current->pending.signal.sig[0]); else Dprintk("TUX: sendfile() FINISHED for req %p, wrote %d bytes.\n", req, req->desc.written); req->bytes_expected = 0; #endif break; } out: Dprintk("sendfile() wrote %d bytes.\n", len); ------------------------------------------------------------------added----- ----------------------------------------------- for(i=0;i<current_p;i++) { Dprintk("in cache loop i=%d\n",i); base.flags = LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_ATOMIC; base.last_type = LAST_ROOT; if (my_req[i].objectname[0] == '/') { base.dentry = dget(my_req[i].docroot_dentry); base.mnt = mntget(my_req[i].docroot_mnt); } else { if (!my_req[i].cwd_dentry) { my_req[i].cwd_dentry = dget(my_req[i].docroot_dentry); my_req[i].cwd_mnt = mntget(my_req[i].docroot_mnt); } base.dentry = my_req[i].cwd_dentry; dget(base.dentry); base.mnt = mntget(my_req[i].cwd_mnt); } err = path_walk(my_req[i].objectname, &base); if (err) { Dprintk("path_walk() returned with %d!\n", err); return ERR_PTR(err); } // set the parameters of file_read my_req[i].dentry = base.dentry; my_req[i].mnt = base.mnt; if (base.dentry) init_private_file(&my_req[i].in_file, base.dentry, FMODE_READ); my_req[i].desc.buf = buf; do_generic_file_read(&my_req[i].in_file, &my_req[i].in_file.f_pos, &my_req[i].desc, file_fetch_actor, 1); if (my_req[i].desc.error == -EWOULDBLOCKIO) { return 1; // send notify message to proxy Dprintk("---------> Bunnybear, Read failed\n"); Dprintk("---------> Oooops, %s was discarded(my_req[%d]) !!! \n", my_req[i].objectname, i); // discard current req, pack the array for(j=i+1;j<current_p;j++) { my_req[j-1] = my_req[j]; } // current_p--; } else{ Dprintk("Read successfully\n"); } } // copy the current req to our array my_req[current_p] = *req; current_p++; Dprintk("current_p=%d\n",current_p); ---------------------------------------------------------added-------------- ------------------------------------------------------------- return len; }