trans_virtio.c (2c06aeb25ca92b839399c4e2c956cffc95b41978) trans_virtio.c (0b36f1adcb5adace6d45ca4d9a0f00860e60d012)
1/*
2 * The Virtio 9p transport driver
3 *
4 * This is a block based transport driver based on the lguest block driver
5 * code.
6 *
7 * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
8 *

--- 180 unchanged lines hidden (view full) ---

189 int s;
190 int index = start;
191
192 while (count) {
193 s = rest_of_page(data);
194 if (s > count)
195 s = count;
196 BUG_ON(index > limit);
1/*
2 * The Virtio 9p transport driver
3 *
4 * This is a block based transport driver based on the lguest block driver
5 * code.
6 *
7 * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
8 *

--- 180 unchanged lines hidden (view full) ---

189 int s;
190 int index = start;
191
192 while (count) {
193 s = rest_of_page(data);
194 if (s > count)
195 s = count;
196 BUG_ON(index > limit);
197 /* Make sure we don't terminate early. */
198 sg_unmark_end(&sg[index]);
197 sg_set_buf(&sg[index++], data, s);
198 count -= s;
199 data += s;
200 }
199 sg_set_buf(&sg[index++], data, s);
200 count -= s;
201 data += s;
202 }
201
203 if (index-start)
204 sg_mark_end(&sg[index - 1]);
202 return index-start;
203}
204
205/* We don't currently allow canceling of virtio requests */
206static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
207{
208 return 1;
209}

--- 21 unchanged lines hidden (view full) ---

231 * if the first page doesn't start at
232 * page boundary find the offset
233 */
234 data_off = offset_in_page(data);
235 while (nr_pages) {
236 s = rest_of_page(data);
237 if (s > count)
238 s = count;
205 return index-start;
206}
207
208/* We don't currently allow canceling of virtio requests */
209static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
210{
211 return 1;
212}

--- 21 unchanged lines hidden (view full) ---

234 * if the first page doesn't start at
235 * page boundary find the offset
236 */
237 data_off = offset_in_page(data);
238 while (nr_pages) {
239 s = rest_of_page(data);
240 if (s > count)
241 s = count;
242 /* Make sure we don't terminate early. */
243 sg_unmark_end(&sg[index]);
239 sg_set_page(&sg[index++], pdata[i++], s, data_off);
240 data_off = 0;
241 data += s;
242 count -= s;
243 nr_pages--;
244 }
244 sg_set_page(&sg[index++], pdata[i++], s, data_off);
245 data_off = 0;
246 data += s;
247 count -= s;
248 nr_pages--;
249 }
250
251 if (index-start)
252 sg_mark_end(&sg[index - 1]);
245 return index - start;
246}
247
248/**
249 * p9_virtio_request - issue a request
250 * @client: client instance issuing the request
251 * @req: request to be issued
252 *
253 */
254
255static int
256p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
257{
258 int err;
253 return index - start;
254}
255
256/**
257 * p9_virtio_request - issue a request
258 * @client: client instance issuing the request
259 * @req: request to be issued
260 *
261 */
262
263static int
264p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
265{
266 int err;
259 int in, out;
267 int in, out, out_sgs, in_sgs;
260 unsigned long flags;
261 struct virtio_chan *chan = client->trans;
268 unsigned long flags;
269 struct virtio_chan *chan = client->trans;
270 struct scatterlist *sgs[2];
262
263 p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
264
265 req->status = REQ_STATUS_SENT;
266req_retry:
267 spin_lock_irqsave(&chan->lock, flags);
268
271
272 p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
273
274 req->status = REQ_STATUS_SENT;
275req_retry:
276 spin_lock_irqsave(&chan->lock, flags);
277
278 out_sgs = in_sgs = 0;
269 /* Handle out VirtIO ring buffers */
270 out = pack_sg_list(chan->sg, 0,
271 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
279 /* Handle out VirtIO ring buffers */
280 out = pack_sg_list(chan->sg, 0,
281 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
282 if (out)
283 sgs[out_sgs++] = chan->sg;
272
273 in = pack_sg_list(chan->sg, out,
274 VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
284
285 in = pack_sg_list(chan->sg, out,
286 VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
287 if (in)
288 sgs[out_sgs + in_sgs++] = chan->sg + out;
275
289
276 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc,
290 err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
277 GFP_ATOMIC);
278 if (err < 0) {
279 if (err == -ENOSPC) {
280 chan->ring_bufs_avail = 0;
281 spin_unlock_irqrestore(&chan->lock, flags);
282 err = wait_event_interruptible(*chan->vc_wq,
283 chan->ring_bufs_avail);
284 if (err == -ERESTARTSYS)
285 return err;
286
287 p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
288 goto req_retry;
289 } else {
290 spin_unlock_irqrestore(&chan->lock, flags);
291 p9_debug(P9_DEBUG_TRANS,
291 GFP_ATOMIC);
292 if (err < 0) {
293 if (err == -ENOSPC) {
294 chan->ring_bufs_avail = 0;
295 spin_unlock_irqrestore(&chan->lock, flags);
296 err = wait_event_interruptible(*chan->vc_wq,
297 chan->ring_bufs_avail);
298 if (err == -ERESTARTSYS)
299 return err;
300
301 p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
302 goto req_retry;
303 } else {
304 spin_unlock_irqrestore(&chan->lock, flags);
305 p9_debug(P9_DEBUG_TRANS,
292 "virtio rpc add_buf returned failure\n");
306 "virtio rpc add_sgs returned failure\n");
293 return -EIO;
294 }
295 }
296 virtqueue_kick(chan->vq);
297 spin_unlock_irqrestore(&chan->lock, flags);
298
299 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
300 return 0;

--- 45 unchanged lines hidden (view full) ---

346 * @hdrlen: reader header size, This is the size of response protocol data
347 *
348 */
349static int
350p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
351 char *uidata, char *uodata, int inlen,
352 int outlen, int in_hdr_len, int kern_buf)
353{
307 return -EIO;
308 }
309 }
310 virtqueue_kick(chan->vq);
311 spin_unlock_irqrestore(&chan->lock, flags);
312
313 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
314 return 0;

--- 45 unchanged lines hidden (view full) ---

360 * @hdrlen: reader header size, This is the size of response protocol data
361 *
362 */
363static int
364p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
365 char *uidata, char *uodata, int inlen,
366 int outlen, int in_hdr_len, int kern_buf)
367{
354 int in, out, err;
368 int in, out, err, out_sgs, in_sgs;
355 unsigned long flags;
356 int in_nr_pages = 0, out_nr_pages = 0;
357 struct page **in_pages = NULL, **out_pages = NULL;
358 struct virtio_chan *chan = client->trans;
369 unsigned long flags;
370 int in_nr_pages = 0, out_nr_pages = 0;
371 struct page **in_pages = NULL, **out_pages = NULL;
372 struct virtio_chan *chan = client->trans;
373 struct scatterlist *sgs[4];
359
360 p9_debug(P9_DEBUG_TRANS, "virtio request\n");
361
362 if (uodata) {
363 out_nr_pages = p9_nr_pages(uodata, outlen);
364 out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
365 GFP_NOFS);
366 if (!out_pages) {

--- 24 unchanged lines hidden (view full) ---

391 kfree(in_pages);
392 in_pages = NULL;
393 goto err_out;
394 }
395 }
396 req->status = REQ_STATUS_SENT;
397req_retry_pinned:
398 spin_lock_irqsave(&chan->lock, flags);
374
375 p9_debug(P9_DEBUG_TRANS, "virtio request\n");
376
377 if (uodata) {
378 out_nr_pages = p9_nr_pages(uodata, outlen);
379 out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
380 GFP_NOFS);
381 if (!out_pages) {

--- 24 unchanged lines hidden (view full) ---

406 kfree(in_pages);
407 in_pages = NULL;
408 goto err_out;
409 }
410 }
411 req->status = REQ_STATUS_SENT;
412req_retry_pinned:
413 spin_lock_irqsave(&chan->lock, flags);
414
415 out_sgs = in_sgs = 0;
416
399 /* out data */
400 out = pack_sg_list(chan->sg, 0,
401 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
402
417 /* out data */
418 out = pack_sg_list(chan->sg, 0,
419 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
420
403 if (out_pages)
421 if (out)
422 sgs[out_sgs++] = chan->sg;
423
424 if (out_pages) {
425 sgs[out_sgs++] = chan->sg + out;
404 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
405 out_pages, out_nr_pages, uodata, outlen);
426 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
427 out_pages, out_nr_pages, uodata, outlen);
428 }
429
406 /*
407 * Take care of in data
408 * For example TREAD have 11.
409 * 11 is the read/write header = PDU Header(7) + IO Size (4).
410 * Arrange in such a way that server places header in the
411 * alloced memory and payload onto the user buffer.
412 */
413 in = pack_sg_list(chan->sg, out,
414 VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
430 /*
431 * Take care of in data
432 * For example TREAD have 11.
433 * 11 is the read/write header = PDU Header(7) + IO Size (4).
434 * Arrange in such a way that server places header in the
435 * alloced memory and payload onto the user buffer.
436 */
437 in = pack_sg_list(chan->sg, out,
438 VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
415 if (in_pages)
439 if (in)
440 sgs[out_sgs + in_sgs++] = chan->sg + out;
441
442 if (in_pages) {
443 sgs[out_sgs + in_sgs++] = chan->sg + out + in;
416 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
417 in_pages, in_nr_pages, uidata, inlen);
444 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
445 in_pages, in_nr_pages, uidata, inlen);
446 }
418
447
419 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc,
448 BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
449 err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
420 GFP_ATOMIC);
421 if (err < 0) {
422 if (err == -ENOSPC) {
423 chan->ring_bufs_avail = 0;
424 spin_unlock_irqrestore(&chan->lock, flags);
425 err = wait_event_interruptible(*chan->vc_wq,
426 chan->ring_bufs_avail);
427 if (err == -ERESTARTSYS)
428 goto err_out;
429
430 p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
431 goto req_retry_pinned;
432 } else {
433 spin_unlock_irqrestore(&chan->lock, flags);
434 p9_debug(P9_DEBUG_TRANS,
450 GFP_ATOMIC);
451 if (err < 0) {
452 if (err == -ENOSPC) {
453 chan->ring_bufs_avail = 0;
454 spin_unlock_irqrestore(&chan->lock, flags);
455 err = wait_event_interruptible(*chan->vc_wq,
456 chan->ring_bufs_avail);
457 if (err == -ERESTARTSYS)
458 goto err_out;
459
460 p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
461 goto req_retry_pinned;
462 } else {
463 spin_unlock_irqrestore(&chan->lock, flags);
464 p9_debug(P9_DEBUG_TRANS,
435 "virtio rpc add_buf returned failure\n");
465 "virtio rpc add_sgs returned failure\n");
436 err = -EIO;
437 goto err_out;
438 }
439 }
440 virtqueue_kick(chan->vq);
441 spin_unlock_irqrestore(&chan->lock, flags);
442 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
443 err = wait_event_interruptible(*req->wq,

--- 249 unchanged lines hidden ---
466 err = -EIO;
467 goto err_out;
468 }
469 }
470 virtqueue_kick(chan->vq);
471 spin_unlock_irqrestore(&chan->lock, flags);
472 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
473 err = wait_event_interruptible(*req->wq,

--- 249 unchanged lines hidden ---