VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    1) // SPDX-License-Identifier: GPL-2.0
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    2) /*
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    3)  * virtio-fs: Virtio Filesystem
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    4)  * Copyright (C) 2018 Red Hat, Inc.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    5)  */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    6) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100    7) #include <linux/fs.h>
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400    8) #include <linux/dax.h>
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400    9) #include <linux/pci.h>
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   10) #include <linux/pfn_t.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   11) #include <linux/module.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   12) #include <linux/virtio.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   13) #include <linux/virtio_fs.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   14) #include <linux/delay.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   15) #include <linux/fs_context.h>
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   16) #include <linux/fs_parser.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   17) #include <linux/highmem.h>
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   18) #include <linux/uio.h>
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   19) #include "fuse_i.h"
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   20) 
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   21) /* Used to help calculate the FUSE connection's max_pages limit for a request's
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   22)  * size. Parts of the struct fuse_req are sliced into scattergather lists in
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   23)  * addition to the pages used, so this can help account for that overhead.
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   24)  */
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   25) #define FUSE_HEADER_OVERHEAD    4
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500   26) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   27) /* List of virtio-fs device instances and a lock for the list. Also provides
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   28)  * mutual exclusion in device removal and mounting path
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   29)  */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   30) static DEFINE_MUTEX(virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   31) static LIST_HEAD(virtio_fs_instances);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   32) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   33) enum {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   34) 	VQ_HIPRIO,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   35) 	VQ_REQUEST
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   36) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   37) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400   38) #define VQ_NAME_LEN	24
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400   39) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   40) /* Per-virtqueue state */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   41) struct virtio_fs_vq {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   42) 	spinlock_t lock;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   43) 	struct virtqueue *vq;     /* protected by ->lock */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   44) 	struct work_struct done_work;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   45) 	struct list_head queued_reqs;
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400   46) 	struct list_head end_reqs;	/* End these requests */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   47) 	struct delayed_work dispatch_work;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   48) 	struct fuse_dev *fud;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   49) 	bool connected;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   50) 	long in_flight;
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400   51) 	struct completion in_flight_zero; /* No inflight requests */
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400   52) 	char name[VQ_NAME_LEN];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   53) } ____cacheline_aligned_in_smp;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   54) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   55) /* A virtio-fs device instance */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   56) struct virtio_fs {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   57) 	struct kref refcount;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   58) 	struct list_head list;    /* on virtio_fs_instances */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   59) 	char *tag;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   60) 	struct virtio_fs_vq *vqs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   61) 	unsigned int nvqs;               /* number of virtqueues */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   62) 	unsigned int num_request_queues; /* number of request queues */
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   63) 	struct dax_device *dax_dev;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   64) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   65) 	/* DAX memory window where file contents are mapped */
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   66) 	void *window_kaddr;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   67) 	phys_addr_t window_phys_addr;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400   68) 	size_t window_len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   69) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   70) 
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400   71) struct virtio_fs_forget_req {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   72) 	struct fuse_in_header ih;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   73) 	struct fuse_forget_in arg;
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400   74) };
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400   75) 
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400   76) struct virtio_fs_forget {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   77) 	/* This request can be temporarily queued on virt queue */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   78) 	struct list_head list;
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400   79) 	struct virtio_fs_forget_req req;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   80) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100   81) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   82) struct virtio_fs_req_work {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   83) 	struct fuse_req *req;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   84) 	struct virtio_fs_vq *fsvq;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   85) 	struct work_struct done_work;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   86) };
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200   87) 
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400   88) static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400   89) 				 struct fuse_req *req, bool in_flight);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400   90) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   91) enum {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   92) 	OPT_DAX,
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   93) };
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   94) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   95) static const struct fs_parameter_spec virtio_fs_parameters[] = {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   96) 	fsparam_flag("dax", OPT_DAX),
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   97) 	{}
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   98) };
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400   99) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  100) static int virtio_fs_parse_param(struct fs_context *fc,
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  101) 				 struct fs_parameter *param)
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  102) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  103) 	struct fs_parse_result result;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  104) 	struct fuse_fs_context *ctx = fc->fs_private;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  105) 	int opt;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  106) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  107) 	opt = fs_parse(fc, virtio_fs_parameters, param, &result);
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  108) 	if (opt < 0)
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  109) 		return opt;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  110) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  111) 	switch (opt) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  112) 	case OPT_DAX:
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  113) 		ctx->dax = 1;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  114) 		break;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  115) 	default:
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  116) 		return -EINVAL;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  117) 	}
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  118) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  119) 	return 0;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  120) }
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  121) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  122) static void virtio_fs_free_fc(struct fs_context *fc)
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  123) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  124) 	struct fuse_fs_context *ctx = fc->fs_private;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  125) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  126) 	kfree(ctx);
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  127) }
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400  128) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  129) static inline struct virtio_fs_vq *vq_to_fsvq(struct virtqueue *vq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  130) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  131) 	struct virtio_fs *fs = vq->vdev->priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  132) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  133) 	return &fs->vqs[vq->index];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  134) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  135) 
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  136) /* Should be called with fsvq->lock held. */
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  137) static inline void inc_in_flight_req(struct virtio_fs_vq *fsvq)
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  138) {
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  139) 	fsvq->in_flight++;
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  140) }
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  141) 
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  142) /* Should be called with fsvq->lock held. */
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  143) static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq)
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  144) {
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  145) 	WARN_ON(fsvq->in_flight <= 0);
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  146) 	fsvq->in_flight--;
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  147) 	if (!fsvq->in_flight)
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  148) 		complete(&fsvq->in_flight_zero);
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  149) }
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  150) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  151) static void release_virtio_fs_obj(struct kref *ref)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  152) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  153) 	struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  154) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  155) 	kfree(vfs->vqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  156) 	kfree(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  157) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  158) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  159) /* Make sure virtiofs_mutex is held */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  160) static void virtio_fs_put(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  161) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  162) 	kref_put(&fs->refcount, release_virtio_fs_obj);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  163) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  164) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  165) static void virtio_fs_fiq_release(struct fuse_iqueue *fiq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  166) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  167) 	struct virtio_fs *vfs = fiq->priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  168) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  169) 	mutex_lock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  170) 	virtio_fs_put(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  171) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  172) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  173) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  174) static void virtio_fs_drain_queue(struct virtio_fs_vq *fsvq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  175) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  176) 	WARN_ON(fsvq->in_flight < 0);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  177) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  178) 	/* Wait for in flight requests to finish.*/
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  179) 	spin_lock(&fsvq->lock);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  180) 	if (fsvq->in_flight) {
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  181) 		/* We are holding virtio_fs_mutex. There should not be any
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  182) 		 * waiters waiting for completion.
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  183) 		 */
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  184) 		reinit_completion(&fsvq->in_flight_zero);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  185) 		spin_unlock(&fsvq->lock);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  186) 		wait_for_completion(&fsvq->in_flight_zero);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  187) 	} else {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  188) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  189) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  190) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  191) 	flush_work(&fsvq->done_work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  192) 	flush_delayed_work(&fsvq->dispatch_work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  193) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  194) 
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  195) static void virtio_fs_drain_all_queues_locked(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  196) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  197) 	struct virtio_fs_vq *fsvq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  198) 	int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  199) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  200) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  201) 		fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  202) 		virtio_fs_drain_queue(fsvq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  203) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  204) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  205) 
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  206) static void virtio_fs_drain_all_queues(struct virtio_fs *fs)
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  207) {
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  208) 	/* Provides mutual exclusion between ->remove and ->kill_sb
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  209) 	 * paths. We don't want both of these draining queue at the
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  210) 	 * same time. Current completion logic reinits completion
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  211) 	 * and that means there should not be any other thread
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  212) 	 * doing reinit or waiting for completion already.
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  213) 	 */
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  214) 	mutex_lock(&virtio_fs_mutex);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  215) 	virtio_fs_drain_all_queues_locked(fs);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  216) 	mutex_unlock(&virtio_fs_mutex);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  217) }
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  218) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  219) static void virtio_fs_start_all_queues(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  220) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  221) 	struct virtio_fs_vq *fsvq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  222) 	int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  223) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  224) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  225) 		fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  226) 		spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  227) 		fsvq->connected = true;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  228) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  229) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  230) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  231) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  232) /* Add a new instance to the list or return -EEXIST if tag name exists*/
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  233) static int virtio_fs_add_instance(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  234) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  235) 	struct virtio_fs *fs2;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  236) 	bool duplicate = false;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  237) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  238) 	mutex_lock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  239) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  240) 	list_for_each_entry(fs2, &virtio_fs_instances, list) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  241) 		if (strcmp(fs->tag, fs2->tag) == 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  242) 			duplicate = true;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  243) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  244) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  245) 	if (!duplicate)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  246) 		list_add_tail(&fs->list, &virtio_fs_instances);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  247) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  248) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  249) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  250) 	if (duplicate)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  251) 		return -EEXIST;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  252) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  253) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  254) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  255) /* Return the virtio_fs with a given tag, or NULL */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  256) static struct virtio_fs *virtio_fs_find_instance(const char *tag)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  257) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  258) 	struct virtio_fs *fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  259) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  260) 	mutex_lock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  261) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  262) 	list_for_each_entry(fs, &virtio_fs_instances, list) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  263) 		if (strcmp(fs->tag, tag) == 0) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  264) 			kref_get(&fs->refcount);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  265) 			goto found;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  266) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  267) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  268) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  269) 	fs = NULL; /* not found */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  270) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  271) found:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  272) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  273) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  274) 	return fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  275) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  276) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  277) static void virtio_fs_free_devs(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  278) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  279) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  280) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  281) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  282) 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  283) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  284) 		if (!fsvq->fud)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  285) 			continue;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  286) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  287) 		fuse_dev_free(fsvq->fud);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  288) 		fsvq->fud = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  289) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  290) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  291) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  292) /* Read filesystem name from virtio config into fs->tag (must kfree()). */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  293) static int virtio_fs_read_tag(struct virtio_device *vdev, struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  294) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  295) 	char tag_buf[sizeof_field(struct virtio_fs_config, tag)];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  296) 	char *end;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  297) 	size_t len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  298) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  299) 	virtio_cread_bytes(vdev, offsetof(struct virtio_fs_config, tag),
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  300) 			   &tag_buf, sizeof(tag_buf));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  301) 	end = memchr(tag_buf, '\0', sizeof(tag_buf));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  302) 	if (end == tag_buf)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  303) 		return -EINVAL; /* empty tag */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  304) 	if (!end)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  305) 		end = &tag_buf[sizeof(tag_buf)];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  306) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  307) 	len = end - tag_buf;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  308) 	fs->tag = devm_kmalloc(&vdev->dev, len + 1, GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  309) 	if (!fs->tag)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  310) 		return -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  311) 	memcpy(fs->tag, tag_buf, len);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  312) 	fs->tag[len] = '\0';
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  313) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  314) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  315) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  316) /* Work function for hiprio completion */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  317) static void virtio_fs_hiprio_done_work(struct work_struct *work)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  318) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  319) 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  320) 						 done_work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  321) 	struct virtqueue *vq = fsvq->vq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  322) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  323) 	/* Free completed FUSE_FORGET requests */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  324) 	spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  325) 	do {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  326) 		unsigned int len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  327) 		void *req;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  328) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  329) 		virtqueue_disable_cb(vq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  330) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  331) 		while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  332) 			kfree(req);
c17ea00961036 (Vivek Goyal        2019-10-15 13:46:25 -0400  333) 			dec_in_flight_req(fsvq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  334) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  335) 	} while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq)));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  336) 	spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  337) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  338) 
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  339) static void virtio_fs_request_dispatch_work(struct work_struct *work)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  340) {
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  341) 	struct fuse_req *req;
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  342) 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  343) 						 dispatch_work.work);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  344) 	int ret;
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  345) 
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  346) 	pr_debug("virtio-fs: worker %s called.\n", __func__);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  347) 	while (1) {
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  348) 		spin_lock(&fsvq->lock);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  349) 		req = list_first_entry_or_null(&fsvq->end_reqs, struct fuse_req,
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  350) 					       list);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  351) 		if (!req) {
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  352) 			spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  353) 			break;
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  354) 		}
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  355) 
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  356) 		list_del_init(&req->list);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  357) 		spin_unlock(&fsvq->lock);
8f622e9497bbb (Max Reitz          2020-04-20 17:59:34 +0200  358) 		fuse_request_end(req);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400  359) 	}
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  360) 
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  361) 	/* Dispatch pending requests */
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  362) 	while (1) {
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  363) 		spin_lock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  364) 		req = list_first_entry_or_null(&fsvq->queued_reqs,
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  365) 					       struct fuse_req, list);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  366) 		if (!req) {
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  367) 			spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  368) 			return;
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  369) 		}
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  370) 		list_del_init(&req->list);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  371) 		spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  372) 
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  373) 		ret = virtio_fs_enqueue_req(fsvq, req, true);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  374) 		if (ret < 0) {
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  375) 			if (ret == -ENOMEM || ret == -ENOSPC) {
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  376) 				spin_lock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  377) 				list_add_tail(&req->list, &fsvq->queued_reqs);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  378) 				schedule_delayed_work(&fsvq->dispatch_work,
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  379) 						      msecs_to_jiffies(1));
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  380) 				spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  381) 				return;
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  382) 			}
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  383) 			req->out.h.error = ret;
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  384) 			spin_lock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  385) 			dec_in_flight_req(fsvq);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  386) 			spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  387) 			pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n",
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  388) 			       ret);
8f622e9497bbb (Max Reitz          2020-04-20 17:59:34 +0200  389) 			fuse_request_end(req);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  390) 		}
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400  391) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  392) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  393) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  394) /*
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  395)  * Returns 1 if queue is full and sender should wait a bit before sending
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  396)  * next request, 0 otherwise.
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  397)  */
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  398) static int send_forget_request(struct virtio_fs_vq *fsvq,
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  399) 			       struct virtio_fs_forget *forget,
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  400) 			       bool in_flight)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  401) {
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  402) 	struct scatterlist sg;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  403) 	struct virtqueue *vq;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  404) 	int ret = 0;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  405) 	bool notify;
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400  406) 	struct virtio_fs_forget_req *req = &forget->req;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  407) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  408) 	spin_lock(&fsvq->lock);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  409) 	if (!fsvq->connected) {
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  410) 		if (in_flight)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  411) 			dec_in_flight_req(fsvq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  412) 		kfree(forget);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  413) 		goto out;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  414) 	}
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  415) 
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400  416) 	sg_init_one(&sg, req, sizeof(*req));
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  417) 	vq = fsvq->vq;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  418) 	dev_dbg(&vq->vdev->dev, "%s\n", __func__);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  419) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  420) 	ret = virtqueue_add_outbuf(vq, &sg, 1, forget, GFP_ATOMIC);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  421) 	if (ret < 0) {
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  422) 		if (ret == -ENOMEM || ret == -ENOSPC) {
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  423) 			pr_debug("virtio-fs: Could not queue FORGET: err=%d. Will try later\n",
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  424) 				 ret);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  425) 			list_add_tail(&forget->list, &fsvq->queued_reqs);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  426) 			schedule_delayed_work(&fsvq->dispatch_work,
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  427) 					      msecs_to_jiffies(1));
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  428) 			if (!in_flight)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  429) 				inc_in_flight_req(fsvq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  430) 			/* Queue is full */
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  431) 			ret = 1;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  432) 		} else {
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  433) 			pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n",
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  434) 				 ret);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  435) 			kfree(forget);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  436) 			if (in_flight)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  437) 				dec_in_flight_req(fsvq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  438) 		}
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  439) 		goto out;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  440) 	}
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  441) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  442) 	if (!in_flight)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  443) 		inc_in_flight_req(fsvq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  444) 	notify = virtqueue_kick_prepare(vq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  445) 	spin_unlock(&fsvq->lock);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  446) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  447) 	if (notify)
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  448) 		virtqueue_notify(vq);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  449) 	return ret;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  450) out:
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  451) 	spin_unlock(&fsvq->lock);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  452) 	return ret;
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  453) }
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  454) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  455) static void virtio_fs_hiprio_dispatch_work(struct work_struct *work)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  456) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  457) 	struct virtio_fs_forget *forget;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  458) 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  459) 						 dispatch_work.work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  460) 	pr_debug("virtio-fs: worker %s called.\n", __func__);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  461) 	while (1) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  462) 		spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  463) 		forget = list_first_entry_or_null(&fsvq->queued_reqs,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  464) 					struct virtio_fs_forget, list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  465) 		if (!forget) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  466) 			spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  467) 			return;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  468) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  469) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  470) 		list_del(&forget->list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  471) 		spin_unlock(&fsvq->lock);
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  472) 		if (send_forget_request(fsvq, forget, true))
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400  473) 			return;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  474) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  475) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  476) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  477) /* Allocate and copy args into req->argbuf */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  478) static int copy_args_to_argbuf(struct fuse_req *req)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  479) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  480) 	struct fuse_args *args = req->args;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  481) 	unsigned int offset = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  482) 	unsigned int num_in;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  483) 	unsigned int num_out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  484) 	unsigned int len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  485) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  486) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  487) 	num_in = args->in_numargs - args->in_pages;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  488) 	num_out = args->out_numargs - args->out_pages;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  489) 	len = fuse_len_args(num_in, (struct fuse_arg *) args->in_args) +
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  490) 	      fuse_len_args(num_out, args->out_args);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  491) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  492) 	req->argbuf = kmalloc(len, GFP_ATOMIC);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  493) 	if (!req->argbuf)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  494) 		return -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  495) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  496) 	for (i = 0; i < num_in; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  497) 		memcpy(req->argbuf + offset,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  498) 		       args->in_args[i].value,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  499) 		       args->in_args[i].size);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  500) 		offset += args->in_args[i].size;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  501) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  502) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  503) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  504) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  505) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  506) /* Copy args out of and free req->argbuf */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  507) static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  508) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  509) 	unsigned int remaining;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  510) 	unsigned int offset;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  511) 	unsigned int num_in;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  512) 	unsigned int num_out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  513) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  514) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  515) 	remaining = req->out.h.len - sizeof(req->out.h);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  516) 	num_in = args->in_numargs - args->in_pages;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  517) 	num_out = args->out_numargs - args->out_pages;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  518) 	offset = fuse_len_args(num_in, (struct fuse_arg *)args->in_args);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  519) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  520) 	for (i = 0; i < num_out; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  521) 		unsigned int argsize = args->out_args[i].size;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  522) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  523) 		if (args->out_argvar &&
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  524) 		    i == args->out_numargs - 1 &&
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  525) 		    argsize > remaining) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  526) 			argsize = remaining;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  527) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  528) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  529) 		memcpy(args->out_args[i].value, req->argbuf + offset, argsize);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  530) 		offset += argsize;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  531) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  532) 		if (i != args->out_numargs - 1)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  533) 			remaining -= argsize;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  534) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  535) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  536) 	/* Store the actual size of the variable-length arg */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  537) 	if (args->out_argvar)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  538) 		args->out_args[args->out_numargs - 1].size = remaining;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  539) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  540) 	kfree(req->argbuf);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  541) 	req->argbuf = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  542) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  543) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  544) /* Work function for request completion */
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  545) static void virtio_fs_request_complete(struct fuse_req *req,
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  546) 				       struct virtio_fs_vq *fsvq)
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  547) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  548) 	struct fuse_pqueue *fpq = &fsvq->fud->pq;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  549) 	struct fuse_args *args;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  550) 	struct fuse_args_pages *ap;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  551) 	unsigned int len, i, thislen;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  552) 	struct page *page;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  553) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  554) 	/*
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  555) 	 * TODO verify that server properly follows FUSE protocol
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  556) 	 * (oh.uniq, oh.len)
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  557) 	 */
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  558) 	args = req->args;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  559) 	copy_args_from_argbuf(args, req);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  560) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  561) 	if (args->out_pages && args->page_zeroing) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  562) 		len = args->out_args[args->out_numargs - 1].size;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  563) 		ap = container_of(args, typeof(*ap), args);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  564) 		for (i = 0; i < ap->num_pages; i++) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  565) 			thislen = ap->descs[i].length;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  566) 			if (len < thislen) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  567) 				WARN_ON(ap->descs[i].offset);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  568) 				page = ap->pages[i];
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  569) 				zero_user_segment(page, len, thislen);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  570) 				len = 0;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  571) 			} else {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  572) 				len -= thislen;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  573) 			}
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  574) 		}
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  575) 	}
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  576) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  577) 	spin_lock(&fpq->lock);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  578) 	clear_bit(FR_SENT, &req->flags);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  579) 	spin_unlock(&fpq->lock);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  580) 
8f622e9497bbb (Max Reitz          2020-04-20 17:59:34 +0200  581) 	fuse_request_end(req);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  582) 	spin_lock(&fsvq->lock);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  583) 	dec_in_flight_req(fsvq);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  584) 	spin_unlock(&fsvq->lock);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  585) }
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  586) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  587) static void virtio_fs_complete_req_work(struct work_struct *work)
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  588) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  589) 	struct virtio_fs_req_work *w =
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  590) 		container_of(work, typeof(*w), done_work);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  591) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  592) 	virtio_fs_request_complete(w->req, w->fsvq);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  593) 	kfree(w);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  594) }
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  595) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  596) static void virtio_fs_requests_done_work(struct work_struct *work)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  597) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  598) 	struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  599) 						 done_work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  600) 	struct fuse_pqueue *fpq = &fsvq->fud->pq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  601) 	struct virtqueue *vq = fsvq->vq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  602) 	struct fuse_req *req;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  603) 	struct fuse_req *next;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  604) 	unsigned int len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  605) 	LIST_HEAD(reqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  606) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  607) 	/* Collect completed requests off the virtqueue */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  608) 	spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  609) 	do {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  610) 		virtqueue_disable_cb(vq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  611) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  612) 		while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  613) 			spin_lock(&fpq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  614) 			list_move_tail(&req->list, &reqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  615) 			spin_unlock(&fpq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  616) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  617) 	} while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq)));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  618) 	spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  619) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  620) 	/* End requests */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  621) 	list_for_each_entry_safe(req, next, &reqs, list) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  622) 		list_del_init(&req->list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  623) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  624) 		/* blocking async request completes in a worker context */
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  625) 		if (req->args->may_block) {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  626) 			struct virtio_fs_req_work *w;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  627) 
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  628) 			w = kzalloc(sizeof(*w), GFP_NOFS | __GFP_NOFAIL);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  629) 			INIT_WORK(&w->done_work, virtio_fs_complete_req_work);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  630) 			w->fsvq = fsvq;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  631) 			w->req = req;
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  632) 			schedule_work(&w->done_work);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  633) 		} else {
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  634) 			virtio_fs_request_complete(req, fsvq);
bb737bbe48bea (Vivek Goyal        2020-04-20 17:01:34 +0200  635) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  636) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  637) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  638) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  639) /* Virtqueue interrupt handler */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  640) static void virtio_fs_vq_done(struct virtqueue *vq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  641) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  642) 	struct virtio_fs_vq *fsvq = vq_to_fsvq(vq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  643) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  644) 	dev_dbg(&vq->vdev->dev, "%s %s\n", __func__, fsvq->name);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  645) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  646) 	schedule_work(&fsvq->done_work);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  647) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  648) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  649) static void virtio_fs_init_vq(struct virtio_fs_vq *fsvq, char *name,
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  650) 			      int vq_type)
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  651) {
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  652) 	strncpy(fsvq->name, name, VQ_NAME_LEN);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  653) 	spin_lock_init(&fsvq->lock);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  654) 	INIT_LIST_HEAD(&fsvq->queued_reqs);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  655) 	INIT_LIST_HEAD(&fsvq->end_reqs);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  656) 	init_completion(&fsvq->in_flight_zero);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  657) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  658) 	if (vq_type == VQ_REQUEST) {
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  659) 		INIT_WORK(&fsvq->done_work, virtio_fs_requests_done_work);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  660) 		INIT_DELAYED_WORK(&fsvq->dispatch_work,
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  661) 				  virtio_fs_request_dispatch_work);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  662) 	} else {
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  663) 		INIT_WORK(&fsvq->done_work, virtio_fs_hiprio_done_work);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  664) 		INIT_DELAYED_WORK(&fsvq->dispatch_work,
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  665) 				  virtio_fs_hiprio_dispatch_work);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  666) 	}
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  667) }
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  668) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  669) /* Initialize virtqueues */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  670) static int virtio_fs_setup_vqs(struct virtio_device *vdev,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  671) 			       struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  672) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  673) 	struct virtqueue **vqs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  674) 	vq_callback_t **callbacks;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  675) 	const char **names;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  676) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  677) 	int ret = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  678) 
2c0349ec1a8ee (Michael S. Tsirkin 2020-08-05 05:39:36 -0400  679) 	virtio_cread_le(vdev, struct virtio_fs_config, num_request_queues,
2c0349ec1a8ee (Michael S. Tsirkin 2020-08-05 05:39:36 -0400  680) 			&fs->num_request_queues);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  681) 	if (fs->num_request_queues == 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  682) 		return -EINVAL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  683) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  684) 	fs->nvqs = VQ_REQUEST + fs->num_request_queues;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  685) 	fs->vqs = kcalloc(fs->nvqs, sizeof(fs->vqs[VQ_HIPRIO]), GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  686) 	if (!fs->vqs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  687) 		return -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  688) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  689) 	vqs = kmalloc_array(fs->nvqs, sizeof(vqs[VQ_HIPRIO]), GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  690) 	callbacks = kmalloc_array(fs->nvqs, sizeof(callbacks[VQ_HIPRIO]),
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  691) 					GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  692) 	names = kmalloc_array(fs->nvqs, sizeof(names[VQ_HIPRIO]), GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  693) 	if (!vqs || !callbacks || !names) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  694) 		ret = -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  695) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  696) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  697) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  698) 	/* Initialize the hiprio/forget request virtqueue */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  699) 	callbacks[VQ_HIPRIO] = virtio_fs_vq_done;
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  700) 	virtio_fs_init_vq(&fs->vqs[VQ_HIPRIO], "hiprio", VQ_HIPRIO);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  701) 	names[VQ_HIPRIO] = fs->vqs[VQ_HIPRIO].name;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  702) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  703) 	/* Initialize the requests virtqueues */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  704) 	for (i = VQ_REQUEST; i < fs->nvqs; i++) {
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  705) 		char vq_name[VQ_NAME_LEN];
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  706) 
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  707) 		snprintf(vq_name, VQ_NAME_LEN, "requests.%u", i - VQ_REQUEST);
b43b7e81eb2b1 (Vivek Goyal        2020-08-19 18:19:44 -0400  708) 		virtio_fs_init_vq(&fs->vqs[i], vq_name, VQ_REQUEST);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  709) 		callbacks[i] = virtio_fs_vq_done;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  710) 		names[i] = fs->vqs[i].name;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  711) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  712) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  713) 	ret = virtio_find_vqs(vdev, fs->nvqs, vqs, callbacks, names, NULL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  714) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  715) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  716) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  717) 	for (i = 0; i < fs->nvqs; i++)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  718) 		fs->vqs[i].vq = vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  719) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  720) 	virtio_fs_start_all_queues(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  721) out:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  722) 	kfree(names);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  723) 	kfree(callbacks);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  724) 	kfree(vqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  725) 	if (ret)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  726) 		kfree(fs->vqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  727) 	return ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  728) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  729) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  730) /* Free virtqueues (device must already be reset) */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  731) static void virtio_fs_cleanup_vqs(struct virtio_device *vdev,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  732) 				  struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  733) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  734) 	vdev->config->del_vqs(vdev);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  735) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  736) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  737) /* Map a window offset to a page frame number.  The window offset will have
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  738)  * been produced by .iomap_begin(), which maps a file offset to a window
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  739)  * offset.
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  740)  */
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  741) static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  742) 				    long nr_pages, void **kaddr, pfn_t *pfn)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  743) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  744) 	struct virtio_fs *fs = dax_get_private(dax_dev);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  745) 	phys_addr_t offset = PFN_PHYS(pgoff);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  746) 	size_t max_nr_pages = fs->window_len/PAGE_SIZE - pgoff;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  747) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  748) 	if (kaddr)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  749) 		*kaddr = fs->window_kaddr + offset;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  750) 	if (pfn)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  751) 		*pfn = phys_to_pfn_t(fs->window_phys_addr + offset,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  752) 					PFN_DEV | PFN_MAP);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  753) 	return nr_pages > max_nr_pages ? max_nr_pages : nr_pages;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  754) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  755) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  756) static size_t virtio_fs_copy_from_iter(struct dax_device *dax_dev,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  757) 				       pgoff_t pgoff, void *addr,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  758) 				       size_t bytes, struct iov_iter *i)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  759) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  760) 	return copy_from_iter(addr, bytes, i);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  761) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  762) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  763) static size_t virtio_fs_copy_to_iter(struct dax_device *dax_dev,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  764) 				       pgoff_t pgoff, void *addr,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  765) 				       size_t bytes, struct iov_iter *i)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  766) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  767) 	return copy_to_iter(addr, bytes, i);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  768) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  769) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  770) static int virtio_fs_zero_page_range(struct dax_device *dax_dev,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  771) 				     pgoff_t pgoff, size_t nr_pages)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  772) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  773) 	long rc;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  774) 	void *kaddr;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  775) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  776) 	rc = dax_direct_access(dax_dev, pgoff, nr_pages, &kaddr, NULL);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  777) 	if (rc < 0)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  778) 		return rc;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  779) 	memset(kaddr, 0, nr_pages << PAGE_SHIFT);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  780) 	dax_flush(dax_dev, kaddr, nr_pages << PAGE_SHIFT);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  781) 	return 0;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  782) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  783) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  784) static const struct dax_operations virtio_fs_dax_ops = {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  785) 	.direct_access = virtio_fs_direct_access,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  786) 	.copy_from_iter = virtio_fs_copy_from_iter,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  787) 	.copy_to_iter = virtio_fs_copy_to_iter,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  788) 	.zero_page_range = virtio_fs_zero_page_range,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  789) };
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  790) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  791) static void virtio_fs_cleanup_dax(void *data)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  792) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  793) 	struct dax_device *dax_dev = data;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  794) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  795) 	kill_dax(dax_dev);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  796) 	put_dax(dax_dev);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  797) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  798) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  799) static int virtio_fs_setup_dax(struct virtio_device *vdev, struct virtio_fs *fs)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  800) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  801) 	struct virtio_shm_region cache_reg;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  802) 	struct dev_pagemap *pgmap;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  803) 	bool have_cache;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  804) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  805) 	if (!IS_ENABLED(CONFIG_FUSE_DAX))
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  806) 		return 0;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  807) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  808) 	/* Get cache region */
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  809) 	have_cache = virtio_get_shm_region(vdev, &cache_reg,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  810) 					   (u8)VIRTIO_FS_SHMCAP_ID_CACHE);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  811) 	if (!have_cache) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  812) 		dev_notice(&vdev->dev, "%s: No cache capability\n", __func__);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  813) 		return 0;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  814) 	}
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  815) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  816) 	if (!devm_request_mem_region(&vdev->dev, cache_reg.addr, cache_reg.len,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  817) 				     dev_name(&vdev->dev))) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  818) 		dev_warn(&vdev->dev, "could not reserve region addr=0x%llx len=0x%llx\n",
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  819) 			 cache_reg.addr, cache_reg.len);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  820) 		return -EBUSY;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  821) 	}
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  822) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  823) 	dev_notice(&vdev->dev, "Cache len: 0x%llx @ 0x%llx\n", cache_reg.len,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  824) 		   cache_reg.addr);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  825) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  826) 	pgmap = devm_kzalloc(&vdev->dev, sizeof(*pgmap), GFP_KERNEL);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  827) 	if (!pgmap)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  828) 		return -ENOMEM;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  829) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  830) 	pgmap->type = MEMORY_DEVICE_FS_DAX;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  831) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  832) 	/* Ideally we would directly use the PCI BAR resource but
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  833) 	 * devm_memremap_pages() wants its own copy in pgmap.  So
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  834) 	 * initialize a struct resource from scratch (only the start
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  835) 	 * and end fields will be used).
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  836) 	 */
694565356c2e0 (Linus Torvalds     2020-10-19 14:28:30 -0700  837) 	pgmap->range = (struct range) {
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  838) 		.start = (phys_addr_t) cache_reg.addr,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  839) 		.end = (phys_addr_t) cache_reg.addr + cache_reg.len - 1,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  840) 	};
694565356c2e0 (Linus Torvalds     2020-10-19 14:28:30 -0700  841) 	pgmap->nr_range = 1;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  842) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  843) 	fs->window_kaddr = devm_memremap_pages(&vdev->dev, pgmap);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  844) 	if (IS_ERR(fs->window_kaddr))
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  845) 		return PTR_ERR(fs->window_kaddr);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  846) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  847) 	fs->window_phys_addr = (phys_addr_t) cache_reg.addr;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  848) 	fs->window_len = (phys_addr_t) cache_reg.len;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  849) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  850) 	dev_dbg(&vdev->dev, "%s: window kaddr 0x%px phys_addr 0x%llx len 0x%llx\n",
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  851) 		__func__, fs->window_kaddr, cache_reg.addr, cache_reg.len);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  852) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  853) 	fs->dax_dev = alloc_dax(fs, NULL, &virtio_fs_dax_ops, 0);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  854) 	if (IS_ERR(fs->dax_dev))
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  855) 		return PTR_ERR(fs->dax_dev);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  856) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  857) 	return devm_add_action_or_reset(&vdev->dev, virtio_fs_cleanup_dax,
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  858) 					fs->dax_dev);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  859) }
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  860) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  861) static int virtio_fs_probe(struct virtio_device *vdev)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  862) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  863) 	struct virtio_fs *fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  864) 	int ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  865) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  866) 	fs = kzalloc(sizeof(*fs), GFP_KERNEL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  867) 	if (!fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  868) 		return -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  869) 	kref_init(&fs->refcount);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  870) 	vdev->priv = fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  871) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  872) 	ret = virtio_fs_read_tag(vdev, fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  873) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  874) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  875) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  876) 	ret = virtio_fs_setup_vqs(vdev, fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  877) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  878) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  879) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  880) 	/* TODO vq affinity */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  881) 
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  882) 	ret = virtio_fs_setup_dax(vdev, fs);
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  883) 	if (ret < 0)
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  884) 		goto out_vqs;
22f3787e9d95e (Stefan Hajnoczi    2020-08-19 18:19:46 -0400  885) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  886) 	/* Bring the device online in case the filesystem is mounted and
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  887) 	 * requests need to be sent before we return.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  888) 	 */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  889) 	virtio_device_ready(vdev);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  890) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  891) 	ret = virtio_fs_add_instance(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  892) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  893) 		goto out_vqs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  894) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  895) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  896) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  897) out_vqs:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  898) 	vdev->config->reset(vdev);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  899) 	virtio_fs_cleanup_vqs(vdev, fs);
c79c5e0178922 (Luis Henriques     2021-03-17 08:44:43 +0000  900) 	kfree(fs->vqs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  901) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  902) out:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  903) 	vdev->priv = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  904) 	kfree(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  905) 	return ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  906) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  907) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  908) static void virtio_fs_stop_all_queues(struct virtio_fs *fs)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  909) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  910) 	struct virtio_fs_vq *fsvq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  911) 	int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  912) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  913) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  914) 		fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  915) 		spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  916) 		fsvq->connected = false;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  917) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  918) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  919) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  920) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  921) static void virtio_fs_remove(struct virtio_device *vdev)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  922) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  923) 	struct virtio_fs *fs = vdev->priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  924) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  925) 	mutex_lock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  926) 	/* This device is going away. No one should get new reference */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  927) 	list_del_init(&fs->list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  928) 	virtio_fs_stop_all_queues(fs);
724c15a43e2c7 (Vivek Goyal        2019-10-30 11:07:19 -0400  929) 	virtio_fs_drain_all_queues_locked(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  930) 	vdev->config->reset(vdev);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  931) 	virtio_fs_cleanup_vqs(vdev, fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  932) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  933) 	vdev->priv = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  934) 	/* Put device reference on virtio_fs object */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  935) 	virtio_fs_put(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  936) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  937) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  938) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  939) #ifdef CONFIG_PM_SLEEP
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  940) static int virtio_fs_freeze(struct virtio_device *vdev)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  941) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  942) 	/* TODO need to save state here */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  943) 	pr_warn("virtio-fs: suspend/resume not yet supported\n");
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  944) 	return -EOPNOTSUPP;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  945) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  946) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  947) static int virtio_fs_restore(struct virtio_device *vdev)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  948) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  949) 	 /* TODO need to restore state here */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  950) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  951) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  952) #endif /* CONFIG_PM_SLEEP */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  953) 
00929447f5758 (YueHaibing         2019-11-11 20:23:59 +0800  954) static const struct virtio_device_id id_table[] = {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  955) 	{ VIRTIO_ID_FS, VIRTIO_DEV_ANY_ID },
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  956) 	{},
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  957) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  958) 
00929447f5758 (YueHaibing         2019-11-11 20:23:59 +0800  959) static const unsigned int feature_table[] = {};
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  960) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  961) static struct virtio_driver virtio_fs_driver = {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  962) 	.driver.name		= KBUILD_MODNAME,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  963) 	.driver.owner		= THIS_MODULE,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  964) 	.id_table		= id_table,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  965) 	.feature_table		= feature_table,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  966) 	.feature_table_size	= ARRAY_SIZE(feature_table),
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  967) 	.probe			= virtio_fs_probe,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  968) 	.remove			= virtio_fs_remove,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  969) #ifdef CONFIG_PM_SLEEP
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  970) 	.freeze			= virtio_fs_freeze,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  971) 	.restore		= virtio_fs_restore,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  972) #endif
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  973) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  974) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  975) static void virtio_fs_wake_forget_and_unlock(struct fuse_iqueue *fiq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  976) __releases(fiq->lock)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  977) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  978) 	struct fuse_forget_link *link;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  979) 	struct virtio_fs_forget *forget;
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400  980) 	struct virtio_fs_forget_req *req;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  981) 	struct virtio_fs *fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  982) 	struct virtio_fs_vq *fsvq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  983) 	u64 unique;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  984) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  985) 	link = fuse_dequeue_forget(fiq, 1, NULL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  986) 	unique = fuse_get_unique(fiq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  987) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  988) 	fs = fiq->priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  989) 	fsvq = &fs->vqs[VQ_HIPRIO];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  990) 	spin_unlock(&fiq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  991) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  992) 	/* Allocate a buffer for the request */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  993) 	forget = kmalloc(sizeof(*forget), GFP_NOFS | __GFP_NOFAIL);
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400  994) 	req = &forget->req;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  995) 
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400  996) 	req->ih = (struct fuse_in_header){
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  997) 		.opcode = FUSE_FORGET,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  998) 		.nodeid = link->forget_one.nodeid,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100  999) 		.unique = unique,
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400 1000) 		.len = sizeof(*req),
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1001) 	};
1efcf39eb6275 (Vivek Goyal        2019-10-30 11:07:18 -0400 1002) 	req->arg = (struct fuse_forget_in){
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1003) 		.nlookup = link->forget_one.nlookup,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1004) 	};
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1005) 
58ada94f95f71 (Vivek Goyal        2019-10-30 11:07:17 -0400 1006) 	send_forget_request(fsvq, forget, false);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1007) 	kfree(link);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1008) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1009) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1010) static void virtio_fs_wake_interrupt_and_unlock(struct fuse_iqueue *fiq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1011) __releases(fiq->lock)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1012) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1013) 	/*
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1014) 	 * TODO interrupts.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1015) 	 *
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1016) 	 * Normal fs operations on a local filesystems aren't interruptible.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1017) 	 * Exceptions are blocking lock operations; for example fcntl(F_SETLKW)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1018) 	 * with shared lock between host and guest.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1019) 	 */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1020) 	spin_unlock(&fiq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1021) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1022) 
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1023) /* Count number of scatter-gather elements required */
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1024) static unsigned int sg_count_fuse_pages(struct fuse_page_desc *page_descs,
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1025) 				       unsigned int num_pages,
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1026) 				       unsigned int total_len)
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1027) {
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1028) 	unsigned int i;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1029) 	unsigned int this_len;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1030) 
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1031) 	for (i = 0; i < num_pages && total_len; i++) {
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1032) 		this_len =  min(page_descs[i].length, total_len);
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1033) 		total_len -= this_len;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1034) 	}
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1035) 
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1036) 	return i;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1037) }
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1038) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1039) /* Return the number of scatter-gather list elements required */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1040) static unsigned int sg_count_fuse_req(struct fuse_req *req)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1041) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1042) 	struct fuse_args *args = req->args;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1043) 	struct fuse_args_pages *ap = container_of(args, typeof(*ap), args);
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1044) 	unsigned int size, total_sgs = 1 /* fuse_in_header */;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1045) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1046) 	if (args->in_numargs - args->in_pages)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1047) 		total_sgs += 1;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1048) 
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1049) 	if (args->in_pages) {
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1050) 		size = args->in_args[args->in_numargs - 1].size;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1051) 		total_sgs += sg_count_fuse_pages(ap->descs, ap->num_pages,
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1052) 						 size);
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1053) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1054) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1055) 	if (!test_bit(FR_ISREPLY, &req->flags))
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1056) 		return total_sgs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1057) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1058) 	total_sgs += 1 /* fuse_out_header */;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1059) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1060) 	if (args->out_numargs - args->out_pages)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1061) 		total_sgs += 1;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1062) 
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1063) 	if (args->out_pages) {
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1064) 		size = args->out_args[args->out_numargs - 1].size;
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1065) 		total_sgs += sg_count_fuse_pages(ap->descs, ap->num_pages,
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1066) 						 size);
42d3e2d041f08 (Vivek Goyal        2020-10-06 14:53:06 -0400 1067) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1068) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1069) 	return total_sgs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1070) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1071) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1072) /* Add pages to scatter-gather list and return number of elements used */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1073) static unsigned int sg_init_fuse_pages(struct scatterlist *sg,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1074) 				       struct page **pages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1075) 				       struct fuse_page_desc *page_descs,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1076) 				       unsigned int num_pages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1077) 				       unsigned int total_len)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1078) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1079) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1080) 	unsigned int this_len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1081) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1082) 	for (i = 0; i < num_pages && total_len; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1083) 		sg_init_table(&sg[i], 1);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1084) 		this_len =  min(page_descs[i].length, total_len);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1085) 		sg_set_page(&sg[i], pages[i], this_len, page_descs[i].offset);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1086) 		total_len -= this_len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1087) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1088) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1089) 	return i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1090) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1091) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1092) /* Add args to scatter-gather list and return number of elements used */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1093) static unsigned int sg_init_fuse_args(struct scatterlist *sg,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1094) 				      struct fuse_req *req,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1095) 				      struct fuse_arg *args,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1096) 				      unsigned int numargs,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1097) 				      bool argpages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1098) 				      void *argbuf,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1099) 				      unsigned int *len_used)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1100) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1101) 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1102) 	unsigned int total_sgs = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1103) 	unsigned int len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1104) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1105) 	len = fuse_len_args(numargs - argpages, args);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1106) 	if (len)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1107) 		sg_init_one(&sg[total_sgs++], argbuf, len);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1108) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1109) 	if (argpages)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1110) 		total_sgs += sg_init_fuse_pages(&sg[total_sgs],
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1111) 						ap->pages, ap->descs,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1112) 						ap->num_pages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1113) 						args[numargs - 1].size);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1114) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1115) 	if (len_used)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1116) 		*len_used = len;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1117) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1118) 	return total_sgs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1119) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1120) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1121) /* Add a request to a virtqueue and kick the device */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1122) static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1123) 				 struct fuse_req *req, bool in_flight)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1124) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1125) 	/* requests need at least 4 elements */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1126) 	struct scatterlist *stack_sgs[6];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1127) 	struct scatterlist stack_sg[ARRAY_SIZE(stack_sgs)];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1128) 	struct scatterlist **sgs = stack_sgs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1129) 	struct scatterlist *sg = stack_sg;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1130) 	struct virtqueue *vq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1131) 	struct fuse_args *args = req->args;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1132) 	unsigned int argbuf_used = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1133) 	unsigned int out_sgs = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1134) 	unsigned int in_sgs = 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1135) 	unsigned int total_sgs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1136) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1137) 	int ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1138) 	bool notify;
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1139) 	struct fuse_pqueue *fpq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1140) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1141) 	/* Does the sglist fit on the stack? */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1142) 	total_sgs = sg_count_fuse_req(req);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1143) 	if (total_sgs > ARRAY_SIZE(stack_sgs)) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1144) 		sgs = kmalloc_array(total_sgs, sizeof(sgs[0]), GFP_ATOMIC);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1145) 		sg = kmalloc_array(total_sgs, sizeof(sg[0]), GFP_ATOMIC);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1146) 		if (!sgs || !sg) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1147) 			ret = -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1148) 			goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1149) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1150) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1151) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1152) 	/* Use a bounce buffer since stack args cannot be mapped */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1153) 	ret = copy_args_to_argbuf(req);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1154) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1155) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1156) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1157) 	/* Request elements */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1158) 	sg_init_one(&sg[out_sgs++], &req->in.h, sizeof(req->in.h));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1159) 	out_sgs += sg_init_fuse_args(&sg[out_sgs], req,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1160) 				     (struct fuse_arg *)args->in_args,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1161) 				     args->in_numargs, args->in_pages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1162) 				     req->argbuf, &argbuf_used);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1163) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1164) 	/* Reply elements */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1165) 	if (test_bit(FR_ISREPLY, &req->flags)) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1166) 		sg_init_one(&sg[out_sgs + in_sgs++],
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1167) 			    &req->out.h, sizeof(req->out.h));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1168) 		in_sgs += sg_init_fuse_args(&sg[out_sgs + in_sgs], req,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1169) 					    args->out_args, args->out_numargs,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1170) 					    args->out_pages,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1171) 					    req->argbuf + argbuf_used, NULL);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1172) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1173) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1174) 	WARN_ON(out_sgs + in_sgs != total_sgs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1175) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1176) 	for (i = 0; i < total_sgs; i++)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1177) 		sgs[i] = &sg[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1178) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1179) 	spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1180) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1181) 	if (!fsvq->connected) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1182) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1183) 		ret = -ENOTCONN;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1184) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1185) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1186) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1187) 	vq = fsvq->vq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1188) 	ret = virtqueue_add_sgs(vq, sgs, out_sgs, in_sgs, req, GFP_ATOMIC);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1189) 	if (ret < 0) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1190) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1191) 		goto out;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1192) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1193) 
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1194) 	/* Request successfully sent. */
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1195) 	fpq = &fsvq->fud->pq;
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1196) 	spin_lock(&fpq->lock);
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1197) 	list_add_tail(&req->list, fpq->processing);
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1198) 	spin_unlock(&fpq->lock);
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1199) 	set_bit(FR_SENT, &req->flags);
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1200) 	/* matches barrier in request_wait_answer() */
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1201) 	smp_mb__after_atomic();
5dbe190f34120 (Vivek Goyal        2019-10-15 13:46:24 -0400 1202) 
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1203) 	if (!in_flight)
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1204) 		inc_in_flight_req(fsvq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1205) 	notify = virtqueue_kick_prepare(vq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1206) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1207) 	spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1208) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1209) 	if (notify)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1210) 		virtqueue_notify(vq);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1211) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1212) out:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1213) 	if (ret < 0 && req->argbuf) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1214) 		kfree(req->argbuf);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1215) 		req->argbuf = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1216) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1217) 	if (sgs != stack_sgs) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1218) 		kfree(sgs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1219) 		kfree(sg);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1220) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1221) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1222) 	return ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1223) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1224) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1225) static void virtio_fs_wake_pending_and_unlock(struct fuse_iqueue *fiq)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1226) __releases(fiq->lock)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1227) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1228) 	unsigned int queue_id = VQ_REQUEST; /* TODO multiqueue */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1229) 	struct virtio_fs *fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1230) 	struct fuse_req *req;
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1231) 	struct virtio_fs_vq *fsvq;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1232) 	int ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1233) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1234) 	WARN_ON(list_empty(&fiq->pending));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1235) 	req = list_last_entry(&fiq->pending, struct fuse_req, list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1236) 	clear_bit(FR_PENDING, &req->flags);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1237) 	list_del_init(&req->list);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1238) 	WARN_ON(!list_empty(&fiq->pending));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1239) 	spin_unlock(&fiq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1240) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1241) 	fs = fiq->priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1242) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1243) 	pr_debug("%s: opcode %u unique %#llx nodeid %#llx in.len %u out.len %u\n",
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1244) 		  __func__, req->in.h.opcode, req->in.h.unique,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1245) 		 req->in.h.nodeid, req->in.h.len,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1246) 		 fuse_len_args(req->args->out_numargs, req->args->out_args));
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1247) 
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1248) 	fsvq = &fs->vqs[queue_id];
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1249) 	ret = virtio_fs_enqueue_req(fsvq, req, false);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1250) 	if (ret < 0) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1251) 		if (ret == -ENOMEM || ret == -ENOSPC) {
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1252) 			/*
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1253) 			 * Virtqueue full. Retry submission from worker
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1254) 			 * context as we might be holding fc->bg_lock.
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1255) 			 */
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1256) 			spin_lock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1257) 			list_add_tail(&req->list, &fsvq->queued_reqs);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1258) 			inc_in_flight_req(fsvq);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1259) 			schedule_delayed_work(&fsvq->dispatch_work,
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1260) 						msecs_to_jiffies(1));
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1261) 			spin_unlock(&fsvq->lock);
a9bfd9dd34175 (Vivek Goyal        2019-10-15 13:46:26 -0400 1262) 			return;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1263) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1264) 		req->out.h.error = ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1265) 		pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1266) 
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1267) 		/* Can't end request in submission context. Use a worker */
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1268) 		spin_lock(&fsvq->lock);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1269) 		list_add_tail(&req->list, &fsvq->end_reqs);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1270) 		schedule_delayed_work(&fsvq->dispatch_work, 0);
51fecdd2555b3 (Vivek Goyal        2019-10-15 13:46:22 -0400 1271) 		spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1272) 		return;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1273) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1274) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1275) 
00929447f5758 (YueHaibing         2019-11-11 20:23:59 +0800 1276) static const struct fuse_iqueue_ops virtio_fs_fiq_ops = {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1277) 	.wake_forget_and_unlock		= virtio_fs_wake_forget_and_unlock,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1278) 	.wake_interrupt_and_unlock	= virtio_fs_wake_interrupt_and_unlock,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1279) 	.wake_pending_and_unlock	= virtio_fs_wake_pending_and_unlock,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1280) 	.release			= virtio_fs_fiq_release,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1281) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1282) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1283) static inline void virtio_fs_ctx_set_defaults(struct fuse_fs_context *ctx)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1284) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1285) 	ctx->rootmode = S_IFDIR;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1286) 	ctx->default_permissions = 1;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1287) 	ctx->allow_other = 1;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1288) 	ctx->max_read = UINT_MAX;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1289) 	ctx->blksize = 512;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1290) 	ctx->destroy = true;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1291) 	ctx->no_control = true;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1292) 	ctx->no_force_umount = true;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1293) }
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1294) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1295) static int virtio_fs_fill_super(struct super_block *sb, struct fs_context *fsc)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1296) {
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1297) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1298) 	struct fuse_conn *fc = fm->fc;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1299) 	struct virtio_fs *fs = fc->iq.priv;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1300) 	struct fuse_fs_context *ctx = fsc->fs_private;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1301) 	unsigned int i;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1302) 	int err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1303) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1304) 	virtio_fs_ctx_set_defaults(ctx);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1305) 	mutex_lock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1306) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1307) 	/* After holding mutex, make sure virtiofs device is still there.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1308) 	 * Though we are holding a reference to it, drive ->remove might
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1309) 	 * still have cleaned up virtual queues. In that case bail out.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1310) 	 */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1311) 	err = -EINVAL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1312) 	if (list_empty(&fs->list)) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1313) 		pr_info("virtio-fs: tag <%s> not found\n", fs->tag);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1314) 		goto err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1315) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1316) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1317) 	err = -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1318) 	/* Allocate fuse_dev for hiprio and notification queues */
7fd3abfa8dd7c (Vivek Goyal        2020-05-04 14:33:15 -0400 1319) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1320) 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1321) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1322) 		fsvq->fud = fuse_dev_alloc();
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1323) 		if (!fsvq->fud)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1324) 			goto err_free_fuse_devs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1325) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1326) 
7fd3abfa8dd7c (Vivek Goyal        2020-05-04 14:33:15 -0400 1327) 	/* virtiofs allocates and installs its own fuse devices */
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1328) 	ctx->fudptr = NULL;
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1329) 	if (ctx->dax) {
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1330) 		if (!fs->dax_dev) {
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1331) 			err = -EINVAL;
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1332) 			pr_err("virtio-fs: dax can't be enabled as filesystem"
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1333) 			       " device does not support it.\n");
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1334) 			goto err_free_fuse_devs;
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1335) 		}
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1336) 		ctx->dax_dev = fs->dax_dev;
3f9b9efd82a84 (Vivek Goyal        2021-02-09 17:47:54 -0500 1337) 	}
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1338) 	err = fuse_fill_super_common(sb, ctx);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1339) 	if (err < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1340) 		goto err_free_fuse_devs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1341) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1342) 	for (i = 0; i < fs->nvqs; i++) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1343) 		struct virtio_fs_vq *fsvq = &fs->vqs[i];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1344) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1345) 		fuse_dev_install(fsvq->fud, fc);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1346) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1347) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1348) 	/* Previous unmount will stop all queues. Start these again */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1349) 	virtio_fs_start_all_queues(fs);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1350) 	fuse_send_init(fm);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1351) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1352) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1353) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1354) err_free_fuse_devs:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1355) 	virtio_fs_free_devs(fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1356) err:
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1357) 	mutex_unlock(&virtio_fs_mutex);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1358) 	return err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1359) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1360) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1361) static void virtio_fs_conn_destroy(struct fuse_mount *fm)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1362) {
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1363) 	struct fuse_conn *fc = fm->fc;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1364) 	struct virtio_fs *vfs = fc->iq.priv;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1365) 	struct virtio_fs_vq *fsvq = &vfs->vqs[VQ_HIPRIO];
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1366) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1367) 	/* Stop dax worker. Soon evict_inodes() will be called which
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1368) 	 * will free all memory ranges belonging to all inodes.
9a752d18c85ae (Vivek Goyal        2020-08-19 18:19:56 -0400 1369) 	 */
9a752d18c85ae (Vivek Goyal        2020-08-19 18:19:56 -0400 1370) 	if (IS_ENABLED(CONFIG_FUSE_DAX))
9a752d18c85ae (Vivek Goyal        2020-08-19 18:19:56 -0400 1371) 		fuse_dax_cancel_work(fc);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1372) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1373) 	/* Stop forget queue. Soon destroy will be sent */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1374) 	spin_lock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1375) 	fsvq->connected = false;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1376) 	spin_unlock(&fsvq->lock);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1377) 	virtio_fs_drain_all_queues(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1378) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1379) 	fuse_conn_destroy(fm);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1380) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1381) 	/* fuse_conn_destroy() must have sent destroy. Stop all queues
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1382) 	 * and drain one more time and free fuse devices. Freeing fuse
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1383) 	 * devices will drop their reference on fuse_conn and that in
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1384) 	 * turn will drop its reference on virtio_fs object.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1385) 	 */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1386) 	virtio_fs_stop_all_queues(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1387) 	virtio_fs_drain_all_queues(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1388) 	virtio_fs_free_devs(vfs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1389) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1390) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1391) static void virtio_kill_sb(struct super_block *sb)
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1392) {
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1393) 	struct fuse_mount *fm = get_fuse_mount_super(sb);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1394) 	bool last;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1395) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1396) 	/* If mount failed, we can still be called without any fc */
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1397) 	if (fm) {
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1398) 		last = fuse_mount_remove(fm);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1399) 		if (last)
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1400) 			virtio_fs_conn_destroy(fm);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1401) 	}
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1402) 	kill_anon_super(sb);
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1403) }
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1404) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1405) static int virtio_fs_test_super(struct super_block *sb,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1406) 				struct fs_context *fsc)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1407) {
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1408) 	struct fuse_mount *fsc_fm = fsc->s_fs_info;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1409) 	struct fuse_mount *sb_fm = get_fuse_mount_super(sb);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1410) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1411) 	return fsc_fm->fc->iq.priv == sb_fm->fc->iq.priv;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1412) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1413) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1414) static int virtio_fs_get_tree(struct fs_context *fsc)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1415) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1416) 	struct virtio_fs *fs;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1417) 	struct super_block *sb;
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1418) 	struct fuse_conn *fc = NULL;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1419) 	struct fuse_mount *fm;
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1420) 	unsigned int virtqueue_size;
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1421) 	int err = -EIO;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1422) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1423) 	/* This gets a reference on virtio_fs object. This ptr gets installed
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1424) 	 * in fc->iq->priv. Once fuse_conn is going away, it calls ->put()
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1425) 	 * to drop the reference to this object.
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1426) 	 */
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1427) 	fs = virtio_fs_find_instance(fsc->source);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1428) 	if (!fs) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1429) 		pr_info("virtio-fs: tag <%s> not found\n", fsc->source);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1430) 		return -EINVAL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1431) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1432) 
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1433) 	virtqueue_size = virtqueue_get_vring_size(fs->vqs[VQ_REQUEST].vq);
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1434) 	if (WARN_ON(virtqueue_size <= FUSE_HEADER_OVERHEAD))
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1435) 		goto out_err;
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1436) 
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1437) 	err = -ENOMEM;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1438) 	fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1439) 	if (!fc)
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1440) 		goto out_err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1441) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1442) 	fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1443) 	if (!fm)
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1444) 		goto out_err;
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1445) 
0a7419c68a45d (Miklos Szeredi     2021-04-14 10:40:58 +0200 1446) 	fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1447) 	fc->release = fuse_free_conn;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1448) 	fc->delete_stale = true;
bf109c64040f5 (Max Reitz          2020-04-21 14:47:15 +0200 1449) 	fc->auto_submounts = true;
6ba041fc3c441 (Greg Kurz          2021-05-20 17:46:54 +0200 1450) 	fc->sync_fs = true;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1451) 
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1452) 	/* Tell FUSE to split requests that exceed the virtqueue's size */
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1453) 	fc->max_pages_limit = min_t(unsigned int, fc->max_pages_limit,
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1454) 				    virtqueue_size - FUSE_HEADER_OVERHEAD);
a7f0d7aab0b4f (Connor Kuehl       2021-03-18 08:52:22 -0500 1455) 
fcee216beb9c1 (Max Reitz          2020-05-06 17:44:12 +0200 1456) 	fsc->s_fs_info = fm;
b19d3d00d662c (Miklos Szeredi     2020-11-11 17:22:31 +0100 1457) 	sb = sget_fc(fsc, virtio_fs_test_super, set_anon_super_fc);
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1458) 	if (fsc->s_fs_info) {
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1459) 		fuse_conn_put(fc);
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1460) 		kfree(fm);
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1461) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1462) 	if (IS_ERR(sb))
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1463) 		return PTR_ERR(sb);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1464) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1465) 	if (!sb->s_root) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1466) 		err = virtio_fs_fill_super(sb, fsc);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1467) 		if (err) {
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1468) 			fuse_conn_put(fc);
514b5e3ff45e6 (Miklos Szeredi     2020-11-11 17:22:32 +0100 1469) 			kfree(fm);
66ab33bf6d434 (Miklos Szeredi     2020-11-11 17:22:31 +0100 1470) 			sb->s_fs_info = NULL;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1471) 			deactivate_locked_super(sb);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1472) 			return err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1473) 		}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1474) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1475) 		sb->s_flags |= SB_ACTIVE;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1476) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1477) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1478) 	WARN_ON(fsc->root);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1479) 	fsc->root = dget(sb->s_root);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1480) 	return 0;
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1481) 
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1482) out_err:
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1483) 	kfree(fc);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1484) 	mutex_lock(&virtio_fs_mutex);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1485) 	virtio_fs_put(fs);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1486) 	mutex_unlock(&virtio_fs_mutex);
833c5a42e28be (Miklos Szeredi     2020-11-11 17:22:32 +0100 1487) 	return err;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1488) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1489) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1490) static const struct fs_context_operations virtio_fs_context_ops = {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1491) 	.free		= virtio_fs_free_fc,
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1492) 	.parse_param	= virtio_fs_parse_param,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1493) 	.get_tree	= virtio_fs_get_tree,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1494) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1495) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1496) static int virtio_fs_init_fs_context(struct fs_context *fsc)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1497) {
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1498) 	struct fuse_fs_context *ctx;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1499) 
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1500) 	ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL);
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1501) 	if (!ctx)
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1502) 		return -ENOMEM;
1dd539577c42b (Vivek Goyal        2020-08-19 18:19:47 -0400 1503) 	fsc->fs_private = ctx;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1504) 	fsc->ops = &virtio_fs_context_ops;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1505) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1506) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1507) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1508) static struct file_system_type virtio_fs_type = {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1509) 	.owner		= THIS_MODULE,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1510) 	.name		= "virtiofs",
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1511) 	.init_fs_context = virtio_fs_init_fs_context,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1512) 	.kill_sb	= virtio_kill_sb,
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1513) };
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1514) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1515) static int __init virtio_fs_init(void)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1516) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1517) 	int ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1518) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1519) 	ret = register_virtio_driver(&virtio_fs_driver);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1520) 	if (ret < 0)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1521) 		return ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1522) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1523) 	ret = register_filesystem(&virtio_fs_type);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1524) 	if (ret < 0) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1525) 		unregister_virtio_driver(&virtio_fs_driver);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1526) 		return ret;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1527) 	}
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1528) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1529) 	return 0;
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1530) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1531) module_init(virtio_fs_init);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1532) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1533) static void __exit virtio_fs_exit(void)
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1534) {
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1535) 	unregister_filesystem(&virtio_fs_type);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1536) 	unregister_virtio_driver(&virtio_fs_driver);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1537) }
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1538) module_exit(virtio_fs_exit);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1539) 
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1540) MODULE_AUTHOR("Stefan Hajnoczi <stefanha@redhat.com>");
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1541) MODULE_DESCRIPTION("Virtio Filesystem");
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1542) MODULE_LICENSE("GPL");
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1543) MODULE_ALIAS_FS(KBUILD_MODNAME);
a62a8ef9d97da (Stefan Hajnoczi    2018-06-12 09:41:17 +0100 1544) MODULE_DEVICE_TABLE(virtio, id_table);