Commit 58ada94f95f71d4f73197ab0e9603dbba6e47fe3

Authored by Vivek Goyal
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

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