2020-05-11 15:51:18 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* RDMA Transport Layer
*
* Copyright ( c ) 2014 - 2018 ProfitBricks GmbH . All rights reserved .
* Copyright ( c ) 2018 - 2019 1 & 1 IONOS Cloud GmbH . All rights reserved .
* Copyright ( c ) 2019 - 2020 1 & 1 IONOS SE . All rights reserved .
*/
# undef pr_fmt
# define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
# include "rtrs-pri.h"
# include "rtrs-srv.h"
# include "rtrs-log.h"
static void rtrs_srv_release ( struct kobject * kobj )
{
struct rtrs_srv_sess * sess ;
sess = container_of ( kobj , struct rtrs_srv_sess , kobj ) ;
kfree ( sess ) ;
}
static struct kobj_type ktype = {
. sysfs_ops = & kobj_sysfs_ops ,
. release = rtrs_srv_release ,
} ;
static ssize_t rtrs_srv_disconnect_show ( struct kobject * kobj ,
RDMA: Convert sysfs kobject * show functions to use sysfs_emit()
Done with cocci script:
@@
identifier k_show;
identifier arg1, arg2, arg3;
@@
ssize_t k_show(struct kobject *
- arg1
+ kobj
, struct kobj_attribute *
- arg2
+ attr
, char *
- arg3
+ buf
)
{
...
(
- arg1
+ kobj
|
- arg2
+ attr
|
- arg3
+ buf
)
...
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- strcpy(buf, chr);
+ sysfs_emit(buf, chr);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
- len += scnprintf(buf + len, PAGE_SIZE - len,
+ len += sysfs_emit_at(buf, len,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
...
- strcpy(buf, chr);
- return strlen(buf);
+ return sysfs_emit(buf, chr);
}
Link: https://lore.kernel.org/r/7761c1efaebb96c432c85171d58405c25a824ccd.1602122880.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2020-10-07 19:36:25 -07:00
struct kobj_attribute * attr , char * buf )
2020-05-11 15:51:18 +02:00
{
RDMA: Convert sysfs kobject * show functions to use sysfs_emit()
Done with cocci script:
@@
identifier k_show;
identifier arg1, arg2, arg3;
@@
ssize_t k_show(struct kobject *
- arg1
+ kobj
, struct kobj_attribute *
- arg2
+ attr
, char *
- arg3
+ buf
)
{
...
(
- arg1
+ kobj
|
- arg2
+ attr
|
- arg3
+ buf
)
...
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- strcpy(buf, chr);
+ sysfs_emit(buf, chr);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
- len += scnprintf(buf + len, PAGE_SIZE - len,
+ len += sysfs_emit_at(buf, len,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
...
- strcpy(buf, chr);
- return strlen(buf);
+ return sysfs_emit(buf, chr);
}
Link: https://lore.kernel.org/r/7761c1efaebb96c432c85171d58405c25a824ccd.1602122880.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2020-10-07 19:36:25 -07:00
return sysfs_emit ( buf , " Usage: echo 1 > %s \n " , attr - > attr . name ) ;
2020-05-11 15:51:18 +02:00
}
static ssize_t rtrs_srv_disconnect_store ( struct kobject * kobj ,
struct kobj_attribute * attr ,
const char * buf , size_t count )
{
struct rtrs_srv_sess * sess ;
struct rtrs_sess * s ;
char str [ MAXHOSTNAMELEN ] ;
sess = container_of ( kobj , struct rtrs_srv_sess , kobj ) ;
s = & sess - > s ;
if ( ! sysfs_streq ( buf , " 1 " ) ) {
rtrs_err ( s , " %s: invalid value: '%s' \n " ,
attr - > attr . name , buf ) ;
return - EINVAL ;
}
sockaddr_to_str ( ( struct sockaddr * ) & sess - > s . dst_addr , str , sizeof ( str ) ) ;
rtrs_info ( s , " disconnect for path %s requested \n " , str ) ;
2020-12-17 15:19:00 +01:00
/* first remove sysfs itself to avoid deadlock */
sysfs_remove_file_self ( & sess - > kobj , & attr - > attr ) ;
2020-05-11 15:51:18 +02:00
close_sess ( sess ) ;
return count ;
}
static struct kobj_attribute rtrs_srv_disconnect_attr =
__ATTR ( disconnect , 0644 ,
rtrs_srv_disconnect_show , rtrs_srv_disconnect_store ) ;
static ssize_t rtrs_srv_hca_port_show ( struct kobject * kobj ,
struct kobj_attribute * attr ,
char * page )
{
struct rtrs_srv_sess * sess ;
struct rtrs_con * usr_con ;
sess = container_of ( kobj , typeof ( * sess ) , kobj ) ;
usr_con = sess - > s . con [ 0 ] ;
RDMA: Convert sysfs kobject * show functions to use sysfs_emit()
Done with cocci script:
@@
identifier k_show;
identifier arg1, arg2, arg3;
@@
ssize_t k_show(struct kobject *
- arg1
+ kobj
, struct kobj_attribute *
- arg2
+ attr
, char *
- arg3
+ buf
)
{
...
(
- arg1
+ kobj
|
- arg2
+ attr
|
- arg3
+ buf
)
...
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- strcpy(buf, chr);
+ sysfs_emit(buf, chr);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
- len += scnprintf(buf + len, PAGE_SIZE - len,
+ len += sysfs_emit_at(buf, len,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
...
- strcpy(buf, chr);
- return strlen(buf);
+ return sysfs_emit(buf, chr);
}
Link: https://lore.kernel.org/r/7761c1efaebb96c432c85171d58405c25a824ccd.1602122880.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2020-10-07 19:36:25 -07:00
return sysfs_emit ( page , " %u \n " , usr_con - > cm_id - > port_num ) ;
2020-05-11 15:51:18 +02:00
}
static struct kobj_attribute rtrs_srv_hca_port_attr =
__ATTR ( hca_port , 0444 , rtrs_srv_hca_port_show , NULL ) ;
static ssize_t rtrs_srv_hca_name_show ( struct kobject * kobj ,
struct kobj_attribute * attr ,
char * page )
{
struct rtrs_srv_sess * sess ;
sess = container_of ( kobj , struct rtrs_srv_sess , kobj ) ;
RDMA: Convert sysfs kobject * show functions to use sysfs_emit()
Done with cocci script:
@@
identifier k_show;
identifier arg1, arg2, arg3;
@@
ssize_t k_show(struct kobject *
- arg1
+ kobj
, struct kobj_attribute *
- arg2
+ attr
, char *
- arg3
+ buf
)
{
...
(
- arg1
+ kobj
|
- arg2
+ attr
|
- arg3
+ buf
)
...
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
return
- strcpy(buf, chr);
+ sysfs_emit(buf, chr);
...>
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
len =
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
identifier len;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
<...
- len += scnprintf(buf + len, PAGE_SIZE - len,
+ len += sysfs_emit_at(buf, len,
...);
...>
return len;
}
@@
identifier k_show;
identifier kobj, attr, buf;
expression chr;
@@
ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
...
- strcpy(buf, chr);
- return strlen(buf);
+ return sysfs_emit(buf, chr);
}
Link: https://lore.kernel.org/r/7761c1efaebb96c432c85171d58405c25a824ccd.1602122880.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2020-10-07 19:36:25 -07:00
return sysfs_emit ( page , " %s \n " , sess - > s . dev - > ib_dev - > name ) ;
2020-05-11 15:51:18 +02:00
}
static struct kobj_attribute rtrs_srv_hca_name_attr =
__ATTR ( hca_name , 0444 , rtrs_srv_hca_name_show , NULL ) ;
static ssize_t rtrs_srv_src_addr_show ( struct kobject * kobj ,
struct kobj_attribute * attr ,
char * page )
{
struct rtrs_srv_sess * sess ;
int cnt ;
sess = container_of ( kobj , struct rtrs_srv_sess , kobj ) ;
cnt = sockaddr_to_str ( ( struct sockaddr * ) & sess - > s . dst_addr ,
page , PAGE_SIZE ) ;
return cnt + scnprintf ( page + cnt , PAGE_SIZE - cnt , " \n " ) ;
}
static struct kobj_attribute rtrs_srv_src_addr_attr =
__ATTR ( src_addr , 0444 , rtrs_srv_src_addr_show , NULL ) ;
static ssize_t rtrs_srv_dst_addr_show ( struct kobject * kobj ,
struct kobj_attribute * attr ,
char * page )
{
struct rtrs_srv_sess * sess ;
2020-10-07 19:36:27 -07:00
int len ;
2020-05-11 15:51:18 +02:00
sess = container_of ( kobj , struct rtrs_srv_sess , kobj ) ;
2020-10-07 19:36:27 -07:00
len = sockaddr_to_str ( ( struct sockaddr * ) & sess - > s . src_addr , page ,
PAGE_SIZE ) ;
len + = sysfs_emit_at ( page , len , " \n " ) ;
return len ;
2020-05-11 15:51:18 +02:00
}
static struct kobj_attribute rtrs_srv_dst_addr_attr =
__ATTR ( dst_addr , 0444 , rtrs_srv_dst_addr_show , NULL ) ;
static struct attribute * rtrs_srv_sess_attrs [ ] = {
& rtrs_srv_hca_name_attr . attr ,
& rtrs_srv_hca_port_attr . attr ,
& rtrs_srv_src_addr_attr . attr ,
& rtrs_srv_dst_addr_attr . attr ,
& rtrs_srv_disconnect_attr . attr ,
NULL ,
} ;
2020-10-01 00:40:04 +02:00
static const struct attribute_group rtrs_srv_sess_attr_group = {
2020-05-11 15:51:18 +02:00
. attrs = rtrs_srv_sess_attrs ,
} ;
STAT_ATTR ( struct rtrs_srv_stats , rdma ,
rtrs_srv_stats_rdma_to_str ,
rtrs_srv_reset_rdma_stats ) ;
static struct attribute * rtrs_srv_stats_attrs [ ] = {
& rdma_attr . attr ,
NULL ,
} ;
2020-10-01 00:40:04 +02:00
static const struct attribute_group rtrs_srv_stats_attr_group = {
2020-05-11 15:51:18 +02:00
. attrs = rtrs_srv_stats_attrs ,
} ;
static int rtrs_srv_create_once_sysfs_root_folders ( struct rtrs_srv_sess * sess )
{
struct rtrs_srv * srv = sess - > srv ;
int err = 0 ;
mutex_lock ( & srv - > paths_mutex ) ;
if ( srv - > dev_ref + + ) {
/*
* Device needs to be registered only on the first session
*/
goto unlock ;
}
srv - > dev . class = rtrs_dev_class ;
err = dev_set_name ( & srv - > dev , " %s " , sess - > s . sessname ) ;
if ( err )
goto unlock ;
/*
* Suppress user space notification until
* sysfs files are created
*/
dev_set_uevent_suppress ( & srv - > dev , true ) ;
2020-08-11 14:57:22 +05:30
err = device_add ( & srv - > dev ) ;
2020-05-11 15:51:18 +02:00
if ( err ) {
2020-08-11 14:57:22 +05:30
pr_err ( " device_add(): %d \n " , err ) ;
2020-05-11 15:51:18 +02:00
goto put ;
}
srv - > kobj_paths = kobject_create_and_add ( " paths " , & srv - > dev . kobj ) ;
if ( ! srv - > kobj_paths ) {
2020-05-19 09:19:12 +00:00
err = - ENOMEM ;
2020-05-11 15:51:18 +02:00
pr_err ( " kobject_create_and_add(): %d \n " , err ) ;
2020-08-11 14:57:22 +05:30
device_del ( & srv - > dev ) ;
2020-05-11 15:51:18 +02:00
goto unlock ;
}
dev_set_uevent_suppress ( & srv - > dev , false ) ;
kobject_uevent ( & srv - > dev . kobj , KOBJ_ADD ) ;
goto unlock ;
put :
put_device ( & srv - > dev ) ;
unlock :
mutex_unlock ( & srv - > paths_mutex ) ;
return err ;
}
static void
rtrs_srv_destroy_once_sysfs_root_folders ( struct rtrs_srv_sess * sess )
{
struct rtrs_srv * srv = sess - > srv ;
mutex_lock ( & srv - > paths_mutex ) ;
if ( ! - - srv - > dev_ref ) {
kobject_del ( srv - > kobj_paths ) ;
kobject_put ( srv - > kobj_paths ) ;
mutex_unlock ( & srv - > paths_mutex ) ;
2020-08-11 14:57:22 +05:30
device_del ( & srv - > dev ) ;
2020-05-11 15:51:18 +02:00
} else {
mutex_unlock ( & srv - > paths_mutex ) ;
}
}
static void rtrs_srv_sess_stats_release ( struct kobject * kobj )
{
struct rtrs_srv_stats * stats ;
stats = container_of ( kobj , struct rtrs_srv_stats , kobj_stats ) ;
kfree ( stats ) ;
}
static struct kobj_type ktype_stats = {
. sysfs_ops = & kobj_sysfs_ops ,
. release = rtrs_srv_sess_stats_release ,
} ;
static int rtrs_srv_create_stats_files ( struct rtrs_srv_sess * sess )
{
int err ;
struct rtrs_sess * s = & sess - > s ;
err = kobject_init_and_add ( & sess - > stats - > kobj_stats , & ktype_stats ,
& sess - > kobj , " stats " ) ;
if ( err ) {
rtrs_err ( s , " kobject_init_and_add(): %d \n " , err ) ;
return err ;
}
err = sysfs_create_group ( & sess - > stats - > kobj_stats ,
& rtrs_srv_stats_attr_group ) ;
if ( err ) {
rtrs_err ( s , " sysfs_create_group(): %d \n " , err ) ;
goto err ;
}
return 0 ;
err :
kobject_del ( & sess - > stats - > kobj_stats ) ;
kobject_put ( & sess - > stats - > kobj_stats ) ;
return err ;
}
int rtrs_srv_create_sess_files ( struct rtrs_srv_sess * sess )
{
struct rtrs_srv * srv = sess - > srv ;
struct rtrs_sess * s = & sess - > s ;
char str [ NAME_MAX ] ;
int err , cnt ;
cnt = sockaddr_to_str ( ( struct sockaddr * ) & sess - > s . dst_addr ,
str , sizeof ( str ) ) ;
cnt + = scnprintf ( str + cnt , sizeof ( str ) - cnt , " @ " ) ;
sockaddr_to_str ( ( struct sockaddr * ) & sess - > s . src_addr ,
str + cnt , sizeof ( str ) - cnt ) ;
err = rtrs_srv_create_once_sysfs_root_folders ( sess ) ;
if ( err )
return err ;
err = kobject_init_and_add ( & sess - > kobj , & ktype , srv - > kobj_paths ,
" %s " , str ) ;
if ( err ) {
rtrs_err ( s , " kobject_init_and_add(): %d \n " , err ) ;
goto destroy_root ;
}
err = sysfs_create_group ( & sess - > kobj , & rtrs_srv_sess_attr_group ) ;
if ( err ) {
rtrs_err ( s , " sysfs_create_group(): %d \n " , err ) ;
goto put_kobj ;
}
err = rtrs_srv_create_stats_files ( sess ) ;
if ( err )
goto remove_group ;
return 0 ;
remove_group :
sysfs_remove_group ( & sess - > kobj , & rtrs_srv_sess_attr_group ) ;
put_kobj :
kobject_del ( & sess - > kobj ) ;
kobject_put ( & sess - > kobj ) ;
destroy_root :
rtrs_srv_destroy_once_sysfs_root_folders ( sess ) ;
return err ;
}
void rtrs_srv_destroy_sess_files ( struct rtrs_srv_sess * sess )
{
if ( sess - > kobj . state_in_sysfs ) {
kobject_del ( & sess - > stats - > kobj_stats ) ;
kobject_put ( & sess - > stats - > kobj_stats ) ;
kobject_del ( & sess - > kobj ) ;
kobject_put ( & sess - > kobj ) ;
rtrs_srv_destroy_once_sysfs_root_folders ( sess ) ;
}
}