On Tue, Sep 7, 2021 at 5:34 PM Miklos Szeredi <miklos@xxxxxxxxxx> wrote: > > On Mon, 6 Sept 2021 at 14:36, Hao Peng <flyingpenghao@xxxxxxxxx> wrote: > > > > For a simple read-only file system, as long as the connection > > is not broken, the recovery of the user-mode read-only file > > system can be realized by putting the request of the processing > > list back into the pending list. > > Thanks for the patch. > > Do you have example userspace code for this? > Under development. When the fuse user-mode file system process is abnormal, the process does not terminate (/dev/fuse will not be closed), enter the reset procedure, and will not open /dev/fuse again during the reinitialization. Of course, this can only solve part of the abnormal problem. > > Signed-off-by: Peng Hao <flyingpeng@xxxxxxxxxxx> > > --- > > fs/fuse/dev.c | 38 +++++++++++++++++++++++++++++++++++++- > > include/uapi/linux/fuse.h | 1 + > > 2 files changed, 38 insertions(+), 1 deletion(-) > > > > diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c > > index 491c092d427b..8e1b69a5b503 100644 > > --- a/fs/fuse/dev.c > > +++ b/fs/fuse/dev.c > > @@ -2239,7 +2239,7 @@ static int fuse_device_clone(struct fuse_conn > > *fc, struct file *new) > > static long fuse_dev_ioctl(struct file *file, unsigned int cmd, > > unsigned long arg) > > { > > - int res; > > + int res = 0; > > int oldfd; > > struct fuse_dev *fud = NULL; > > > > @@ -2268,6 +2268,42 @@ static long fuse_dev_ioctl(struct file *file, > > unsigned int cmd, > > } > > } > > break; > > + > > + case FUSE_DEV_IOC_RECOVERY: > > + { > > + struct fuse_iqueue *fiq; > > + struct fuse_pqueue *fpq; > > + struct fuse_req *req, *next; > > + LIST_HEAD(recovery); > > + unsigned int i; > > + > > + fud = fuse_get_dev(file); > > + fiq = &fud->fc->iq; > > + fpq = &fud->pq; > > + > > + spin_lock(&fpq->lock); > > + list_for_each_entry_safe(req, next, &fpq->io, list) { > > + spin_lock(&req->waitq.lock); > > + clear_bit(FR_LOCKED, &req->flags); > > + list_move(&req->list, &recovery); > > + spin_unlock(&req->waitq.lock); > > + } > > I don't get it. Recovery means the previous server process is dead. > If there are requests on the fpq->io queue, than that's obviously not > true and having two processes messing with the same requests isn't > going to do any good. > > So I suggest just erroring out if fpq->io is not empty. I will modify it in the next version. > > > > + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) > > + list_splice_tail_init(&fpq->processing[i], > > + &recovery); > > + list_for_each_entry_safe(req, next, &recovery, list) { > > + clear_bit(FR_SENT, &req->flags); > > + } > > + spin_unlock(&fpq->lock); > > + > > + spin_lock(&fiq->lock); > > + list_for_each_entry_safe(req, next, &recovery, list) { > > + set_bit(FR_PENDING, &req->flags); > > + } > > + list_splice(&recovery, &fiq->pending); > > + spin_unlock(&fiq->lock); > > + break; > > + } > > default: > > res = -ENOTTY; > > break; > > diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h > > index 36ed092227fa..fc07324efa9d 100644 > > --- a/include/uapi/linux/fuse.h > > +++ b/include/uapi/linux/fuse.h > > @@ -923,6 +923,7 @@ struct fuse_notify_retrieve_in { > > /* Device ioctls: */ > > #define FUSE_DEV_IOC_MAGIC 229 > > #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t) > > +#define FUSE_DEV_IOC_RECOVERY _IOR(FUSE_DEV_IOC_MAGIC+1, 0, uint32_t) > > > > struct fuse_lseek_in { > > uint64_t fh; > > -- > > 2.27.0