2009-01-06 06:05:12 +03:00
/*
* Copyright ( C ) 2008 Red Hat , Inc . All rights reserved .
*
* This file is released under the GPL .
*/
# include <linux/sysfs.h>
# include <linux/dm-ioctl.h>
# include "dm.h"
struct dm_sysfs_attr {
struct attribute attr ;
ssize_t ( * show ) ( struct mapped_device * , char * ) ;
2015-02-28 01:58:42 +03:00
ssize_t ( * store ) ( struct mapped_device * , const char * , size_t count ) ;
2009-01-06 06:05:12 +03:00
} ;
# define DM_ATTR_RO(_name) \
struct dm_sysfs_attr dm_attr_ # # _name = \
__ATTR ( _name , S_IRUGO , dm_attr_ # # _name # # _show , NULL )
static ssize_t dm_attr_show ( struct kobject * kobj , struct attribute * attr ,
char * page )
{
struct dm_sysfs_attr * dm_attr ;
struct mapped_device * md ;
ssize_t ret ;
dm_attr = container_of ( attr , struct dm_sysfs_attr , attr ) ;
if ( ! dm_attr - > show )
return - EIO ;
md = dm_get_from_kobject ( kobj ) ;
if ( ! md )
return - EINVAL ;
ret = dm_attr - > show ( md , page ) ;
dm_put ( md ) ;
return ret ;
}
2015-02-28 01:58:42 +03:00
# define DM_ATTR_RW(_name) \
struct dm_sysfs_attr dm_attr_ # # _name = \
__ATTR ( _name , S_IRUGO | S_IWUSR , dm_attr_ # # _name # # _show , dm_attr_ # # _name # # _store )
static ssize_t dm_attr_store ( struct kobject * kobj , struct attribute * attr ,
const char * page , size_t count )
{
struct dm_sysfs_attr * dm_attr ;
struct mapped_device * md ;
ssize_t ret ;
dm_attr = container_of ( attr , struct dm_sysfs_attr , attr ) ;
if ( ! dm_attr - > store )
return - EIO ;
md = dm_get_from_kobject ( kobj ) ;
if ( ! md )
return - EINVAL ;
ret = dm_attr - > store ( md , page , count ) ;
dm_put ( md ) ;
return ret ;
}
2009-01-06 06:05:12 +03:00
static ssize_t dm_attr_name_show ( struct mapped_device * md , char * buf )
{
if ( dm_copy_name_and_uuid ( md , buf , NULL ) )
return - EIO ;
strcat ( buf , " \n " ) ;
return strlen ( buf ) ;
}
static ssize_t dm_attr_uuid_show ( struct mapped_device * md , char * buf )
{
if ( dm_copy_name_and_uuid ( md , NULL , buf ) )
return - EIO ;
strcat ( buf , " \n " ) ;
return strlen ( buf ) ;
}
2009-06-22 13:12:29 +04:00
static ssize_t dm_attr_suspended_show ( struct mapped_device * md , char * buf )
{
2009-12-11 02:52:26 +03:00
sprintf ( buf , " %d \n " , dm_suspended_md ( md ) ) ;
2009-06-22 13:12:29 +04:00
return strlen ( buf ) ;
}
2015-03-11 22:01:09 +03:00
static ssize_t dm_attr_use_blk_mq_show ( struct mapped_device * md , char * buf )
{
sprintf ( buf , " %d \n " , dm_use_blk_mq ( md ) ) ;
return strlen ( buf ) ;
}
2009-01-06 06:05:12 +03:00
static DM_ATTR_RO ( name ) ;
static DM_ATTR_RO ( uuid ) ;
2009-06-22 13:12:29 +04:00
static DM_ATTR_RO ( suspended ) ;
2015-03-11 22:01:09 +03:00
static DM_ATTR_RO ( use_blk_mq ) ;
2015-02-26 08:50:28 +03:00
static DM_ATTR_RW ( rq_based_seq_io_merge_deadline ) ;
2009-01-06 06:05:12 +03:00
static struct attribute * dm_attrs [ ] = {
& dm_attr_name . attr ,
& dm_attr_uuid . attr ,
2009-06-22 13:12:29 +04:00
& dm_attr_suspended . attr ,
2015-03-11 22:01:09 +03:00
& dm_attr_use_blk_mq . attr ,
2015-02-26 08:50:28 +03:00
& dm_attr_rq_based_seq_io_merge_deadline . attr ,
2009-01-06 06:05:12 +03:00
NULL ,
} ;
2010-01-19 04:58:23 +03:00
static const struct sysfs_ops dm_sysfs_ops = {
2009-01-06 06:05:12 +03:00
. show = dm_attr_show ,
2015-02-28 01:58:42 +03:00
. store = dm_attr_store ,
2009-01-06 06:05:12 +03:00
} ;
static struct kobj_type dm_ktype = {
. sysfs_ops = & dm_sysfs_ops ,
. default_attrs = dm_attrs ,
2014-01-07 08:01:22 +04:00
. release = dm_kobject_release ,
2009-01-06 06:05:12 +03:00
} ;
/*
* Initialize kobj
* because nobody using md yet , no need to call explicit dm_get / put
*/
int dm_sysfs_init ( struct mapped_device * md )
{
return kobject_init_and_add ( dm_kobject ( md ) , & dm_ktype ,
& disk_to_dev ( dm_disk ( md ) ) - > kobj ,
" %s " , " dm " ) ;
}
/*
* Remove kobj , called after all references removed
*/
void dm_sysfs_exit ( struct mapped_device * md )
{
2014-01-07 08:01:22 +04:00
struct kobject * kobj = dm_kobject ( md ) ;
kobject_put ( kobj ) ;
wait_for_completion ( dm_get_completion_from_kobject ( kobj ) ) ;
2009-01-06 06:05:12 +03:00
}