2005-04-16 15:20:36 -07:00
/*
2007-09-20 17:31:38 +09:00
* fs / sysfs / symlink . c - operations for initializing and mounting sysfs
*
* Copyright ( c ) 2001 - 3 Patrick Mochel
* Copyright ( c ) 2007 SUSE Linux Products GmbH
* Copyright ( c ) 2007 Tejun Heo < teheo @ suse . de >
*
* This file is released under the GPLv2 .
*
* Please see Documentation / filesystems / sysfs . txt for more information .
2005-04-16 15:20:36 -07:00
*/
2012-12-06 17:08:56 +08:00
# define DEBUG
2005-04-16 15:20:36 -07:00
# include <linux/fs.h>
2014-04-26 15:40:28 +08:00
# include <linux/magic.h>
2005-04-16 15:20:36 -07:00
# include <linux/mount.h>
# include <linux/init.h>
2013-03-24 14:28:27 -07:00
# include <linux/user_namespace.h>
2005-04-16 15:20:36 -07:00
# include "sysfs.h"
2013-11-28 14:54:40 -05:00
static struct kernfs_root * sysfs_root ;
2013-12-11 14:11:53 -05:00
struct kernfs_node * sysfs_root_kn ;
2013-11-28 14:54:39 -05:00
2010-07-26 13:30:36 +04:00
static struct dentry * sysfs_mount ( struct file_system_type * fs_type ,
int flags , const char * dev_name , void * data )
2005-04-16 15:20:36 -07:00
{
2013-11-28 14:54:43 -05:00
struct dentry * root ;
void * ns ;
2014-02-25 19:28:44 +08:00
bool new_sb ;
2010-03-30 11:31:24 -07:00
2013-03-25 20:07:01 -07:00
if ( ! ( flags & MS_KERNMOUNT ) ) {
2013-11-23 18:01:46 -05:00
if ( ! kobj_ns_current_may_mount ( KOBJ_NS_TYPE_NET ) )
return ERR_PTR ( - EPERM ) ;
2013-03-25 20:07:01 -07:00
}
2013-03-24 14:28:27 -07:00
2013-11-28 14:54:43 -05:00
ns = kobj_ns_grab_current ( KOBJ_NS_TYPE_NET ) ;
2014-04-26 15:40:28 +08:00
root = kernfs_mount_ns ( fs_type , flags , sysfs_root ,
SYSFS_MAGIC , & new_sb , ns ) ;
2014-02-25 19:28:44 +08:00
if ( IS_ERR ( root ) | | ! new_sb )
2013-11-28 14:54:43 -05:00
kobj_ns_drop ( KOBJ_NS_TYPE_NET , ns ) ;
return root ;
}
2010-03-30 11:31:24 -07:00
static void sysfs_kill_sb ( struct super_block * sb )
2013-11-28 14:54:43 -05:00
{
2013-12-10 10:22:30 -05:00
void * ns = ( void * ) kernfs_super_ns ( sb ) ;
2013-11-28 14:54:43 -05:00
kernfs_kill_sb ( sb ) ;
2013-12-10 10:22:30 -05:00
kobj_ns_drop ( KOBJ_NS_TYPE_NET , ns ) ;
2013-11-28 14:54:43 -05:00
}
2005-04-16 15:20:36 -07:00
static struct file_system_type sysfs_fs_type = {
. name = " sysfs " ,
2010-07-26 13:30:36 +04:00
. mount = sysfs_mount ,
2010-03-30 11:31:24 -07:00
. kill_sb = sysfs_kill_sb ,
2015-05-08 23:22:29 -05:00
. fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT ,
2005-04-16 15:20:36 -07:00
} ;
2013-11-28 14:54:43 -05:00
int __init sysfs_init ( void )
{
int err ;
2007-10-16 23:25:46 -07:00
2014-05-12 13:56:27 -04:00
sysfs_root = kernfs_create_root ( NULL , KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK ,
NULL ) ;
2013-11-28 14:54:43 -05:00
if ( IS_ERR ( sysfs_root ) )
return PTR_ERR ( sysfs_root ) ;
2013-12-11 14:11:53 -05:00
sysfs_root_kn = sysfs_root - > kn ;
2013-11-28 14:54:40 -05:00
2005-04-16 15:20:36 -07:00
err = register_filesystem ( & sysfs_fs_type ) ;
2013-11-28 14:54:43 -05:00
if ( err ) {
kernfs_destroy_root ( sysfs_root ) ;
return err ;
}
2013-11-28 14:54:38 -05:00
return 0 ;
2005-04-16 15:20:36 -07:00
}