2005-04-16 15:20:36 -07:00
/*
* fs / sysfs / group . c - Operations for adding / removing multiple files at once .
*
* Copyright ( c ) 2003 Patrick Mochel
* Copyright ( c ) 2003 Open Source Development Lab
*
* This file is released undert the GPL v2 .
*
*/
# include <linux/kobject.h>
# include <linux/module.h>
# include <linux/dcache.h>
2005-06-23 00:09:12 -07:00
# include <linux/namei.h>
2005-04-16 15:20:36 -07:00
# include <linux/err.h>
2007-01-24 12:35:52 -07:00
# include <linux/fs.h>
2006-12-20 10:52:44 +01:00
# include <asm/semaphore.h>
2005-04-16 15:20:36 -07:00
# include "sysfs.h"
2007-06-14 04:27:22 +09:00
static void remove_files ( struct sysfs_dirent * dir_sd ,
const struct attribute_group * grp )
2005-04-16 15:20:36 -07:00
{
struct attribute * const * attr ;
for ( attr = grp - > attrs ; * attr ; attr + + )
2007-06-14 04:27:22 +09:00
sysfs_hash_and_remove ( dir_sd , ( * attr ) - > name ) ;
2005-04-16 15:20:36 -07:00
}
2007-06-14 04:27:22 +09:00
static int create_files ( struct sysfs_dirent * dir_sd ,
const struct attribute_group * grp )
2005-04-16 15:20:36 -07:00
{
struct attribute * const * attr ;
int error = 0 ;
2007-06-14 04:27:22 +09:00
for ( attr = grp - > attrs ; * attr & & ! error ; attr + + )
error = sysfs_add_file ( dir_sd , * attr , SYSFS_KOBJ_ATTR ) ;
2005-04-16 15:20:36 -07:00
if ( error )
2007-06-14 04:27:22 +09:00
remove_files ( dir_sd , grp ) ;
2005-04-16 15:20:36 -07:00
return error ;
}
int sysfs_create_group ( struct kobject * kobj ,
const struct attribute_group * grp )
{
2007-06-14 04:27:22 +09:00
struct sysfs_dirent * sd ;
2005-04-16 15:20:36 -07:00
int error ;
2007-06-14 04:27:22 +09:00
BUG_ON ( ! kobj | | ! kobj - > sd ) ;
2005-04-16 15:20:36 -07:00
if ( grp - > name ) {
2007-06-14 04:27:22 +09:00
error = sysfs_create_subdir ( kobj , grp - > name , & sd ) ;
2005-04-16 15:20:36 -07:00
if ( error )
return error ;
} else
2007-06-14 04:27:22 +09:00
sd = kobj - > sd ;
sysfs_get ( sd ) ;
error = create_files ( sd , grp ) ;
if ( error ) {
2005-04-16 15:20:36 -07:00
if ( grp - > name )
2007-06-14 04:27:22 +09:00
sysfs_remove_subdir ( sd ) ;
2005-04-16 15:20:36 -07:00
}
2007-06-14 04:27:22 +09:00
sysfs_put ( sd ) ;
2005-04-16 15:20:36 -07:00
return error ;
}
void sysfs_remove_group ( struct kobject * kobj ,
const struct attribute_group * grp )
{
2007-06-14 04:27:22 +09:00
struct sysfs_dirent * dir_sd = kobj - > sd ;
struct sysfs_dirent * sd ;
2005-04-16 15:20:36 -07:00
2007-04-26 00:12:05 -07:00
if ( grp - > name ) {
2007-06-14 04:27:22 +09:00
sd = sysfs_get_dirent ( dir_sd , grp - > name ) ;
BUG_ON ( ! sd ) ;
} else
sd = sysfs_get ( dir_sd ) ;
2005-04-16 15:20:36 -07:00
2007-06-14 04:27:22 +09:00
remove_files ( sd , grp ) ;
2005-04-16 15:20:36 -07:00
if ( grp - > name )
2007-06-14 04:27:22 +09:00
sysfs_remove_subdir ( sd ) ;
sysfs_put ( sd ) ;
2005-04-16 15:20:36 -07:00
}
EXPORT_SYMBOL_GPL ( sysfs_create_group ) ;
EXPORT_SYMBOL_GPL ( sysfs_remove_group ) ;