Commit 58ada94f95f71d4f73197ab0e9603dbba6e47fe3
Committed by
Miklos Szeredi
1 parent
00929447f5
virtiofs: Use a common function to send forget
Currently we are duplicating logic to send forgets at two places. Consolidate the code by calling one helper function. This also uses virtqueue_add_outbuf() instead of virtqueue_add_sgs(). Former is simpler to call. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Showing 1 changed file with 63 additions and 87 deletions Side-by-side Diff
fs/fuse/virtio_fs.c
... | ... | @@ -313,17 +313,71 @@ |
313 | 313 | } |
314 | 314 | } |
315 | 315 | |
316 | +/* | |
317 | + * Returns 1 if queue is full and sender should wait a bit before sending | |
318 | + * next request, 0 otherwise. | |
319 | + */ | |
320 | +static int send_forget_request(struct virtio_fs_vq *fsvq, | |
321 | + struct virtio_fs_forget *forget, | |
322 | + bool in_flight) | |
323 | +{ | |
324 | + struct scatterlist sg; | |
325 | + struct virtqueue *vq; | |
326 | + int ret = 0; | |
327 | + bool notify; | |
328 | + | |
329 | + spin_lock(&fsvq->lock); | |
330 | + if (!fsvq->connected) { | |
331 | + if (in_flight) | |
332 | + dec_in_flight_req(fsvq); | |
333 | + kfree(forget); | |
334 | + goto out; | |
335 | + } | |
336 | + | |
337 | + sg_init_one(&sg, forget, sizeof(*forget)); | |
338 | + vq = fsvq->vq; | |
339 | + dev_dbg(&vq->vdev->dev, "%s\n", __func__); | |
340 | + | |
341 | + ret = virtqueue_add_outbuf(vq, &sg, 1, forget, GFP_ATOMIC); | |
342 | + if (ret < 0) { | |
343 | + if (ret == -ENOMEM || ret == -ENOSPC) { | |
344 | + pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n", | |
345 | + ret); | |
346 | + list_add_tail(&forget->list, &fsvq->queued_reqs); | |
347 | + schedule_delayed_work(&fsvq->dispatch_work, | |
348 | + msecs_to_jiffies(1)); | |
349 | + if (!in_flight) | |
350 | + inc_in_flight_req(fsvq); | |
351 | + /* Queue is full */ | |
352 | + ret = 1; | |
353 | + } else { | |
354 | + pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n", | |
355 | + ret); | |
356 | + kfree(forget); | |
357 | + if (in_flight) | |
358 | + dec_in_flight_req(fsvq); | |
359 | + } | |
360 | + goto out; | |
361 | + } | |
362 | + | |
363 | + if (!in_flight) | |
364 | + inc_in_flight_req(fsvq); | |
365 | + notify = virtqueue_kick_prepare(vq); | |
366 | + spin_unlock(&fsvq->lock); | |
367 | + | |
368 | + if (notify) | |
369 | + virtqueue_notify(vq); | |
370 | + return ret; | |
371 | +out: | |
372 | + spin_unlock(&fsvq->lock); | |
373 | + return ret; | |
374 | +} | |
375 | + | |
316 | 376 | static void virtio_fs_hiprio_dispatch_work(struct work_struct *work) |
317 | 377 | { |
318 | 378 | struct virtio_fs_forget *forget; |
319 | 379 | struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq, |
320 | 380 | dispatch_work.work); |
321 | - struct virtqueue *vq = fsvq->vq; | |
322 | - struct scatterlist sg; | |
323 | - struct scatterlist *sgs[] = {&sg}; | |
324 | - bool notify; | |
325 | - int ret; | |
326 | - | |
327 | 381 | pr_debug("virtio-fs: worker %s called.\n", __func__); |
328 | 382 | while (1) { |
329 | 383 | spin_lock(&fsvq->lock); |
330 | 384 | |
... | ... | @@ -335,43 +389,9 @@ |
335 | 389 | } |
336 | 390 | |
337 | 391 | list_del(&forget->list); |
338 | - if (!fsvq->connected) { | |
339 | - dec_in_flight_req(fsvq); | |
340 | - spin_unlock(&fsvq->lock); | |
341 | - kfree(forget); | |
342 | - continue; | |
343 | - } | |
344 | - | |
345 | - sg_init_one(&sg, forget, sizeof(*forget)); | |
346 | - | |
347 | - /* Enqueue the request */ | |
348 | - dev_dbg(&vq->vdev->dev, "%s\n", __func__); | |
349 | - ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC); | |
350 | - if (ret < 0) { | |
351 | - if (ret == -ENOMEM || ret == -ENOSPC) { | |
352 | - pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n", | |
353 | - ret); | |
354 | - list_add_tail(&forget->list, | |
355 | - &fsvq->queued_reqs); | |
356 | - schedule_delayed_work(&fsvq->dispatch_work, | |
357 | - msecs_to_jiffies(1)); | |
358 | - } else { | |
359 | - pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n", | |
360 | - ret); | |
361 | - dec_in_flight_req(fsvq); | |
362 | - kfree(forget); | |
363 | - } | |
364 | - spin_unlock(&fsvq->lock); | |
365 | - return; | |
366 | - } | |
367 | - | |
368 | - notify = virtqueue_kick_prepare(vq); | |
369 | 392 | spin_unlock(&fsvq->lock); |
370 | - | |
371 | - if (notify) | |
372 | - virtqueue_notify(vq); | |
373 | - pr_debug("virtio-fs: worker %s dispatched one forget request.\n", | |
374 | - __func__); | |
393 | + if (send_forget_request(fsvq, forget, true)) | |
394 | + return; | |
375 | 395 | } |
376 | 396 | } |
377 | 397 | |
378 | 398 | |
379 | 399 | |
380 | 400 | |
... | ... | @@ -710,14 +730,9 @@ |
710 | 730 | { |
711 | 731 | struct fuse_forget_link *link; |
712 | 732 | struct virtio_fs_forget *forget; |
713 | - struct scatterlist sg; | |
714 | - struct scatterlist *sgs[] = {&sg}; | |
715 | 733 | struct virtio_fs *fs; |
716 | - struct virtqueue *vq; | |
717 | 734 | struct virtio_fs_vq *fsvq; |
718 | - bool notify; | |
719 | 735 | u64 unique; |
720 | - int ret; | |
721 | 736 | |
722 | 737 | link = fuse_dequeue_forget(fiq, 1, NULL); |
723 | 738 | unique = fuse_get_unique(fiq); |
... | ... | @@ -739,46 +754,7 @@ |
739 | 754 | .nlookup = link->forget_one.nlookup, |
740 | 755 | }; |
741 | 756 | |
742 | - sg_init_one(&sg, forget, sizeof(*forget)); | |
743 | - | |
744 | - /* Enqueue the request */ | |
745 | - spin_lock(&fsvq->lock); | |
746 | - | |
747 | - if (!fsvq->connected) { | |
748 | - kfree(forget); | |
749 | - spin_unlock(&fsvq->lock); | |
750 | - goto out; | |
751 | - } | |
752 | - | |
753 | - vq = fsvq->vq; | |
754 | - dev_dbg(&vq->vdev->dev, "%s\n", __func__); | |
755 | - | |
756 | - ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC); | |
757 | - if (ret < 0) { | |
758 | - if (ret == -ENOMEM || ret == -ENOSPC) { | |
759 | - pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later.\n", | |
760 | - ret); | |
761 | - list_add_tail(&forget->list, &fsvq->queued_reqs); | |
762 | - schedule_delayed_work(&fsvq->dispatch_work, | |
763 | - msecs_to_jiffies(1)); | |
764 | - inc_in_flight_req(fsvq); | |
765 | - } else { | |
766 | - pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n", | |
767 | - ret); | |
768 | - kfree(forget); | |
769 | - } | |
770 | - spin_unlock(&fsvq->lock); | |
771 | - goto out; | |
772 | - } | |
773 | - | |
774 | - inc_in_flight_req(fsvq); | |
775 | - notify = virtqueue_kick_prepare(vq); | |
776 | - | |
777 | - spin_unlock(&fsvq->lock); | |
778 | - | |
779 | - if (notify) | |
780 | - virtqueue_notify(vq); | |
781 | -out: | |
757 | + send_forget_request(fsvq, forget, false); | |
782 | 758 | kfree(link); |
783 | 759 | } |
784 | 760 |