[Devel] [PATCH] fs/fuse kio: add support jumbo chunks
Pavel Butsykin
pbutsykin at virtuozzo.com
Wed Jun 5 13:47:00 MSK 2019
This patch adds support for chunks size > 4G in FPath.
#VSTOR-20454
Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
fs/fuse/kio/pcs/pcs_client_types.h | 6 +++---
fs/fuse/kio/pcs/pcs_cs_prot.h | 6 ++++--
fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 9 ---------
fs/fuse/kio/pcs/pcs_map.c | 15 ++++++++++-----
fs/fuse/kio/pcs/pcs_mds_prot.h | 6 +++---
fs/fuse/kio/pcs/pcs_prot_types.h | 9 +++++++++
fs/fuse/kio/pcs/pcs_req.c | 3 +--
7 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/fs/fuse/kio/pcs/pcs_client_types.h b/fs/fuse/kio/pcs/pcs_client_types.h
index 5e72eb0fac3e..ec180b41cee4 100644
--- a/fs/fuse/kio/pcs/pcs_client_types.h
+++ b/fs/fuse/kio/pcs/pcs_client_types.h
@@ -90,9 +90,9 @@ static inline void pcs_set_fileinfo(struct pcs_dentry_info *i, const struct pcs_
if (mi->sys.stripe_depth == 0) {
mi->sys.stripe_depth = 1;
- mi->sys.strip_width = mi->sys.chunk_size_lo;
+ mi->sys.strip_width = PCS_DEF_STRIP_WIDTH;
}
- i->mapping.chunk_size_bits = ilog2(mi->sys.chunk_size_lo);
+ i->mapping.chunk_size_bits = ilog2(pcs_sys_info_get_chunk_size(&mi->sys));
}
@@ -173,7 +173,7 @@ typedef struct _pcs_api_csconnreq_t {
#define DENTRY_ARGS(de) PCS_FILE_ID_ARGS((de)->id.parent), PCS_FILE_ID_ARGS((de)->fileinfo.attr.id)
#define DENTRY_SIZE(de) ((de)->fileinfo.attr.size)
-#define DENTRY_CHUNK_SIZE(de) ((de)->fileinfo.sys.chunk_size_lo)
+#define DENTRY_CHUNK_SIZE(de) pcs_sys_info_get_chunk_size(&(de)->fileinfo.sys)
#define DENTRY_CHUNK_SIZE_BITS(de) ((de)->mapping.chunk_size_bits)
void pcs_mapset_limit(struct pcs_map_set *maps, int limit);
diff --git a/fs/fuse/kio/pcs/pcs_cs_prot.h b/fs/fuse/kio/pcs/pcs_cs_prot.h
index 8ca6cbabf741..e7545c55923d 100644
--- a/fs/fuse/kio/pcs/pcs_cs_prot.h
+++ b/fs/fuse/kio/pcs/pcs_cs_prot.h
@@ -67,6 +67,7 @@ struct pcs_cs_iohdr {
struct pcs_cs_sync_resp sync_resp[0]; /* Used only in response to write/sync */
} __attribute__((aligned(8)));
+#define PCS_CS_MAX_IOSIZE ((u32)-4096)
/* Maximal message size. Actually, random */
#define PCS_CS_MSG_MAX_SIZE (1024*1024 + sizeof(struct pcs_cs_iohdr))
@@ -139,10 +140,11 @@ struct pcs_cs_map_prop {
/* During replication this version indicates the newest dirty mask version allowed to be using for recovery. */
PCS_MAP_VERSION_T dirty_version;
u32 flags; /* CS_MAPF_XXX */
- u32 chunk_size;
+ u32 chunk_size_lo;
/* The maximum number of nodes in the chain. Intended to be using in timeout calculation. */
u16 chain_nodes;
- u16 reserved;
+ u8 chunk_size_hi;
+ u8 reserved;
u32 nnodes;
struct pcs_cs_node_desc nodes[0];
} __attribute__((aligned(8)));
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 0d8cb3a751e2..ac5616e5cc1e 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -326,15 +326,6 @@ static int kpcs_do_file_open(struct fuse_conn *fc, struct file *file, struct ino
if (info.sys.map_type != PCS_MAP_PLAIN) {
TRACE("Unsupported map_type:%x, ignore\n", info.sys.map_type);
-
- if (info.sys.map_type & PCS_JUMBO_CHUNK_FLAG)
- pr_warn_once("kio: fpath doesn't support jumbo chunks\n");
- return 0;
- }
-
- if (info.sys.chunk_size_hi) {
- TRACE("Unsupported chunk_size_hi:%x\n", info.sys.chunk_size_hi);
- pr_warn_once("kio: fpath doesn't support jumbo chunks\n");
return 0;
}
diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c
index 273697b840ff..2ff07b773fe8 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -242,7 +242,7 @@ void pcs_mapping_dump(struct pcs_mapping * mapping)
void map_truncate_tail(struct pcs_mapping * mapping, u64 offset)
{
- unsigned long pos = DIV_ROUND_UP(offset, 1 << mapping->chunk_size_bits);
+ unsigned long pos = DIV_ROUND_UP(offset, 1LLU << mapping->chunk_size_bits);
struct pcs_map_entry *maps[MAP_BATCH];
int nr_maps;
LIST_HEAD(dispose);
@@ -2337,17 +2337,22 @@ void map_submit(struct pcs_map_entry * m, struct pcs_int_request *ireq)
if (ireq->type != PCS_IREQ_FLUSH && !(ireq->flags & IREQ_F_MAPPED)) {
u64 pos = ireq->iochunk.chunk + ireq->iochunk.offset;
+ u64 iochunk;
BUG_ON(pos < map_start);
ireq->iochunk.chunk = map_start;
ireq->iochunk.offset = pos - ireq->iochunk.chunk;
- if (pos + ireq->iochunk.size > map_end) {
+ iochunk = ireq->iochunk.size;
+ if (pos + ireq->iochunk.size > map_end)
+ iochunk = map_end - pos;
+ if (iochunk > PCS_CS_MAX_IOSIZE)
+ iochunk = PCS_CS_MAX_IOSIZE;
+ if (iochunk < ireq->iochunk.size) {
if (ireq->iochunk.cmd == PCS_REQ_T_FIEMAP) {
pcs_api_iorequest_t *ar = ireq->completion_data.parent->apireq.req;
- ireq->iochunk.size = map_end - pos;
- ar->size = ireq->iochunk.size;
+ ireq->iochunk.size = ar->size = iochunk;
} else {
struct pcs_int_request *sreq;
- sreq = pcs_ireq_split(ireq, map_end - pos, 0);
+ sreq = pcs_ireq_split(ireq, iochunk, 0);
if (ireq->iochunk.map) {
pcs_map_put(ireq->iochunk.map);
ireq->iochunk.map = NULL;
diff --git a/fs/fuse/kio/pcs/pcs_mds_prot.h b/fs/fuse/kio/pcs/pcs_mds_prot.h
index 1dc1724fa94d..962b8296732c 100644
--- a/fs/fuse/kio/pcs/pcs_mds_prot.h
+++ b/fs/fuse/kio/pcs/pcs_mds_prot.h
@@ -1312,7 +1312,7 @@ struct pcs_mds_disk_info_msg {
/* The function translates bytes offset in file to byte offset in actual storage.
* This map is identical for plain layout and non trivial for RAID0 layout.
*/
-static inline u64 map_file_to_chunk(u64 pos, unsigned int chunk_size, unsigned int stripe_depth, unsigned int strip_width)
+static inline u64 map_file_to_chunk(u64 pos, u64 chunk_size, unsigned int stripe_depth, unsigned int strip_width)
{
unsigned int strip_off, chunk_idx;
u64 base, strip_idx, chunk_off;
@@ -1321,9 +1321,9 @@ static inline u64 map_file_to_chunk(u64 pos, unsigned int chunk_size, unsigned i
if (stripe_depth == 1)
return pos;
- group_size = (u64)chunk_size * stripe_depth;
+ group_size = chunk_size * stripe_depth;
- base = (pos / group_size) * group_size;
+ base = round_down(pos, group_size);
pos -= base;
strip_off = pos % strip_width;
diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h
index 11986252f23c..5a2adb7b62e5 100644
--- a/fs/fuse/kio/pcs/pcs_prot_types.h
+++ b/fs/fuse/kio/pcs/pcs_prot_types.h
@@ -120,6 +120,15 @@ struct __pre_aligned(8) pcs_mds_sys_info {
u32 reserved3;
} __aligned(8);
+static inline u64 pcs_sys_info_get_chunk_size(struct pcs_mds_sys_info const *si)
+{
+ return ((u64)si->chunk_size_hi << 32) | si->chunk_size_lo;
+}
+
+/* Defaults and limits */
+#define PCS_DEF_CHUNK_SIZE 0x10000000 /* 256Mb */
+#define PCS_DEF_STRIP_WIDTH (1*1024*1024)
+
#define PCS_CHUNK_SIZE_MIN 4096u
#define PCS_CHUNK_SIZE_MAX 2147483648u
#define PCS_STRIPE_DEPTH_MAX 64
diff --git a/fs/fuse/kio/pcs/pcs_req.c b/fs/fuse/kio/pcs/pcs_req.c
index 55fb39e91b93..d533e2d79bf5 100644
--- a/fs/fuse/kio/pcs/pcs_req.c
+++ b/fs/fuse/kio/pcs/pcs_req.c
@@ -83,8 +83,7 @@ void ireq_delay(struct pcs_int_request *ireq)
void ireq_handle_hole(struct pcs_int_request *ireq)
{
- unsigned int len;
- unsigned int offset;
+ u64 offset, len;
struct iov_iter it;
pcs_api_iorequest_t * ar = ireq->completion_data.parent->apireq.req;
--
2.15.1
More information about the Devel
mailing list