[PATCH] fuse: add a dev ioctl for recovery
From: Hao Peng <hidden>
Date: 2021-09-06 12:36:48
Subsystem:
filesystems (vfs and infrastructure), fuse filesystem [core], the rest · Maintainers:
Alexander Viro, Christian Brauner, Miklos Szeredi, Linus Torvalds
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. Signed-off-by: Peng Hao <redacted> --- 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);
+ }
+ 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