[Devel] [PATCH v2] fs/fuse kio: invalidate files for kio
Pavel Butsykin
pbutsykin at virtuozzo.com
Mon Jan 21 19:30:22 MSK 2019
Make fuse_invalidate_files() work for kio. This is necessary to maintain
vstorage revoke in FPath mode. To do this, let's add a list of inflight kio
requests to be able to handle this list in fuse_invalidate_files(). The list
will also be useful to implement the full-featured .vstorage.info and
fuse_abort_conn() for kio.
#VSTOR-19620
Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
fs/fuse/fuse_i.h | 4 ++++
fs/fuse/inode.c | 8 ++++++--
fs/fuse/kio/pcs/fuse_io.c | 5 +++++
fs/fuse/kio/pcs/pcs_client_types.h | 2 ++
fs/fuse/kio/pcs/pcs_cluster.h | 7 +++++++
fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 27 +++++++++++++++++++++++++++
6 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 4c27bfa0e74d..0914940d6735 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -528,6 +528,7 @@ struct fuse_kio_ops {
int (*file_open)(struct fuse_conn *fc, struct file *file,
struct inode *inode);
void (*inode_release)(struct fuse_inode *fi);
+ void (*kill_requests)(struct fuse_conn *fc, struct inode *inode);
};
int fuse_register_kio(struct fuse_kio_ops *ops);
@@ -1107,4 +1108,7 @@ struct fuse_file *fuse_write_file(struct fuse_conn *fc, struct fuse_inode *fi);
void fuse_release_ff(struct inode *inode, struct fuse_file *ff);
+void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
+ struct list_head *req_list);
+
#endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 34e52262d37e..cb275ff21991 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -369,8 +369,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
return 0;
}
-static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
- struct list_head *req_list)
+void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
+ struct list_head *req_list)
{
struct fuse_req *req;
@@ -393,6 +393,7 @@ static void fuse_kill_requests(struct fuse_conn *fc, struct inode *inode,
req->num_pages = 0;
}
}
+EXPORT_SYMBOL_GPL(fuse_kill_requests);
int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)
{
@@ -442,6 +443,9 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)
}
fuse_kill_requests(fc, inode, &fc->main_iq.pending);
fuse_kill_requests(fc, inode, &fc->bg_queue);
+ if (fc->kio.op && fc->kio.op->kill_requests)
+ fc->kio.op->kill_requests(fc, inode);
+
wake_up(&fi->page_waitq); /* readpage[s] can wait on fuse wb */
spin_unlock(&fc->lock);
diff --git a/fs/fuse/kio/pcs/fuse_io.c b/fs/fuse/kio/pcs/fuse_io.c
index 61a2e7f1eac6..219f4e3423af 100644
--- a/fs/fuse/kio/pcs/fuse_io.c
+++ b/fs/fuse/kio/pcs/fuse_io.c
@@ -205,6 +205,7 @@ static void prepare_io_(struct pcs_fuse_req *r, unsigned short type, off_t offse
static void ioreq_complete(pcs_api_iorequest_t *ioreq)
{
struct pcs_fuse_req *r = ioreq->datasource;
+ struct pcs_dentry_info *di = get_pcs_inode(r->req.io_inode);
BUG_ON(ioreq != &r->exec.io.req);
@@ -217,6 +218,10 @@ static void ioreq_complete(pcs_api_iorequest_t *ioreq)
r->req.out.h.error = 0;
}
+ spin_lock(&di->kq_lock);
+ list_del_init(&r->req.list);
+ spin_unlock(&di->kq_lock);
+
switch (ioreq->type) {
case PCS_REQ_T_READ:
on_read_done(r, ioreq->size);
diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h
index 9ddce5cff3f5..1be32cbbf285 100644
--- a/fs/fuse/kio/pcs/pcs_client_types.h
+++ b/fs/fuse/kio/pcs/pcs_client_types.h
@@ -68,6 +68,8 @@ struct pcs_dentry_info {
size_op_t op;
} size;
struct fuse_inode *inode;
+ struct list_head kq;
+ spinlock_t kq_lock;
};
static inline void pcs_clear_fileinfo(struct pcs_dentry_info *i)
diff --git a/fs/fuse/kio/pcs/pcs_cluster.h b/fs/fuse/kio/pcs/pcs_cluster.h
index 9c537cb43b30..73af9359706e 100644
--- a/fs/fuse/kio/pcs/pcs_cluster.h
+++ b/fs/fuse/kio/pcs/pcs_cluster.h
@@ -78,6 +78,13 @@ static inline struct pcs_dentry_info *pcs_inode_from_fuse(struct fuse_inode *fi)
return (struct pcs_dentry_info *)fi->private;
}
+static inline struct pcs_dentry_info *get_pcs_inode(struct inode *inode)
+{
+ struct fuse_inode *fi = get_fuse_inode(inode);
+
+ return pcs_inode_from_fuse(fi);
+}
+
static inline struct pcs_fuse_cluster *cl_from_req(struct pcs_fuse_req *r)
{
return pcs_cluster_from_cc(r->exec.ireq.cc);
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index cdd4fe578128..da4b5fba03fb 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -341,6 +341,8 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino
pcs_set_fileinfo(di, &info);
di->cluster = &pfc->cc;
di->inode = fi;
+ INIT_LIST_HEAD(&di->kq);
+ spin_lock_init(&di->kq_lock);
TRACE("init id:%llu chunk_size:%d stripe_depth:%d strip_width:%d\n",
fi->nodeid, di->fileinfo.sys.chunk_size,
di->fileinfo.sys.stripe_depth, di->fileinfo.sys.strip_width);
@@ -983,6 +985,10 @@ error:
return;
submit:
+ spin_lock(&di->kq_lock);
+ list_add_tail(&req->list, &di->kq);
+ spin_unlock(&di->kq_lock);
+
if (async)
pcs_cc_submit(ireq->cc, ireq);
else
@@ -1488,6 +1494,26 @@ void __kfuse_trace(struct fuse_conn * fc, unsigned long ip, const char * fmt, ..
put_cpu();
}
+static void kpcs_kill_requests(struct fuse_conn *fc, struct inode *inode)
+{
+ struct fuse_file *ff;
+
+ assert_spin_locked(&fc->lock);
+
+ list_for_each_entry(ff, &fc->conn_files, fl) {
+ struct pcs_dentry_info *di;
+
+ if (!ff->ff_dentry)
+ continue;
+
+ di = get_pcs_inode(ff->ff_dentry->d_inode);
+
+ spin_lock(&di->kq_lock);
+ fuse_kill_requests(fc, inode, &di->kq);
+ spin_unlock(&di->kq_lock);
+ }
+}
+
static struct fuse_kio_ops kio_pcs_ops = {
.name = "pcs",
.owner = THIS_MODULE,
@@ -1500,6 +1526,7 @@ static struct fuse_kio_ops kio_pcs_ops = {
.req_send = kpcs_req_send,
.file_open = kpcs_file_open,
.inode_release = kpcs_inode_release,
+ .kill_requests = kpcs_kill_requests,
};
--
2.15.1
More information about the Devel
mailing list