xref: /openbmc/linux/fs/fuse/virtio_fs.c (revision a62a8ef9d97da23762a588592c8b8eb50a8deb6a)
1*a62a8ef9SStefan Hajnoczi // SPDX-License-Identifier: GPL-2.0
2*a62a8ef9SStefan Hajnoczi /*
3*a62a8ef9SStefan Hajnoczi  * virtio-fs: Virtio Filesystem
4*a62a8ef9SStefan Hajnoczi  * Copyright (C) 2018 Red Hat, Inc.
5*a62a8ef9SStefan Hajnoczi  */
6*a62a8ef9SStefan Hajnoczi 
7*a62a8ef9SStefan Hajnoczi #include <linux/fs.h>
8*a62a8ef9SStefan Hajnoczi #include <linux/module.h>
9*a62a8ef9SStefan Hajnoczi #include <linux/virtio.h>
10*a62a8ef9SStefan Hajnoczi #include <linux/virtio_fs.h>
11*a62a8ef9SStefan Hajnoczi #include <linux/delay.h>
12*a62a8ef9SStefan Hajnoczi #include <linux/fs_context.h>
13*a62a8ef9SStefan Hajnoczi #include <linux/highmem.h>
14*a62a8ef9SStefan Hajnoczi #include "fuse_i.h"
15*a62a8ef9SStefan Hajnoczi 
16*a62a8ef9SStefan Hajnoczi /* List of virtio-fs device instances and a lock for the list. Also provides
17*a62a8ef9SStefan Hajnoczi  * mutual exclusion in device removal and mounting path
18*a62a8ef9SStefan Hajnoczi  */
19*a62a8ef9SStefan Hajnoczi static DEFINE_MUTEX(virtio_fs_mutex);
20*a62a8ef9SStefan Hajnoczi static LIST_HEAD(virtio_fs_instances);
21*a62a8ef9SStefan Hajnoczi 
22*a62a8ef9SStefan Hajnoczi enum {
23*a62a8ef9SStefan Hajnoczi 	VQ_HIPRIO,
24*a62a8ef9SStefan Hajnoczi 	VQ_REQUEST
25*a62a8ef9SStefan Hajnoczi };
26*a62a8ef9SStefan Hajnoczi 
27*a62a8ef9SStefan Hajnoczi /* Per-virtqueue state */
28*a62a8ef9SStefan Hajnoczi struct virtio_fs_vq {
29*a62a8ef9SStefan Hajnoczi 	spinlock_t lock;
30*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq;     /* protected by ->lock */
31*a62a8ef9SStefan Hajnoczi 	struct work_struct done_work;
32*a62a8ef9SStefan Hajnoczi 	struct list_head queued_reqs;
33*a62a8ef9SStefan Hajnoczi 	struct delayed_work dispatch_work;
34*a62a8ef9SStefan Hajnoczi 	struct fuse_dev *fud;
35*a62a8ef9SStefan Hajnoczi 	bool connected;
36*a62a8ef9SStefan Hajnoczi 	long in_flight;
37*a62a8ef9SStefan Hajnoczi 	char name[24];
38*a62a8ef9SStefan Hajnoczi } ____cacheline_aligned_in_smp;
39*a62a8ef9SStefan Hajnoczi 
40*a62a8ef9SStefan Hajnoczi /* A virtio-fs device instance */
41*a62a8ef9SStefan Hajnoczi struct virtio_fs {
42*a62a8ef9SStefan Hajnoczi 	struct kref refcount;
43*a62a8ef9SStefan Hajnoczi 	struct list_head list;    /* on virtio_fs_instances */
44*a62a8ef9SStefan Hajnoczi 	char *tag;
45*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *vqs;
46*a62a8ef9SStefan Hajnoczi 	unsigned int nvqs;               /* number of virtqueues */
47*a62a8ef9SStefan Hajnoczi 	unsigned int num_request_queues; /* number of request queues */
48*a62a8ef9SStefan Hajnoczi };
49*a62a8ef9SStefan Hajnoczi 
50*a62a8ef9SStefan Hajnoczi struct virtio_fs_forget {
51*a62a8ef9SStefan Hajnoczi 	struct fuse_in_header ih;
52*a62a8ef9SStefan Hajnoczi 	struct fuse_forget_in arg;
53*a62a8ef9SStefan Hajnoczi 	/* This request can be temporarily queued on virt queue */
54*a62a8ef9SStefan Hajnoczi 	struct list_head list;
55*a62a8ef9SStefan Hajnoczi };
56*a62a8ef9SStefan Hajnoczi 
57*a62a8ef9SStefan Hajnoczi static inline struct virtio_fs_vq *vq_to_fsvq(struct virtqueue *vq)
58*a62a8ef9SStefan Hajnoczi {
59*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs = vq->vdev->priv;
60*a62a8ef9SStefan Hajnoczi 
61*a62a8ef9SStefan Hajnoczi 	return &fs->vqs[vq->index];
62*a62a8ef9SStefan Hajnoczi }
63*a62a8ef9SStefan Hajnoczi 
64*a62a8ef9SStefan Hajnoczi static inline struct fuse_pqueue *vq_to_fpq(struct virtqueue *vq)
65*a62a8ef9SStefan Hajnoczi {
66*a62a8ef9SStefan Hajnoczi 	return &vq_to_fsvq(vq)->fud->pq;
67*a62a8ef9SStefan Hajnoczi }
68*a62a8ef9SStefan Hajnoczi 
69*a62a8ef9SStefan Hajnoczi static void release_virtio_fs_obj(struct kref *ref)
70*a62a8ef9SStefan Hajnoczi {
71*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount);
72*a62a8ef9SStefan Hajnoczi 
73*a62a8ef9SStefan Hajnoczi 	kfree(vfs->vqs);
74*a62a8ef9SStefan Hajnoczi 	kfree(vfs);
75*a62a8ef9SStefan Hajnoczi }
76*a62a8ef9SStefan Hajnoczi 
77*a62a8ef9SStefan Hajnoczi /* Make sure virtiofs_mutex is held */
78*a62a8ef9SStefan Hajnoczi static void virtio_fs_put(struct virtio_fs *fs)
79*a62a8ef9SStefan Hajnoczi {
80*a62a8ef9SStefan Hajnoczi 	kref_put(&fs->refcount, release_virtio_fs_obj);
81*a62a8ef9SStefan Hajnoczi }
82*a62a8ef9SStefan Hajnoczi 
83*a62a8ef9SStefan Hajnoczi static void virtio_fs_fiq_release(struct fuse_iqueue *fiq)
84*a62a8ef9SStefan Hajnoczi {
85*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *vfs = fiq->priv;
86*a62a8ef9SStefan Hajnoczi 
87*a62a8ef9SStefan Hajnoczi 	mutex_lock(&virtio_fs_mutex);
88*a62a8ef9SStefan Hajnoczi 	virtio_fs_put(vfs);
89*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
90*a62a8ef9SStefan Hajnoczi }
91*a62a8ef9SStefan Hajnoczi 
92*a62a8ef9SStefan Hajnoczi static void virtio_fs_drain_queue(struct virtio_fs_vq *fsvq)
93*a62a8ef9SStefan Hajnoczi {
94*a62a8ef9SStefan Hajnoczi 	WARN_ON(fsvq->in_flight < 0);
95*a62a8ef9SStefan Hajnoczi 
96*a62a8ef9SStefan Hajnoczi 	/* Wait for in flight requests to finish.*/
97*a62a8ef9SStefan Hajnoczi 	while (1) {
98*a62a8ef9SStefan Hajnoczi 		spin_lock(&fsvq->lock);
99*a62a8ef9SStefan Hajnoczi 		if (!fsvq->in_flight) {
100*a62a8ef9SStefan Hajnoczi 			spin_unlock(&fsvq->lock);
101*a62a8ef9SStefan Hajnoczi 			break;
102*a62a8ef9SStefan Hajnoczi 		}
103*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
104*a62a8ef9SStefan Hajnoczi 		/* TODO use completion instead of timeout */
105*a62a8ef9SStefan Hajnoczi 		usleep_range(1000, 2000);
106*a62a8ef9SStefan Hajnoczi 	}
107*a62a8ef9SStefan Hajnoczi 
108*a62a8ef9SStefan Hajnoczi 	flush_work(&fsvq->done_work);
109*a62a8ef9SStefan Hajnoczi 	flush_delayed_work(&fsvq->dispatch_work);
110*a62a8ef9SStefan Hajnoczi }
111*a62a8ef9SStefan Hajnoczi 
112*a62a8ef9SStefan Hajnoczi static inline void drain_hiprio_queued_reqs(struct virtio_fs_vq *fsvq)
113*a62a8ef9SStefan Hajnoczi {
114*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_forget *forget;
115*a62a8ef9SStefan Hajnoczi 
116*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
117*a62a8ef9SStefan Hajnoczi 	while (1) {
118*a62a8ef9SStefan Hajnoczi 		forget = list_first_entry_or_null(&fsvq->queued_reqs,
119*a62a8ef9SStefan Hajnoczi 						struct virtio_fs_forget, list);
120*a62a8ef9SStefan Hajnoczi 		if (!forget)
121*a62a8ef9SStefan Hajnoczi 			break;
122*a62a8ef9SStefan Hajnoczi 		list_del(&forget->list);
123*a62a8ef9SStefan Hajnoczi 		kfree(forget);
124*a62a8ef9SStefan Hajnoczi 	}
125*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
126*a62a8ef9SStefan Hajnoczi }
127*a62a8ef9SStefan Hajnoczi 
128*a62a8ef9SStefan Hajnoczi static void virtio_fs_drain_all_queues(struct virtio_fs *fs)
129*a62a8ef9SStefan Hajnoczi {
130*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq;
131*a62a8ef9SStefan Hajnoczi 	int i;
132*a62a8ef9SStefan Hajnoczi 
133*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++) {
134*a62a8ef9SStefan Hajnoczi 		fsvq = &fs->vqs[i];
135*a62a8ef9SStefan Hajnoczi 		if (i == VQ_HIPRIO)
136*a62a8ef9SStefan Hajnoczi 			drain_hiprio_queued_reqs(fsvq);
137*a62a8ef9SStefan Hajnoczi 
138*a62a8ef9SStefan Hajnoczi 		virtio_fs_drain_queue(fsvq);
139*a62a8ef9SStefan Hajnoczi 	}
140*a62a8ef9SStefan Hajnoczi }
141*a62a8ef9SStefan Hajnoczi 
142*a62a8ef9SStefan Hajnoczi static void virtio_fs_start_all_queues(struct virtio_fs *fs)
143*a62a8ef9SStefan Hajnoczi {
144*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq;
145*a62a8ef9SStefan Hajnoczi 	int i;
146*a62a8ef9SStefan Hajnoczi 
147*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++) {
148*a62a8ef9SStefan Hajnoczi 		fsvq = &fs->vqs[i];
149*a62a8ef9SStefan Hajnoczi 		spin_lock(&fsvq->lock);
150*a62a8ef9SStefan Hajnoczi 		fsvq->connected = true;
151*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
152*a62a8ef9SStefan Hajnoczi 	}
153*a62a8ef9SStefan Hajnoczi }
154*a62a8ef9SStefan Hajnoczi 
155*a62a8ef9SStefan Hajnoczi /* Add a new instance to the list or return -EEXIST if tag name exists*/
156*a62a8ef9SStefan Hajnoczi static int virtio_fs_add_instance(struct virtio_fs *fs)
157*a62a8ef9SStefan Hajnoczi {
158*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs2;
159*a62a8ef9SStefan Hajnoczi 	bool duplicate = false;
160*a62a8ef9SStefan Hajnoczi 
161*a62a8ef9SStefan Hajnoczi 	mutex_lock(&virtio_fs_mutex);
162*a62a8ef9SStefan Hajnoczi 
163*a62a8ef9SStefan Hajnoczi 	list_for_each_entry(fs2, &virtio_fs_instances, list) {
164*a62a8ef9SStefan Hajnoczi 		if (strcmp(fs->tag, fs2->tag) == 0)
165*a62a8ef9SStefan Hajnoczi 			duplicate = true;
166*a62a8ef9SStefan Hajnoczi 	}
167*a62a8ef9SStefan Hajnoczi 
168*a62a8ef9SStefan Hajnoczi 	if (!duplicate)
169*a62a8ef9SStefan Hajnoczi 		list_add_tail(&fs->list, &virtio_fs_instances);
170*a62a8ef9SStefan Hajnoczi 
171*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
172*a62a8ef9SStefan Hajnoczi 
173*a62a8ef9SStefan Hajnoczi 	if (duplicate)
174*a62a8ef9SStefan Hajnoczi 		return -EEXIST;
175*a62a8ef9SStefan Hajnoczi 	return 0;
176*a62a8ef9SStefan Hajnoczi }
177*a62a8ef9SStefan Hajnoczi 
178*a62a8ef9SStefan Hajnoczi /* Return the virtio_fs with a given tag, or NULL */
179*a62a8ef9SStefan Hajnoczi static struct virtio_fs *virtio_fs_find_instance(const char *tag)
180*a62a8ef9SStefan Hajnoczi {
181*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs;
182*a62a8ef9SStefan Hajnoczi 
183*a62a8ef9SStefan Hajnoczi 	mutex_lock(&virtio_fs_mutex);
184*a62a8ef9SStefan Hajnoczi 
185*a62a8ef9SStefan Hajnoczi 	list_for_each_entry(fs, &virtio_fs_instances, list) {
186*a62a8ef9SStefan Hajnoczi 		if (strcmp(fs->tag, tag) == 0) {
187*a62a8ef9SStefan Hajnoczi 			kref_get(&fs->refcount);
188*a62a8ef9SStefan Hajnoczi 			goto found;
189*a62a8ef9SStefan Hajnoczi 		}
190*a62a8ef9SStefan Hajnoczi 	}
191*a62a8ef9SStefan Hajnoczi 
192*a62a8ef9SStefan Hajnoczi 	fs = NULL; /* not found */
193*a62a8ef9SStefan Hajnoczi 
194*a62a8ef9SStefan Hajnoczi found:
195*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
196*a62a8ef9SStefan Hajnoczi 
197*a62a8ef9SStefan Hajnoczi 	return fs;
198*a62a8ef9SStefan Hajnoczi }
199*a62a8ef9SStefan Hajnoczi 
200*a62a8ef9SStefan Hajnoczi static void virtio_fs_free_devs(struct virtio_fs *fs)
201*a62a8ef9SStefan Hajnoczi {
202*a62a8ef9SStefan Hajnoczi 	unsigned int i;
203*a62a8ef9SStefan Hajnoczi 
204*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++) {
205*a62a8ef9SStefan Hajnoczi 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
206*a62a8ef9SStefan Hajnoczi 
207*a62a8ef9SStefan Hajnoczi 		if (!fsvq->fud)
208*a62a8ef9SStefan Hajnoczi 			continue;
209*a62a8ef9SStefan Hajnoczi 
210*a62a8ef9SStefan Hajnoczi 		fuse_dev_free(fsvq->fud);
211*a62a8ef9SStefan Hajnoczi 		fsvq->fud = NULL;
212*a62a8ef9SStefan Hajnoczi 	}
213*a62a8ef9SStefan Hajnoczi }
214*a62a8ef9SStefan Hajnoczi 
215*a62a8ef9SStefan Hajnoczi /* Read filesystem name from virtio config into fs->tag (must kfree()). */
216*a62a8ef9SStefan Hajnoczi static int virtio_fs_read_tag(struct virtio_device *vdev, struct virtio_fs *fs)
217*a62a8ef9SStefan Hajnoczi {
218*a62a8ef9SStefan Hajnoczi 	char tag_buf[sizeof_field(struct virtio_fs_config, tag)];
219*a62a8ef9SStefan Hajnoczi 	char *end;
220*a62a8ef9SStefan Hajnoczi 	size_t len;
221*a62a8ef9SStefan Hajnoczi 
222*a62a8ef9SStefan Hajnoczi 	virtio_cread_bytes(vdev, offsetof(struct virtio_fs_config, tag),
223*a62a8ef9SStefan Hajnoczi 			   &tag_buf, sizeof(tag_buf));
224*a62a8ef9SStefan Hajnoczi 	end = memchr(tag_buf, '\0', sizeof(tag_buf));
225*a62a8ef9SStefan Hajnoczi 	if (end == tag_buf)
226*a62a8ef9SStefan Hajnoczi 		return -EINVAL; /* empty tag */
227*a62a8ef9SStefan Hajnoczi 	if (!end)
228*a62a8ef9SStefan Hajnoczi 		end = &tag_buf[sizeof(tag_buf)];
229*a62a8ef9SStefan Hajnoczi 
230*a62a8ef9SStefan Hajnoczi 	len = end - tag_buf;
231*a62a8ef9SStefan Hajnoczi 	fs->tag = devm_kmalloc(&vdev->dev, len + 1, GFP_KERNEL);
232*a62a8ef9SStefan Hajnoczi 	if (!fs->tag)
233*a62a8ef9SStefan Hajnoczi 		return -ENOMEM;
234*a62a8ef9SStefan Hajnoczi 	memcpy(fs->tag, tag_buf, len);
235*a62a8ef9SStefan Hajnoczi 	fs->tag[len] = '\0';
236*a62a8ef9SStefan Hajnoczi 	return 0;
237*a62a8ef9SStefan Hajnoczi }
238*a62a8ef9SStefan Hajnoczi 
239*a62a8ef9SStefan Hajnoczi /* Work function for hiprio completion */
240*a62a8ef9SStefan Hajnoczi static void virtio_fs_hiprio_done_work(struct work_struct *work)
241*a62a8ef9SStefan Hajnoczi {
242*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
243*a62a8ef9SStefan Hajnoczi 						 done_work);
244*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq = fsvq->vq;
245*a62a8ef9SStefan Hajnoczi 
246*a62a8ef9SStefan Hajnoczi 	/* Free completed FUSE_FORGET requests */
247*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
248*a62a8ef9SStefan Hajnoczi 	do {
249*a62a8ef9SStefan Hajnoczi 		unsigned int len;
250*a62a8ef9SStefan Hajnoczi 		void *req;
251*a62a8ef9SStefan Hajnoczi 
252*a62a8ef9SStefan Hajnoczi 		virtqueue_disable_cb(vq);
253*a62a8ef9SStefan Hajnoczi 
254*a62a8ef9SStefan Hajnoczi 		while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
255*a62a8ef9SStefan Hajnoczi 			kfree(req);
256*a62a8ef9SStefan Hajnoczi 			fsvq->in_flight--;
257*a62a8ef9SStefan Hajnoczi 		}
258*a62a8ef9SStefan Hajnoczi 	} while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq)));
259*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
260*a62a8ef9SStefan Hajnoczi }
261*a62a8ef9SStefan Hajnoczi 
262*a62a8ef9SStefan Hajnoczi static void virtio_fs_dummy_dispatch_work(struct work_struct *work)
263*a62a8ef9SStefan Hajnoczi {
264*a62a8ef9SStefan Hajnoczi }
265*a62a8ef9SStefan Hajnoczi 
266*a62a8ef9SStefan Hajnoczi static void virtio_fs_hiprio_dispatch_work(struct work_struct *work)
267*a62a8ef9SStefan Hajnoczi {
268*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_forget *forget;
269*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
270*a62a8ef9SStefan Hajnoczi 						 dispatch_work.work);
271*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq = fsvq->vq;
272*a62a8ef9SStefan Hajnoczi 	struct scatterlist sg;
273*a62a8ef9SStefan Hajnoczi 	struct scatterlist *sgs[] = {&sg};
274*a62a8ef9SStefan Hajnoczi 	bool notify;
275*a62a8ef9SStefan Hajnoczi 	int ret;
276*a62a8ef9SStefan Hajnoczi 
277*a62a8ef9SStefan Hajnoczi 	pr_debug("virtio-fs: worker %s called.\n", __func__);
278*a62a8ef9SStefan Hajnoczi 	while (1) {
279*a62a8ef9SStefan Hajnoczi 		spin_lock(&fsvq->lock);
280*a62a8ef9SStefan Hajnoczi 		forget = list_first_entry_or_null(&fsvq->queued_reqs,
281*a62a8ef9SStefan Hajnoczi 					struct virtio_fs_forget, list);
282*a62a8ef9SStefan Hajnoczi 		if (!forget) {
283*a62a8ef9SStefan Hajnoczi 			spin_unlock(&fsvq->lock);
284*a62a8ef9SStefan Hajnoczi 			return;
285*a62a8ef9SStefan Hajnoczi 		}
286*a62a8ef9SStefan Hajnoczi 
287*a62a8ef9SStefan Hajnoczi 		list_del(&forget->list);
288*a62a8ef9SStefan Hajnoczi 		if (!fsvq->connected) {
289*a62a8ef9SStefan Hajnoczi 			spin_unlock(&fsvq->lock);
290*a62a8ef9SStefan Hajnoczi 			kfree(forget);
291*a62a8ef9SStefan Hajnoczi 			continue;
292*a62a8ef9SStefan Hajnoczi 		}
293*a62a8ef9SStefan Hajnoczi 
294*a62a8ef9SStefan Hajnoczi 		sg_init_one(&sg, forget, sizeof(*forget));
295*a62a8ef9SStefan Hajnoczi 
296*a62a8ef9SStefan Hajnoczi 		/* Enqueue the request */
297*a62a8ef9SStefan Hajnoczi 		dev_dbg(&vq->vdev->dev, "%s\n", __func__);
298*a62a8ef9SStefan Hajnoczi 		ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC);
299*a62a8ef9SStefan Hajnoczi 		if (ret < 0) {
300*a62a8ef9SStefan Hajnoczi 			if (ret == -ENOMEM || ret == -ENOSPC) {
301*a62a8ef9SStefan Hajnoczi 				pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n",
302*a62a8ef9SStefan Hajnoczi 					 ret);
303*a62a8ef9SStefan Hajnoczi 				list_add_tail(&forget->list,
304*a62a8ef9SStefan Hajnoczi 						&fsvq->queued_reqs);
305*a62a8ef9SStefan Hajnoczi 				schedule_delayed_work(&fsvq->dispatch_work,
306*a62a8ef9SStefan Hajnoczi 						msecs_to_jiffies(1));
307*a62a8ef9SStefan Hajnoczi 			} else {
308*a62a8ef9SStefan Hajnoczi 				pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
309*a62a8ef9SStefan Hajnoczi 					 ret);
310*a62a8ef9SStefan Hajnoczi 				kfree(forget);
311*a62a8ef9SStefan Hajnoczi 			}
312*a62a8ef9SStefan Hajnoczi 			spin_unlock(&fsvq->lock);
313*a62a8ef9SStefan Hajnoczi 			return;
314*a62a8ef9SStefan Hajnoczi 		}
315*a62a8ef9SStefan Hajnoczi 
316*a62a8ef9SStefan Hajnoczi 		fsvq->in_flight++;
317*a62a8ef9SStefan Hajnoczi 		notify = virtqueue_kick_prepare(vq);
318*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
319*a62a8ef9SStefan Hajnoczi 
320*a62a8ef9SStefan Hajnoczi 		if (notify)
321*a62a8ef9SStefan Hajnoczi 			virtqueue_notify(vq);
322*a62a8ef9SStefan Hajnoczi 		pr_debug("virtio-fs: worker %s dispatched one forget request.\n",
323*a62a8ef9SStefan Hajnoczi 			 __func__);
324*a62a8ef9SStefan Hajnoczi 	}
325*a62a8ef9SStefan Hajnoczi }
326*a62a8ef9SStefan Hajnoczi 
327*a62a8ef9SStefan Hajnoczi /* Allocate and copy args into req->argbuf */
328*a62a8ef9SStefan Hajnoczi static int copy_args_to_argbuf(struct fuse_req *req)
329*a62a8ef9SStefan Hajnoczi {
330*a62a8ef9SStefan Hajnoczi 	struct fuse_args *args = req->args;
331*a62a8ef9SStefan Hajnoczi 	unsigned int offset = 0;
332*a62a8ef9SStefan Hajnoczi 	unsigned int num_in;
333*a62a8ef9SStefan Hajnoczi 	unsigned int num_out;
334*a62a8ef9SStefan Hajnoczi 	unsigned int len;
335*a62a8ef9SStefan Hajnoczi 	unsigned int i;
336*a62a8ef9SStefan Hajnoczi 
337*a62a8ef9SStefan Hajnoczi 	num_in = args->in_numargs - args->in_pages;
338*a62a8ef9SStefan Hajnoczi 	num_out = args->out_numargs - args->out_pages;
339*a62a8ef9SStefan Hajnoczi 	len = fuse_len_args(num_in, (struct fuse_arg *) args->in_args) +
340*a62a8ef9SStefan Hajnoczi 	      fuse_len_args(num_out, args->out_args);
341*a62a8ef9SStefan Hajnoczi 
342*a62a8ef9SStefan Hajnoczi 	req->argbuf = kmalloc(len, GFP_ATOMIC);
343*a62a8ef9SStefan Hajnoczi 	if (!req->argbuf)
344*a62a8ef9SStefan Hajnoczi 		return -ENOMEM;
345*a62a8ef9SStefan Hajnoczi 
346*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < num_in; i++) {
347*a62a8ef9SStefan Hajnoczi 		memcpy(req->argbuf + offset,
348*a62a8ef9SStefan Hajnoczi 		       args->in_args[i].value,
349*a62a8ef9SStefan Hajnoczi 		       args->in_args[i].size);
350*a62a8ef9SStefan Hajnoczi 		offset += args->in_args[i].size;
351*a62a8ef9SStefan Hajnoczi 	}
352*a62a8ef9SStefan Hajnoczi 
353*a62a8ef9SStefan Hajnoczi 	return 0;
354*a62a8ef9SStefan Hajnoczi }
355*a62a8ef9SStefan Hajnoczi 
356*a62a8ef9SStefan Hajnoczi /* Copy args out of and free req->argbuf */
357*a62a8ef9SStefan Hajnoczi static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
358*a62a8ef9SStefan Hajnoczi {
359*a62a8ef9SStefan Hajnoczi 	unsigned int remaining;
360*a62a8ef9SStefan Hajnoczi 	unsigned int offset;
361*a62a8ef9SStefan Hajnoczi 	unsigned int num_in;
362*a62a8ef9SStefan Hajnoczi 	unsigned int num_out;
363*a62a8ef9SStefan Hajnoczi 	unsigned int i;
364*a62a8ef9SStefan Hajnoczi 
365*a62a8ef9SStefan Hajnoczi 	remaining = req->out.h.len - sizeof(req->out.h);
366*a62a8ef9SStefan Hajnoczi 	num_in = args->in_numargs - args->in_pages;
367*a62a8ef9SStefan Hajnoczi 	num_out = args->out_numargs - args->out_pages;
368*a62a8ef9SStefan Hajnoczi 	offset = fuse_len_args(num_in, (struct fuse_arg *)args->in_args);
369*a62a8ef9SStefan Hajnoczi 
370*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < num_out; i++) {
371*a62a8ef9SStefan Hajnoczi 		unsigned int argsize = args->out_args[i].size;
372*a62a8ef9SStefan Hajnoczi 
373*a62a8ef9SStefan Hajnoczi 		if (args->out_argvar &&
374*a62a8ef9SStefan Hajnoczi 		    i == args->out_numargs - 1 &&
375*a62a8ef9SStefan Hajnoczi 		    argsize > remaining) {
376*a62a8ef9SStefan Hajnoczi 			argsize = remaining;
377*a62a8ef9SStefan Hajnoczi 		}
378*a62a8ef9SStefan Hajnoczi 
379*a62a8ef9SStefan Hajnoczi 		memcpy(args->out_args[i].value, req->argbuf + offset, argsize);
380*a62a8ef9SStefan Hajnoczi 		offset += argsize;
381*a62a8ef9SStefan Hajnoczi 
382*a62a8ef9SStefan Hajnoczi 		if (i != args->out_numargs - 1)
383*a62a8ef9SStefan Hajnoczi 			remaining -= argsize;
384*a62a8ef9SStefan Hajnoczi 	}
385*a62a8ef9SStefan Hajnoczi 
386*a62a8ef9SStefan Hajnoczi 	/* Store the actual size of the variable-length arg */
387*a62a8ef9SStefan Hajnoczi 	if (args->out_argvar)
388*a62a8ef9SStefan Hajnoczi 		args->out_args[args->out_numargs - 1].size = remaining;
389*a62a8ef9SStefan Hajnoczi 
390*a62a8ef9SStefan Hajnoczi 	kfree(req->argbuf);
391*a62a8ef9SStefan Hajnoczi 	req->argbuf = NULL;
392*a62a8ef9SStefan Hajnoczi }
393*a62a8ef9SStefan Hajnoczi 
394*a62a8ef9SStefan Hajnoczi /* Work function for request completion */
395*a62a8ef9SStefan Hajnoczi static void virtio_fs_requests_done_work(struct work_struct *work)
396*a62a8ef9SStefan Hajnoczi {
397*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
398*a62a8ef9SStefan Hajnoczi 						 done_work);
399*a62a8ef9SStefan Hajnoczi 	struct fuse_pqueue *fpq = &fsvq->fud->pq;
400*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc = fsvq->fud->fc;
401*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq = fsvq->vq;
402*a62a8ef9SStefan Hajnoczi 	struct fuse_req *req;
403*a62a8ef9SStefan Hajnoczi 	struct fuse_args_pages *ap;
404*a62a8ef9SStefan Hajnoczi 	struct fuse_req *next;
405*a62a8ef9SStefan Hajnoczi 	struct fuse_args *args;
406*a62a8ef9SStefan Hajnoczi 	unsigned int len, i, thislen;
407*a62a8ef9SStefan Hajnoczi 	struct page *page;
408*a62a8ef9SStefan Hajnoczi 	LIST_HEAD(reqs);
409*a62a8ef9SStefan Hajnoczi 
410*a62a8ef9SStefan Hajnoczi 	/* Collect completed requests off the virtqueue */
411*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
412*a62a8ef9SStefan Hajnoczi 	do {
413*a62a8ef9SStefan Hajnoczi 		virtqueue_disable_cb(vq);
414*a62a8ef9SStefan Hajnoczi 
415*a62a8ef9SStefan Hajnoczi 		while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
416*a62a8ef9SStefan Hajnoczi 			spin_lock(&fpq->lock);
417*a62a8ef9SStefan Hajnoczi 			list_move_tail(&req->list, &reqs);
418*a62a8ef9SStefan Hajnoczi 			spin_unlock(&fpq->lock);
419*a62a8ef9SStefan Hajnoczi 		}
420*a62a8ef9SStefan Hajnoczi 	} while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq)));
421*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
422*a62a8ef9SStefan Hajnoczi 
423*a62a8ef9SStefan Hajnoczi 	/* End requests */
424*a62a8ef9SStefan Hajnoczi 	list_for_each_entry_safe(req, next, &reqs, list) {
425*a62a8ef9SStefan Hajnoczi 		/*
426*a62a8ef9SStefan Hajnoczi 		 * TODO verify that server properly follows FUSE protocol
427*a62a8ef9SStefan Hajnoczi 		 * (oh.uniq, oh.len)
428*a62a8ef9SStefan Hajnoczi 		 */
429*a62a8ef9SStefan Hajnoczi 		args = req->args;
430*a62a8ef9SStefan Hajnoczi 		copy_args_from_argbuf(args, req);
431*a62a8ef9SStefan Hajnoczi 
432*a62a8ef9SStefan Hajnoczi 		if (args->out_pages && args->page_zeroing) {
433*a62a8ef9SStefan Hajnoczi 			len = args->out_args[args->out_numargs - 1].size;
434*a62a8ef9SStefan Hajnoczi 			ap = container_of(args, typeof(*ap), args);
435*a62a8ef9SStefan Hajnoczi 			for (i = 0; i < ap->num_pages; i++) {
436*a62a8ef9SStefan Hajnoczi 				thislen = ap->descs[i].length;
437*a62a8ef9SStefan Hajnoczi 				if (len < thislen) {
438*a62a8ef9SStefan Hajnoczi 					WARN_ON(ap->descs[i].offset);
439*a62a8ef9SStefan Hajnoczi 					page = ap->pages[i];
440*a62a8ef9SStefan Hajnoczi 					zero_user_segment(page, len, thislen);
441*a62a8ef9SStefan Hajnoczi 					len = 0;
442*a62a8ef9SStefan Hajnoczi 				} else {
443*a62a8ef9SStefan Hajnoczi 					len -= thislen;
444*a62a8ef9SStefan Hajnoczi 				}
445*a62a8ef9SStefan Hajnoczi 			}
446*a62a8ef9SStefan Hajnoczi 		}
447*a62a8ef9SStefan Hajnoczi 
448*a62a8ef9SStefan Hajnoczi 		spin_lock(&fpq->lock);
449*a62a8ef9SStefan Hajnoczi 		clear_bit(FR_SENT, &req->flags);
450*a62a8ef9SStefan Hajnoczi 		list_del_init(&req->list);
451*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fpq->lock);
452*a62a8ef9SStefan Hajnoczi 
453*a62a8ef9SStefan Hajnoczi 		fuse_request_end(fc, req);
454*a62a8ef9SStefan Hajnoczi 		spin_lock(&fsvq->lock);
455*a62a8ef9SStefan Hajnoczi 		fsvq->in_flight--;
456*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
457*a62a8ef9SStefan Hajnoczi 	}
458*a62a8ef9SStefan Hajnoczi }
459*a62a8ef9SStefan Hajnoczi 
460*a62a8ef9SStefan Hajnoczi /* Virtqueue interrupt handler */
461*a62a8ef9SStefan Hajnoczi static void virtio_fs_vq_done(struct virtqueue *vq)
462*a62a8ef9SStefan Hajnoczi {
463*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq = vq_to_fsvq(vq);
464*a62a8ef9SStefan Hajnoczi 
465*a62a8ef9SStefan Hajnoczi 	dev_dbg(&vq->vdev->dev, "%s %s\n", __func__, fsvq->name);
466*a62a8ef9SStefan Hajnoczi 
467*a62a8ef9SStefan Hajnoczi 	schedule_work(&fsvq->done_work);
468*a62a8ef9SStefan Hajnoczi }
469*a62a8ef9SStefan Hajnoczi 
470*a62a8ef9SStefan Hajnoczi /* Initialize virtqueues */
471*a62a8ef9SStefan Hajnoczi static int virtio_fs_setup_vqs(struct virtio_device *vdev,
472*a62a8ef9SStefan Hajnoczi 			       struct virtio_fs *fs)
473*a62a8ef9SStefan Hajnoczi {
474*a62a8ef9SStefan Hajnoczi 	struct virtqueue **vqs;
475*a62a8ef9SStefan Hajnoczi 	vq_callback_t **callbacks;
476*a62a8ef9SStefan Hajnoczi 	const char **names;
477*a62a8ef9SStefan Hajnoczi 	unsigned int i;
478*a62a8ef9SStefan Hajnoczi 	int ret = 0;
479*a62a8ef9SStefan Hajnoczi 
480*a62a8ef9SStefan Hajnoczi 	virtio_cread(vdev, struct virtio_fs_config, num_request_queues,
481*a62a8ef9SStefan Hajnoczi 		     &fs->num_request_queues);
482*a62a8ef9SStefan Hajnoczi 	if (fs->num_request_queues == 0)
483*a62a8ef9SStefan Hajnoczi 		return -EINVAL;
484*a62a8ef9SStefan Hajnoczi 
485*a62a8ef9SStefan Hajnoczi 	fs->nvqs = 1 + fs->num_request_queues;
486*a62a8ef9SStefan Hajnoczi 	fs->vqs = kcalloc(fs->nvqs, sizeof(fs->vqs[VQ_HIPRIO]), GFP_KERNEL);
487*a62a8ef9SStefan Hajnoczi 	if (!fs->vqs)
488*a62a8ef9SStefan Hajnoczi 		return -ENOMEM;
489*a62a8ef9SStefan Hajnoczi 
490*a62a8ef9SStefan Hajnoczi 	vqs = kmalloc_array(fs->nvqs, sizeof(vqs[VQ_HIPRIO]), GFP_KERNEL);
491*a62a8ef9SStefan Hajnoczi 	callbacks = kmalloc_array(fs->nvqs, sizeof(callbacks[VQ_HIPRIO]),
492*a62a8ef9SStefan Hajnoczi 					GFP_KERNEL);
493*a62a8ef9SStefan Hajnoczi 	names = kmalloc_array(fs->nvqs, sizeof(names[VQ_HIPRIO]), GFP_KERNEL);
494*a62a8ef9SStefan Hajnoczi 	if (!vqs || !callbacks || !names) {
495*a62a8ef9SStefan Hajnoczi 		ret = -ENOMEM;
496*a62a8ef9SStefan Hajnoczi 		goto out;
497*a62a8ef9SStefan Hajnoczi 	}
498*a62a8ef9SStefan Hajnoczi 
499*a62a8ef9SStefan Hajnoczi 	callbacks[VQ_HIPRIO] = virtio_fs_vq_done;
500*a62a8ef9SStefan Hajnoczi 	snprintf(fs->vqs[VQ_HIPRIO].name, sizeof(fs->vqs[VQ_HIPRIO].name),
501*a62a8ef9SStefan Hajnoczi 			"hiprio");
502*a62a8ef9SStefan Hajnoczi 	names[VQ_HIPRIO] = fs->vqs[VQ_HIPRIO].name;
503*a62a8ef9SStefan Hajnoczi 	INIT_WORK(&fs->vqs[VQ_HIPRIO].done_work, virtio_fs_hiprio_done_work);
504*a62a8ef9SStefan Hajnoczi 	INIT_LIST_HEAD(&fs->vqs[VQ_HIPRIO].queued_reqs);
505*a62a8ef9SStefan Hajnoczi 	INIT_DELAYED_WORK(&fs->vqs[VQ_HIPRIO].dispatch_work,
506*a62a8ef9SStefan Hajnoczi 			virtio_fs_hiprio_dispatch_work);
507*a62a8ef9SStefan Hajnoczi 	spin_lock_init(&fs->vqs[VQ_HIPRIO].lock);
508*a62a8ef9SStefan Hajnoczi 
509*a62a8ef9SStefan Hajnoczi 	/* Initialize the requests virtqueues */
510*a62a8ef9SStefan Hajnoczi 	for (i = VQ_REQUEST; i < fs->nvqs; i++) {
511*a62a8ef9SStefan Hajnoczi 		spin_lock_init(&fs->vqs[i].lock);
512*a62a8ef9SStefan Hajnoczi 		INIT_WORK(&fs->vqs[i].done_work, virtio_fs_requests_done_work);
513*a62a8ef9SStefan Hajnoczi 		INIT_DELAYED_WORK(&fs->vqs[i].dispatch_work,
514*a62a8ef9SStefan Hajnoczi 					virtio_fs_dummy_dispatch_work);
515*a62a8ef9SStefan Hajnoczi 		INIT_LIST_HEAD(&fs->vqs[i].queued_reqs);
516*a62a8ef9SStefan Hajnoczi 		snprintf(fs->vqs[i].name, sizeof(fs->vqs[i].name),
517*a62a8ef9SStefan Hajnoczi 			 "requests.%u", i - VQ_REQUEST);
518*a62a8ef9SStefan Hajnoczi 		callbacks[i] = virtio_fs_vq_done;
519*a62a8ef9SStefan Hajnoczi 		names[i] = fs->vqs[i].name;
520*a62a8ef9SStefan Hajnoczi 	}
521*a62a8ef9SStefan Hajnoczi 
522*a62a8ef9SStefan Hajnoczi 	ret = virtio_find_vqs(vdev, fs->nvqs, vqs, callbacks, names, NULL);
523*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
524*a62a8ef9SStefan Hajnoczi 		goto out;
525*a62a8ef9SStefan Hajnoczi 
526*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++)
527*a62a8ef9SStefan Hajnoczi 		fs->vqs[i].vq = vqs[i];
528*a62a8ef9SStefan Hajnoczi 
529*a62a8ef9SStefan Hajnoczi 	virtio_fs_start_all_queues(fs);
530*a62a8ef9SStefan Hajnoczi out:
531*a62a8ef9SStefan Hajnoczi 	kfree(names);
532*a62a8ef9SStefan Hajnoczi 	kfree(callbacks);
533*a62a8ef9SStefan Hajnoczi 	kfree(vqs);
534*a62a8ef9SStefan Hajnoczi 	if (ret)
535*a62a8ef9SStefan Hajnoczi 		kfree(fs->vqs);
536*a62a8ef9SStefan Hajnoczi 	return ret;
537*a62a8ef9SStefan Hajnoczi }
538*a62a8ef9SStefan Hajnoczi 
539*a62a8ef9SStefan Hajnoczi /* Free virtqueues (device must already be reset) */
540*a62a8ef9SStefan Hajnoczi static void virtio_fs_cleanup_vqs(struct virtio_device *vdev,
541*a62a8ef9SStefan Hajnoczi 				  struct virtio_fs *fs)
542*a62a8ef9SStefan Hajnoczi {
543*a62a8ef9SStefan Hajnoczi 	vdev->config->del_vqs(vdev);
544*a62a8ef9SStefan Hajnoczi }
545*a62a8ef9SStefan Hajnoczi 
546*a62a8ef9SStefan Hajnoczi static int virtio_fs_probe(struct virtio_device *vdev)
547*a62a8ef9SStefan Hajnoczi {
548*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs;
549*a62a8ef9SStefan Hajnoczi 	int ret;
550*a62a8ef9SStefan Hajnoczi 
551*a62a8ef9SStefan Hajnoczi 	fs = kzalloc(sizeof(*fs), GFP_KERNEL);
552*a62a8ef9SStefan Hajnoczi 	if (!fs)
553*a62a8ef9SStefan Hajnoczi 		return -ENOMEM;
554*a62a8ef9SStefan Hajnoczi 	kref_init(&fs->refcount);
555*a62a8ef9SStefan Hajnoczi 	vdev->priv = fs;
556*a62a8ef9SStefan Hajnoczi 
557*a62a8ef9SStefan Hajnoczi 	ret = virtio_fs_read_tag(vdev, fs);
558*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
559*a62a8ef9SStefan Hajnoczi 		goto out;
560*a62a8ef9SStefan Hajnoczi 
561*a62a8ef9SStefan Hajnoczi 	ret = virtio_fs_setup_vqs(vdev, fs);
562*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
563*a62a8ef9SStefan Hajnoczi 		goto out;
564*a62a8ef9SStefan Hajnoczi 
565*a62a8ef9SStefan Hajnoczi 	/* TODO vq affinity */
566*a62a8ef9SStefan Hajnoczi 
567*a62a8ef9SStefan Hajnoczi 	/* Bring the device online in case the filesystem is mounted and
568*a62a8ef9SStefan Hajnoczi 	 * requests need to be sent before we return.
569*a62a8ef9SStefan Hajnoczi 	 */
570*a62a8ef9SStefan Hajnoczi 	virtio_device_ready(vdev);
571*a62a8ef9SStefan Hajnoczi 
572*a62a8ef9SStefan Hajnoczi 	ret = virtio_fs_add_instance(fs);
573*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
574*a62a8ef9SStefan Hajnoczi 		goto out_vqs;
575*a62a8ef9SStefan Hajnoczi 
576*a62a8ef9SStefan Hajnoczi 	return 0;
577*a62a8ef9SStefan Hajnoczi 
578*a62a8ef9SStefan Hajnoczi out_vqs:
579*a62a8ef9SStefan Hajnoczi 	vdev->config->reset(vdev);
580*a62a8ef9SStefan Hajnoczi 	virtio_fs_cleanup_vqs(vdev, fs);
581*a62a8ef9SStefan Hajnoczi 
582*a62a8ef9SStefan Hajnoczi out:
583*a62a8ef9SStefan Hajnoczi 	vdev->priv = NULL;
584*a62a8ef9SStefan Hajnoczi 	kfree(fs);
585*a62a8ef9SStefan Hajnoczi 	return ret;
586*a62a8ef9SStefan Hajnoczi }
587*a62a8ef9SStefan Hajnoczi 
588*a62a8ef9SStefan Hajnoczi static void virtio_fs_stop_all_queues(struct virtio_fs *fs)
589*a62a8ef9SStefan Hajnoczi {
590*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq;
591*a62a8ef9SStefan Hajnoczi 	int i;
592*a62a8ef9SStefan Hajnoczi 
593*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++) {
594*a62a8ef9SStefan Hajnoczi 		fsvq = &fs->vqs[i];
595*a62a8ef9SStefan Hajnoczi 		spin_lock(&fsvq->lock);
596*a62a8ef9SStefan Hajnoczi 		fsvq->connected = false;
597*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
598*a62a8ef9SStefan Hajnoczi 	}
599*a62a8ef9SStefan Hajnoczi }
600*a62a8ef9SStefan Hajnoczi 
601*a62a8ef9SStefan Hajnoczi static void virtio_fs_remove(struct virtio_device *vdev)
602*a62a8ef9SStefan Hajnoczi {
603*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs = vdev->priv;
604*a62a8ef9SStefan Hajnoczi 
605*a62a8ef9SStefan Hajnoczi 	mutex_lock(&virtio_fs_mutex);
606*a62a8ef9SStefan Hajnoczi 	/* This device is going away. No one should get new reference */
607*a62a8ef9SStefan Hajnoczi 	list_del_init(&fs->list);
608*a62a8ef9SStefan Hajnoczi 	virtio_fs_stop_all_queues(fs);
609*a62a8ef9SStefan Hajnoczi 	virtio_fs_drain_all_queues(fs);
610*a62a8ef9SStefan Hajnoczi 	vdev->config->reset(vdev);
611*a62a8ef9SStefan Hajnoczi 	virtio_fs_cleanup_vqs(vdev, fs);
612*a62a8ef9SStefan Hajnoczi 
613*a62a8ef9SStefan Hajnoczi 	vdev->priv = NULL;
614*a62a8ef9SStefan Hajnoczi 	/* Put device reference on virtio_fs object */
615*a62a8ef9SStefan Hajnoczi 	virtio_fs_put(fs);
616*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
617*a62a8ef9SStefan Hajnoczi }
618*a62a8ef9SStefan Hajnoczi 
619*a62a8ef9SStefan Hajnoczi #ifdef CONFIG_PM_SLEEP
620*a62a8ef9SStefan Hajnoczi static int virtio_fs_freeze(struct virtio_device *vdev)
621*a62a8ef9SStefan Hajnoczi {
622*a62a8ef9SStefan Hajnoczi 	/* TODO need to save state here */
623*a62a8ef9SStefan Hajnoczi 	pr_warn("virtio-fs: suspend/resume not yet supported\n");
624*a62a8ef9SStefan Hajnoczi 	return -EOPNOTSUPP;
625*a62a8ef9SStefan Hajnoczi }
626*a62a8ef9SStefan Hajnoczi 
627*a62a8ef9SStefan Hajnoczi static int virtio_fs_restore(struct virtio_device *vdev)
628*a62a8ef9SStefan Hajnoczi {
629*a62a8ef9SStefan Hajnoczi 	 /* TODO need to restore state here */
630*a62a8ef9SStefan Hajnoczi 	return 0;
631*a62a8ef9SStefan Hajnoczi }
632*a62a8ef9SStefan Hajnoczi #endif /* CONFIG_PM_SLEEP */
633*a62a8ef9SStefan Hajnoczi 
634*a62a8ef9SStefan Hajnoczi const static struct virtio_device_id id_table[] = {
635*a62a8ef9SStefan Hajnoczi 	{ VIRTIO_ID_FS, VIRTIO_DEV_ANY_ID },
636*a62a8ef9SStefan Hajnoczi 	{},
637*a62a8ef9SStefan Hajnoczi };
638*a62a8ef9SStefan Hajnoczi 
639*a62a8ef9SStefan Hajnoczi const static unsigned int feature_table[] = {};
640*a62a8ef9SStefan Hajnoczi 
641*a62a8ef9SStefan Hajnoczi static struct virtio_driver virtio_fs_driver = {
642*a62a8ef9SStefan Hajnoczi 	.driver.name		= KBUILD_MODNAME,
643*a62a8ef9SStefan Hajnoczi 	.driver.owner		= THIS_MODULE,
644*a62a8ef9SStefan Hajnoczi 	.id_table		= id_table,
645*a62a8ef9SStefan Hajnoczi 	.feature_table		= feature_table,
646*a62a8ef9SStefan Hajnoczi 	.feature_table_size	= ARRAY_SIZE(feature_table),
647*a62a8ef9SStefan Hajnoczi 	.probe			= virtio_fs_probe,
648*a62a8ef9SStefan Hajnoczi 	.remove			= virtio_fs_remove,
649*a62a8ef9SStefan Hajnoczi #ifdef CONFIG_PM_SLEEP
650*a62a8ef9SStefan Hajnoczi 	.freeze			= virtio_fs_freeze,
651*a62a8ef9SStefan Hajnoczi 	.restore		= virtio_fs_restore,
652*a62a8ef9SStefan Hajnoczi #endif
653*a62a8ef9SStefan Hajnoczi };
654*a62a8ef9SStefan Hajnoczi 
655*a62a8ef9SStefan Hajnoczi static void virtio_fs_wake_forget_and_unlock(struct fuse_iqueue *fiq)
656*a62a8ef9SStefan Hajnoczi __releases(fiq->lock)
657*a62a8ef9SStefan Hajnoczi {
658*a62a8ef9SStefan Hajnoczi 	struct fuse_forget_link *link;
659*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_forget *forget;
660*a62a8ef9SStefan Hajnoczi 	struct scatterlist sg;
661*a62a8ef9SStefan Hajnoczi 	struct scatterlist *sgs[] = {&sg};
662*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs;
663*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq;
664*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq;
665*a62a8ef9SStefan Hajnoczi 	bool notify;
666*a62a8ef9SStefan Hajnoczi 	u64 unique;
667*a62a8ef9SStefan Hajnoczi 	int ret;
668*a62a8ef9SStefan Hajnoczi 
669*a62a8ef9SStefan Hajnoczi 	link = fuse_dequeue_forget(fiq, 1, NULL);
670*a62a8ef9SStefan Hajnoczi 	unique = fuse_get_unique(fiq);
671*a62a8ef9SStefan Hajnoczi 
672*a62a8ef9SStefan Hajnoczi 	fs = fiq->priv;
673*a62a8ef9SStefan Hajnoczi 	fsvq = &fs->vqs[VQ_HIPRIO];
674*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fiq->lock);
675*a62a8ef9SStefan Hajnoczi 
676*a62a8ef9SStefan Hajnoczi 	/* Allocate a buffer for the request */
677*a62a8ef9SStefan Hajnoczi 	forget = kmalloc(sizeof(*forget), GFP_NOFS | __GFP_NOFAIL);
678*a62a8ef9SStefan Hajnoczi 
679*a62a8ef9SStefan Hajnoczi 	forget->ih = (struct fuse_in_header){
680*a62a8ef9SStefan Hajnoczi 		.opcode = FUSE_FORGET,
681*a62a8ef9SStefan Hajnoczi 		.nodeid = link->forget_one.nodeid,
682*a62a8ef9SStefan Hajnoczi 		.unique = unique,
683*a62a8ef9SStefan Hajnoczi 		.len = sizeof(*forget),
684*a62a8ef9SStefan Hajnoczi 	};
685*a62a8ef9SStefan Hajnoczi 	forget->arg = (struct fuse_forget_in){
686*a62a8ef9SStefan Hajnoczi 		.nlookup = link->forget_one.nlookup,
687*a62a8ef9SStefan Hajnoczi 	};
688*a62a8ef9SStefan Hajnoczi 
689*a62a8ef9SStefan Hajnoczi 	sg_init_one(&sg, forget, sizeof(*forget));
690*a62a8ef9SStefan Hajnoczi 
691*a62a8ef9SStefan Hajnoczi 	/* Enqueue the request */
692*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
693*a62a8ef9SStefan Hajnoczi 
694*a62a8ef9SStefan Hajnoczi 	if (!fsvq->connected) {
695*a62a8ef9SStefan Hajnoczi 		kfree(forget);
696*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
697*a62a8ef9SStefan Hajnoczi 		goto out;
698*a62a8ef9SStefan Hajnoczi 	}
699*a62a8ef9SStefan Hajnoczi 
700*a62a8ef9SStefan Hajnoczi 	vq = fsvq->vq;
701*a62a8ef9SStefan Hajnoczi 	dev_dbg(&vq->vdev->dev, "%s\n", __func__);
702*a62a8ef9SStefan Hajnoczi 
703*a62a8ef9SStefan Hajnoczi 	ret = virtqueue_add_sgs(vq, sgs, 1, 0, forget, GFP_ATOMIC);
704*a62a8ef9SStefan Hajnoczi 	if (ret < 0) {
705*a62a8ef9SStefan Hajnoczi 		if (ret == -ENOMEM || ret == -ENOSPC) {
706*a62a8ef9SStefan Hajnoczi 			pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later.\n",
707*a62a8ef9SStefan Hajnoczi 				 ret);
708*a62a8ef9SStefan Hajnoczi 			list_add_tail(&forget->list, &fsvq->queued_reqs);
709*a62a8ef9SStefan Hajnoczi 			schedule_delayed_work(&fsvq->dispatch_work,
710*a62a8ef9SStefan Hajnoczi 					msecs_to_jiffies(1));
711*a62a8ef9SStefan Hajnoczi 		} else {
712*a62a8ef9SStefan Hajnoczi 			pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
713*a62a8ef9SStefan Hajnoczi 				 ret);
714*a62a8ef9SStefan Hajnoczi 			kfree(forget);
715*a62a8ef9SStefan Hajnoczi 		}
716*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
717*a62a8ef9SStefan Hajnoczi 		goto out;
718*a62a8ef9SStefan Hajnoczi 	}
719*a62a8ef9SStefan Hajnoczi 
720*a62a8ef9SStefan Hajnoczi 	fsvq->in_flight++;
721*a62a8ef9SStefan Hajnoczi 	notify = virtqueue_kick_prepare(vq);
722*a62a8ef9SStefan Hajnoczi 
723*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
724*a62a8ef9SStefan Hajnoczi 
725*a62a8ef9SStefan Hajnoczi 	if (notify)
726*a62a8ef9SStefan Hajnoczi 		virtqueue_notify(vq);
727*a62a8ef9SStefan Hajnoczi out:
728*a62a8ef9SStefan Hajnoczi 	kfree(link);
729*a62a8ef9SStefan Hajnoczi }
730*a62a8ef9SStefan Hajnoczi 
731*a62a8ef9SStefan Hajnoczi static void virtio_fs_wake_interrupt_and_unlock(struct fuse_iqueue *fiq)
732*a62a8ef9SStefan Hajnoczi __releases(fiq->lock)
733*a62a8ef9SStefan Hajnoczi {
734*a62a8ef9SStefan Hajnoczi 	/*
735*a62a8ef9SStefan Hajnoczi 	 * TODO interrupts.
736*a62a8ef9SStefan Hajnoczi 	 *
737*a62a8ef9SStefan Hajnoczi 	 * Normal fs operations on a local filesystems aren't interruptible.
738*a62a8ef9SStefan Hajnoczi 	 * Exceptions are blocking lock operations; for example fcntl(F_SETLKW)
739*a62a8ef9SStefan Hajnoczi 	 * with shared lock between host and guest.
740*a62a8ef9SStefan Hajnoczi 	 */
741*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fiq->lock);
742*a62a8ef9SStefan Hajnoczi }
743*a62a8ef9SStefan Hajnoczi 
744*a62a8ef9SStefan Hajnoczi /* Return the number of scatter-gather list elements required */
745*a62a8ef9SStefan Hajnoczi static unsigned int sg_count_fuse_req(struct fuse_req *req)
746*a62a8ef9SStefan Hajnoczi {
747*a62a8ef9SStefan Hajnoczi 	struct fuse_args *args = req->args;
748*a62a8ef9SStefan Hajnoczi 	struct fuse_args_pages *ap = container_of(args, typeof(*ap), args);
749*a62a8ef9SStefan Hajnoczi 	unsigned int total_sgs = 1 /* fuse_in_header */;
750*a62a8ef9SStefan Hajnoczi 
751*a62a8ef9SStefan Hajnoczi 	if (args->in_numargs - args->in_pages)
752*a62a8ef9SStefan Hajnoczi 		total_sgs += 1;
753*a62a8ef9SStefan Hajnoczi 
754*a62a8ef9SStefan Hajnoczi 	if (args->in_pages)
755*a62a8ef9SStefan Hajnoczi 		total_sgs += ap->num_pages;
756*a62a8ef9SStefan Hajnoczi 
757*a62a8ef9SStefan Hajnoczi 	if (!test_bit(FR_ISREPLY, &req->flags))
758*a62a8ef9SStefan Hajnoczi 		return total_sgs;
759*a62a8ef9SStefan Hajnoczi 
760*a62a8ef9SStefan Hajnoczi 	total_sgs += 1 /* fuse_out_header */;
761*a62a8ef9SStefan Hajnoczi 
762*a62a8ef9SStefan Hajnoczi 	if (args->out_numargs - args->out_pages)
763*a62a8ef9SStefan Hajnoczi 		total_sgs += 1;
764*a62a8ef9SStefan Hajnoczi 
765*a62a8ef9SStefan Hajnoczi 	if (args->out_pages)
766*a62a8ef9SStefan Hajnoczi 		total_sgs += ap->num_pages;
767*a62a8ef9SStefan Hajnoczi 
768*a62a8ef9SStefan Hajnoczi 	return total_sgs;
769*a62a8ef9SStefan Hajnoczi }
770*a62a8ef9SStefan Hajnoczi 
771*a62a8ef9SStefan Hajnoczi /* Add pages to scatter-gather list and return number of elements used */
772*a62a8ef9SStefan Hajnoczi static unsigned int sg_init_fuse_pages(struct scatterlist *sg,
773*a62a8ef9SStefan Hajnoczi 				       struct page **pages,
774*a62a8ef9SStefan Hajnoczi 				       struct fuse_page_desc *page_descs,
775*a62a8ef9SStefan Hajnoczi 				       unsigned int num_pages,
776*a62a8ef9SStefan Hajnoczi 				       unsigned int total_len)
777*a62a8ef9SStefan Hajnoczi {
778*a62a8ef9SStefan Hajnoczi 	unsigned int i;
779*a62a8ef9SStefan Hajnoczi 	unsigned int this_len;
780*a62a8ef9SStefan Hajnoczi 
781*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < num_pages && total_len; i++) {
782*a62a8ef9SStefan Hajnoczi 		sg_init_table(&sg[i], 1);
783*a62a8ef9SStefan Hajnoczi 		this_len =  min(page_descs[i].length, total_len);
784*a62a8ef9SStefan Hajnoczi 		sg_set_page(&sg[i], pages[i], this_len, page_descs[i].offset);
785*a62a8ef9SStefan Hajnoczi 		total_len -= this_len;
786*a62a8ef9SStefan Hajnoczi 	}
787*a62a8ef9SStefan Hajnoczi 
788*a62a8ef9SStefan Hajnoczi 	return i;
789*a62a8ef9SStefan Hajnoczi }
790*a62a8ef9SStefan Hajnoczi 
791*a62a8ef9SStefan Hajnoczi /* Add args to scatter-gather list and return number of elements used */
792*a62a8ef9SStefan Hajnoczi static unsigned int sg_init_fuse_args(struct scatterlist *sg,
793*a62a8ef9SStefan Hajnoczi 				      struct fuse_req *req,
794*a62a8ef9SStefan Hajnoczi 				      struct fuse_arg *args,
795*a62a8ef9SStefan Hajnoczi 				      unsigned int numargs,
796*a62a8ef9SStefan Hajnoczi 				      bool argpages,
797*a62a8ef9SStefan Hajnoczi 				      void *argbuf,
798*a62a8ef9SStefan Hajnoczi 				      unsigned int *len_used)
799*a62a8ef9SStefan Hajnoczi {
800*a62a8ef9SStefan Hajnoczi 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
801*a62a8ef9SStefan Hajnoczi 	unsigned int total_sgs = 0;
802*a62a8ef9SStefan Hajnoczi 	unsigned int len;
803*a62a8ef9SStefan Hajnoczi 
804*a62a8ef9SStefan Hajnoczi 	len = fuse_len_args(numargs - argpages, args);
805*a62a8ef9SStefan Hajnoczi 	if (len)
806*a62a8ef9SStefan Hajnoczi 		sg_init_one(&sg[total_sgs++], argbuf, len);
807*a62a8ef9SStefan Hajnoczi 
808*a62a8ef9SStefan Hajnoczi 	if (argpages)
809*a62a8ef9SStefan Hajnoczi 		total_sgs += sg_init_fuse_pages(&sg[total_sgs],
810*a62a8ef9SStefan Hajnoczi 						ap->pages, ap->descs,
811*a62a8ef9SStefan Hajnoczi 						ap->num_pages,
812*a62a8ef9SStefan Hajnoczi 						args[numargs - 1].size);
813*a62a8ef9SStefan Hajnoczi 
814*a62a8ef9SStefan Hajnoczi 	if (len_used)
815*a62a8ef9SStefan Hajnoczi 		*len_used = len;
816*a62a8ef9SStefan Hajnoczi 
817*a62a8ef9SStefan Hajnoczi 	return total_sgs;
818*a62a8ef9SStefan Hajnoczi }
819*a62a8ef9SStefan Hajnoczi 
820*a62a8ef9SStefan Hajnoczi /* Add a request to a virtqueue and kick the device */
821*a62a8ef9SStefan Hajnoczi static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
822*a62a8ef9SStefan Hajnoczi 				 struct fuse_req *req)
823*a62a8ef9SStefan Hajnoczi {
824*a62a8ef9SStefan Hajnoczi 	/* requests need at least 4 elements */
825*a62a8ef9SStefan Hajnoczi 	struct scatterlist *stack_sgs[6];
826*a62a8ef9SStefan Hajnoczi 	struct scatterlist stack_sg[ARRAY_SIZE(stack_sgs)];
827*a62a8ef9SStefan Hajnoczi 	struct scatterlist **sgs = stack_sgs;
828*a62a8ef9SStefan Hajnoczi 	struct scatterlist *sg = stack_sg;
829*a62a8ef9SStefan Hajnoczi 	struct virtqueue *vq;
830*a62a8ef9SStefan Hajnoczi 	struct fuse_args *args = req->args;
831*a62a8ef9SStefan Hajnoczi 	unsigned int argbuf_used = 0;
832*a62a8ef9SStefan Hajnoczi 	unsigned int out_sgs = 0;
833*a62a8ef9SStefan Hajnoczi 	unsigned int in_sgs = 0;
834*a62a8ef9SStefan Hajnoczi 	unsigned int total_sgs;
835*a62a8ef9SStefan Hajnoczi 	unsigned int i;
836*a62a8ef9SStefan Hajnoczi 	int ret;
837*a62a8ef9SStefan Hajnoczi 	bool notify;
838*a62a8ef9SStefan Hajnoczi 
839*a62a8ef9SStefan Hajnoczi 	/* Does the sglist fit on the stack? */
840*a62a8ef9SStefan Hajnoczi 	total_sgs = sg_count_fuse_req(req);
841*a62a8ef9SStefan Hajnoczi 	if (total_sgs > ARRAY_SIZE(stack_sgs)) {
842*a62a8ef9SStefan Hajnoczi 		sgs = kmalloc_array(total_sgs, sizeof(sgs[0]), GFP_ATOMIC);
843*a62a8ef9SStefan Hajnoczi 		sg = kmalloc_array(total_sgs, sizeof(sg[0]), GFP_ATOMIC);
844*a62a8ef9SStefan Hajnoczi 		if (!sgs || !sg) {
845*a62a8ef9SStefan Hajnoczi 			ret = -ENOMEM;
846*a62a8ef9SStefan Hajnoczi 			goto out;
847*a62a8ef9SStefan Hajnoczi 		}
848*a62a8ef9SStefan Hajnoczi 	}
849*a62a8ef9SStefan Hajnoczi 
850*a62a8ef9SStefan Hajnoczi 	/* Use a bounce buffer since stack args cannot be mapped */
851*a62a8ef9SStefan Hajnoczi 	ret = copy_args_to_argbuf(req);
852*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
853*a62a8ef9SStefan Hajnoczi 		goto out;
854*a62a8ef9SStefan Hajnoczi 
855*a62a8ef9SStefan Hajnoczi 	/* Request elements */
856*a62a8ef9SStefan Hajnoczi 	sg_init_one(&sg[out_sgs++], &req->in.h, sizeof(req->in.h));
857*a62a8ef9SStefan Hajnoczi 	out_sgs += sg_init_fuse_args(&sg[out_sgs], req,
858*a62a8ef9SStefan Hajnoczi 				     (struct fuse_arg *)args->in_args,
859*a62a8ef9SStefan Hajnoczi 				     args->in_numargs, args->in_pages,
860*a62a8ef9SStefan Hajnoczi 				     req->argbuf, &argbuf_used);
861*a62a8ef9SStefan Hajnoczi 
862*a62a8ef9SStefan Hajnoczi 	/* Reply elements */
863*a62a8ef9SStefan Hajnoczi 	if (test_bit(FR_ISREPLY, &req->flags)) {
864*a62a8ef9SStefan Hajnoczi 		sg_init_one(&sg[out_sgs + in_sgs++],
865*a62a8ef9SStefan Hajnoczi 			    &req->out.h, sizeof(req->out.h));
866*a62a8ef9SStefan Hajnoczi 		in_sgs += sg_init_fuse_args(&sg[out_sgs + in_sgs], req,
867*a62a8ef9SStefan Hajnoczi 					    args->out_args, args->out_numargs,
868*a62a8ef9SStefan Hajnoczi 					    args->out_pages,
869*a62a8ef9SStefan Hajnoczi 					    req->argbuf + argbuf_used, NULL);
870*a62a8ef9SStefan Hajnoczi 	}
871*a62a8ef9SStefan Hajnoczi 
872*a62a8ef9SStefan Hajnoczi 	WARN_ON(out_sgs + in_sgs != total_sgs);
873*a62a8ef9SStefan Hajnoczi 
874*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < total_sgs; i++)
875*a62a8ef9SStefan Hajnoczi 		sgs[i] = &sg[i];
876*a62a8ef9SStefan Hajnoczi 
877*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
878*a62a8ef9SStefan Hajnoczi 
879*a62a8ef9SStefan Hajnoczi 	if (!fsvq->connected) {
880*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
881*a62a8ef9SStefan Hajnoczi 		ret = -ENOTCONN;
882*a62a8ef9SStefan Hajnoczi 		goto out;
883*a62a8ef9SStefan Hajnoczi 	}
884*a62a8ef9SStefan Hajnoczi 
885*a62a8ef9SStefan Hajnoczi 	vq = fsvq->vq;
886*a62a8ef9SStefan Hajnoczi 	ret = virtqueue_add_sgs(vq, sgs, out_sgs, in_sgs, req, GFP_ATOMIC);
887*a62a8ef9SStefan Hajnoczi 	if (ret < 0) {
888*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fsvq->lock);
889*a62a8ef9SStefan Hajnoczi 		goto out;
890*a62a8ef9SStefan Hajnoczi 	}
891*a62a8ef9SStefan Hajnoczi 
892*a62a8ef9SStefan Hajnoczi 	fsvq->in_flight++;
893*a62a8ef9SStefan Hajnoczi 	notify = virtqueue_kick_prepare(vq);
894*a62a8ef9SStefan Hajnoczi 
895*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
896*a62a8ef9SStefan Hajnoczi 
897*a62a8ef9SStefan Hajnoczi 	if (notify)
898*a62a8ef9SStefan Hajnoczi 		virtqueue_notify(vq);
899*a62a8ef9SStefan Hajnoczi 
900*a62a8ef9SStefan Hajnoczi out:
901*a62a8ef9SStefan Hajnoczi 	if (ret < 0 && req->argbuf) {
902*a62a8ef9SStefan Hajnoczi 		kfree(req->argbuf);
903*a62a8ef9SStefan Hajnoczi 		req->argbuf = NULL;
904*a62a8ef9SStefan Hajnoczi 	}
905*a62a8ef9SStefan Hajnoczi 	if (sgs != stack_sgs) {
906*a62a8ef9SStefan Hajnoczi 		kfree(sgs);
907*a62a8ef9SStefan Hajnoczi 		kfree(sg);
908*a62a8ef9SStefan Hajnoczi 	}
909*a62a8ef9SStefan Hajnoczi 
910*a62a8ef9SStefan Hajnoczi 	return ret;
911*a62a8ef9SStefan Hajnoczi }
912*a62a8ef9SStefan Hajnoczi 
913*a62a8ef9SStefan Hajnoczi static void virtio_fs_wake_pending_and_unlock(struct fuse_iqueue *fiq)
914*a62a8ef9SStefan Hajnoczi __releases(fiq->lock)
915*a62a8ef9SStefan Hajnoczi {
916*a62a8ef9SStefan Hajnoczi 	unsigned int queue_id = VQ_REQUEST; /* TODO multiqueue */
917*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs;
918*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc;
919*a62a8ef9SStefan Hajnoczi 	struct fuse_req *req;
920*a62a8ef9SStefan Hajnoczi 	struct fuse_pqueue *fpq;
921*a62a8ef9SStefan Hajnoczi 	int ret;
922*a62a8ef9SStefan Hajnoczi 
923*a62a8ef9SStefan Hajnoczi 	WARN_ON(list_empty(&fiq->pending));
924*a62a8ef9SStefan Hajnoczi 	req = list_last_entry(&fiq->pending, struct fuse_req, list);
925*a62a8ef9SStefan Hajnoczi 	clear_bit(FR_PENDING, &req->flags);
926*a62a8ef9SStefan Hajnoczi 	list_del_init(&req->list);
927*a62a8ef9SStefan Hajnoczi 	WARN_ON(!list_empty(&fiq->pending));
928*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fiq->lock);
929*a62a8ef9SStefan Hajnoczi 
930*a62a8ef9SStefan Hajnoczi 	fs = fiq->priv;
931*a62a8ef9SStefan Hajnoczi 	fc = fs->vqs[queue_id].fud->fc;
932*a62a8ef9SStefan Hajnoczi 
933*a62a8ef9SStefan Hajnoczi 	pr_debug("%s: opcode %u unique %#llx nodeid %#llx in.len %u out.len %u\n",
934*a62a8ef9SStefan Hajnoczi 		  __func__, req->in.h.opcode, req->in.h.unique,
935*a62a8ef9SStefan Hajnoczi 		 req->in.h.nodeid, req->in.h.len,
936*a62a8ef9SStefan Hajnoczi 		 fuse_len_args(req->args->out_numargs, req->args->out_args));
937*a62a8ef9SStefan Hajnoczi 
938*a62a8ef9SStefan Hajnoczi 	fpq = &fs->vqs[queue_id].fud->pq;
939*a62a8ef9SStefan Hajnoczi 	spin_lock(&fpq->lock);
940*a62a8ef9SStefan Hajnoczi 	if (!fpq->connected) {
941*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fpq->lock);
942*a62a8ef9SStefan Hajnoczi 		req->out.h.error = -ENODEV;
943*a62a8ef9SStefan Hajnoczi 		pr_err("virtio-fs: %s disconnected\n", __func__);
944*a62a8ef9SStefan Hajnoczi 		fuse_request_end(fc, req);
945*a62a8ef9SStefan Hajnoczi 		return;
946*a62a8ef9SStefan Hajnoczi 	}
947*a62a8ef9SStefan Hajnoczi 	list_add_tail(&req->list, fpq->processing);
948*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fpq->lock);
949*a62a8ef9SStefan Hajnoczi 	set_bit(FR_SENT, &req->flags);
950*a62a8ef9SStefan Hajnoczi 	/* matches barrier in request_wait_answer() */
951*a62a8ef9SStefan Hajnoczi 	smp_mb__after_atomic();
952*a62a8ef9SStefan Hajnoczi 
953*a62a8ef9SStefan Hajnoczi retry:
954*a62a8ef9SStefan Hajnoczi 	ret = virtio_fs_enqueue_req(&fs->vqs[queue_id], req);
955*a62a8ef9SStefan Hajnoczi 	if (ret < 0) {
956*a62a8ef9SStefan Hajnoczi 		if (ret == -ENOMEM || ret == -ENOSPC) {
957*a62a8ef9SStefan Hajnoczi 			/* Virtqueue full. Retry submission */
958*a62a8ef9SStefan Hajnoczi 			/* TODO use completion instead of timeout */
959*a62a8ef9SStefan Hajnoczi 			usleep_range(20, 30);
960*a62a8ef9SStefan Hajnoczi 			goto retry;
961*a62a8ef9SStefan Hajnoczi 		}
962*a62a8ef9SStefan Hajnoczi 		req->out.h.error = ret;
963*a62a8ef9SStefan Hajnoczi 		pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret);
964*a62a8ef9SStefan Hajnoczi 		spin_lock(&fpq->lock);
965*a62a8ef9SStefan Hajnoczi 		clear_bit(FR_SENT, &req->flags);
966*a62a8ef9SStefan Hajnoczi 		list_del_init(&req->list);
967*a62a8ef9SStefan Hajnoczi 		spin_unlock(&fpq->lock);
968*a62a8ef9SStefan Hajnoczi 		fuse_request_end(fc, req);
969*a62a8ef9SStefan Hajnoczi 		return;
970*a62a8ef9SStefan Hajnoczi 	}
971*a62a8ef9SStefan Hajnoczi }
972*a62a8ef9SStefan Hajnoczi 
973*a62a8ef9SStefan Hajnoczi const static struct fuse_iqueue_ops virtio_fs_fiq_ops = {
974*a62a8ef9SStefan Hajnoczi 	.wake_forget_and_unlock		= virtio_fs_wake_forget_and_unlock,
975*a62a8ef9SStefan Hajnoczi 	.wake_interrupt_and_unlock	= virtio_fs_wake_interrupt_and_unlock,
976*a62a8ef9SStefan Hajnoczi 	.wake_pending_and_unlock	= virtio_fs_wake_pending_and_unlock,
977*a62a8ef9SStefan Hajnoczi 	.release			= virtio_fs_fiq_release,
978*a62a8ef9SStefan Hajnoczi };
979*a62a8ef9SStefan Hajnoczi 
980*a62a8ef9SStefan Hajnoczi static int virtio_fs_fill_super(struct super_block *sb)
981*a62a8ef9SStefan Hajnoczi {
982*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
983*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs = fc->iq.priv;
984*a62a8ef9SStefan Hajnoczi 	unsigned int i;
985*a62a8ef9SStefan Hajnoczi 	int err;
986*a62a8ef9SStefan Hajnoczi 	struct fuse_fs_context ctx = {
987*a62a8ef9SStefan Hajnoczi 		.rootmode = S_IFDIR,
988*a62a8ef9SStefan Hajnoczi 		.default_permissions = 1,
989*a62a8ef9SStefan Hajnoczi 		.allow_other = 1,
990*a62a8ef9SStefan Hajnoczi 		.max_read = UINT_MAX,
991*a62a8ef9SStefan Hajnoczi 		.blksize = 512,
992*a62a8ef9SStefan Hajnoczi 		.destroy = true,
993*a62a8ef9SStefan Hajnoczi 		.no_control = true,
994*a62a8ef9SStefan Hajnoczi 		.no_force_umount = true,
995*a62a8ef9SStefan Hajnoczi 	};
996*a62a8ef9SStefan Hajnoczi 
997*a62a8ef9SStefan Hajnoczi 	mutex_lock(&virtio_fs_mutex);
998*a62a8ef9SStefan Hajnoczi 
999*a62a8ef9SStefan Hajnoczi 	/* After holding mutex, make sure virtiofs device is still there.
1000*a62a8ef9SStefan Hajnoczi 	 * Though we are holding a reference to it, drive ->remove might
1001*a62a8ef9SStefan Hajnoczi 	 * still have cleaned up virtual queues. In that case bail out.
1002*a62a8ef9SStefan Hajnoczi 	 */
1003*a62a8ef9SStefan Hajnoczi 	err = -EINVAL;
1004*a62a8ef9SStefan Hajnoczi 	if (list_empty(&fs->list)) {
1005*a62a8ef9SStefan Hajnoczi 		pr_info("virtio-fs: tag <%s> not found\n", fs->tag);
1006*a62a8ef9SStefan Hajnoczi 		goto err;
1007*a62a8ef9SStefan Hajnoczi 	}
1008*a62a8ef9SStefan Hajnoczi 
1009*a62a8ef9SStefan Hajnoczi 	err = -ENOMEM;
1010*a62a8ef9SStefan Hajnoczi 	/* Allocate fuse_dev for hiprio and notification queues */
1011*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < VQ_REQUEST; i++) {
1012*a62a8ef9SStefan Hajnoczi 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
1013*a62a8ef9SStefan Hajnoczi 
1014*a62a8ef9SStefan Hajnoczi 		fsvq->fud = fuse_dev_alloc();
1015*a62a8ef9SStefan Hajnoczi 		if (!fsvq->fud)
1016*a62a8ef9SStefan Hajnoczi 			goto err_free_fuse_devs;
1017*a62a8ef9SStefan Hajnoczi 	}
1018*a62a8ef9SStefan Hajnoczi 
1019*a62a8ef9SStefan Hajnoczi 	ctx.fudptr = (void **)&fs->vqs[VQ_REQUEST].fud;
1020*a62a8ef9SStefan Hajnoczi 	err = fuse_fill_super_common(sb, &ctx);
1021*a62a8ef9SStefan Hajnoczi 	if (err < 0)
1022*a62a8ef9SStefan Hajnoczi 		goto err_free_fuse_devs;
1023*a62a8ef9SStefan Hajnoczi 
1024*a62a8ef9SStefan Hajnoczi 	fc = fs->vqs[VQ_REQUEST].fud->fc;
1025*a62a8ef9SStefan Hajnoczi 
1026*a62a8ef9SStefan Hajnoczi 	for (i = 0; i < fs->nvqs; i++) {
1027*a62a8ef9SStefan Hajnoczi 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
1028*a62a8ef9SStefan Hajnoczi 
1029*a62a8ef9SStefan Hajnoczi 		if (i == VQ_REQUEST)
1030*a62a8ef9SStefan Hajnoczi 			continue; /* already initialized */
1031*a62a8ef9SStefan Hajnoczi 		fuse_dev_install(fsvq->fud, fc);
1032*a62a8ef9SStefan Hajnoczi 	}
1033*a62a8ef9SStefan Hajnoczi 
1034*a62a8ef9SStefan Hajnoczi 	/* Previous unmount will stop all queues. Start these again */
1035*a62a8ef9SStefan Hajnoczi 	virtio_fs_start_all_queues(fs);
1036*a62a8ef9SStefan Hajnoczi 	fuse_send_init(fc);
1037*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
1038*a62a8ef9SStefan Hajnoczi 	return 0;
1039*a62a8ef9SStefan Hajnoczi 
1040*a62a8ef9SStefan Hajnoczi err_free_fuse_devs:
1041*a62a8ef9SStefan Hajnoczi 	virtio_fs_free_devs(fs);
1042*a62a8ef9SStefan Hajnoczi err:
1043*a62a8ef9SStefan Hajnoczi 	mutex_unlock(&virtio_fs_mutex);
1044*a62a8ef9SStefan Hajnoczi 	return err;
1045*a62a8ef9SStefan Hajnoczi }
1046*a62a8ef9SStefan Hajnoczi 
1047*a62a8ef9SStefan Hajnoczi static void virtio_kill_sb(struct super_block *sb)
1048*a62a8ef9SStefan Hajnoczi {
1049*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
1050*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *vfs;
1051*a62a8ef9SStefan Hajnoczi 	struct virtio_fs_vq *fsvq;
1052*a62a8ef9SStefan Hajnoczi 
1053*a62a8ef9SStefan Hajnoczi 	/* If mount failed, we can still be called without any fc */
1054*a62a8ef9SStefan Hajnoczi 	if (!fc)
1055*a62a8ef9SStefan Hajnoczi 		return fuse_kill_sb_anon(sb);
1056*a62a8ef9SStefan Hajnoczi 
1057*a62a8ef9SStefan Hajnoczi 	vfs = fc->iq.priv;
1058*a62a8ef9SStefan Hajnoczi 	fsvq = &vfs->vqs[VQ_HIPRIO];
1059*a62a8ef9SStefan Hajnoczi 
1060*a62a8ef9SStefan Hajnoczi 	/* Stop forget queue. Soon destroy will be sent */
1061*a62a8ef9SStefan Hajnoczi 	spin_lock(&fsvq->lock);
1062*a62a8ef9SStefan Hajnoczi 	fsvq->connected = false;
1063*a62a8ef9SStefan Hajnoczi 	spin_unlock(&fsvq->lock);
1064*a62a8ef9SStefan Hajnoczi 	virtio_fs_drain_all_queues(vfs);
1065*a62a8ef9SStefan Hajnoczi 
1066*a62a8ef9SStefan Hajnoczi 	fuse_kill_sb_anon(sb);
1067*a62a8ef9SStefan Hajnoczi 
1068*a62a8ef9SStefan Hajnoczi 	/* fuse_kill_sb_anon() must have sent destroy. Stop all queues
1069*a62a8ef9SStefan Hajnoczi 	 * and drain one more time and free fuse devices. Freeing fuse
1070*a62a8ef9SStefan Hajnoczi 	 * devices will drop their reference on fuse_conn and that in
1071*a62a8ef9SStefan Hajnoczi 	 * turn will drop its reference on virtio_fs object.
1072*a62a8ef9SStefan Hajnoczi 	 */
1073*a62a8ef9SStefan Hajnoczi 	virtio_fs_stop_all_queues(vfs);
1074*a62a8ef9SStefan Hajnoczi 	virtio_fs_drain_all_queues(vfs);
1075*a62a8ef9SStefan Hajnoczi 	virtio_fs_free_devs(vfs);
1076*a62a8ef9SStefan Hajnoczi }
1077*a62a8ef9SStefan Hajnoczi 
1078*a62a8ef9SStefan Hajnoczi static int virtio_fs_test_super(struct super_block *sb,
1079*a62a8ef9SStefan Hajnoczi 				struct fs_context *fsc)
1080*a62a8ef9SStefan Hajnoczi {
1081*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc = fsc->s_fs_info;
1082*a62a8ef9SStefan Hajnoczi 
1083*a62a8ef9SStefan Hajnoczi 	return fc->iq.priv == get_fuse_conn_super(sb)->iq.priv;
1084*a62a8ef9SStefan Hajnoczi }
1085*a62a8ef9SStefan Hajnoczi 
1086*a62a8ef9SStefan Hajnoczi static int virtio_fs_set_super(struct super_block *sb,
1087*a62a8ef9SStefan Hajnoczi 			       struct fs_context *fsc)
1088*a62a8ef9SStefan Hajnoczi {
1089*a62a8ef9SStefan Hajnoczi 	int err;
1090*a62a8ef9SStefan Hajnoczi 
1091*a62a8ef9SStefan Hajnoczi 	err = get_anon_bdev(&sb->s_dev);
1092*a62a8ef9SStefan Hajnoczi 	if (!err)
1093*a62a8ef9SStefan Hajnoczi 		fuse_conn_get(fsc->s_fs_info);
1094*a62a8ef9SStefan Hajnoczi 
1095*a62a8ef9SStefan Hajnoczi 	return err;
1096*a62a8ef9SStefan Hajnoczi }
1097*a62a8ef9SStefan Hajnoczi 
1098*a62a8ef9SStefan Hajnoczi static int virtio_fs_get_tree(struct fs_context *fsc)
1099*a62a8ef9SStefan Hajnoczi {
1100*a62a8ef9SStefan Hajnoczi 	struct virtio_fs *fs;
1101*a62a8ef9SStefan Hajnoczi 	struct super_block *sb;
1102*a62a8ef9SStefan Hajnoczi 	struct fuse_conn *fc;
1103*a62a8ef9SStefan Hajnoczi 	int err;
1104*a62a8ef9SStefan Hajnoczi 
1105*a62a8ef9SStefan Hajnoczi 	/* This gets a reference on virtio_fs object. This ptr gets installed
1106*a62a8ef9SStefan Hajnoczi 	 * in fc->iq->priv. Once fuse_conn is going away, it calls ->put()
1107*a62a8ef9SStefan Hajnoczi 	 * to drop the reference to this object.
1108*a62a8ef9SStefan Hajnoczi 	 */
1109*a62a8ef9SStefan Hajnoczi 	fs = virtio_fs_find_instance(fsc->source);
1110*a62a8ef9SStefan Hajnoczi 	if (!fs) {
1111*a62a8ef9SStefan Hajnoczi 		pr_info("virtio-fs: tag <%s> not found\n", fsc->source);
1112*a62a8ef9SStefan Hajnoczi 		return -EINVAL;
1113*a62a8ef9SStefan Hajnoczi 	}
1114*a62a8ef9SStefan Hajnoczi 
1115*a62a8ef9SStefan Hajnoczi 	fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL);
1116*a62a8ef9SStefan Hajnoczi 	if (!fc) {
1117*a62a8ef9SStefan Hajnoczi 		mutex_lock(&virtio_fs_mutex);
1118*a62a8ef9SStefan Hajnoczi 		virtio_fs_put(fs);
1119*a62a8ef9SStefan Hajnoczi 		mutex_unlock(&virtio_fs_mutex);
1120*a62a8ef9SStefan Hajnoczi 		return -ENOMEM;
1121*a62a8ef9SStefan Hajnoczi 	}
1122*a62a8ef9SStefan Hajnoczi 
1123*a62a8ef9SStefan Hajnoczi 	fuse_conn_init(fc, get_user_ns(current_user_ns()), &virtio_fs_fiq_ops,
1124*a62a8ef9SStefan Hajnoczi 		       fs);
1125*a62a8ef9SStefan Hajnoczi 	fc->release = fuse_free_conn;
1126*a62a8ef9SStefan Hajnoczi 	fc->delete_stale = true;
1127*a62a8ef9SStefan Hajnoczi 
1128*a62a8ef9SStefan Hajnoczi 	fsc->s_fs_info = fc;
1129*a62a8ef9SStefan Hajnoczi 	sb = sget_fc(fsc, virtio_fs_test_super, virtio_fs_set_super);
1130*a62a8ef9SStefan Hajnoczi 	fuse_conn_put(fc);
1131*a62a8ef9SStefan Hajnoczi 	if (IS_ERR(sb))
1132*a62a8ef9SStefan Hajnoczi 		return PTR_ERR(sb);
1133*a62a8ef9SStefan Hajnoczi 
1134*a62a8ef9SStefan Hajnoczi 	if (!sb->s_root) {
1135*a62a8ef9SStefan Hajnoczi 		err = virtio_fs_fill_super(sb);
1136*a62a8ef9SStefan Hajnoczi 		if (err) {
1137*a62a8ef9SStefan Hajnoczi 			deactivate_locked_super(sb);
1138*a62a8ef9SStefan Hajnoczi 			return err;
1139*a62a8ef9SStefan Hajnoczi 		}
1140*a62a8ef9SStefan Hajnoczi 
1141*a62a8ef9SStefan Hajnoczi 		sb->s_flags |= SB_ACTIVE;
1142*a62a8ef9SStefan Hajnoczi 	}
1143*a62a8ef9SStefan Hajnoczi 
1144*a62a8ef9SStefan Hajnoczi 	WARN_ON(fsc->root);
1145*a62a8ef9SStefan Hajnoczi 	fsc->root = dget(sb->s_root);
1146*a62a8ef9SStefan Hajnoczi 	return 0;
1147*a62a8ef9SStefan Hajnoczi }
1148*a62a8ef9SStefan Hajnoczi 
1149*a62a8ef9SStefan Hajnoczi static const struct fs_context_operations virtio_fs_context_ops = {
1150*a62a8ef9SStefan Hajnoczi 	.get_tree	= virtio_fs_get_tree,
1151*a62a8ef9SStefan Hajnoczi };
1152*a62a8ef9SStefan Hajnoczi 
1153*a62a8ef9SStefan Hajnoczi static int virtio_fs_init_fs_context(struct fs_context *fsc)
1154*a62a8ef9SStefan Hajnoczi {
1155*a62a8ef9SStefan Hajnoczi 	fsc->ops = &virtio_fs_context_ops;
1156*a62a8ef9SStefan Hajnoczi 	return 0;
1157*a62a8ef9SStefan Hajnoczi }
1158*a62a8ef9SStefan Hajnoczi 
1159*a62a8ef9SStefan Hajnoczi static struct file_system_type virtio_fs_type = {
1160*a62a8ef9SStefan Hajnoczi 	.owner		= THIS_MODULE,
1161*a62a8ef9SStefan Hajnoczi 	.name		= "virtiofs",
1162*a62a8ef9SStefan Hajnoczi 	.init_fs_context = virtio_fs_init_fs_context,
1163*a62a8ef9SStefan Hajnoczi 	.kill_sb	= virtio_kill_sb,
1164*a62a8ef9SStefan Hajnoczi };
1165*a62a8ef9SStefan Hajnoczi 
1166*a62a8ef9SStefan Hajnoczi static int __init virtio_fs_init(void)
1167*a62a8ef9SStefan Hajnoczi {
1168*a62a8ef9SStefan Hajnoczi 	int ret;
1169*a62a8ef9SStefan Hajnoczi 
1170*a62a8ef9SStefan Hajnoczi 	ret = register_virtio_driver(&virtio_fs_driver);
1171*a62a8ef9SStefan Hajnoczi 	if (ret < 0)
1172*a62a8ef9SStefan Hajnoczi 		return ret;
1173*a62a8ef9SStefan Hajnoczi 
1174*a62a8ef9SStefan Hajnoczi 	ret = register_filesystem(&virtio_fs_type);
1175*a62a8ef9SStefan Hajnoczi 	if (ret < 0) {
1176*a62a8ef9SStefan Hajnoczi 		unregister_virtio_driver(&virtio_fs_driver);
1177*a62a8ef9SStefan Hajnoczi 		return ret;
1178*a62a8ef9SStefan Hajnoczi 	}
1179*a62a8ef9SStefan Hajnoczi 
1180*a62a8ef9SStefan Hajnoczi 	return 0;
1181*a62a8ef9SStefan Hajnoczi }
1182*a62a8ef9SStefan Hajnoczi module_init(virtio_fs_init);
1183*a62a8ef9SStefan Hajnoczi 
1184*a62a8ef9SStefan Hajnoczi static void __exit virtio_fs_exit(void)
1185*a62a8ef9SStefan Hajnoczi {
1186*a62a8ef9SStefan Hajnoczi 	unregister_filesystem(&virtio_fs_type);
1187*a62a8ef9SStefan Hajnoczi 	unregister_virtio_driver(&virtio_fs_driver);
1188*a62a8ef9SStefan Hajnoczi }
1189*a62a8ef9SStefan Hajnoczi module_exit(virtio_fs_exit);
1190*a62a8ef9SStefan Hajnoczi 
1191*a62a8ef9SStefan Hajnoczi MODULE_AUTHOR("Stefan Hajnoczi <stefanha@redhat.com>");
1192*a62a8ef9SStefan Hajnoczi MODULE_DESCRIPTION("Virtio Filesystem");
1193*a62a8ef9SStefan Hajnoczi MODULE_LICENSE("GPL");
1194*a62a8ef9SStefan Hajnoczi MODULE_ALIAS_FS(KBUILD_MODNAME);
1195*a62a8ef9SStefan Hajnoczi MODULE_DEVICE_TABLE(virtio, id_table);
1196