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