[Devel] [PATCH VZ9 04/20] fuse: direct access to journaled cs
Alexey Kuznetsov
kuznet at virtuozzo.com
Fri Oct 6 13:42:35 MSK 2023
Data checksumming was requied. The patch implements required modficiations
to communication protocol and io engine.
Also, the patch implements two ioctls which are present in user space
but were ignored in kio, PCS_IOC_NOWRITEDELAY and PCS_IOC_NOCSUMONREAD.
The last one is especially important from user viewpoint, it can be used
in places where user has its own integrity protection and can relieve
vstorage.
Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
---
fs/fuse/ioctl.c | 7 ++
fs/fuse/kio/pcs/pcs_client_types.h | 2 +
fs/fuse/kio/pcs/pcs_cs.c | 12 ++-
fs/fuse/kio/pcs/pcs_cs_accel.c | 189 ++++++++++++++++++++++++++++++++++++-
fs/fuse/kio/pcs/pcs_cs_prot.h | 3 +
fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 58 ++++++++++--
fs/fuse/kio/pcs/pcs_ioctl.h | 9 +-
fs/fuse/kio/pcs/pcs_req.h | 8 ++
8 files changed, 266 insertions(+), 22 deletions(-)
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c
index 310cd25..ee3b882 100644
--- a/fs/fuse/ioctl.c
+++ b/fs/fuse/ioctl.c
@@ -356,6 +356,13 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd,
return fc->kio.op->ioctl(file, inode, req.cmd, req.data, req.len);
}
+ if (fc->kio.op && fc->kio.op->ioctl) {
+ int err;
+ err = fc->kio.op->ioctl(file, inode, cmd, arg, -1);
+ if (err != -ENOIOCTLCMD)
+ return err;
+ }
+
return fuse_do_ioctl(file, cmd, arg, flags);
}
diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h
index 10ffa14..0b06a0e 100644
--- a/fs/fuse/kio/pcs/pcs_client_types.h
+++ b/fs/fuse/kio/pcs/pcs_client_types.h
@@ -78,6 +78,8 @@ struct pcs_dentry_info {
struct fuse_inode *inode;
struct list_head kq;
spinlock_t kq_lock;
+ unsigned char no_csum_on_read;
+ unsigned char no_write_delay;
struct fuse_io_cnt stat;
};
diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c
index 7e5070d..4af8f16 100644
--- a/fs/fuse/kio/pcs/pcs_cs.c
+++ b/fs/fuse/kio/pcs/pcs_cs.c
@@ -609,7 +609,8 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq)
int storage_version = atomic_read(&ireq->cc->storage_version);
int aligned_msg;
- if (ireq->iochunk.cmd == PCS_REQ_T_READ && !((ireq->iochunk.size|ireq->iochunk.offset) & 511)) {
+ if (ireq->iochunk.cmd == PCS_REQ_T_READ && !((ireq->iochunk.size|ireq->iochunk.offset) & 511) &&
+ !(ireq->flags & IREQ_F_NO_ACCEL)) {
if (pcs_csa_cs_submit(cs, ireq))
return;
}
@@ -631,8 +632,8 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq)
if (aligned_msg)
ioh->hdr.type = PCS_CS_WRITE_AL_REQ;
else
- ioh->hdr.type = (ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) ?
- PCS_CS_WRITE_SYNC_REQ : PCS_CS_WRITE_REQ;
+ ioh->hdr.type = ((ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) ||
+ ireq->dentry->no_write_delay) ? PCS_CS_WRITE_SYNC_REQ : PCS_CS_WRITE_REQ;
ioh->hdr.len = pcs_cs_msg_size(ioh->hdr.len + ireq->iochunk.size,
storage_version);
break;
@@ -657,8 +658,9 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq)
if (ireq->flags & IREQ_F_SEQ)
ioh->sync.misc = PCS_CS_IO_SEQ;
-
- if (ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE)
+ if (ireq->dentry->no_csum_on_read)
+ ioh->sync.misc |= PCS_CS_IO_NOCSUM;
+ if ((ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) || ireq->dentry->no_write_delay)
ioh->sync.misc |= PCS_CS_IO_SYNC;
msg->size = ioh->hdr.len;
diff --git a/fs/fuse/kio/pcs/pcs_cs_accel.c b/fs/fuse/kio/pcs/pcs_cs_accel.c
index 9444f75..24a962f 100644
--- a/fs/fuse/kio/pcs/pcs_cs_accel.c
+++ b/fs/fuse/kio/pcs/pcs_cs_accel.c
@@ -5,6 +5,8 @@
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/anon_inodes.h>
+#include <linux/pagemap.h>
+#include <crypto/hash.h>
#include "pcs_types.h"
#include "pcs_sock_io.h"
@@ -52,6 +54,7 @@ struct pcs_csa_entry
unsigned int flags;
int dead;
struct file *file;
+ struct file *cfile;
};
static inline void __cse_destroy(struct pcs_csa_entry * cse)
@@ -60,6 +63,10 @@ static inline void __cse_destroy(struct pcs_csa_entry * cse)
fput(cse->file);
cse->file = NULL;
}
+ if (cse->cfile) {
+ fput(cse->cfile);
+ cse->cfile = NULL;
+ }
kmem_cache_free(pcs_csa_cachep, cse);
}
@@ -139,7 +146,7 @@ static inline struct pcs_csa_entry * cse_lookup(struct pcs_csa_context * ctx, u6
}
static int csa_update(struct pcs_csa_context * ctx, PCS_CHUNK_UID_T chunk_id, u32 flags, PCS_MAP_VERSION_T * vers,
- struct file * file)
+ struct file * file, struct file * cfile)
{
struct pcs_csa_entry * csa, * csb;
@@ -157,6 +164,9 @@ static int csa_update(struct pcs_csa_context * ctx, PCS_CHUNK_UID_T chunk_id, u3
return 0;
}
+ if ((flags & PCS_CSA_FL_CSUM) && !crc_tfm)
+ return -EOPNOTSUPP;
+
csb = kmem_cache_zalloc(pcs_csa_cachep, GFP_NOIO);
if (!csb)
return -ENOMEM;
@@ -166,6 +176,10 @@ static int csa_update(struct pcs_csa_context * ctx, PCS_CHUNK_UID_T chunk_id, u3
csb->flags = flags;
csb->file = file;
get_file(file);
+ if (cfile) {
+ csb->cfile = cfile;
+ get_file(cfile);
+ }
again:
if (radix_tree_preload(GFP_NOIO)) {
@@ -174,6 +188,10 @@ static int csa_update(struct pcs_csa_context * ctx, PCS_CHUNK_UID_T chunk_id, u3
}
spin_lock(&ctx->lock);
+ /* This is wrong to delete entry before insert. rcu lookup will see
+ * the gap. Not disasterous for us but dirty yet.
+ * But I do not see appropriate function in lib/radix-tree.c
+ */
csa = radix_tree_lookup(&ctx->tree, chunk_id);
if (csa) {
void *ret;
@@ -202,6 +220,51 @@ static int csa_update(struct pcs_csa_context * ctx, PCS_CHUNK_UID_T chunk_id, u3
return 0;
}
+static int verify_crc(struct pcs_int_request * ireq, u32 * crc)
+{
+ struct iov_iter it;
+ struct pcs_int_request *parent = ireq->completion_data.parent;
+ pcs_api_iorequest_t *ar = parent->apireq.req;
+ char crc_desc[sizeof(struct shash_desc) + 4] __aligned(__alignof__(struct shash_desc));
+ struct shash_desc *shash = (struct shash_desc *)crc_desc;
+ int i;
+
+ shash->tfm = crc_tfm;
+
+ ar->get_iter(ar->datasource, ireq->iochunk.dio_offset, &it, 0);
+
+ for (i = 0; i < ireq->iochunk.size/4096; i++) {
+ unsigned int left = 4096;
+ u32 ccrc;
+
+ *(u32*)shash->__ctx = ~0U;
+
+ do {
+ size_t offset;
+ int len;
+ struct page * page;
+
+ len = iov_iter_get_pages(&it, &page, left, 1, &offset);
+ BUG_ON(len <= 0);
+
+ crypto_shash_alg(crc_tfm)->update(shash, kmap(page) + offset, len);
+ kunmap(page);
+ put_page(page);
+ iov_iter_advance(&it, len);
+ left -= len;
+ } while (left > 0);
+
+ crypto_shash_alg(crc_tfm)->final(shash, (u8*)&ccrc);
+
+ if (ccrc != crc[i]) {
+ FUSE_KTRACE(ireq->cc->fc, "CRC error pg=%d@%u %08x %08x\n", i,
+ (unsigned)ireq->iochunk.offset, ccrc, crc[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void pcs_csa_do_completion(struct pcs_aio_req *areq)
{
struct pcs_int_request * ireq;
@@ -213,6 +276,21 @@ static void pcs_csa_do_completion(struct pcs_aio_req *areq)
ireq = container_of(areq, struct pcs_int_request, iochunk.ar);
+ if (areq->crc) {
+ if (!pcs_if_error(&ireq->error)) {
+ if (verify_crc(ireq, areq->crc)) {
+ ireq->error.remote = 1;
+ ireq->error.offender = ireq->iochunk.csl->cs[ireq->iochunk.cs_index].info.id;
+ ireq->error.value = PCS_ERR_IO;
+ }
+ }
+
+ if (areq->crc && areq->crc != areq->crcb) {
+ kfree(areq->crc);
+ areq->crc = NULL;
+ }
+ }
+
if (!pcs_if_error(&ireq->error)) {
struct fuse_conn * fc = ireq->cc->fc;
@@ -250,6 +328,7 @@ static void pcs_csa_do_completion(struct pcs_aio_req *areq)
ireq, (unsigned long long)ireq->iochunk.chunk,
(unsigned)ireq->iochunk.offset,
(unsigned)ireq->iochunk.size);
+ ireq->flags |= IREQ_F_NO_ACCEL;
}
ireq_complete(ireq);
@@ -262,6 +341,66 @@ static void csa_complete_work(struct work_struct *w)
pcs_csa_do_completion(areq);
}
+static inline int quick_crc_fetch(struct pcs_int_request * ireq, struct file * cfile)
+{
+ unsigned offset = (ireq->iochunk.offset / 4096) * 4;
+ unsigned sz = (ireq->iochunk.size / 4096) * 4;
+ pgoff_t idx = offset / PAGE_SIZE;
+ struct page * page;
+
+ if (idx != ((offset + sz - 1) / PAGE_SIZE) || sz > sizeof(ireq->iochunk.ar.crcb))
+ return 0;
+
+ page = find_get_page(cfile->f_mapping, idx);
+ if (!page)
+ return 0;
+
+ memcpy(ireq->iochunk.ar.crcb, kmap(page) + (offset & (PAGE_SIZE-1)), sz);
+ ireq->iochunk.ar.crc = ireq->iochunk.ar.crcb;
+ kunmap(page);
+ put_page(page);
+ return 1;
+}
+
+static void csa_crc_work(struct work_struct *w)
+{
+ struct pcs_aio_req * areq = container_of(w, struct pcs_aio_req, work);
+ struct pcs_int_request * ireq = container_of(areq, struct pcs_int_request, iochunk.ar);
+ int ncrc = (ireq->iochunk.size / 4096) * 4;
+ ssize_t sz;
+ loff_t pos;
+
+ if (ncrc <= PCS_MAX_INLINE_CRC)
+ areq->crc = areq->crcb;
+ else {
+ areq->crc = kmalloc(ncrc, GFP_KERNEL);
+ if (areq->crc == NULL) {
+out:
+ if (!ireq->error.value) {
+ ireq->error.remote = 1;
+ ireq->error.offender = ireq->iochunk.csl->cs[ireq->iochunk.cs_index].info.id;
+ ireq->error.value = PCS_ERR_NORES;
+ }
+ fput(areq->cfile);
+ if (areq->crc && areq->crc != areq->crcb) {
+ kfree(areq->crc);
+ areq->crc = NULL;
+ }
+ pcs_csa_do_completion(areq);
+ return;
+ }
+ }
+
+ pos = (ireq->iochunk.offset / 4096) * 4;
+ sz = kernel_read(areq->cfile, areq->crc, ncrc, &pos);
+ if (sz != ncrc) {
+ FUSE_KTRACE(ireq->cc->fc, "Did not read crc res=%u expected=%u", (unsigned)sz, (unsigned)ncrc);
+ goto out;
+ }
+ fput(areq->cfile);
+ pcs_csa_do_completion(areq);
+}
+
static void pcs_csa_complete(struct kiocb *iocb, long ret)
{
struct pcs_aio_req * areq;
@@ -283,7 +422,7 @@ static void pcs_csa_complete(struct kiocb *iocb, long ret)
queue_work(ireq->cc->wq, &areq->work);
}
-static inline int csa_submit(struct file * file, struct pcs_int_request * ireq)
+static inline int csa_submit(struct file * file, struct file *cfile, int do_csum, struct pcs_int_request * ireq)
{
struct pcs_aio_req * areq = &ireq->iochunk.ar;
struct kiocb * iocb = &areq->iocb;
@@ -311,9 +450,40 @@ static inline int csa_submit(struct file * file, struct pcs_int_request * ireq)
atomic_set(&areq->iocount, 2);
+ areq->cfile = NULL;
+ areq->crc = NULL;
+
+ if (do_csum) {
+ if (cfile == NULL)
+ return -EINVAL;
+
+ if ((ireq->iochunk.size|ireq->iochunk.offset) & 4095)
+ return -EINVAL;
+
+ if (!quick_crc_fetch(ireq, cfile)) {
+ INIT_WORK(&areq->work, csa_crc_work);
+ atomic_inc(&areq->iocount);
+ areq->cfile = cfile;
+ get_file(cfile);
+ }
+ }
+
ireq->ts_sent = ktime_get();
ret = call_read_iter(file, iocb, it);
+ if (do_csum) {
+ if (ret == -EIOCBQUEUED || ret == ireq->iochunk.size) {
+ if (!areq->crc) {
+ FUSE_KTRACE(ireq->cc->fc, "Not a quicky");
+ queue_work(ireq->cc->wq, &areq->work);
+ }
+ pcs_csa_do_completion(areq);
+ return 0;
+ }
+ if (!areq->crc)
+ pcs_csa_do_completion(areq);
+ }
+
pcs_csa_do_completion(areq);
if (ret == -EIOCBQUEUED)
@@ -343,7 +513,7 @@ int pcs_csa_cs_submit(struct pcs_cs * cs, struct pcs_int_request * ireq)
(csa->flags & PCS_CSA_FL_READ)) {
/* XXX Paranoia? Verify! */
if (!(map->state & PCS_MAP_DEAD) && map->cs_list == ireq->iochunk.csl) {
- if (!csa_submit(csa->file, ireq))
+ if (!csa_submit(csa->file, csa->cfile, csa->flags&PCS_CSA_FL_CSUM, ireq))
return 1;
}
}
@@ -355,6 +525,7 @@ static long csa_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct pcs_csa_context *ctx = file->private_data;
struct file * filp = NULL;
+ struct file * cfilp = NULL;
int err;
struct pcs_csa_setmap req;
@@ -365,12 +536,22 @@ static long csa_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case PCS_CSA_IOC_SETMAP:
if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
return -EFAULT;
+
if (req.fd >= 0) {
filp = fget(req.fd);
if (filp == NULL)
return -EBADF;
}
- err = csa_update(ctx, req.chunk_id, req.flags, &req.version, filp);
+ if (req.cfd >= 0) {
+ cfilp = fget(req.cfd);
+ err = -EBADF;
+ if (cfilp == NULL)
+ goto out;
+ }
+ err = csa_update(ctx, req.chunk_id, req.flags, &req.version, filp, cfilp);
+ if (cfilp)
+ fput(cfilp);
+out:
if (filp)
fput(filp);
return err;
diff --git a/fs/fuse/kio/pcs/pcs_cs_prot.h b/fs/fuse/kio/pcs/pcs_cs_prot.h
index d823426..6e0d371 100644
--- a/fs/fuse/kio/pcs/pcs_cs_prot.h
+++ b/fs/fuse/kio/pcs/pcs_cs_prot.h
@@ -37,6 +37,9 @@ struct pcs_cs_sync_data
* This means that at the req completion time, the output
* data will be transferred to disk.
*/
+#define PCS_CS_IO_NOCSUM (1ULL<<61) /* Req: skip crc verification */
+#define PCS_CS_IO_SYNC (1ULL<<60) /* Req: DSYNC request */
+#define PCS_CS_IO_BACKGROUND (1ULL<<59) /* Req: low priority request */
#define PCS_CS_RESET_TS_RECV(sdata, ts) do { (sdata)->misc = ((u64)ts & 0xFFFFFFFFFFFFFULL); } while (0)
#define PCS_CS_SET_TS_RECV(sdata, ts) do { (sdata)->misc = ((sdata)->misc & ~0xFFFFFFFFFFFFFULL) | ((u64)ts & 0xFFFFFFFFFFFFFULL); } while (0)
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 29ccabd..4bbabfd 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -28,6 +28,7 @@
#include <linux/net.h>
#include <linux/debugfs.h>
#include <linux/fiemap.h>
+#include <crypto/hash.h>
#include "pcs_ioctl.h"
#include "pcs_cluster.h"
@@ -72,6 +73,8 @@
static LIST_HEAD(pcs_client_list);
spinlock_t pcs_clients_lock;
+struct crypto_shash *crc_tfm;
+
static void register_client(struct pcs_fuse_cluster * pfc)
{
spin_lock(&pcs_clients_lock);
@@ -217,7 +220,7 @@ static void process_pcs_init_reply(struct fuse_mount *fm, struct fuse_args *args
}
-int kpcs_conn_init(struct fuse_mount *fm)
+static int kpcs_conn_init(struct fuse_mount *fm)
{
struct fuse_conn *fc = fm->fc;
struct fuse_io_args *ia;
@@ -268,7 +271,7 @@ int kpcs_conn_init(struct fuse_mount *fm)
return 0;
}
-void kpcs_conn_fini(struct fuse_mount *fm)
+static void kpcs_conn_fini(struct fuse_mount *fm)
{
struct fuse_conn *fc = fm->fc;
@@ -284,7 +287,7 @@ void kpcs_conn_fini(struct fuse_mount *fm)
pcs_cluster_fini((struct pcs_fuse_cluster *) fc->kio.ctx);
}
-void kpcs_conn_abort(struct fuse_conn *fc)
+static void kpcs_conn_abort(struct fuse_conn *fc)
{
/* XXX: Implement abort pending kio */
}
@@ -450,7 +453,7 @@ static int kpcs_do_file_open(struct file *file, struct inode *inode)
return 0;
}
-int kpcs_file_open(struct file *file, struct inode *inode)
+static int kpcs_file_open(struct file *file, struct inode *inode)
{
struct fuse_inode *fi = get_fuse_inode(inode);
struct pcs_dentry_info *di = fi->private;
@@ -501,7 +504,7 @@ static void kpcs_file_close(struct file *file, struct inode *inode)
pcs_mapping_invalidate(&di->mapping);
}
-void kpcs_inode_release(struct fuse_inode *fi)
+static void kpcs_inode_release(struct fuse_inode *fi)
{
struct pcs_dentry_info *di = fi->private;
@@ -648,7 +651,7 @@ int fuse_map_resolve(struct pcs_map_entry *m, int direction)
return 0;
}
-struct fuse_req *kpcs_req_alloc(struct fuse_mount *fm, gfp_t flags)
+static struct fuse_req *kpcs_req_alloc(struct fuse_mount *fm, gfp_t flags)
{
return fuse_generic_request_alloc(fm, pcs_fuse_req_cachep, flags);
}
@@ -1567,7 +1570,7 @@ static ssize_t prometheus_file_read(struct file *filp,
return count;
}
-const struct file_operations prometheus_file_operations = {
+static const struct file_operations prometheus_file_operations = {
.open = prometheus_file_open,
.read = prometheus_file_read,
.release = prometheus_file_release,
@@ -1745,13 +1748,39 @@ static void kpcs_kill_requests(struct fuse_conn *fc, struct inode *inode)
static int kpcs_ioctl(struct file *file, struct inode *inode, unsigned int cmd, unsigned long arg, int len)
{
- struct fuse_conn *fc = inode ? get_fuse_conn(inode) : NULL;
+ struct fuse_conn * fc = NULL;
+ struct fuse_inode *fi = NULL;
+ struct pcs_dentry_info *di = NULL;
struct pcs_fuse_cluster *pfc;
struct fuse_pcs_ioc_register req;
int res;
- if (cmd != PCS_KIO_CALL_REG)
- return -EINVAL;
+ if (inode) {
+ fc = get_fuse_conn(inode);
+ fi = get_fuse_inode(inode);
+ if (fi)
+ di = fi->private;
+ }
+
+ switch (cmd) {
+ case PCS_KIO_CALL_REG:
+ break;
+ case PCS_IOC_NOCSUMONREAD:
+ case PCS_IOC_NOWRITEDELAY:
+ if (di) {
+ u32 data;
+ if (copy_from_user(&data, (void __user *)arg, 4))
+ return -EFAULT;
+ if (cmd == PCS_IOC_NOCSUMONREAD)
+ di->no_csum_on_read = !!data;
+ else
+ di->no_write_delay = !!data;
+ return 0;
+ }
+ fallthrough;
+ default:
+ return -ENOIOCTLCMD;
+ }
if (len != sizeof(req))
return -EINVAL;
@@ -1759,6 +1788,9 @@ static int kpcs_ioctl(struct file *file, struct inode *inode, unsigned int cmd,
if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
return -EFAULT;
+ if (req.crypto_algo)
+ return -EOPNOTSUPP;
+
if (fc) {
pfc = (struct pcs_fuse_cluster*)fc->kio.ctx;
if (memcmp(&req.cluster_id, &pfc->cc.eng.cluster_id, sizeof(PCS_CLUSTER_ID_T)))
@@ -1843,6 +1875,10 @@ static int __init kpcs_mod_init(void)
fuse_trace_root = debugfs_create_dir("fuse", NULL);
+ crc_tfm = crypto_alloc_shash("crc32c", 0, 0);
+ if (IS_ERR(crc_tfm))
+ crc_tfm = NULL;
+
printk("%s fuse_c:%p ireq_c:%p pcs_wq:%p\n", __FUNCTION__,
pcs_fuse_req_cachep, pcs_ireq_cachep, pcs_wq);
@@ -1866,6 +1902,8 @@ static void __exit kpcs_mod_exit(void)
{
if (fuse_trace_root)
debugfs_remove(fuse_trace_root);
+ if (crc_tfm)
+ crypto_free_shash(crc_tfm);
fuse_unregister_kio(&kio_pcs_ops);
destroy_workqueue(pcs_cleanup_wq);
diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h
index 24e6b0b..5972873 100644
--- a/fs/fuse/kio/pcs/pcs_ioctl.h
+++ b/fs/fuse/kio/pcs/pcs_ioctl.h
@@ -88,7 +88,6 @@ struct pcs_ioc_getmap
#define PCS_IOC_GETMAP _IOWR('V',37, struct pcs_ioc_getmap)
-#define PCS_KIO_CALL_REG 1
struct fuse_pcs_ioc_register
{
@@ -96,7 +95,8 @@ struct fuse_pcs_ioc_register
PCS_NODE_ID_T client_id;
PCS_CLUSTER_ID_T cluster_id;
PCS_INTEGRITY_SEQ_T integrity_seq;
- u32 reserved;
+ u32 crypto_algo;
+ u64 key_data;
};
struct pcs_csa_setmap
@@ -104,14 +104,17 @@ struct pcs_csa_setmap
PCS_CHUNK_UID_T chunk_id;
PCS_MAP_VERSION_T version;
int fd;
+ int cfd;
u32 flags;
+ u32 reserved;
#define PCS_CSA_FL_READ 1
#define PCS_CSA_FL_WRITE 2
+#define PCS_CSA_FL_CSUM 4
PCS_SYNC_SEQ_T sync_epoch;
PCS_SYNC_SEQ_T sync_seq;
- u64 reserved;
};
#define PCS_CSA_IOC_SETMAP _IOR('V',38, struct pcs_csa_setmap)
+#define PCS_KIO_CALL_REG _IOR('V',39, struct fuse_pcs_ioc_register)
#endif /* _PCS_IOCTL_H_ */
diff --git a/fs/fuse/kio/pcs/pcs_req.h b/fs/fuse/kio/pcs/pcs_req.h
index 8c0bd3e..7c86f5d 100644
--- a/fs/fuse/kio/pcs/pcs_req.h
+++ b/fs/fuse/kio/pcs/pcs_req.h
@@ -52,6 +52,12 @@ struct pcs_aio_req
atomic_t iocount;
struct iov_iter iter;
struct work_struct work;
+
+#define PCS_MAX_INLINE_CRC 2
+ u32 crcb[PCS_MAX_INLINE_CRC];
+ u32 *crc;
+ struct file *cfile;
+ struct work_struct cwork;
};
struct pcs_int_request
@@ -76,6 +82,7 @@ struct pcs_int_request
#define IREQ_F_NOFLUSH 0x200
#define IREQ_F_WB_SUSP 0x400
#define IREQ_F_RECV_SPLICE 0x800
+#define IREQ_F_NO_ACCEL 0x1000
atomic_t iocount;
@@ -362,5 +369,6 @@ typedef void (*kio_file_itr)(struct fuse_file *ff, struct pcs_dentry_info *di,
typedef void (*kio_req_itr)(struct fuse_file *ff, struct fuse_req *req,
void *ctx);
void pcs_kio_req_list(struct fuse_conn *fc, kio_req_itr kreq_cb, void *ctx);
+extern struct crypto_shash *crc_tfm;
#endif /* _PCS_REQ_H_ */
--
1.8.3.1
More information about the Devel
mailing list