diff options
author | Greg Kroah-Hartman <greg@kroah.com> | 2004-12-21 23:48:48 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2004-12-21 23:48:48 -0800 |
commit | 65aef3c7d24ff1de1ca304455d0474ceb99ce56d (patch) | |
tree | 43999b69321ca6498eb08c249d5b5d453541e0ef /kernel | |
parent | cf5bd50cc6d3fc4c78d1ba6a800af699d084ae5d (diff) | |
parent | ac014fc32bf4c41a2aff3986a7058e1514c17671 (diff) | |
download | history-65aef3c7d24ff1de1ca304455d0474ceb99ce56d.tar.gz |
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/usb-2.6
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/ksysfs.c | 3 | ||||
-rw-r--r-- | kernel/module.c | 111 | ||||
-rw-r--r-- | kernel/params.c | 191 |
3 files changed, 107 insertions, 198 deletions
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 31f1a60df73372..1f064a63f8cfe7 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -30,7 +30,8 @@ static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page) KERNEL_ATTR_RO(hotplug_seqnum); #endif -static decl_subsys(kernel, NULL, NULL); +decl_subsys(kernel, NULL, NULL); +EXPORT_SYMBOL_GPL(kernel_subsys); static struct attribute * kernel_attrs[] = { #ifdef CONFIG_HOTPLUG diff --git a/kernel/module.c b/kernel/module.c index 0798443ce00279..6247bf4ab003b2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -651,7 +651,8 @@ void symbol_put_addr(void *addr) } EXPORT_SYMBOL_GPL(symbol_put_addr); -static ssize_t show_refcnt(struct module *mod, char *buffer) +static ssize_t show_refcnt(struct module_attribute *mattr, + struct module *mod, char *buffer) { /* sysfs holds a reference */ return sprintf(buffer, "%u\n", module_refcount(mod)-1); @@ -936,79 +937,71 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, * J. Corbet <corbet@lwn.net> */ #ifdef CONFIG_KALLSYMS -static void module_sect_attrs_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct module_sections, kobj)); -} - -static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr, - char *buf) +static ssize_t module_sect_show(struct module_attribute *mattr, + struct module *mod, char *buf) { struct module_sect_attr *sattr = - container_of(attr, struct module_sect_attr, attr); + container_of(mattr, struct module_sect_attr, mattr); return sprintf(buf, "0x%lx\n", sattr->address); } -static struct sysfs_ops module_sect_ops = { - .show = module_sect_show, -}; - -static struct kobj_type module_sect_ktype = { - .sysfs_ops = &module_sect_ops, - .release = module_sect_attrs_release, -}; - static void add_sect_attrs(struct module *mod, unsigned int nsect, char *secstrings, Elf_Shdr *sechdrs) { - unsigned int nloaded = 0, i; + unsigned int nloaded = 0, i, size[2]; + struct module_sect_attrs *sect_attrs; struct module_sect_attr *sattr; - - if (!mod->mkobj) - return; + struct attribute **gattr; /* Count loaded sections and allocate structures */ for (i = 0; i < nsect; i++) if (sechdrs[i].sh_flags & SHF_ALLOC) nloaded++; - mod->sect_attrs = kmalloc(sizeof(struct module_sections) + - nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL); - if (! mod->sect_attrs) + size[0] = ALIGN(sizeof(*sect_attrs) + + nloaded * sizeof(sect_attrs->attrs[0]), + sizeof(sect_attrs->grp.attrs[0])); + size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); + if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL))) return; - /* sections entry setup */ - memset(mod->sect_attrs, 0, sizeof(struct module_sections)); - if (kobject_set_name(&mod->sect_attrs->kobj, "sections")) - goto out; - mod->sect_attrs->kobj.parent = &mod->mkobj->kobj; - mod->sect_attrs->kobj.ktype = &module_sect_ktype; - if (kobject_register(&mod->sect_attrs->kobj)) - goto out; + /* Setup section attributes. */ + sect_attrs->grp.name = "sections"; + sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; - /* And the section attributes. */ - sattr = &mod->sect_attrs->attrs[0]; + sattr = §_attrs->attrs[0]; + gattr = §_attrs->grp.attrs[0]; for (i = 0; i < nsect; i++) { if (! (sechdrs[i].sh_flags & SHF_ALLOC)) continue; sattr->address = sechdrs[i].sh_addr; strlcpy(sattr->name, secstrings + sechdrs[i].sh_name, - MODULE_SECT_NAME_LEN); - sattr->attr.name = sattr->name; - sattr->attr.owner = mod; - sattr->attr.mode = S_IRUGO; - (void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr); - sattr++; + MODULE_SECT_NAME_LEN); + sattr->mattr.show = module_sect_show; + sattr->mattr.store = NULL; + sattr->mattr.attr.name = sattr->name; + sattr->mattr.attr.owner = mod; + sattr->mattr.attr.mode = S_IRUGO; + *(gattr++) = &(sattr++)->mattr.attr; } + *gattr = NULL; + + if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp)) + goto out; + + mod->sect_attrs = sect_attrs; return; out: - kfree(mod->sect_attrs); - mod->sect_attrs = NULL; + kfree(sect_attrs); } static void remove_sect_attrs(struct module *mod) { if (mod->sect_attrs) { - kobject_unregister(&mod->sect_attrs->kobj); + sysfs_remove_group(&mod->mkobj.kobj, + &mod->sect_attrs->grp); + /* We are positive that no one is using any sect attrs + * at this point. Deallocate immediately. */ + kfree(mod->sect_attrs); mod->sect_attrs = NULL; } } @@ -1029,11 +1022,11 @@ static inline void remove_sect_attrs(struct module *mod) #ifdef CONFIG_MODULE_UNLOAD static inline int module_add_refcnt_attr(struct module *mod) { - return sysfs_create_file(&mod->mkobj->kobj, &refcnt.attr); + return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr); } static void module_remove_refcnt_attr(struct module *mod) { - return sysfs_remove_file(&mod->mkobj->kobj, &refcnt.attr); + return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr); } #else static inline int module_add_refcnt_attr(struct module *mod) @@ -1052,17 +1045,13 @@ static int mod_sysfs_setup(struct module *mod, { int err; - mod->mkobj = kmalloc(sizeof(struct module_kobject), GFP_KERNEL); - if (!mod->mkobj) - return -ENOMEM; - - memset(&mod->mkobj->kobj, 0, sizeof(mod->mkobj->kobj)); - err = kobject_set_name(&mod->mkobj->kobj, "%s", mod->name); + memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); + err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name); if (err) goto out; - kobj_set_kset_s(mod->mkobj, module_subsys); - mod->mkobj->mod = mod; - err = kobject_register(&mod->mkobj->kobj); + kobj_set_kset_s(&mod->mkobj, module_subsys); + mod->mkobj.mod = mod; + err = kobject_register(&mod->mkobj.kobj); if (err) goto out; @@ -1077,11 +1066,8 @@ static int mod_sysfs_setup(struct module *mod, return 0; out_unreg: - /* Calls module_kobj_release */ - kobject_unregister(&mod->mkobj->kobj); - return err; + kobject_unregister(&mod->mkobj.kobj); out: - kfree(mod->mkobj); return err; } @@ -1090,8 +1076,7 @@ static void mod_kobject_remove(struct module *mod) module_remove_refcnt_attr(mod); module_param_sysfs_remove(mod); - /* Calls module_kobj_release */ - kobject_unregister(&mod->mkobj->kobj); + kobject_unregister(&mod->mkobj.kobj); } /* Free a module, remove from lists, etc (must hold module mutex). */ @@ -2089,11 +2074,9 @@ void module_add_driver(struct module *mod, struct device_driver *drv) { if (!mod || !drv) return; - if (!mod->mkobj) - return; /* Don't check return code; this call is idempotent */ - sysfs_create_link(&drv->kobj, &mod->mkobj->kobj, "module"); + sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); } EXPORT_SYMBOL(module_add_driver); diff --git a/kernel/params.c b/kernel/params.c index 45dd451e17c169..a4888d7860ae3c 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -357,26 +357,23 @@ extern struct kernel_param __start___param[], __stop___param[]; struct param_attribute { - struct attribute attr; + struct module_attribute mattr; struct kernel_param *param; }; -struct param_kobject +struct module_param_attrs { - struct kobject kobj; - - unsigned int num_attributes; - struct param_attribute attr[0]; + struct attribute_group grp; + struct param_attribute attrs[0]; }; -#define to_param_attr(n) container_of(n, struct param_attribute, attr); +#define to_param_attr(n) container_of(n, struct param_attribute, mattr); -static ssize_t param_attr_show(struct kobject *kobj, - struct attribute *attr, - char *buf) +static ssize_t param_attr_show(struct module_attribute *mattr, + struct module *mod, char *buf) { int count; - struct param_attribute *attribute = to_param_attr(attr); + struct param_attribute *attribute = to_param_attr(mattr); if (!attribute->param->get) return -EPERM; @@ -390,12 +387,12 @@ static ssize_t param_attr_show(struct kobject *kobj, } /* sysfs always hands a nul-terminated string in buf. We rely on that. */ -static ssize_t param_attr_store(struct kobject *kobj, - struct attribute *attr, +static ssize_t param_attr_store(struct module_attribute *mattr, + struct module *owner, const char *buf, size_t len) { int err; - struct param_attribute *attribute = to_param_attr(attr); + struct param_attribute *attribute = to_param_attr(mattr); if (!attribute->param->set) return -EPERM; @@ -406,27 +403,6 @@ static ssize_t param_attr_store(struct kobject *kobj, return err; } - -static struct sysfs_ops param_sysfs_ops = { - .show = param_attr_show, - .store = param_attr_store, -}; - -static void param_kobj_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct param_kobject, kobj)); -} - -static struct kobj_type param_ktype = { - .sysfs_ops = ¶m_sysfs_ops, - .release = ¶m_kobj_release, -}; - -static struct kset param_kset = { - .subsys = &module_subsys, - .ktype = ¶m_ktype, -}; - #ifdef CONFIG_MODULES #define __modinit #else @@ -434,54 +410,6 @@ static struct kset param_kset = { #endif /* - * param_add_attribute - actually adds an parameter to sysfs - * @mod: owner of parameter - * @pk: param_kobject the attribute shall be assigned to. - * One per module, one per KBUILD_MODNAME. - * @kp: kernel_param to be added - * @skip: offset where the parameter name start in kp->name. - * Needed for built-in modules - * - * Fill in data into appropriate &pk->attr[], and create sysfs file. - */ -static __modinit int param_add_attribute(struct module *mod, - struct param_kobject *pk, - struct kernel_param *kp, - unsigned int skip) -{ - struct param_attribute *a; - int err; - - a = &pk->attr[pk->num_attributes]; - a->attr.name = (char *) &kp->name[skip]; - a->attr.owner = mod; - a->attr.mode = kp->perm; - a->param = kp; - err = sysfs_create_file(&pk->kobj, &a->attr); - if (!err) - pk->num_attributes++; - return err; -} - -/* - * param_sysfs_remove - remove sysfs support for one module or KBUILD_MODNAME - * @pk: struct param_kobject which is to be removed - * - * Called when an error in registration occurs or a module is removed - * from the system. - */ -static __modinit void param_sysfs_remove(struct param_kobject *pk) -{ - unsigned int i; - for (i = 0; i < pk->num_attributes; i++) - sysfs_remove_file(&pk->kobj,&pk->attr[i].attr); - - /* Calls param_kobj_release */ - kobject_unregister(&pk->kobj); -} - - -/* * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME * @mk: struct module_kobject (contains parent kobject) * @kparam: array of struct kernel_param, the actual parameter definitions @@ -492,15 +420,17 @@ static __modinit void param_sysfs_remove(struct param_kobject *pk) * in sysfs. A pointer to the param_kobject is returned on success, * NULL if there's no parameter to export, or other ERR_PTR(err). */ -static __modinit struct param_kobject * +static __modinit struct module_param_attrs * param_sysfs_setup(struct module_kobject *mk, struct kernel_param *kparam, unsigned int num_params, unsigned int name_skip) { - struct param_kobject *pk; + struct module_param_attrs *mp; unsigned int valid_attrs = 0; - unsigned int i; + unsigned int i, size[2]; + struct param_attribute *pattr; + struct attribute **gattr; int err; for (i=0; i<num_params; i++) { @@ -511,42 +441,39 @@ param_sysfs_setup(struct module_kobject *mk, if (!valid_attrs) return NULL; - pk = kmalloc(sizeof(struct param_kobject) - + sizeof(struct param_attribute) * valid_attrs, - GFP_KERNEL); - if (!pk) - return ERR_PTR(-ENOMEM); - memset(pk, 0, sizeof(struct param_kobject) - + sizeof(struct param_attribute) * valid_attrs); + size[0] = ALIGN(sizeof(*mp) + + valid_attrs * sizeof(mp->attrs[0]), + sizeof(mp->grp.attrs[0])); + size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]); - err = kobject_set_name(&pk->kobj, "parameters"); - if (err) - goto out; + mp = kmalloc(size[0] + size[1], GFP_KERNEL); + if (!mp) + return ERR_PTR(-ENOMEM); - pk->kobj.kset = ¶m_kset; - pk->kobj.parent = &mk->kobj; - err = kobject_register(&pk->kobj); - if (err) - goto out; + mp->grp.name = "parameters"; + mp->grp.attrs = (void *)mp + size[0]; + pattr = &mp->attrs[0]; + gattr = &mp->grp.attrs[0]; for (i = 0; i < num_params; i++) { - if (kparam[i].perm) { - err = param_add_attribute(mk->mod, pk, - &kparam[i], name_skip); - if (err) - goto out_unreg; + struct kernel_param *kp = &kparam[i]; + if (kp->perm) { + pattr->param = kp; + pattr->mattr.show = param_attr_show; + pattr->mattr.store = param_attr_store; + pattr->mattr.attr.name = (char *)&kp->name[name_skip]; + pattr->mattr.attr.owner = mk->mod; + pattr->mattr.attr.mode = kp->perm; + *(gattr++) = &(pattr++)->mattr.attr; } } + *gattr = NULL; - return pk; - -out_unreg: - param_sysfs_remove(pk); - return ERR_PTR(err); - -out: - kfree(pk); - return ERR_PTR(err); + if ((err = sysfs_create_group(&mk->kobj, &mp->grp))) { + kfree(mp); + return ERR_PTR(err); + } + return mp; } @@ -565,13 +492,13 @@ int module_param_sysfs_setup(struct module *mod, struct kernel_param *kparam, unsigned int num_params) { - struct param_kobject *pk; + struct module_param_attrs *mp; - pk = param_sysfs_setup(mod->mkobj, kparam, num_params, 0); - if (IS_ERR(pk)) - return PTR_ERR(pk); + mp = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0); + if (IS_ERR(mp)) + return PTR_ERR(mp); - mod->params_kobject = pk; + mod->param_attrs = mp; return 0; } @@ -584,9 +511,13 @@ int module_param_sysfs_setup(struct module *mod, */ void module_param_sysfs_remove(struct module *mod) { - if (mod->params_kobject) { - param_sysfs_remove(mod->params_kobject); - mod->params_kobject = NULL; + if (mod->param_attrs) { + sysfs_remove_group(&mod->mkobj.kobj, + &mod->param_attrs->grp); + /* We are positive that no one is using any param + * attrs at this point. Deallocate immediately. */ + kfree(mod->param_attrs); + mod->param_attrs = NULL; } } #endif @@ -610,8 +541,10 @@ static void __init kernel_param_sysfs_setup(const char *name, kobject_register(&mk->kobj); /* no need to keep the kobject if no parameter is exported */ - if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) + if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) { kobject_unregister(&mk->kobj); + kfree(mk); + } } /* @@ -691,7 +624,7 @@ static ssize_t module_attr_show(struct kobject *kobj, if (!try_module_get(mk->mod)) return -ENODEV; - ret = attribute->show(mk->mod, buf); + ret = attribute->show(attribute, mk->mod, buf); module_put(mk->mod); @@ -710,14 +643,8 @@ static struct sysfs_ops module_sysfs_ops = { }; #endif -static void module_kobj_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct module_kobject, kobj)); -} - static struct kobj_type module_ktype = { .sysfs_ops = &module_sysfs_ops, - .release = &module_kobj_release, }; decl_subsys(module, &module_ktype, NULL); @@ -728,8 +655,6 @@ decl_subsys(module, &module_ktype, NULL); static int __init param_sysfs_init(void) { subsystem_register(&module_subsys); - kobject_set_name(¶m_kset.kobj, "parameters"); - kset_init(¶m_kset); param_sysfs_builtin(); |