From 2033c555fd2d2e3b7bc53eb14155ba4750de242f Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Wed, 1 Nov 2023 17:07:23 -0400 Subject: [PATCH] EX-7601 ofd: add obd level compression lib Some compression functions will be used by several areas of of Lustre, so they need to be in obdclass. This moves merge_chunk and unmerge_chunk there and adds the ability for them to merge lnbs. This is used in a future patch. Signed-off-by: Patrick Farrell Change-Id: If4a318119bb7685e41adb9f3b31a66074031e6ac Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52938 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/include/lustre_compr.h | 6 ++ lustre/include/obd.h | 5 ++ lustre/include/uapi/linux/lustre/lustre_user.h | 3 + lustre/obdclass/lustre_compr.c | 80 +++++++++++++++++++++++++- lustre/ofd/Makefile.in | 4 +- lustre/ofd/ofd_compress.c | 34 +++++++++++ lustre/ofd/ofd_compress.h | 35 +++++++++++ lustre/ofd/ofd_dev.c | 2 + lustre/ofd/ofd_io.c | 1 + lustre/osc/osc_compress.c | 63 ++------------------ 10 files changed, 172 insertions(+), 61 deletions(-) create mode 100644 lustre/ofd/ofd_compress.c create mode 100644 lustre/ofd/ofd_compress.h diff --git a/lustre/include/lustre_compr.h b/lustre/include/lustre_compr.h index 6e53ddc..5c46f57 100644 --- a/lustre/include/lustre_compr.h +++ b/lustre/include/lustre_compr.h @@ -23,6 +23,10 @@ * Copyright (c) 2023, DataDirect Networks Inc, all rights reserved. * Author: Artem Blagodarenko */ +#ifndef _LUSTRE_COMPR_H_ +#define _LUSTRE_COMPR_H_ + +#include int alloc_compr(enum ll_compr_type *type, unsigned int lvl, struct crypto_comp **cc); @@ -47,3 +51,5 @@ int decompress_chunk(const char *obd_name, unsigned char *in, unsigned int in_len, unsigned char *out, unsigned int *out_len, enum ll_compr_type type, unsigned int lvl); + +#endif /* _LUSTRE_COMPR_H_ */ diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 4513a0b..9018262 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -475,6 +475,11 @@ struct niobuf_local { __u16 lnb_locked:1; }; +void merge_chunk(struct brw_page **pga, struct niobuf_local *lnb, + int first, int count, char *merged, unsigned int *size); +void unmerge_chunk(struct brw_page **pga, struct niobuf_local *lnb, int first, + int count, char *merged, unsigned int size); + struct tgt_thread_big_cache { struct niobuf_local local[PTLRPC_MAX_BRW_PAGES]; }; diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 2446a51..0970f7b 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -2968,6 +2968,9 @@ enum ll_compr_type { }; #define COMPR_CHUNK_MIN_BITS 16 +#define COMPR_GET_CHUNK_SIZE(log_bits) (1 << (log_bits + COMPR_CHUNK_MIN_BITS)) + + /* 64 MiB - a compressed chunk can never be bigger than PTLRPC_MAX_BRW_SIZE * (which isn't easily accessed here) */ diff --git a/lustre/obdclass/lustre_compr.c b/lustre/obdclass/lustre_compr.c index daa3ff0..05c072c 100644 --- a/lustre/obdclass/lustre_compr.c +++ b/lustre/obdclass/lustre_compr.c @@ -29,8 +29,8 @@ #include #include #include - #include +#include /* "one-shot" try to load our own compression modules * the first time that a compressed file is accessed @@ -251,3 +251,81 @@ fail: return rc; } EXPORT_SYMBOL(decompress_chunk); + +void merge_chunk(struct brw_page **pga, struct niobuf_local *lnb, + int first, int count, char *merged, unsigned int *size) +{ + struct brw_page *brwpg; + struct page *vmpage; + __u64 offset; + int pg_len; + char *kaddr; + int i; + + *size = 0; + for (i = 0; i < count; i++) { + if (pga) { + brwpg = pga[first + i]; + vmpage = brwpg->pg; + pg_len = brwpg->count; + offset = brwpg->off; + } else { + vmpage = lnb[first + i].lnb_page; + pg_len = lnb[first + i].lnb_len; + offset = lnb[first + i].lnb_file_offset; + } + CDEBUG(D_SEC, "page %pK [%d] at offset %llu\n", + vmpage, pg_len, offset); + kaddr = kmap_atomic(vmpage); + memcpy(merged + i * PAGE_SIZE, kaddr, pg_len); + kunmap_atomic(kaddr); + *size += pg_len; + } +} +EXPORT_SYMBOL(merge_chunk); + +void unmerge_chunk(struct brw_page **pga, struct niobuf_local *lnb, int first, + int count, char *merged, unsigned int size) +{ + struct brw_page *brwpg; + struct page *vmpage; + unsigned int left = size; + int *pg_len; + __u64 offset; + char *kaddr; + int i; + + for (i = 0; i < count; i++) { + if (pga) { + brwpg = pga[first + i]; + if (!brwpg) + continue; + vmpage = brwpg->pg; + pg_len = &brwpg->count; + offset = brwpg->off; + } else { + vmpage = lnb[first + i].lnb_page; + pg_len = &lnb[first + i].lnb_len; + offset = lnb[first + i].lnb_file_offset; + } + CDEBUG(D_SEC, "page %p [%d] at offset %llu\n", + vmpage, *pg_len, offset); + + kaddr = kmap_atomic(vmpage); + memcpy(kaddr, merged + (i << PAGE_SHIFT), + PAGE_SIZE); + kunmap_atomic(kaddr); + if (left < PAGE_SIZE) { + *pg_len = left; + left = 0; + } else { + *pg_len = PAGE_SIZE; + left -= PAGE_SIZE; + } + if (lnb) + lnb[first + i].lnb_rc = 0; + CDEBUG(D_SEC, "pg_len: %u, left %u\n", + *pg_len, left); + } +} +EXPORT_SYMBOL(unmerge_chunk); diff --git a/lustre/ofd/Makefile.in b/lustre/ofd/Makefile.in index 186172e..86081a1 100644 --- a/lustre/ofd/Makefile.in +++ b/lustre/ofd/Makefile.in @@ -1,8 +1,8 @@ MODULES := ofd ofd-objs := ofd_dev.o ofd_obd.o ofd_fs.o ofd_trans.o ofd_objects.o ofd_io.o -ofd-objs += lproc_ofd.o ofd_dlm.o ofd_lvb.o ofd_access_log.o +ofd-objs += lproc_ofd.o ofd_dlm.o ofd_lvb.o ofd_access_log.o ofd_compress.o -EXTRA_DIST = $(ofd-objs:%.o=%.c) ofd_internal.h +EXTRA_DIST = $(ofd-objs:%.o=%.c) ofd_internal.h ofd_compress.h @INCLUDE_RULES@ diff --git a/lustre/ofd/ofd_compress.c b/lustre/ofd/ofd_compress.c new file mode 100644 index 0000000..a2ae44d --- /dev/null +++ b/lustre/ofd/ofd_compress.c @@ -0,0 +1,34 @@ +/* GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ + +/* + * Copyright (c) 2023, DataDirect Networks Inc, all rights reserved. + * Author: Artem Blagodarenko + */ + +#define DEBUG_SUBSYSTEM S_FILTER + +#include +#include +#include "ofd_internal.h" +#include "ofd_compress.h" +#include +#include diff --git a/lustre/ofd/ofd_compress.h b/lustre/ofd/ofd_compress.h new file mode 100644 index 0000000..a5de51f --- /dev/null +++ b/lustre/ofd/ofd_compress.h @@ -0,0 +1,35 @@ +/* GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ + +/* + * Copyright (c) 2023, DataDirect Networks Inc, all rights reserved. + * Author: Artem Blagodarenko + */ +#ifndef _OFD_COMPRESS_H +#define _OFD_COMPRESS_H + +#define DEBUG_SUBSYSTEM S_FILTER + +#include +#include +#include "ofd_internal.h" + +#endif /* _OFD_COMPRESS_H */ diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index 2a542f9..c0eb9fb 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -80,6 +80,8 @@ #include #include "ofd_internal.h" +#include "ofd_compress.h" +#include /* Slab for OFD object allocation */ static struct kmem_cache *ofd_object_kmem; diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index 96e1807..069afda 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -42,6 +42,7 @@ #include #include "ofd_internal.h" +#include "ofd_compress.h" #include struct ofd_inconsistency_item { diff --git a/lustre/osc/osc_compress.c b/lustre/osc/osc_compress.c index 58bd390..dfbb299 100644 --- a/lustre/osc/osc_compress.c +++ b/lustre/osc/osc_compress.c @@ -37,59 +37,6 @@ enum cpga_fill_bits { CPGA_FILL_ENCRYPTED = 0x0002, }; -static void merge_chunk(struct brw_page **pga, int first, int count, - char *merged, unsigned int *size) -{ - struct brw_page *pg; - int page; - - *size = 0; - for (page = 0; page < count; page++) { - char *kaddr; - - pg = pga[first + page]; - - kaddr = kmap_atomic(pg->pg); - memcpy(merged + page * PAGE_SIZE, kaddr, - pg->count); - kunmap_atomic(kaddr); - *size += pg->count; - } -} - -static void unmerge_chunk(struct brw_page **pga, int first, int count, - char *merged, unsigned int size) -{ - struct brw_page *pg; - int page; - char *kaddr; - unsigned int left = size; - - for (page = 0; page < count; page++) { - pg = pga[first + page]; - - if (!pg) - continue; - - LASSERT(pg->count > 0); - CDEBUG(D_SEC, - "address 0x%px, offset 0x%llx, count %i, flag 0x%x\n", - page_address(pg->pg), pg->off, pg->count, - pg->flag); - kaddr = kmap_atomic(pg->pg); - memcpy(kaddr, merged + page * PAGE_SIZE, - PAGE_SIZE); - kunmap_atomic(kaddr); - - if (left < PAGE_SIZE) { - pg->count = left; - } else { - pg->count = PAGE_SIZE; - left -= PAGE_SIZE; - } - } -} - void free_cpga(struct brw_page **cpga, u32 page_count) { int i; @@ -239,8 +186,8 @@ int compress_request(const char *obd_name, struct obdo *oa, chunk_start, pga_i, clpage->cp_comp_type, clpage->cp_comp_level); - merge_chunk(pga, chunk_start, pga_i + 1 - chunk_start, - src, &src_size); + merge_chunk(pga, NULL, chunk_start, + pga_i + 1 - chunk_start, src, &src_size); dst_size = 2 * chunk_size; sptlrpc_pool_get_pages(&dst, dest_buf_bits); if (dst == NULL) @@ -391,7 +338,8 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count) CDEBUG(D_SEC, "Merge chunk [%i, %i], src: %px\n", i, i + pages_left - 1, src); - merge_chunk(pga, i, pages_left, src, &src_size); + + merge_chunk(pga, NULL, i, pages_left, src, &src_size); LASSERT(src_size <= chunk_size); dst_size = 2 * chunk_size; CDEBUG(D_SEC, "Compressed size %lu, type %i\n", @@ -411,8 +359,7 @@ int decompress_request(struct osc_brw_async_args *aa, int page_count) dst_size, done); LASSERT(dst_size <= chunk_size); - unmerge_chunk(pga, i, pages_left, - dst, dst_size); + unmerge_chunk(pga, NULL, i, pages_in_chunk, dst, dst_size); count++; } -- 1.8.3.1