diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 312d8bf4..d683cb71 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -518,3 +518,11 @@ endif ifneq (,$(shell grep 'struct posix_acl ...get_acl..struct mnt_idmap ., struct dentry' include/linux/fs.h)) ccflags-y += -DKC_GET_ACL_DENTRY endif + +# +# v5.1-rc3-29-gaa30f47cf666 +# +# struct kobj_type now has member `default_groups` +ifneq (,$(shell grep 'const struct attribute_group ..default_groups;' include/linux/kobject.h)) +ccflags-y += -DKC_KOBJECT_DEFAULT_GROUPS +endif diff --git a/kmod/src/counters.c b/kmod/src/counters.c index 5578ae26..f879cc83 100644 --- a/kmod/src/counters.c +++ b/kmod/src/counters.c @@ -24,31 +24,51 @@ * makes this a whole lot more noisy than it needs to be. */ +static ssize_t scoutfs_counter_attr_show(struct kobject *, struct kobj_attribute *, char *); + #undef EXPAND_COUNTER -#define EXPAND_COUNTER(which) { .name = __stringify(which), .mode = 0644 }, -static struct attribute scoutfs_counter_attrs[] = { +#define EXPAND_COUNTER(which) static struct kobj_attribute which##_attr = \ + __ATTR(which, 0444, scoutfs_counter_attr_show, NULL); +EXPAND_EACH_COUNTER + +#undef EXPAND_COUNTER +#define EXPAND_COUNTER(which) &which##_attr.attr, +static struct attribute *scoutfs_counter_attrs[] = { EXPAND_EACH_COUNTER + NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(scoutfs_counter); +#endif /* zero BSS and + 1 makes this null terminated */ #define NR_ATTRS ARRAY_SIZE(scoutfs_counter_attrs) -static struct attribute *scoutfs_counter_attr_ptrs[NR_ATTRS + 1]; -static ssize_t scoutfs_counter_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) +#ifndef KC_KOBJECT_DEFAULT_GROUPS +static struct attribute *scoutfs_counter_attr_ptrs[NR_ATTRS + 1]; +#endif + +static ssize_t scoutfs_counter_show(struct kobject *kobj, + struct attribute *attr, char *buf) { struct scoutfs_counters *counters; struct percpu_counter *pcpu; size_t index; - /* use the index in the _attrs array to discover the pcpu pointer */ counters = container_of(kobj, struct scoutfs_counters, kobj); - index = attr - scoutfs_counter_attrs; + index = scoutfs_counter_attrs[0] - attr; //WAT + index = index / 2; // sizeof(attr) / sizeof(pcpu) pcpu = &counters->FIRST_COUNTER + index; return snprintf(buf, PAGE_SIZE, "%lld\n", percpu_counter_sum(pcpu)); } +static ssize_t scoutfs_counter_attr_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scoutfs_counter_show(kobj, &attr->attr, buf); +} + static void scoutfs_counters_kobj_release(struct kobject *kobj) { struct scoutfs_counters *counters; @@ -59,11 +79,15 @@ static void scoutfs_counters_kobj_release(struct kobject *kobj) } static const struct sysfs_ops scoutfs_counter_attr_ops = { - .show = scoutfs_counter_attr_show, + .show = scoutfs_counter_show, }; static struct kobj_type scoutfs_counters_ktype = { +#ifdef KC_KOBJECT_DEFAULT_GROUPS + .default_groups = scoutfs_counter_groups, +#else .default_attrs = scoutfs_counter_attr_ptrs, +#endif .sysfs_ops = &scoutfs_counter_attr_ops, .release = scoutfs_counters_kobj_release, }; @@ -124,9 +148,11 @@ void scoutfs_destroy_counters(struct super_block *sb) void __init scoutfs_init_counters(void) { +#ifndef KC_KOBJECT_DEFAULT_GROUPS int i; /* not ARRAY_SIZE because that would clobber null term */ for (i = 0; i < NR_ATTRS; i++) - scoutfs_counter_attr_ptrs[i] = &scoutfs_counter_attrs[i]; + scoutfs_counter_attr_ptrs[i] = scoutfs_counter_attrs[i]; +#endif } diff --git a/kmod/src/fence.c b/kmod/src/fence.c index 3669dc2d..4139da8b 100644 --- a/kmod/src/fence.c +++ b/kmod/src/fence.c @@ -217,6 +217,9 @@ static struct attribute *fence_attrs[] = { SCOUTFS_ATTR_PTR(rid), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(fence); +#endif #define FENCE_TIMEOUT_MS (MSEC_PER_SEC * 30) @@ -255,7 +258,8 @@ int scoutfs_fence_start(struct super_block *sb, u64 rid, __be32 ipv4_addr, int r fence->rid = rid; ret = scoutfs_sysfs_create_attrs_parent(sb, &fi->kset->kobj, - &fence->ssa, fence_attrs, + &fence->ssa, + KC_KOBJ_DEFAULT(fence), "%016llx", rid); if (ret < 0) { kfree(fence); diff --git a/kmod/src/kernelcompat.h b/kmod/src/kernelcompat.h index 0fde3ef2..91d13fc9 100644 --- a/kmod/src/kernelcompat.h +++ b/kmod/src/kernelcompat.h @@ -562,4 +562,12 @@ static inline long inode_get_atime_nsec(const struct inode *inode) #define kc__assign_str(a, b) __assign_str(a) #endif +#ifdef KC_KOBJECT_DEFAULT_GROUPS +#define KC_KOBJ_DEFAULT_OP default_groups +#define KC_KOBJ_DEFAULT(name) name##_groups +#else +#define KC_KOBJ_DEFAULT_OP default_attrs +#define KC_KOBJ_DEFAULT(name) name##_attrs +#endif + #endif diff --git a/kmod/src/options.c b/kmod/src/options.c index 8ce78067..dd340543 100644 --- a/kmod/src/options.c +++ b/kmod/src/options.c @@ -599,13 +599,18 @@ static struct attribute *options_attrs[] = { SCOUTFS_ATTR_PTR(quorum_slot_nr), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(options); +#endif int scoutfs_options_setup(struct super_block *sb) { DECLARE_OPTIONS_INFO(sb, optinf); int ret; - ret = scoutfs_sysfs_create_attrs(sb, &optinf->sysfs_attrs, options_attrs, "mount_options"); + ret = scoutfs_sysfs_create_attrs(sb, &optinf->sysfs_attrs, + KC_KOBJ_DEFAULT(options), + "mount_options"); if (ret < 0) scoutfs_options_destroy(sb); return ret; diff --git a/kmod/src/quorum.c b/kmod/src/quorum.c index ee969bdb..a65d5011 100644 --- a/kmod/src/quorum.c +++ b/kmod/src/quorum.c @@ -1201,6 +1201,9 @@ static struct attribute *quorum_attrs[] = { SCOUTFS_ATTR_PTR(is_leader), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(quorum); +#endif static inline bool valid_ipv4_unicast(__be32 addr) { @@ -1361,7 +1364,8 @@ int scoutfs_quorum_setup(struct super_block *sb) if (ret < 0) goto out; - ret = scoutfs_sysfs_create_attrs(sb, &qinf->ssa, quorum_attrs, + ret = scoutfs_sysfs_create_attrs(sb, &qinf->ssa, + KC_KOBJ_DEFAULT(quorum), "quorum"); if (ret < 0) goto out; diff --git a/kmod/src/srch.c b/kmod/src/srch.c index d8b2ba35..5a7d7742 100644 --- a/kmod/src/srch.c +++ b/kmod/src/srch.c @@ -2356,6 +2356,9 @@ static struct attribute *srch_attrs[] = { SCOUTFS_ATTR_PTR(compact_delay_ms), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(srch); +#endif void scoutfs_srch_destroy(struct super_block *sb) { @@ -2397,7 +2400,9 @@ int scoutfs_srch_setup(struct super_block *sb) sbi->srch_info = srinf; - ret = scoutfs_sysfs_create_attrs(sb, &srinf->ssa, srch_attrs, "srch"); + ret = scoutfs_sysfs_create_attrs(sb, &srinf->ssa, + KC_KOBJ_DEFAULT(srch), + "srch"); if (ret < 0) goto out; diff --git a/kmod/src/sysfs.c b/kmod/src/sysfs.c index b3c7ddbf..3b7e176f 100644 --- a/kmod/src/sysfs.c +++ b/kmod/src/sysfs.c @@ -103,12 +103,11 @@ static ssize_t attr_funcs_show(struct kobject *kobj, struct attribute *attr, }; \ \ static struct kobj_type _name##_ktype = { \ - .default_attrs = _name##_attrs, \ + .KC_KOBJ_DEFAULT_OP = KC_KOBJ_DEFAULT(_name), \ .sysfs_ops = &_name##_sysfs_ops, \ .release = _name##_release, \ }; - static struct attribute *sb_id_attrs[] = { &data_device_maj_min_attr_funcs.attr, &format_version_attr_funcs.attr, @@ -116,6 +115,9 @@ static struct attribute *sb_id_attrs[] = { &rid_attr_funcs.attr, NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(sb_id); +#endif KTYPE(sb_id); struct kobject *scoutfs_sysfs_sb_dir(struct super_block *sb) @@ -155,7 +157,12 @@ void scoutfs_sysfs_init_attrs(struct super_block *sb, int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, struct kobject *parent, struct scoutfs_sysfs_attrs *ssa, - struct attribute **attrs, char *fmt, ...) +#ifdef KC_KOBJECT_DEFAULT_GROUPS + const struct attribute_group **groups, +#else + struct attribute **attrs, +#endif + char *fmt, ...) { va_list args; size_t name_len; @@ -168,7 +175,11 @@ int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, ssa->sb = sb; init_completion(&ssa->comp); +#ifdef KC_KOBJECT_DEFAULT_GROUPS + ssa->ktype.default_groups = groups; +#else ssa->ktype.default_attrs = attrs; +#endif ssa->ktype.sysfs_ops = &kobj_sysfs_ops; ssa->ktype.release = scoutfs_sysfs_release; diff --git a/kmod/src/sysfs.h b/kmod/src/sysfs.h index 70b85af8..5e323044 100644 --- a/kmod/src/sysfs.h +++ b/kmod/src/sysfs.h @@ -39,10 +39,15 @@ void scoutfs_sysfs_init_attrs(struct super_block *sb, int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, struct kobject *parent, struct scoutfs_sysfs_attrs *ssa, - struct attribute **attrs, char *fmt, ...); -#define scoutfs_sysfs_create_attrs(sb, ssa, attrs, fmt, args...) \ +#ifdef KC_KOBJECT_DEFAULT_GROUPS + const struct attribute_group **groups, +#else + struct attribute **attrs, +#endif + char *fmt, ...); +#define scoutfs_sysfs_create_attrs(sb, ssa, attrs_or_group, fmt, args...) \ scoutfs_sysfs_create_attrs_parent(sb, scoutfs_sysfs_sb_dir(sb), \ - ssa, attrs, fmt, ##args) + ssa, attrs_or_group, fmt, ##args) void scoutfs_sysfs_destroy_attrs(struct super_block *sb, struct scoutfs_sysfs_attrs *ssa); diff --git a/kmod/src/volopt.c b/kmod/src/volopt.c index 303d94b0..763e82a3 100644 --- a/kmod/src/volopt.c +++ b/kmod/src/volopt.c @@ -52,6 +52,15 @@ static struct volopt_nr_name { /* initialized by setup, pointer array is null terminated */ static struct kobj_attribute volopt_attrs[ARRAY_SIZE(volopt_table)]; static struct attribute *volopt_attr_ptrs[ARRAY_SIZE(volopt_table) + 1]; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +static const struct attribute_group volopt_group = { + .attrs = volopt_attr_ptrs, +}; +static const struct attribute_group *volopt_groups[] = { + &volopt_group, + NULL, +}; +#endif static void get_opt_data(struct kobj_attribute *attr, struct scoutfs_volume_options *volopt, u64 *bit, __le64 **opt) @@ -164,7 +173,9 @@ int scoutfs_volopt_setup(struct super_block *sb) BUILD_BUG_ON(ARRAY_SIZE(volopt_table) != ARRAY_SIZE(volopt_attr_ptrs) - 1); volopt_attr_ptrs[i] = NULL; - ret = scoutfs_sysfs_create_attrs(sb, &vinf->ssa, volopt_attr_ptrs, "volume_options"); + ret = scoutfs_sysfs_create_attrs(sb, &vinf->ssa, + KC_KOBJ_DEFAULT(volopt), + "volume_options"); if (ret < 0) goto out;