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