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 process can be realized by putting the request of the processing list back into the pending list. Signed-off-by: Peng Hao <flyingpeng@xxxxxxxxxxx> --- fs/fuse/dev.c | 31 ++++++++++++++++++++++++++++++- include/uapi/linux/fuse.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 491c092d427b..9b0f34468494 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,35 @@ 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); + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) + list_splice_tail_init(&fpq->processing[i], + &recovery); + spin_unlock(&fpq->lock); + + list_for_each_entry_safe(req, next, &recovery, list) { + clear_bit(FR_SENT, &req->flags); + set_bit(FR_PENDING, &req->flags); + } + + spin_lock(&fiq->lock); + 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