[ENBD] proxing ioctl's
Peter T. Breuer
ptb@it.uc3m.es
Fri, 16 Mar 2001 16:01:35 +0100 (MET)
"A month of sundays ago Daniel Shane wrote:"
> I was quite busy these two days so I did not have a chance to look at your comments, I'll take the week-end to sort this out, looks pretty interresting.
>
> Btw, the rd.c driver is very different on 2.2.18 so I wonder if your modifications will work on it?
It won't until I do a backport and add whatever is required to the
compatibility layer.
My current changes are in nbd-2.4.23.tgz, which is on the httpd site
and the ftp site (i.e. http://www.it.uc3m.es/ptb/nbd/src/ and
ftp://oboe.it.uc3m.es/pub/Programs/).
Yes, I did a distclean.
You have to load with "buffer_writes=1", or else echo -n "buffer_writes=1"
>/proc/nbdinfo.
I can't get the buffers to go away again! I've tried with
destroy_buffers() as well as with invalidate_buffers(), and they
definitely are still there. Whatever the trick is, it has to be added
to cleanup module.
The current code is horrible, but works, although I suspect that it may
be doing something wrong, but I can't finger what. It looks as though
memory might be filling up with buffers ... but I don't see it. There
doesn't seem to be a buffer count that I can measure anywhere.
I also increased the userspace buffer to 256KB. If people still see
bufferblowing sized requests from the kernel, they should load with
plug=0, or echo -n "plug=0" >/proc/nbdinfo. If the kernel can't plug,
it can't merge requests.
The stuff I added to the nbd_do_request loop for you is too hoorible
at the moment to publish .. but aww, anyway, it looks like this.
PARANOIA_END
if (buffer_writes) {
if ((req->cmd & 0x03) == WRITE) {
struct buffer_head * bh;
// PTB go through and copy and protect the written
// buffers
for (bh = req->bh; bh; bh = bh->b_reqnext) {
struct buffer_head * rbh;
char * bdata;
rbh = getblk(bh->b_rdev,
bh->b_rsector/(bh->b_size>>9), bh->b_size);
bdata = bh_kmap(bh);
if (bh != rbh) {
memcpy(rbh->b_data, bdata, rbh->b_size);
NBD_ALERT ("got new bh sector %lu on write\n",
bh->b_rsector);
}
bh_kunmap(bh);
mark_buffer_protected(rbh);
brelse(rbh);
}
// PTB now ack the source request normally
nbd_end_request(req);
}
else
if ((req->cmd & 0x03) == READ) {
struct buffer_head * bh;
// PTB mama, we have to check each buffer
// individually
for (bh = req->bh; bh; bh = bh->b_reqnext) {
struct buffer_head * rbh;
char * bdata;
rbh = getblk(bh->b_rdev,
bh->b_rsector/(bh->b_size>>9), bh->b_size);
bdata = bh_kmap(bh);
if (bh == rbh) {
// we found it! Surely we should ack this and
// then remove it from the request? Or is it
// just what the kernel wants us to write into?
} else {
// well, this bh surely needs tossing, It's useless.
// is it full of zeros, or what?
rbh->b_end_io(rbh,1);
NBD_ALERT ("got new bh sector %lu on read\n",
bh->b_rsector);
}
}
// only if the req is nonzero, surely?
nbd_enqueue(lo,req);
}
lo->requests_buf += req_blks;
} else {
nbd_enqueue(lo,req);
}