2005-04-17 02:20:36 +04:00
/*
2007-09-20 12:31:38 +04: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-17 02:20:36 +04:00
*/
2012-12-06 13:08:56 +04:00
# define DEBUG
2005-04-17 02:20:36 +04:00
# include <linux/fs.h>
# include <linux/mount.h>
# include <linux/init.h>
2013-03-25 01:28:27 +04:00
# include <linux/user_namespace.h>
2005-04-17 02:20:36 +04:00
# include "sysfs.h"
2013-11-28 23:54:40 +04:00
static struct kernfs_root * sysfs_root ;
struct sysfs_dirent * sysfs_root_sd ;
2013-11-28 23:54:39 +04: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-17 02:20:36 +04:00
{
2013-11-28 23:54:43 +04:00
struct dentry * root ;
void * ns ;
2010-03-30 22:31:24 +04:00
2013-03-26 07:07:01 +04:00
if ( ! ( flags & MS_KERNMOUNT ) ) {
if ( ! capable ( CAP_SYS_ADMIN ) & & ! fs_fully_visible ( fs_type ) )
return ERR_PTR ( - EPERM ) ;
2013-11-24 03:01:46 +04:00
if ( ! kobj_ns_current_may_mount ( KOBJ_NS_TYPE_NET ) )
return ERR_PTR ( - EPERM ) ;
2013-03-26 07:07:01 +04:00
}
2013-03-25 01:28:27 +04:00
2013-11-28 23:54:43 +04:00
ns = kobj_ns_grab_current ( KOBJ_NS_TYPE_NET ) ;
root = kernfs_mount_ns ( fs_type , flags , sysfs_root , ns ) ;
if ( IS_ERR ( root ) )
kobj_ns_drop ( KOBJ_NS_TYPE_NET , ns ) ;
return root ;
}
2010-03-30 22:31:24 +04:00
static void sysfs_kill_sb ( struct super_block * sb )
2013-11-28 23:54:43 +04:00
{
kernfs_kill_sb ( sb ) ;
kobj_ns_drop ( KOBJ_NS_TYPE_NET , ( void * ) kernfs_super_ns ( sb ) ) ;
}
2005-04-17 02:20:36 +04: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 22:31:24 +04:00
. kill_sb = sysfs_kill_sb ,
2012-07-27 16:56:48 +04:00
. fs_flags = FS_USERNS_MOUNT ,
2005-04-17 02:20:36 +04:00
} ;
2013-11-28 23:54:43 +04:00
int __init sysfs_init ( void )
{
int err ;
2007-10-17 10:25:46 +04:00
2013-11-28 23:54:40 +04:00
sysfs_root = kernfs_create_root ( NULL ) ;
2013-11-28 23:54:43 +04:00
if ( IS_ERR ( sysfs_root ) )
return PTR_ERR ( sysfs_root ) ;
2013-11-28 23:54:40 +04:00
sysfs_root_sd = sysfs_root - > sd ;
2005-04-17 02:20:36 +04:00
err = register_filesystem ( & sysfs_fs_type ) ;
2013-11-28 23:54:43 +04:00
if ( err ) {
kernfs_destroy_root ( sysfs_root ) ;
return err ;
}
2013-11-28 23:54:38 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}