summaryrefslogtreecommitdiff
path: root/fs/fuse
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2019-10-15 20:46:24 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2019-10-21 16:57:07 +0300
commit5dbe190f341206a7896f7e40c1e3a36933d812f3 (patch)
tree3129c354c0777d5d1bd0447d9cbfd8ebb9389734 /fs/fuse
parent7ee1e2e631dbf0ff0df2a67a1e01ba3c1dce7a46 (diff)
downloadlinux-5dbe190f341206a7896f7e40c1e3a36933d812f3.tar.xz
virtiofs: Set FR_SENT flag only after request has been sent
FR_SENT flag should be set when request has been sent successfully sent over virtqueue. This is used by interrupt logic to figure out if interrupt request should be sent or not. Also add it to fqp->processing list after sending it successfully. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/virtio_fs.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index a2724b77221d..6d153e70c87b 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -857,6 +857,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
unsigned int i;
int ret;
bool notify;
+ struct fuse_pqueue *fpq;
/* Does the sglist fit on the stack? */
total_sgs = sg_count_fuse_req(req);
@@ -911,6 +912,15 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
goto out;
}
+ /* Request successfully sent. */
+ fpq = &fsvq->fud->pq;
+ spin_lock(&fpq->lock);
+ list_add_tail(&req->list, fpq->processing);
+ spin_unlock(&fpq->lock);
+ set_bit(FR_SENT, &req->flags);
+ /* matches barrier in request_wait_answer() */
+ smp_mb__after_atomic();
+
fsvq->in_flight++;
notify = virtqueue_kick_prepare(vq);
@@ -939,7 +949,6 @@ __releases(fiq->lock)
struct virtio_fs *fs;
struct fuse_conn *fc;
struct fuse_req *req;
- struct fuse_pqueue *fpq;
struct virtio_fs_vq *fsvq;
int ret;
@@ -958,14 +967,6 @@ __releases(fiq->lock)
req->in.h.nodeid, req->in.h.len,
fuse_len_args(req->args->out_numargs, req->args->out_args));
- fpq = &fs->vqs[queue_id].fud->pq;
- spin_lock(&fpq->lock);
- list_add_tail(&req->list, fpq->processing);
- spin_unlock(&fpq->lock);
- set_bit(FR_SENT, &req->flags);
- /* matches barrier in request_wait_answer() */
- smp_mb__after_atomic();
-
retry:
fsvq = &fs->vqs[queue_id];
ret = virtio_fs_enqueue_req(fsvq, req);
@@ -978,10 +979,6 @@ retry:
}
req->out.h.error = ret;
pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret);
- spin_lock(&fpq->lock);
- clear_bit(FR_SENT, &req->flags);
- list_del_init(&req->list);
- spin_unlock(&fpq->lock);
/* Can't end request in submission context. Use a worker */
spin_lock(&fsvq->lock);