17063fbf2SJoel Becker /* -*- mode: c; c-basic-offset: 8; -*- 27063fbf2SJoel Becker * vim: noexpandtab sw=8 ts=8 sts=0: 37063fbf2SJoel Becker * 47063fbf2SJoel Becker * mount.c - operations for initializing and mounting configfs. 57063fbf2SJoel Becker * 67063fbf2SJoel Becker * This program is free software; you can redistribute it and/or 77063fbf2SJoel Becker * modify it under the terms of the GNU General Public 87063fbf2SJoel Becker * License as published by the Free Software Foundation; either 97063fbf2SJoel Becker * version 2 of the License, or (at your option) any later version. 107063fbf2SJoel Becker * 117063fbf2SJoel Becker * This program is distributed in the hope that it will be useful, 127063fbf2SJoel Becker * but WITHOUT ANY WARRANTY; without even the implied warranty of 137063fbf2SJoel Becker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 147063fbf2SJoel Becker * General Public License for more details. 157063fbf2SJoel Becker * 167063fbf2SJoel Becker * You should have received a copy of the GNU General Public 177063fbf2SJoel Becker * License along with this program; if not, write to the 187063fbf2SJoel Becker * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 197063fbf2SJoel Becker * Boston, MA 021110-1307, USA. 207063fbf2SJoel Becker * 217063fbf2SJoel Becker * Based on sysfs: 227063fbf2SJoel Becker * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 237063fbf2SJoel Becker * 247063fbf2SJoel Becker * configfs Copyright (C) 2005 Oracle. All rights reserved. 257063fbf2SJoel Becker */ 267063fbf2SJoel Becker 277063fbf2SJoel Becker #include <linux/fs.h> 287063fbf2SJoel Becker #include <linux/module.h> 297063fbf2SJoel Becker #include <linux/mount.h> 307063fbf2SJoel Becker #include <linux/pagemap.h> 317063fbf2SJoel Becker #include <linux/init.h> 327063fbf2SJoel Becker 337063fbf2SJoel Becker #include <linux/configfs.h> 347063fbf2SJoel Becker #include "configfs_internal.h" 357063fbf2SJoel Becker 367063fbf2SJoel Becker /* Random magic number */ 377063fbf2SJoel Becker #define CONFIGFS_MAGIC 0x62656570 387063fbf2SJoel Becker 397063fbf2SJoel Becker struct vfsmount * configfs_mount = NULL; 407063fbf2SJoel Becker struct super_block * configfs_sb = NULL; 417063fbf2SJoel Becker static int configfs_mnt_count = 0; 427063fbf2SJoel Becker 437063fbf2SJoel Becker static struct super_operations configfs_ops = { 447063fbf2SJoel Becker .statfs = simple_statfs, 457063fbf2SJoel Becker .drop_inode = generic_delete_inode, 467063fbf2SJoel Becker }; 477063fbf2SJoel Becker 487063fbf2SJoel Becker static struct config_group configfs_root_group = { 497063fbf2SJoel Becker .cg_item = { 507063fbf2SJoel Becker .ci_namebuf = "root", 517063fbf2SJoel Becker .ci_name = configfs_root_group.cg_item.ci_namebuf, 527063fbf2SJoel Becker }, 537063fbf2SJoel Becker }; 547063fbf2SJoel Becker 557063fbf2SJoel Becker int configfs_is_root(struct config_item *item) 567063fbf2SJoel Becker { 577063fbf2SJoel Becker return item == &configfs_root_group.cg_item; 587063fbf2SJoel Becker } 597063fbf2SJoel Becker 607063fbf2SJoel Becker static struct configfs_dirent configfs_root = { 617063fbf2SJoel Becker .s_sibling = LIST_HEAD_INIT(configfs_root.s_sibling), 627063fbf2SJoel Becker .s_children = LIST_HEAD_INIT(configfs_root.s_children), 637063fbf2SJoel Becker .s_element = &configfs_root_group.cg_item, 647063fbf2SJoel Becker .s_type = CONFIGFS_ROOT, 657063fbf2SJoel Becker }; 667063fbf2SJoel Becker 677063fbf2SJoel Becker static int configfs_fill_super(struct super_block *sb, void *data, int silent) 687063fbf2SJoel Becker { 697063fbf2SJoel Becker struct inode *inode; 707063fbf2SJoel Becker struct dentry *root; 717063fbf2SJoel Becker 727063fbf2SJoel Becker sb->s_blocksize = PAGE_CACHE_SIZE; 737063fbf2SJoel Becker sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 747063fbf2SJoel Becker sb->s_magic = CONFIGFS_MAGIC; 757063fbf2SJoel Becker sb->s_op = &configfs_ops; 767063fbf2SJoel Becker configfs_sb = sb; 777063fbf2SJoel Becker 787063fbf2SJoel Becker inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); 797063fbf2SJoel Becker if (inode) { 807063fbf2SJoel Becker inode->i_op = &configfs_dir_inode_operations; 817063fbf2SJoel Becker inode->i_fop = &configfs_dir_operations; 827063fbf2SJoel Becker /* directory inodes start off with i_nlink == 2 (for "." entry) */ 837063fbf2SJoel Becker inode->i_nlink++; 847063fbf2SJoel Becker } else { 857063fbf2SJoel Becker pr_debug("configfs: could not get root inode\n"); 867063fbf2SJoel Becker return -ENOMEM; 877063fbf2SJoel Becker } 887063fbf2SJoel Becker 897063fbf2SJoel Becker root = d_alloc_root(inode); 907063fbf2SJoel Becker if (!root) { 917063fbf2SJoel Becker pr_debug("%s: could not get root dentry!\n",__FUNCTION__); 927063fbf2SJoel Becker iput(inode); 937063fbf2SJoel Becker return -ENOMEM; 947063fbf2SJoel Becker } 957063fbf2SJoel Becker config_group_init(&configfs_root_group); 967063fbf2SJoel Becker configfs_root_group.cg_item.ci_dentry = root; 977063fbf2SJoel Becker root->d_fsdata = &configfs_root; 987063fbf2SJoel Becker sb->s_root = root; 997063fbf2SJoel Becker return 0; 1007063fbf2SJoel Becker } 1017063fbf2SJoel Becker 1027063fbf2SJoel Becker static struct super_block *configfs_get_sb(struct file_system_type *fs_type, 1037063fbf2SJoel Becker int flags, const char *dev_name, void *data) 1047063fbf2SJoel Becker { 1057063fbf2SJoel Becker return get_sb_single(fs_type, flags, data, configfs_fill_super); 1067063fbf2SJoel Becker } 1077063fbf2SJoel Becker 1087063fbf2SJoel Becker static struct file_system_type configfs_fs_type = { 1097063fbf2SJoel Becker .owner = THIS_MODULE, 1107063fbf2SJoel Becker .name = "configfs", 1117063fbf2SJoel Becker .get_sb = configfs_get_sb, 1127063fbf2SJoel Becker .kill_sb = kill_litter_super, 1137063fbf2SJoel Becker }; 1147063fbf2SJoel Becker 1157063fbf2SJoel Becker int configfs_pin_fs(void) 1167063fbf2SJoel Becker { 1177063fbf2SJoel Becker return simple_pin_fs("configfs", &configfs_mount, 1187063fbf2SJoel Becker &configfs_mnt_count); 1197063fbf2SJoel Becker } 1207063fbf2SJoel Becker 1217063fbf2SJoel Becker void configfs_release_fs(void) 1227063fbf2SJoel Becker { 1237063fbf2SJoel Becker simple_release_fs(&configfs_mount, &configfs_mnt_count); 1247063fbf2SJoel Becker } 1257063fbf2SJoel Becker 1267063fbf2SJoel Becker 1277063fbf2SJoel Becker static decl_subsys(config, NULL, NULL); 1287063fbf2SJoel Becker 1297063fbf2SJoel Becker static int __init configfs_init(void) 1307063fbf2SJoel Becker { 1317063fbf2SJoel Becker int err; 1327063fbf2SJoel Becker 1337063fbf2SJoel Becker kset_set_kset_s(&config_subsys, kernel_subsys); 1347063fbf2SJoel Becker err = subsystem_register(&config_subsys); 1357063fbf2SJoel Becker if (err) 1367063fbf2SJoel Becker return err; 1377063fbf2SJoel Becker 1387063fbf2SJoel Becker err = register_filesystem(&configfs_fs_type); 1397063fbf2SJoel Becker if (err) { 1407063fbf2SJoel Becker printk(KERN_ERR "configfs: Unable to register filesystem!\n"); 1417063fbf2SJoel Becker subsystem_unregister(&config_subsys); 1427063fbf2SJoel Becker } 1437063fbf2SJoel Becker 1447063fbf2SJoel Becker return err; 1457063fbf2SJoel Becker } 1467063fbf2SJoel Becker 1477063fbf2SJoel Becker static void __exit configfs_exit(void) 1487063fbf2SJoel Becker { 1497063fbf2SJoel Becker unregister_filesystem(&configfs_fs_type); 1507063fbf2SJoel Becker subsystem_unregister(&config_subsys); 1517063fbf2SJoel Becker } 1527063fbf2SJoel Becker 1537063fbf2SJoel Becker MODULE_AUTHOR("Oracle"); 1547063fbf2SJoel Becker MODULE_LICENSE("GPL"); 1557063fbf2SJoel Becker MODULE_VERSION("0.0.1"); 1567063fbf2SJoel Becker MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration."); 1577063fbf2SJoel Becker 1587063fbf2SJoel Becker module_init(configfs_init); 1597063fbf2SJoel Becker module_exit(configfs_exit); 160