From 17fc6dbcd62836f5892177c96d06c518d18c9c2b Mon Sep 17 00:00:00 2001 From: Shaun Tancheff Date: Wed, 21 May 2025 22:54:48 -0700 Subject: [PATCH] LU-17784 build: improve wiretest for flexible arrays Flexible array checking can additionally probe that the size of the array element is correct. Lustre-change: https://review.whamcloud.com/54929 Lustre-commit: 339b585c257d7f47d0c9b74f9d940fd20b8c04a3 Was-Change-Id: Ib7de3d156a2e77dfaf2e9ab1df8fab524c073610 LU-17504 libcfs: safer LIBCFS_ALLOC Make the LIBCFS_ALLOC() family of macros safer by adding parenthesis around arguments such as (size) to avoid uninteded expansion. CoverityID: 415056 ("Integer handling issues") Lustre-change: https://review.whamcloud.com/55015 Lustre-commit: 0d3a9607655adc8f9dd4ae1c341bde0b57fe88bf Was-Change-Id: I9701f87025bc5ce038a6bf34413b64a3f019d998 Fixes: 718e3f3e68 ("LU-17504 build: fix gcc-13 [-Werror=stringop-overread] error") LU-17504 build: fix lock_handle array-index-out-of-bounds After Linux kernel patch "ubsan: Tighten UBSAN_BOUNDS on GCC" (commit v6.4-rc2-1-g2d47c6956ab3), flexible trailing arrays declared like 'lock_handle[2]' will generate warnings when CONFIG_UBSAN & co. is enabled: UBSAN: array-index-out-of-bounds in ldlm_request.c:1282:18 index 2 is out of range for type 'lustre_handle [2]' The declaration lock_handle[LDLM_LOCKREQ_HANDLES] confuses the compiler into thinking there are only two fields in lock_handle, but the caller often allocates extra fields beyond this for more locks to be cancelled due to Early Lock Cancellation or from LRU. Rather than have a second flexible array after lustre_handle[2], declare the whole array as flexible, and fix up the few sites that are allocating this array to ensure LDLM_LOCKREQ_HANDLES fields are allocated at a minimum. This subtly changes the checks in wiretest.c due to the removal of the 2 "base" handles in ldlm_request, but I believe this is not changing the wire protocol because it still allocates those handles directly, and I have verified interoperability with a 2.14.0 server. Lustre-change: https://review.whamcloud.com/54926 Lustre-commit: e3a9d87370c4ccc58d1d3a97ea1b221d88f9e57a Was-Change-Id: I9695fb44f1b5c84bb750d2983cdd8b939e3ebbe5 Test-Parameters: testlist=runtests clientversion=2.14 Test-Parameters: testlist=runtests serverversion=2.14 Test-Parameters: testlist=runtests clientversion=2.15 Test-Parameters: testlist=runtests serverversion=2.15 Test-Parameters: testlist=runtests clientversion=EXA5 Test-Parameters: testlist=runtests serverversion=EXA5 Test-Parameters: testlist=runtests clientversion=EXA6 Test-Parameters: testlist=runtests serverversion=EXA6 Signed-off-by: Andreas Dilger LU-17504 build: fix gcc-13 [-Werror=stringop-overread] error This patch fixes the following [-Werror=stringop-overread] and [-Werror=attribute-warning] errors detected by gcc 13: lustre/mgc/mgc_request.c:190:21: error: 'strcmp' reading 1 or more bytes from a region of size 0 [-Werror=stringop-overread] 190 | if (strcmp(logname, cld->cld_logname) == 0) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In function 'fortify_memcpy_chk', inlined from 'class_handle_ioctl' at /root/lustre-release/lustre/obdclass/class_obd.c:381:3: include/linux/fortify-string.h:528:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 528 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lustre-change: https://review.whamcloud.com/54834 Lustre-commit: 718e3f3e680f422d865a15890ac60e66dcd9e240 Was-Change-Id: I59f5a88b4cd64c9f4e67e568546baada371543b1 Signed-off-by: Jian Yu LU-17504 build: fix array-index-out-of-bounds warning On Linux kernel 6.5, due to commit 2d47c6956ab3 ("ubsan: Tighten UBSAN_BOUNDS on GCC"), flexible trailing arrays declared like 'lc_array_sum[1];' will generate warnings when CONFIG_UBSAN & co. is enabled: UBSAN: array-index-out-of-bounds in lprocfs_status.c:1609:17 index 1 is out of range for type '__s64 [1]' Since LPROCFS_STATS_FLAG_IRQ_SAFE flag is only used in one place - obd_memory() counter, we can just remove it and change obd_memory over to a regular percpu_counter. This would both simplify the lprocfs_counter() code, move over to using more kernel functionality instead of libcfs, as well as reduce overhead slightly for the memory accounting code. Lustre-change: https://review.whamcloud.com/54365 Lustre-commit: b698abd415bc4a810f307611fe984e50e007581e Was-Change-Id: Ic461c4b30317bfd2b1e9f5b6be84c4a7fb4e3eb9 Signed-off-by: Jian Yu LU-16363 build: fiemap flexible array Linux commit v5.19-rc2-1-g94dfc73e7cf4 treewide: uapi: Replace zero-length arrays with flexible-array members Adjust wiretest to handle flexible array when sizeof(fiemap->fm_extents) is undefined. Lustre-change: https://review.whamcloud.com/49305 Lustre-commit: fedf1e8bd70ccb2aaa64cb90111a7298d9bb2bf7 Was-Change-Id: Ia2692d126a871b43e9144e5d151215166604702d HPE-bug-id: LUS-11388 Signed-off-by: Shaun Tancheff Change-Id: Ib7de3d156a2e77dfaf2e9ab1df8fab524c073610 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59303 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/libcfs_hash.h | 4 +- libcfs/include/libcfs/libcfs_private.h | 10 ++--- libcfs/libcfs/hash.c | 6 +-- lnet/autoconf/lustre-lnet.m4 | 3 +- lnet/lnet/config.c | 2 +- lnet/selftest/module.c | 8 +++- lustre/autoconf/lustre-core.m4 | 23 ++++++++++ lustre/include/lprocfs_status.h | 18 +------- lustre/include/obd_class.h | 2 +- lustre/include/obd_support.h | 54 ++++++++++-------------- lustre/include/uapi/linux/lustre/lustre_idl.h | 22 +++++----- lustre/include/uapi/linux/lustre/lustre_ioctl.h | 2 +- lustre/include/uapi/linux/lustre/lustre_user.h | 4 +- lustre/ldlm/ldlm_lockd.c | 5 +-- lustre/ldlm/ldlm_request.c | 17 ++++---- lustre/lfsck/lfsck_internal.h | 2 +- lustre/mgc/mgc_request.c | 8 ++-- lustre/obdclass/class_obd.c | 48 +++++++-------------- lustre/obdclass/dt_object.c | 2 +- lustre/obdclass/lprocfs_counters.c | 20 +-------- lustre/obdclass/lprocfs_status.c | 38 +++-------------- lustre/ptlrpc/layout.c | 3 +- lustre/ptlrpc/wiretest.c | 56 +++++++++++++++---------- lustre/utils/wirecheck.c | 35 +++++++++++----- lustre/utils/wiretest.c | 36 +++++++--------- 25 files changed, 193 insertions(+), 235 deletions(-) diff --git a/libcfs/include/libcfs/libcfs_hash.h b/libcfs/include/libcfs/libcfs_hash.h index bdf3cdd..f0e0e0e 100644 --- a/libcfs/include/libcfs/libcfs_hash.h +++ b/libcfs/include/libcfs/libcfs_hash.h @@ -265,8 +265,8 @@ struct cfs_hash { /** workitem to output max depth */ struct work_struct hs_dep_work; #endif - /** name of htable */ - char hs_name[0]; + /** name of htable */ + char hs_name[]; }; struct cfs_hash_lock_ops { diff --git a/libcfs/include/libcfs/libcfs_private.h b/libcfs/include/libcfs/libcfs_private.h index 4fd841b..31df5f4 100644 --- a/libcfs/include/libcfs/libcfs_private.h +++ b/libcfs/include/libcfs/libcfs_private.h @@ -128,12 +128,12 @@ extern atomic64_t libcfs_kmem; # define libcfs_kmem_inc(ptr, size) \ do { \ - atomic64_add(size, &libcfs_kmem); \ + atomic64_add((size), &libcfs_kmem); \ } while (0) # define libcfs_kmem_dec(ptr, size) \ do { \ - atomic64_sub(size, &libcfs_kmem); \ + atomic64_sub((size), &libcfs_kmem); \ } while (0) # define libcfs_kmem_read() \ @@ -186,13 +186,13 @@ do { \ * default allocator */ #define LIBCFS_ALLOC(ptr, size) \ - LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS) + LIBCFS_ALLOC_GFP(ptr, (size), GFP_NOFS) /** * non-sleeping allocator */ #define LIBCFS_ALLOC_ATOMIC(ptr, size) \ - LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC) + LIBCFS_ALLOC_GFP(ptr, (size), GFP_ATOMIC) /** * allocate memory for specified CPU partition @@ -211,7 +211,7 @@ do { \ /** default numa allocator */ #define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \ - LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS) + LIBCFS_CPT_ALLOC_GFP(ptr, (cptab), (cpt), (size), GFP_NOFS) #define LIBCFS_FREE(ptr, size) \ do { \ diff --git a/libcfs/libcfs/hash.c b/libcfs/libcfs/hash.c index 6fb32ad..96a792c 100644 --- a/libcfs/libcfs/hash.c +++ b/libcfs/libcfs/hash.c @@ -1064,7 +1064,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, len = (flags & CFS_HASH_BIGNAME) == 0 ? CFS_HASH_NAME_LEN : CFS_HASH_BIGNAME_LEN; - LIBCFS_ALLOC(hs, offsetof(struct cfs_hash, hs_name[len])); + LIBCFS_ALLOC(hs, sizeof(struct cfs_hash) + len); if (hs == NULL) RETURN(NULL); @@ -1096,7 +1096,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, if (hs->hs_buckets != NULL) return hs; - LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[len])); + LIBCFS_FREE(hs, sizeof(struct cfs_hash) + len); RETURN(NULL); } EXPORT_SYMBOL(cfs_hash_create); @@ -1161,7 +1161,7 @@ cfs_hash_destroy(struct cfs_hash *hs) 0, CFS_HASH_NBKT(hs)); i = cfs_hash_with_bigname(hs) ? CFS_HASH_BIGNAME_LEN : CFS_HASH_NAME_LEN; - LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[i])); + LIBCFS_FREE(hs, sizeof(struct cfs_hash) + i); EXIT; } diff --git a/lnet/autoconf/lustre-lnet.m4 b/lnet/autoconf/lustre-lnet.m4 index 5d90e64..815ad86 100644 --- a/lnet/autoconf/lustre-lnet.m4 +++ b/lnet/autoconf/lustre-lnet.m4 @@ -294,7 +294,8 @@ AC_SUBST(ENABLEO2IB) AS_IF([test $ENABLEO2IB != "no"], [ EXTRA_CHECK_INCLUDE="$EXTRA_OFED_CONFIG $EXTRA_OFED_INCLUDE" - if test ! $O2IBPATH -ef $LINUX_OBJ; then + if test ! $O2IBPATH -ef $LINUX_OBJ && + test -f $O2IBPATH/Module.symvers; then KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS $O2IBPATH/Module.symvers" fi diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c index 01dd3d8..a1d49df 100644 --- a/lnet/lnet/config.c +++ b/lnet/lnet/config.c @@ -41,7 +41,7 @@ struct lnet_text_buf { struct list_head ltb_list; /* stash on lists */ int ltb_size; /* allocated size */ - char ltb_text[0]; /* text buffer */ + char ltb_text[]; /* text buffer */ }; static int lnet_tbnob = 0; /* track text buf allocation */ diff --git a/lnet/selftest/module.c b/lnet/selftest/module.c index ae73095..bb7a3e6 100644 --- a/lnet/selftest/module.c +++ b/lnet/selftest/module.c @@ -85,7 +85,7 @@ lnet_selftest_exit(void) } } -void +static void lnet_selftest_structure_assertion(void) { BUILD_BUG_ON(sizeof(struct srpc_msg) != 160); @@ -105,6 +105,12 @@ lnet_selftest_init(void) int rc = -ENOMEM; int i; + /* This assertion checks that struct sizes do not drift + * inadvertently and induce crashes when different nodes + * running LNet Selftest have mismatched structures. + */ + lnet_selftest_structure_assertion(); + lst_serial_wq = alloc_ordered_workqueue("lst_s", 0); if (!lst_serial_wq) { CERROR("Failed to create serial WI scheduler for LST\n"); diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 1fb10d1..98f5bcb 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -2336,6 +2336,27 @@ AC_DEFUN([LC_HAVE_CRYPTO_MAX_ALG_NAME_128], [ ]) # LC_HAVE_CRYPTO_MAX_ALG_NAME_128 # +# LC_HAVE_PERCPU_COUNTER_ADD_BATCH +# +# Linux commit v4.11-12447-g104b4e5139fe +# percpu_counter: Rename __percpu_counter_add to percpu_counter_add_batch +# +AC_DEFUN([LC_SRC_HAVE_PERCPU_COUNTER_ADD_BATCH], [ + LB2_LINUX_TEST_SRC([percpu_counter_add_batch_exists], [ + #include + ],[ + (void)percpu_counter_add_batch(NULL, 0, 0); + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_PERCPU_COUNTER_ADD_BATCH], [ + AC_MSG_CHECKING([if 'percpu_counter_add_batch()' exists]) + LB2_LINUX_TEST_RESULT([percpu_counter_add_batch_exists], [ + AC_DEFINE(HAVE_PERCPU_COUNTER_ADD_BATCH, 1, + ['percpu_counter_add_batch()' exists]) + ]) +]) # LC_HAVE_PERCPU_COUNTER_ADD_BATCH + +# # LC_CURRENT_TIME # # Kernel version 4.12 commit 47f38c539e9a42344ff5a664942075bd4df93876 @@ -4234,6 +4255,7 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [ LC_SRC_VM_OPERATIONS_REMOVE_VMF_ARG LC_SRC_HAVE_KEY_USAGE_REFCOUNT LC_SRC_HAVE_CRYPTO_MAX_ALG_NAME_128 + LC_SRC_HAVE_PERCPU_COUNTER_ADD_BATCH # 4.12 LC_SRC_CURRENT_TIME @@ -4511,6 +4533,7 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [ LC_VM_OPERATIONS_REMOVE_VMF_ARG LC_HAVE_KEY_USAGE_REFCOUNT LC_HAVE_CRYPTO_MAX_ALG_NAME_128 + LC_HAVE_PERCPU_COUNTER_ADD_BATCH # 4.12 LC_CURRENT_TIME diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 7cf9b8e..a7e363c 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -174,17 +174,9 @@ struct lprocfs_counter { __s64 lc_count; __s64 lc_min; __s64 lc_max; + __s64 lc_sum; __s64 lc_sumsquare; - /* - * Every counter has lc_array_sum[0], while lc_array_sum[1] is only - * for irq context counter, i.e. stats with - * LPROCFS_STATS_FLAG_IRQ_SAFE flag, its counter need - * lc_array_sum[1] - */ - __s64 lc_array_sum[1]; }; -#define lc_sum lc_array_sum[0] -#define lc_sum_irq lc_array_sum[1] struct lprocfs_percpu { struct lprocfs_counter lp_cntr[0]; @@ -199,7 +191,6 @@ enum lprocfs_stats_flags { LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */ LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu * area and need locking */ - LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */ }; enum lprocfs_fields_flags { @@ -481,10 +472,6 @@ lprocfs_stats_counter_size(struct lprocfs_stats *stats) percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); - /* irq safe stats need lc_array_sum[1] */ - if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - percpusize += stats->ls_num * sizeof(__s64); - if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0) percpusize = L1_CACHE_ALIGN(percpusize); @@ -499,9 +486,6 @@ lprocfs_stats_counter_get(struct lprocfs_stats *stats, unsigned int cpuid, cntr = &stats->ls_percpu[cpuid]->lp_cntr[index]; - if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - cntr = (void *)cntr + index * sizeof(__s64); - return cntr; } diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 1cf5d39..7d01d53 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -265,7 +265,7 @@ struct config_llog_data { unsigned int cld_stopping:1, /* we were told to stop * watching */ cld_lostlock:1; /* lock not requeued */ - char cld_logname[0]; + char cld_logname[]; }; struct lustre_profile { diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 13da93c..51ddef3 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -44,11 +45,7 @@ #include /* global variables */ -extern struct lprocfs_stats *obd_memory; -enum { - OBD_MEMORY_STAT = 0, - OBD_STATS_NUM, -}; +extern struct percpu_counter obd_memory; extern unsigned int obd_debug_peer_on_timeout; extern unsigned int obd_dump_on_timeout; @@ -765,41 +762,36 @@ extern char obd_jobid_var[]; extern atomic64_t libcfs_kmem; -#ifdef CONFIG_PROC_FS -#define obd_memory_add(size) \ - lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size)) -#define obd_memory_sub(size) \ - lprocfs_counter_sub(obd_memory, OBD_MEMORY_STAT, (long)(size)) -#define obd_memory_sum() \ - lprocfs_stats_collector(obd_memory, OBD_MEMORY_STAT, \ - LPROCFS_FIELDS_FLAGS_SUM) - -extern void obd_update_maxusage(void); -extern __u64 obd_memory_max(void); - -#else /* CONFIG_PROC_FS */ - -extern __u64 obd_alloc; +/* OBD_MEMORY_BATCH is the maximum error allowed per CPU core. Since + * obd_memory_sum() is calling percpu_counter_sum_positive(), it adds + * up the per-core local delta anyway, so the per-core batch size is + * can be large. This could be percpu_counter_add_local(), but that + * only exists in kernel 6.0 and later, and just uses a larger batch. + */ +#define OBD_MEMORY_BATCH (16 * 1024 * 1024) -extern __u64 obd_max_alloc; +#ifndef HAVE_PERCPU_COUNTER_ADD_BATCH +#define percpu_counter_add_batch(fbc, amount, batch) \ + __percpu_counter_add(fbc, amount, batch) +#endif -static inline void obd_memory_add(long size) +static inline void obd_memory_add(size_t size) { - obd_alloc += size; - if (obd_alloc > obd_max_alloc) - obd_max_alloc = obd_alloc; + percpu_counter_add_batch(&obd_memory, size, OBD_MEMORY_BATCH); } -static inline void obd_memory_sub(long size) +static inline void obd_memory_sub(size_t size) { - obd_alloc -= size; + percpu_counter_add_batch(&obd_memory, -size, OBD_MEMORY_BATCH); } -#define obd_memory_sum() (obd_alloc) - -#define obd_memory_max() (obd_max_alloc) +static inline s64 obd_memory_sum(void) +{ + return percpu_counter_sum_positive(&obd_memory); +} -#endif /* !CONFIG_PROC_FS */ +extern void obd_update_maxusage(void); +extern __u64 obd_memory_max(void); #define OBD_DEBUG_MEMUSAGE (1) diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index ef6d11f..d15cae7 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -438,7 +438,7 @@ struct lu_dirent { * their natural order. After the last attribute, padding bytes are * added to make ->lde_reclen a multiple of 8. */ - char lde_name[0]; + char lde_name[]; }; /* @@ -2552,8 +2552,8 @@ struct ldlm_lock_desc { struct ldlm_request { __u32 lock_flags; /* LDLM_FL_*, see lustre_dlm_flags.h */ __u32 lock_count; /* number of locks in lock_handle[] */ - struct ldlm_lock_desc lock_desc;/* lock descriptor */ - struct lustre_handle lock_handle[LDLM_LOCKREQ_HANDLES]; + struct ldlm_lock_desc lock_desc; /* lock descriptor */ + struct lustre_handle lock_handle[]; /* was LDLM_LOCKREQ_HANDLES */ }; struct ldlm_reply { @@ -3270,7 +3270,7 @@ struct lu_idxpage { * - the record size (II_FL_VARREC is set) * * For the time being, we only support fixed-size key & record. */ - char lip_entries[0]; + char lip_entries[]; }; #define LIP_HDR_SIZE (offsetof(struct lu_idxpage, lip_entries)) @@ -3435,7 +3435,7 @@ struct object_update_param { __u16 oup_len; /* length of this parameter */ __u16 oup_padding; __u32 oup_padding2; - char oup_buf[0]; + char oup_buf[]; } __attribute__((packed)); /* object update */ @@ -3447,7 +3447,7 @@ struct object_update { __u32 ou_padding1; /* padding 1 */ __u64 ou_batchid; /* op transno on master */ struct lu_fid ou_fid; /* object to be updated */ - struct object_update_param ou_params[0]; /* update params */ + struct object_update_param ou_params[]; /* update params */ }; #define UPDATE_REQUEST_MAGIC_V1 0xBDDE0001 @@ -3458,7 +3458,7 @@ struct object_update_request { __u32 ourq_magic; __u16 ourq_count; /* number of ourq_updates[] */ __u16 ourq_padding; - struct object_update ourq_updates[0]; + struct object_update ourq_updates[]; }; #define OUT_UPDATE_HEADER_MAGIC 0xBDDF0001 @@ -3469,7 +3469,7 @@ struct out_update_header { __u32 ouh_count; __u32 ouh_inline_length; __u32 ouh_reply_size; - __u32 ouh_inline_data[0]; + __u32 ouh_inline_data[]; }; struct out_update_buffer { @@ -3482,7 +3482,7 @@ struct object_update_result { __u32 our_rc; __u16 our_datalen; __u16 our_padding; - __u32 our_data[0]; + __u32 our_data[]; }; #define UPDATE_REPLY_MAGIC_V1 0x00BD0001 @@ -3493,7 +3493,7 @@ struct object_update_reply { __u32 ourp_magic; __u16 ourp_count; __u16 ourp_padding; - __u16 ourp_lens[0]; + __u16 ourp_lens[]; }; /* read update result */ @@ -3501,7 +3501,7 @@ struct out_read_reply { __u32 orr_size; __u32 orr_padding; __u64 orr_offset; - char orr_data[0]; + char orr_data[]; }; /** layout swap request structure diff --git a/lustre/include/uapi/linux/lustre/lustre_ioctl.h b/lustre/include/uapi/linux/lustre/lustre_ioctl.h index 4a70e11..3aac087 100644 --- a/lustre/include/uapi/linux/lustre/lustre_ioctl.h +++ b/lustre/include/uapi/linux/lustre/lustre_ioctl.h @@ -103,7 +103,7 @@ struct obd_ioctl_data { __u32 ioc_inllen4; char *ioc_inlbuf4; - char ioc_bulk[0]; + char ioc_bulk[]; }; struct obd_ioctl_hdr { diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 7c807e2..2b113fa 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -982,7 +982,7 @@ struct lov_comp_md_v1 { __u16 lcm_mirror_count; __u16 lcm_padding1[3]; __u64 lcm_padding2; - struct lov_comp_md_entry_v1 lcm_entries[0]; + struct lov_comp_md_entry_v1 lcm_entries[]; } __attribute__((packed)); static inline __u32 lov_user_md_size(__u16 stripes, __u32 lmm_magic) @@ -2467,7 +2467,7 @@ struct hsm_action_list { __u64 hal_flags; __u32 hal_archive_id; /* which archive backend */ __u32 padding1; - char hal_fsname[0]; /* null-terminated */ + char hal_fsname[]; /* null-terminated */ /* struct hsm_action_item[hal_count] follows, aligned on 8-byte boundaries. See hai_zero */ } __attribute__((packed)); diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index caba0cc..3c8698e 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -1698,9 +1698,8 @@ int ldlm_request_cancel(struct ptlrpc_request *req, ENTRY; size = req_capsule_get_size(&req->rq_pill, &RMF_DLM_REQ, RCL_CLIENT); - if (size <= offsetof(struct ldlm_request, lock_handle) || - (size - offsetof(struct ldlm_request, lock_handle)) / - sizeof(struct lustre_handle) < dlm_req->lock_count) + if (size <= sizeof(*dlm_req) || dlm_req->lock_count > + (size - sizeof(*dlm_req)) / sizeof(struct lustre_handle)) RETURN(0); count = dlm_req->lock_count ? dlm_req->lock_count : 1; diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 8b34923..26bdf93 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -88,24 +88,21 @@ struct ldlm_async_args { * LDLM_LOCKREQ_HANDLE -1 slots are available. * Otherwise, LDLM_LOCKREQ_HANDLE slots are available. * - * \param[in] count - * \param[in] type + * \param[in] count - total number of lock handles to include for cancel + * \param[in] type - LDLM RPC request type * * \retval size of the request buffer */ int ldlm_request_bufsize(int count, int type) { - int avail = LDLM_LOCKREQ_HANDLES; - if (type == LDLM_ENQUEUE) - avail -= LDLM_ENQUEUE_CANCEL_OFF; + count++; - if (count > avail) - avail = (count - avail) * sizeof(struct lustre_handle); - else - avail = 0; + /* keep minimum handles to keep struct size for compatibility */ + if (count < LDLM_LOCKREQ_HANDLES) + count = LDLM_LOCKREQ_HANDLES; - return sizeof(struct ldlm_request) + avail; + return offsetof(struct ldlm_request, lock_handle[count]); } void ldlm_expired_completion_wait(struct lock_wait_data *lwd) diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h index 8e048e7..eb5fe7b 100644 --- a/lustre/lfsck/lfsck_internal.h +++ b/lustre/lfsck/lfsck_internal.h @@ -788,7 +788,7 @@ struct lfsck_namespace_req { __u32 lnr_size; __u16 lnr_type; __u16 lnr_namelen; - char lnr_name[0]; + char lnr_name[]; }; struct lfsck_layout_req { diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 39df17e..70a2d3f 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -208,23 +208,25 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, { struct config_llog_data *cld; int rc; + int logname_size; ENTRY; CDEBUG(D_MGC, "do adding config log %s-%016lx\n", logname, cfg ? cfg->cfg_instance : 0); - OBD_ALLOC(cld, sizeof(*cld) + strlen(logname) + 1); + logname_size = strlen(logname) + 1; + OBD_ALLOC(cld, sizeof(*cld) + logname_size); if (!cld) RETURN(ERR_PTR(-ENOMEM)); rc = mgc_logname2resid(logname, &cld->cld_resid, type); if (rc) { - OBD_FREE(cld, sizeof(*cld) + strlen(cld->cld_logname) + 1); + OBD_FREE(cld, sizeof(*cld) + logname_size); RETURN(ERR_PTR(rc)); } - strcpy(cld->cld_logname, logname); + strscpy(cld->cld_logname, logname, logname_size); if (cfg) cld->cld_cfg = *cfg; else diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index ddd7fe6..6f7d891 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -51,11 +51,7 @@ #include #include "llog_internal.h" -#ifdef CONFIG_PROC_FS static __u64 obd_max_alloc; -#else -__u64 obd_max_alloc; -#endif static DEFINE_SPINLOCK(obd_updatemax_lock); @@ -95,19 +91,15 @@ EXPORT_SYMBOL(at_early_margin); int at_extra = 30; EXPORT_SYMBOL(at_extra); -#ifdef CONFIG_PROC_FS -struct lprocfs_stats *obd_memory = NULL; +struct percpu_counter obd_memory; EXPORT_SYMBOL(obd_memory); -#endif static int obdclass_oom_handler(struct notifier_block *self, unsigned long notused, void *nfreed) { -#ifdef CONFIG_PROC_FS /* in bytes */ pr_info("obd_memory max: %llu, obd_memory current: %llu\n", obd_memory_max(), obd_memory_sum()); -#endif /* CONFIG_PROC_FS */ return NOTIFY_OK; } @@ -338,13 +330,14 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) case OBD_GET_VERSION: { static bool warned; + size_t vstr_size = sizeof(LUSTRE_VERSION_STRING); if (!data->ioc_inlbuf1) { CERROR("No buffer passed in ioctl\n"); GOTO(out, err = -EINVAL); } - if (strlen(LUSTRE_VERSION_STRING) + 1 > data->ioc_inllen1) { + if (vstr_size > data->ioc_inllen1) { CERROR("ioctl buffer too small to hold version\n"); GOTO(out, err = -EINVAL); } @@ -355,8 +348,8 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) "use llapi_get_version_string() and/or relink\n", current->comm); } - memcpy(data->ioc_bulk, LUSTRE_VERSION_STRING, - strlen(LUSTRE_VERSION_STRING) + 1); + + strscpy(data->ioc_bulk, LUSTRE_VERSION_STRING, vstr_size); if (copy_to_user((void __user *)arg, data, len)) err = -EFAULT; @@ -684,19 +677,13 @@ static int __init obdclass_init(void) if (err) return err; -#ifdef CONFIG_PROC_FS - obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM, - LPROCFS_STATS_FLAG_NONE | - LPROCFS_STATS_FLAG_IRQ_SAFE); - if (obd_memory == NULL) { - CERROR("kmalloc of 'obd_memory' failed\n"); - return -ENOMEM; + err = percpu_counter_init(&obd_memory, 0, GFP_KERNEL); + if (err < 0) { + CERROR("obdclass: initializing 'obd_memory' failed: rc = %d\n", + err); + return err; } - lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT, - LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_BYTES, - "memused"); -#endif err = obd_zombie_impexp_init(); if (err) goto cleanup_obd_memory; @@ -707,7 +694,7 @@ static int __init obdclass_init(void) err = misc_register(&obd_psdev); if (err) { - CERROR("cannot register OBD miscdevice: err = %d\n", err); + CERROR("cannot register OBD miscdevice: rc = %d\n", err); goto cleanup_class_handle; } @@ -804,9 +791,7 @@ cleanup_zombie_impexp: obd_zombie_impexp_stop(); cleanup_obd_memory: -#ifdef CONFIG_PROC_FS - lprocfs_free_stats(&obd_memory); -#endif + percpu_counter_destroy(&obd_memory); unregister_oom_notifier(&obdclass_oom); return err; @@ -825,7 +810,6 @@ void obd_update_maxusage(void) } EXPORT_SYMBOL(obd_update_maxusage); -#ifdef CONFIG_PROC_FS __u64 obd_memory_max(void) { __u64 ret; @@ -837,14 +821,12 @@ __u64 obd_memory_max(void) return ret; } -#endif /* CONFIG_PROC_FS */ +EXPORT_SYMBOL(obd_memory_max); static void __exit obdclass_exit(void) { -#ifdef CONFIG_PROC_FS __u64 memory_leaked; __u64 memory_max; -#endif /* CONFIG_PROC_FS */ ENTRY; misc_deregister(&obd_psdev); @@ -865,16 +847,14 @@ static void __exit obdclass_exit(void) class_del_uuid(NULL); /* Delete all UUIDs. */ obd_zombie_impexp_stop(); -#ifdef CONFIG_PROC_FS memory_leaked = obd_memory_sum(); memory_max = obd_memory_max(); - lprocfs_free_stats(&obd_memory); + percpu_counter_destroy(&obd_memory); /* the below message is checked in test-framework.sh check_mem_leak() */ CDEBUG((memory_leaked) ? D_ERROR : D_INFO, "obd_memory max: %llu, leaked: %llu\n", memory_max, memory_leaked); -#endif /* CONFIG_PROC_FS */ unregister_oom_notifier(&obdclass_oom); diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c index b7059fb..3b87d35 100644 --- a/lustre/obdclass/dt_object.c +++ b/lustre/obdclass/dt_object.c @@ -698,7 +698,7 @@ static int dt_index_page_build(const struct lu_env *env, union lu_page *lp, { struct idx_info *ii = (struct idx_info *)arg; struct lu_idxpage *lip = &lp->lp_idx; - char *entry; + void *entry; __u64 hash; __u16 hashsize = 0; __u16 keysize = 0; diff --git a/lustre/obdclass/lprocfs_counters.c b/lustre/obdclass/lprocfs_counters.c index 521e59c..9cf47d2 100644 --- a/lustre/obdclass/lprocfs_counters.c +++ b/lustre/obdclass/lprocfs_counters.c @@ -69,16 +69,8 @@ void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount) * as memory allocation could trigger memory shrinker call * ldlm_pool_shrink(), which calls lprocfs_counter_add(). * LU-1727. - * - * Only obd_memory uses LPROCFS_STATS_FLAG_IRQ_SAFE - * flag, because it needs accurate counting lest memory leak - * check reports error. */ - if (in_interrupt() && - (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - percpu_cntr->lc_sum_irq += amount; - else - percpu_cntr->lc_sum += amount; + percpu_cntr->lc_sum += amount; if (header->lc_config & LPROCFS_CNTR_STDDEV) percpu_cntr->lc_sumsquare += (__s64)amount * amount; @@ -119,16 +111,8 @@ void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, long amount) * softirq context - right now that's the only case we're in * softirq context here, use separate counter for that. * bz20650. - * - * Only obd_memory uses LPROCFS_STATS_FLAG_IRQ_SAFE - * flag, because it needs accurate counting lest memory leak - * check reports error. */ - if (in_interrupt() && - (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - percpu_cntr->lc_sum_irq -= amount; - else - percpu_cntr->lc_sum -= amount; + percpu_cntr->lc_sum -= amount; } lprocfs_stats_unlock(stats, LPROCFS_GET_SMP_ID, &flags); } diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 0176888..7911d48 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -441,10 +441,7 @@ int lprocfs_stats_lock(struct lprocfs_stats *stats, unsigned long *flags) { if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { - if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) - spin_lock_irqsave(&stats->ls_lock, *flags); - else - spin_lock(&stats->ls_lock); + spin_lock(&stats->ls_lock); return opc == LPROCFS_GET_NUM_CPU ? 1 : 0; } @@ -487,10 +484,7 @@ void lprocfs_stats_unlock(struct lprocfs_stats *stats, unsigned long *flags) { if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { - if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) - spin_unlock_irqrestore(&stats->ls_lock, *flags); - else - spin_unlock(&stats->ls_lock); + spin_unlock(&stats->ls_lock); } else if (opc == LPROCFS_GET_SMP_ID) { put_cpu(); } @@ -1163,7 +1157,6 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid) struct lprocfs_counter *cntr; unsigned int percpusize; int rc = -ENOMEM; - unsigned long flags = 0; int i; LASSERT(stats->ls_percpu[cpuid] == NULL); @@ -1174,17 +1167,10 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid) if (stats->ls_percpu[cpuid]) { rc = 0; if (unlikely(stats->ls_biggest_alloc_num <= cpuid)) { - if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) - spin_lock_irqsave(&stats->ls_lock, flags); - else - spin_lock(&stats->ls_lock); + spin_lock(&stats->ls_lock); if (stats->ls_biggest_alloc_num <= cpuid) stats->ls_biggest_alloc_num = cpuid + 1; - if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { - spin_unlock_irqrestore(&stats->ls_lock, flags); - } else { - spin_unlock(&stats->ls_lock); - } + spin_unlock(&stats->ls_lock); } /* initialize the ls_percpu[cpuid] non-zero counter */ for (i = 0; i < stats->ls_num; ++i) { @@ -1201,7 +1187,6 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, struct lprocfs_stats *stats; unsigned int num_entry; unsigned int percpusize = 0; - int i; if (num == 0) return NULL; @@ -1236,11 +1221,6 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, if (!stats->ls_percpu[0]) goto fail; stats->ls_biggest_alloc_num = 1; - } else if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) { - /* alloc all percpu data, currently only obd_memory use this */ - for (i = 0; i < num_entry; ++i) - if (lprocfs_stats_alloc_one(stats, i) < 0) - goto fail; } return stats; @@ -1323,8 +1303,6 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats) percpu_cntr->lc_max = 0; percpu_cntr->lc_sumsquare = 0; percpu_cntr->lc_sum = 0; - if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) - percpu_cntr->lc_sum_irq = 0; } } stats->ls_init = ktime_get_real(); @@ -1539,8 +1517,6 @@ void lprocfs_counter_init_units(struct lprocfs_stats *stats, int index, percpu_cntr->lc_max = 0; percpu_cntr->lc_sumsquare = 0; percpu_cntr->lc_sum = 0; - if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - percpu_cntr->lc_sum_irq = 0; } lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } @@ -1662,8 +1638,6 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc, break; case LPROCFS_FIELDS_FLAGS_SUM: ret = lc->lc_sum; - if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) - ret += lc->lc_sum_irq; break; case LPROCFS_FIELDS_FLAGS_MIN: ret = lc->lc_min; @@ -1672,9 +1646,7 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc, ret = lc->lc_max; break; case LPROCFS_FIELDS_FLAGS_AVG: - ret = div64_u64((flags & LPROCFS_STATS_FLAG_IRQ_SAFE ? - lc->lc_sum_irq : 0) + lc->lc_sum, - lc->lc_count); + ret = div64_u64(lc->lc_sum, lc->lc_count); break; case LPROCFS_FIELDS_FLAGS_SUMSQUARE: ret = lc->lc_sumsquare; diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 973c422..c8783f6 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -1102,7 +1102,8 @@ EXPORT_SYMBOL(RMF_CONNECT_DATA); struct req_msg_field RMF_DLM_REQ = DEFINE_MSGF("dlm_req", RMF_F_NO_SIZE_CHECK /* ldlm_request_bufsize */, - sizeof(struct ldlm_request), + offsetof(struct ldlm_request, + lock_handle[LDLM_LOCKREQ_HANDLES]), lustre_swab_ldlm_request, NULL); EXPORT_SYMBOL(RMF_DLM_REQ); diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 7c3168a..59d735b 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -1868,10 +1868,11 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct lov_comp_md_v1, lcm_padding2)); LASSERTF((int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_padding2) == 8, "found %lld\n", (long long)(int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_padding2)); - LASSERTF((int)offsetof(struct lov_comp_md_v1, lcm_entries[0]) == 32, "found %lld\n", - (long long)(int)offsetof(struct lov_comp_md_v1, lcm_entries[0])); - LASSERTF((int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_entries[0]) == 48, "found %lld\n", - (long long)(int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_entries[0])); + LASSERTF((int)offsetof(struct lov_comp_md_v1, lcm_entries) == 32, "found %lld\n", + (long long)(int)offsetof(struct lov_comp_md_v1, lcm_entries)); + LASSERTF((int)sizeof(*((struct lov_comp_md_v1 *)0)->lcm_entries) == 48, "found %lld\n", + (long long)(int)sizeof(*((struct lov_comp_md_v1 *)0)->lcm_entries)); + BUILD_BUG_ON(offsetof(struct lov_comp_md_v1, lcm_entries) != sizeof(struct lov_comp_md_v1)); BUILD_BUG_ON(LOV_MAGIC_COMP_V1 != (0x0BD60000 | 0x0BD0)); LASSERTF(LCM_FL_NONE == 0, "found %lld\n", (long long)LCM_FL_NONE); @@ -3679,7 +3680,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct ldlm_lock_desc *)0)->l_policy_data)); /* Checks for struct ldlm_request */ - LASSERTF((int)sizeof(struct ldlm_request) == 104, "found %lld\n", + LASSERTF((int)sizeof(struct ldlm_request) == 88, "found %lld\n", (long long)(int)sizeof(struct ldlm_request)); LASSERTF((int)offsetof(struct ldlm_request, lock_flags) == 0, "found %lld\n", (long long)(int)offsetof(struct ldlm_request, lock_flags)); @@ -3695,8 +3696,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct ldlm_request *)0)->lock_desc)); LASSERTF((int)offsetof(struct ldlm_request, lock_handle) == 88, "found %lld\n", (long long)(int)offsetof(struct ldlm_request, lock_handle)); - LASSERTF((int)sizeof(((struct ldlm_request *)0)->lock_handle) == 16, "found %lld\n", - (long long)(int)sizeof(((struct ldlm_request *)0)->lock_handle)); + LASSERTF((int)sizeof(*((struct ldlm_request *)0)->lock_handle) == 8, "found %lld\n", + (long long)(int)sizeof(*((struct ldlm_request *)0)->lock_handle)); + BUILD_BUG_ON(offsetof(struct ldlm_request, lock_handle) != sizeof(struct ldlm_request)); /* Checks for struct ldlm_reply */ LASSERTF((int)sizeof(struct ldlm_reply) == 112, "found %lld\n", @@ -4719,8 +4721,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct fiemap *)0)->fm_reserved)); LASSERTF((int)offsetof(struct fiemap, fm_extents) == 32, "found %lld\n", (long long)(int)offsetof(struct fiemap, fm_extents)); - LASSERTF((int)sizeof(((struct fiemap *)0)->fm_extents) == 0, "found %lld\n", - (long long)(int)sizeof(((struct fiemap *)0)->fm_extents)); + LASSERTF((int)sizeof(*((struct fiemap *)0)->fm_extents) == 56, "found %lld\n", + (long long)(int)sizeof(*((struct fiemap *)0)->fm_extents)); + BUILD_BUG_ON(offsetof(struct fiemap, fm_extents) != sizeof(struct fiemap)); BUILD_BUG_ON(FIEMAP_FLAG_SYNC != 0x00000001); BUILD_BUG_ON(FIEMAP_FLAG_XATTR != 0x00000002); BUILD_BUG_ON(FIEMAP_FLAG_DEVICE_ORDER != 0x40000000); @@ -4931,8 +4934,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct hsm_action_list *)0)->padding1)); LASSERTF((int)offsetof(struct hsm_action_list, hal_fsname) == 32, "found %lld\n", (long long)(int)offsetof(struct hsm_action_list, hal_fsname)); - LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_fsname) == 0, "found %lld\n", - (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_fsname)); + LASSERTF((int)sizeof(*((struct hsm_action_list *)0)->hal_fsname) == 1, "found %lld\n", + (long long)(int)sizeof(*((struct hsm_action_list *)0)->hal_fsname)); + BUILD_BUG_ON(offsetof(struct hsm_action_list, hal_fsname) != sizeof(struct hsm_action_list)); /* Checks for struct hsm_progress */ LASSERTF((int)sizeof(struct hsm_progress) == 48, "found %lld\n", @@ -5399,8 +5403,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_param *)0)->oup_padding2)); LASSERTF((int)offsetof(struct object_update_param, oup_buf) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_param, oup_buf)); - LASSERTF((int)sizeof(((struct object_update_param *)0)->oup_buf) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_param *)0)->oup_buf)); + LASSERTF((int)sizeof(*((struct object_update_param *)0)->oup_buf) == 1, "found %lld\n", + (long long)(int)sizeof(*((struct object_update_param *)0)->oup_buf)); + BUILD_BUG_ON(offsetof(struct object_update_param, oup_buf) != sizeof(struct object_update_param)); /* Checks for struct object_update */ LASSERTF((int)sizeof(struct object_update) == 40, "found %lld\n", @@ -5435,8 +5440,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update *)0)->ou_fid)); LASSERTF((int)offsetof(struct object_update, ou_params) == 40, "found %lld\n", (long long)(int)offsetof(struct object_update, ou_params)); - LASSERTF((int)sizeof(((struct object_update *)0)->ou_params) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update *)0)->ou_params)); + LASSERTF((int)sizeof(*((struct object_update *)0)->ou_params) == 8, "found %lld\n", + (long long)(int)sizeof(*((struct object_update *)0)->ou_params)); + BUILD_BUG_ON(offsetof(struct object_update, ou_params) != sizeof(struct object_update)); BUILD_BUG_ON(UPDATE_FL_OST != 0x00000001); BUILD_BUG_ON(UPDATE_FL_SYNC != 0x00000002); BUILD_BUG_ON(UPDATE_FL_COMMITTED != 0x00000004); @@ -5459,8 +5465,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_request *)0)->ourq_padding)); LASSERTF((int)offsetof(struct object_update_request, ourq_updates) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_request, ourq_updates)); - LASSERTF((int)sizeof(((struct object_update_request *)0)->ourq_updates) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_request *)0)->ourq_updates)); + LASSERTF((int)sizeof(*((struct object_update_request *)0)->ourq_updates) == 40, "found %lld\n", + (long long)(int)sizeof(*((struct object_update_request *)0)->ourq_updates)); + BUILD_BUG_ON(offsetof(struct object_update_request, ourq_updates) != sizeof(struct object_update_request)); BUILD_BUG_ON(UPDATE_REQUEST_MAGIC != 0xBDDE0002); /* Checks for struct object_update_result */ @@ -5480,8 +5487,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_result *)0)->our_padding)); LASSERTF((int)offsetof(struct object_update_result, our_data) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_result, our_data)); - LASSERTF((int)sizeof(((struct object_update_result *)0)->our_data) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_result *)0)->our_data)); + LASSERTF((int)sizeof(*((struct object_update_result *)0)->our_data) == 4, "found %lld\n", + (long long)(int)sizeof(*((struct object_update_result *)0)->our_data)); + BUILD_BUG_ON(offsetof(struct object_update_result, our_data) != sizeof(struct object_update_result)); /* Checks for struct object_update_reply */ LASSERTF((int)sizeof(struct object_update_reply) == 8, "found %lld\n", @@ -5500,8 +5508,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_reply *)0)->ourp_padding)); LASSERTF((int)offsetof(struct object_update_reply, ourp_lens) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_reply, ourp_lens)); - LASSERTF((int)sizeof(((struct object_update_reply *)0)->ourp_lens) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_reply *)0)->ourp_lens)); + LASSERTF((int)sizeof(*((struct object_update_reply *)0)->ourp_lens) == 2, "found %lld\n", + (long long)(int)sizeof(*((struct object_update_reply *)0)->ourp_lens)); + BUILD_BUG_ON(offsetof(struct object_update_reply, ourp_lens) != sizeof(struct object_update_reply)); BUILD_BUG_ON(UPDATE_REPLY_MAGIC != 0x00BD0002); /* Checks for struct out_update_header */ @@ -5525,8 +5534,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct out_update_header *)0)->ouh_reply_size)); LASSERTF((int)offsetof(struct out_update_header, ouh_inline_data) == 16, "found %lld\n", (long long)(int)offsetof(struct out_update_header, ouh_inline_data)); - LASSERTF((int)sizeof(((struct out_update_header *)0)->ouh_inline_data) == 0, "found %lld\n", - (long long)(int)sizeof(((struct out_update_header *)0)->ouh_inline_data)); + LASSERTF((int)sizeof(*((struct out_update_header *)0)->ouh_inline_data) == 4, "found %lld\n", + (long long)(int)sizeof(*((struct out_update_header *)0)->ouh_inline_data)); + BUILD_BUG_ON(offsetof(struct out_update_header, ouh_inline_data) != sizeof(struct out_update_header)); BUILD_BUG_ON(OUT_UPDATE_HEADER_MAGIC != 0xBDDF0001); BUILD_BUG_ON(OUT_UPDATE_MAX_INLINE_SIZE != 4096); diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index b62cbff..d0dc90c 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -57,6 +57,9 @@ do { \ #define STRINGIFY(a) #a +#define CHECK_BUILD_TEST(a) \ + printf(" BUILD_BUG_ON("#a");\n") + #define CHECK_CDEFINE(a) \ printf(" BUILD_BUG_ON("#a" != "STRINGIFY(a) ");\n") @@ -137,12 +140,24 @@ do { \ CHECK_VALUE((int)sizeof(((struct s *)0)->m)); \ } while(0) +#define CHECK_MEMBER_SIZEOF_ARRAY_ELEMENT(s, m) \ +do { \ + CHECK_VALUE((int)sizeof(*((struct s *)0)->m)); \ +} while(0) + #define CHECK_MEMBER_SIZEOF_TYPEDEF(s, m) \ do { \ CHECK_VALUE((int)sizeof(((s *)0)->m)); \ } while(0) -#define CHECK_MEMBER_IS_FLEXIBLE(s, m) \ +#define CHECK_MEMBER_IS_FLEXIBLE(s, m) \ +do { \ + CHECK_MEMBER_OFFSET(s, m); \ + CHECK_MEMBER_SIZEOF_ARRAY_ELEMENT(s, m); \ + CHECK_BUILD_TEST(offsetof(struct s, m) != sizeof(struct s)); \ +} while (0) + +#define CHECK_MEMBER_IS_FLEXIBLE_OR_ZERO_LENGTH(s, m) \ do { \ CHECK_MEMBER_OFFSET(s, m); \ CHECK_BUILD_TEST(offsetof(struct s, m) != sizeof(struct s)); \ @@ -877,7 +892,7 @@ check_lov_comp_md_v1(void) CHECK_MEMBER(lov_comp_md_v1, lcm_mirror_count); CHECK_MEMBER(lov_comp_md_v1, lcm_padding1); CHECK_MEMBER(lov_comp_md_v1, lcm_padding2); - CHECK_MEMBER(lov_comp_md_v1, lcm_entries[0]); + CHECK_MEMBER_IS_FLEXIBLE(lov_comp_md_v1, lcm_entries); CHECK_CDEFINE(LOV_MAGIC_COMP_V1); @@ -1630,7 +1645,7 @@ check_ldlm_request(void) CHECK_MEMBER(ldlm_request, lock_flags); CHECK_MEMBER(ldlm_request, lock_count); CHECK_MEMBER(ldlm_request, lock_desc); - CHECK_MEMBER(ldlm_request, lock_handle); + CHECK_MEMBER_IS_FLEXIBLE(ldlm_request, lock_handle); } static void @@ -2331,7 +2346,7 @@ check_hsm_action_list(void) CHECK_MEMBER(hsm_action_list, hal_flags); CHECK_MEMBER(hsm_action_list, hal_archive_id); CHECK_MEMBER(hsm_action_list, padding1); - CHECK_MEMBER(hsm_action_list, hal_fsname); + CHECK_MEMBER_IS_FLEXIBLE(hsm_action_list, hal_fsname); } static void @@ -2549,7 +2564,7 @@ static void check_object_update_param(void) CHECK_MEMBER(object_update_param, oup_len); CHECK_MEMBER(object_update_param, oup_padding); CHECK_MEMBER(object_update_param, oup_padding2); - CHECK_MEMBER(object_update_param, oup_buf); + CHECK_MEMBER_IS_FLEXIBLE(object_update_param, oup_buf); } static void check_object_update(void) @@ -2563,7 +2578,7 @@ static void check_object_update(void) CHECK_MEMBER(object_update, ou_padding1); CHECK_MEMBER(object_update, ou_batchid); CHECK_MEMBER(object_update, ou_fid); - CHECK_MEMBER(object_update, ou_params); + CHECK_MEMBER_IS_FLEXIBLE(object_update, ou_params); CHECK_CVALUE_X(UPDATE_FL_OST); CHECK_CVALUE_X(UPDATE_FL_SYNC); @@ -2578,7 +2593,7 @@ static void check_object_update_request(void) CHECK_MEMBER(object_update_request, ourq_magic); CHECK_MEMBER(object_update_request, ourq_count); CHECK_MEMBER(object_update_request, ourq_padding); - CHECK_MEMBER(object_update_request, ourq_updates); + CHECK_MEMBER_IS_FLEXIBLE(object_update_request, ourq_updates); CHECK_CDEFINE(UPDATE_REQUEST_MAGIC); } @@ -2590,7 +2605,7 @@ static void check_object_update_result(void) CHECK_MEMBER(object_update_result, our_rc); CHECK_MEMBER(object_update_result, our_datalen); CHECK_MEMBER(object_update_result, our_padding); - CHECK_MEMBER(object_update_result, our_data); + CHECK_MEMBER_IS_FLEXIBLE(object_update_result, our_data); } static void check_object_update_reply(void) @@ -2600,7 +2615,7 @@ static void check_object_update_reply(void) CHECK_MEMBER(object_update_reply, ourp_magic); CHECK_MEMBER(object_update_reply, ourp_count); CHECK_MEMBER(object_update_reply, ourp_padding); - CHECK_MEMBER(object_update_reply, ourp_lens); + CHECK_MEMBER_IS_FLEXIBLE(object_update_reply, ourp_lens); CHECK_CDEFINE(UPDATE_REPLY_MAGIC); } @@ -2613,7 +2628,7 @@ static void check_out_update_header(void) CHECK_MEMBER(out_update_header, ouh_count); CHECK_MEMBER(out_update_header, ouh_inline_length); CHECK_MEMBER(out_update_header, ouh_reply_size); - CHECK_MEMBER(out_update_header, ouh_inline_data); + CHECK_MEMBER_IS_FLEXIBLE(out_update_header, ouh_inline_data); CHECK_CDEFINE(OUT_UPDATE_HEADER_MAGIC); CHECK_CDEFINE(OUT_UPDATE_MAX_INLINE_SIZE); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index f47ed7b..5ed25b1 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -1618,7 +1618,7 @@ void lustre_assert_wire_constants(void) OBD_MD_FLGID); LASSERTF(OBD_MD_FLFLAGS == (0x00000800ULL), "found 0x%.16llxULL\n", OBD_MD_FLFLAGS); - LASSERTF(OBD_MD_DOM_SIZE == (0x00001000ULL), "found 0x%.16llxULL\n", + LASSERTF(OBD_MD_DOM_SIZE == (0X00001000ULL), "found 0x%.16llxULL\n", OBD_MD_DOM_SIZE); LASSERTF(OBD_MD_FLNLINK == (0x00002000ULL), "found 0x%.16llxULL\n", OBD_MD_FLNLINK); @@ -1896,8 +1896,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_padding2)); LASSERTF((int)offsetof(struct lov_comp_md_v1, lcm_entries[0]) == 32, "found %lld\n", (long long)(int)offsetof(struct lov_comp_md_v1, lcm_entries[0])); - LASSERTF((int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_entries[0]) == 48, "found %lld\n", - (long long)(int)sizeof(((struct lov_comp_md_v1 *)0)->lcm_entries[0])); + BUILD_BUG_ON(offsetof(struct lov_comp_md_v1, lcm_entries) != sizeof(struct lov_comp_md_v1)); BUILD_BUG_ON(LOV_MAGIC_COMP_V1 != (0x0BD60000 | 0x0BD0)); LASSERTF(LCM_FL_NONE == 0, "found %lld\n", (long long)LCM_FL_NONE); @@ -3705,7 +3704,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct ldlm_lock_desc *)0)->l_policy_data)); /* Checks for struct ldlm_request */ - LASSERTF((int)sizeof(struct ldlm_request) == 104, "found %lld\n", + LASSERTF((int)sizeof(struct ldlm_request) == 88, "found %lld\n", (long long)(int)sizeof(struct ldlm_request)); LASSERTF((int)offsetof(struct ldlm_request, lock_flags) == 0, "found %lld\n", (long long)(int)offsetof(struct ldlm_request, lock_flags)); @@ -3721,8 +3720,9 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct ldlm_request *)0)->lock_desc)); LASSERTF((int)offsetof(struct ldlm_request, lock_handle) == 88, "found %lld\n", (long long)(int)offsetof(struct ldlm_request, lock_handle)); - LASSERTF((int)sizeof(((struct ldlm_request *)0)->lock_handle) == 16, "found %lld\n", - (long long)(int)sizeof(((struct ldlm_request *)0)->lock_handle)); + LASSERTF((int)sizeof(*((struct ldlm_request *)0)->lock_handle) == 8, "found %lld\n", + (long long)(int)sizeof(*((struct ldlm_request *)0)->lock_handle)); + BUILD_BUG_ON(offsetof(struct ldlm_request, lock_handle) != sizeof(struct ldlm_request)); /* Checks for struct ldlm_reply */ LASSERTF((int)sizeof(struct ldlm_reply) == 112, "found %lld\n", @@ -4745,8 +4745,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct fiemap *)0)->fm_reserved)); LASSERTF((int)offsetof(struct fiemap, fm_extents) == 32, "found %lld\n", (long long)(int)offsetof(struct fiemap, fm_extents)); - LASSERTF((int)sizeof(((struct fiemap *)0)->fm_extents) == 0, "found %lld\n", - (long long)(int)sizeof(((struct fiemap *)0)->fm_extents)); + BUILD_BUG_ON(offsetof(struct fiemap, fm_extents) != sizeof(struct fiemap)); BUILD_BUG_ON(FIEMAP_FLAG_SYNC != 0x00000001); BUILD_BUG_ON(FIEMAP_FLAG_XATTR != 0x00000002); BUILD_BUG_ON(FIEMAP_FLAG_DEVICE_ORDER != 0x40000000); @@ -4957,8 +4956,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct hsm_action_list *)0)->padding1)); LASSERTF((int)offsetof(struct hsm_action_list, hal_fsname) == 32, "found %lld\n", (long long)(int)offsetof(struct hsm_action_list, hal_fsname)); - LASSERTF((int)sizeof(((struct hsm_action_list *)0)->hal_fsname) == 0, "found %lld\n", - (long long)(int)sizeof(((struct hsm_action_list *)0)->hal_fsname)); + BUILD_BUG_ON(offsetof(struct hsm_action_list, hal_fsname) != sizeof(struct hsm_action_list)); /* Checks for struct hsm_progress */ LASSERTF((int)sizeof(struct hsm_progress) == 48, "found %lld\n", @@ -5425,8 +5423,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_param *)0)->oup_padding2)); LASSERTF((int)offsetof(struct object_update_param, oup_buf) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_param, oup_buf)); - LASSERTF((int)sizeof(((struct object_update_param *)0)->oup_buf) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_param *)0)->oup_buf)); + BUILD_BUG_ON(offsetof(struct object_update_param, oup_buf) != sizeof(struct object_update_param)); /* Checks for struct object_update */ LASSERTF((int)sizeof(struct object_update) == 40, "found %lld\n", @@ -5461,8 +5458,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update *)0)->ou_fid)); LASSERTF((int)offsetof(struct object_update, ou_params) == 40, "found %lld\n", (long long)(int)offsetof(struct object_update, ou_params)); - LASSERTF((int)sizeof(((struct object_update *)0)->ou_params) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update *)0)->ou_params)); + BUILD_BUG_ON(offsetof(struct object_update, ou_params) != sizeof(struct object_update)); BUILD_BUG_ON(UPDATE_FL_OST != 0x00000001); BUILD_BUG_ON(UPDATE_FL_SYNC != 0x00000002); BUILD_BUG_ON(UPDATE_FL_COMMITTED != 0x00000004); @@ -5485,8 +5481,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_request *)0)->ourq_padding)); LASSERTF((int)offsetof(struct object_update_request, ourq_updates) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_request, ourq_updates)); - LASSERTF((int)sizeof(((struct object_update_request *)0)->ourq_updates) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_request *)0)->ourq_updates)); + BUILD_BUG_ON(offsetof(struct object_update_request, ourq_updates) != sizeof(struct object_update_request)); BUILD_BUG_ON(UPDATE_REQUEST_MAGIC != 0xBDDE0002); /* Checks for struct object_update_result */ @@ -5506,8 +5501,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_result *)0)->our_padding)); LASSERTF((int)offsetof(struct object_update_result, our_data) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_result, our_data)); - LASSERTF((int)sizeof(((struct object_update_result *)0)->our_data) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_result *)0)->our_data)); + BUILD_BUG_ON(offsetof(struct object_update_result, our_data) != sizeof(struct object_update_result)); /* Checks for struct object_update_reply */ LASSERTF((int)sizeof(struct object_update_reply) == 8, "found %lld\n", @@ -5526,8 +5520,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct object_update_reply *)0)->ourp_padding)); LASSERTF((int)offsetof(struct object_update_reply, ourp_lens) == 8, "found %lld\n", (long long)(int)offsetof(struct object_update_reply, ourp_lens)); - LASSERTF((int)sizeof(((struct object_update_reply *)0)->ourp_lens) == 0, "found %lld\n", - (long long)(int)sizeof(((struct object_update_reply *)0)->ourp_lens)); + BUILD_BUG_ON(offsetof(struct object_update_reply, ourp_lens) != sizeof(struct object_update_reply)); BUILD_BUG_ON(UPDATE_REPLY_MAGIC != 0x00BD0002); /* Checks for struct out_update_header */ @@ -5551,8 +5544,7 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct out_update_header *)0)->ouh_reply_size)); LASSERTF((int)offsetof(struct out_update_header, ouh_inline_data) == 16, "found %lld\n", (long long)(int)offsetof(struct out_update_header, ouh_inline_data)); - LASSERTF((int)sizeof(((struct out_update_header *)0)->ouh_inline_data) == 0, "found %lld\n", - (long long)(int)sizeof(((struct out_update_header *)0)->ouh_inline_data)); + BUILD_BUG_ON(offsetof(struct out_update_header, ouh_inline_data) != sizeof(struct out_update_header)); BUILD_BUG_ON(OUT_UPDATE_HEADER_MAGIC != 0xBDDF0001); BUILD_BUG_ON(OUT_UPDATE_MAX_INLINE_SIZE != 4096); -- 1.8.3.1