Kernel crashed when I add path_walk() in output.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;
}





[Index of Archives]     [Apache Users]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Packaging]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Docs]