public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: linux-kernel@vger.kernel.org
Subject: [ANNOUNCE] ndevfs - a "nano" devfs
Date: Fri, 24 Jun 2005 01:18:08 -0700	[thread overview]
Message-ID: <20050624081808.GA26174@kroah.com> (raw)

Now I just know I'm going to regret this somehow...

Anyway, here's yet-another-ramfs-based filesystem, ndevfs.  It's a very
tiny:
$ size fs/ndevfs/inode.o 
   text    data     bss     dec     hex filename
   1571     200       8    1779     6f3 fs/ndevfs/inode.o
replacement for devfs for those embedded users who just can't live
without the damm thing.  It doesn't allow subdirectories, and only uses
LSB compliant names.  But it works, and should be enough for people to
use, if they just can't wean themselves off of the idea of an in-kernel
fs to provide device nodes.

Now, with this, is there still anyone out there who just can't live
without devfs in their kernel?

Damm, the depths I've sunk to these days, I'm such a people pleaser...

Comments?  Questions?  Criticisms?

I need sleep.

greg k-h
---------------

ndevfs - a "nano" devfs

For embedded people to use since they seem to hate userspace.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/base/class.c   |    3 
 fs/Kconfig             |    3 
 fs/Makefile            |    1 
 fs/ndevfs/Makefile     |    4 
 fs/ndevfs/inode.c      |  249 +++++++++++++++++++++++++++++++++++++++++++++++++
 fs/partitions/check.c  |    6 +
 include/linux/ndevfs.h |   13 ++
 7 files changed, 279 insertions(+)

--- gregkh-2.6.orig/fs/Kconfig	2005-06-24 01:05:59.000000000 -0700
+++ gregkh-2.6/fs/Kconfig	2005-06-24 01:06:02.000000000 -0700
@@ -1700,6 +1700,9 @@
 config RXRPC
 	tristate
 
+config NDEV_FS
+	bool "Nano Device File System"
+
 endmenu
 
 menu "Partition Types"
--- gregkh-2.6.orig/fs/Makefile	2005-06-24 01:05:59.000000000 -0700
+++ gregkh-2.6/fs/Makefile	2005-06-24 01:06:02.000000000 -0700
@@ -95,3 +95,4 @@
 obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
+obj-$(CONFIG_NDEV_FS)		+= ndevfs/
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gregkh-2.6/include/linux/ndevfs.h	2005-06-24 01:06:02.000000000 -0700
@@ -0,0 +1,13 @@
+#ifndef _NDEVFS_H_
+#define _NDEVFS_H_
+
+#if defined(CONFIG_NDEV_FS)
+extern void ndevfs_create(const char *name, dev_t dev, int is_char);
+extern void ndevfs_remove(const char *name);
+#else
+static inline void ndevfs_create(const char *name, dev_t dev, int is_char) {}
+static inline void ndevfs_remove(const char *name) {}
+#endif
+
+#endif
+
--- gregkh-2.6.orig/drivers/base/class.c	2005-06-24 01:05:59.000000000 -0700
+++ gregkh-2.6/drivers/base/class.c	2005-06-24 01:06:02.000000000 -0700
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/kdev_t.h>
 #include <linux/err.h>
+#include <linux/ndevfs.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -492,6 +493,7 @@
 		attr->store = NULL;
 		class_device_create_file(class_dev, attr);
 		class_dev->devt_attr = attr;
+		ndevfs_create(class_dev->class_id, class_dev->devt, 1);
 	}
 
 	class_device_add_attrs(class_dev);
@@ -595,6 +597,7 @@
 		class_device_remove_file(class_dev, class_dev->devt_attr);
 		kfree(class_dev->devt_attr);
 		class_dev->devt_attr = NULL;
+		ndevfs_remove(class_dev->class_id);
 	}
 	class_device_remove_attrs(class_dev);
 
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gregkh-2.6/fs/ndevfs/Makefile	2005-06-24 01:06:02.000000000 -0700
@@ -0,0 +1,4 @@
+ndevfs-objs	:= inode.o
+
+obj-$(CONFIG_NDEV_FS)	+= ndevfs.o
+
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gregkh-2.6/fs/ndevfs/inode.c	2005-06-24 01:06:02.000000000 -0700
@@ -0,0 +1,249 @@
+/*
+ *  inode.c - part of ndevfs, a tiny little device file system
+ *
+ *  Copyright (C) 2004,2005 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License version
+ *	2 as published by the Free Software Foundation.
+ *
+ * Written for all of the people out there who just hate userspace solutions.
+ *
+ */
+
+/* uncomment to get debug messages */
+#define DEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/device.h>
+#include <linux/ndevfs.h>
+
+#define MAGIC	0x64756d62
+
+struct entry {
+	struct list_head node;
+	struct dentry *dentry;
+	char name[BUS_ID_SIZE];
+};
+static LIST_HEAD(entries);
+
+static struct vfsmount *mount;
+static int mount_count;
+
+static struct file_operations stupid_file_ops = {
+	.read	= generic_file_read,
+	.write	= generic_file_write,
+	.mmap	= generic_file_mmap,
+	.fsync	= simple_sync_file,
+	.llseek	= generic_file_llseek,
+};
+
+static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = 0;
+		inode->i_gid = 0;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &stupid_file_ops;
+			break;
+		case S_IFDIR:
+			inode->i_op = &simple_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2 (for "." entry) */
+			inode->i_nlink++;
+			break;
+		}
+	}
+	return inode;
+}
+
+/* SMP-safe */
+static int mknod(struct inode *dir, struct dentry *dentry,
+			 int mode, dev_t dev)
+{
+	struct inode *inode = get_inode(dir->i_sb, mode, dev);
+	int error = -EPERM;
+
+	if (dentry->d_inode)
+		return -EEXIST;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);
+		error = 0;
+	}
+	return error;
+}
+
+static inline int positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr files[] = {{""}};
+
+	return simple_fill_super(sb, MAGIC, files);
+}
+
+static struct super_block *get_sb(struct file_system_type *fs_type,
+				  int flags, const char *dev_name,
+				  void *data)
+{
+	return get_sb_single(fs_type, flags, data, fill_super);
+}
+
+static void remove(struct dentry *dentry)
+{
+	struct dentry *parent;
+
+	if (!dentry)
+		return;
+
+	parent = dentry->d_parent;
+	if (!parent || !parent->d_inode)
+		return;
+
+	down(&parent->d_inode->i_sem);
+	if (positive(dentry)) {
+		if (dentry->d_inode) {
+			if (S_ISDIR(dentry->d_inode->i_mode))
+				simple_rmdir(parent->d_inode, dentry);
+			else
+				simple_unlink(parent->d_inode, dentry);
+		dput(dentry);
+		}
+	}
+	up(&parent->d_inode->i_sem);
+	simple_release_fs(&mount, &mount_count);
+}
+
+/**
+ * ndevfs_create - create a device node in ndevfs
+ *
+ * @name: the name to create
+ * @dev: the dev_t of the node
+ * @is_char: if the node is a char device or not
+ */
+void ndevfs_create(const char *name, dev_t dev, int is_char)
+{
+	struct dentry *parent;
+	struct dentry *dentry;
+	struct entry *entry;
+	int err;
+	int mode = S_IRUSR | S_IWUSR;
+
+	pr_debug("ndevfs: creating file '%s' with major %d and minor %d\n",
+		 name, MAJOR(dev), MINOR(dev));
+
+	if (is_char)
+		mode |= S_IFCHR;
+	else
+		mode |= S_IFBLK;
+
+	err = simple_pin_fs("ndevfs", &mount, &mount_count);
+	if (err)
+		return;
+
+	/* everything is at the root fs, no directories allowed */
+	if (mount && mount->mnt_sb) {
+		parent = mount->mnt_sb->s_root;
+	} else {
+		pr_debug("%s: no parent?\n", __FUNCTION__);
+		goto error;
+	}
+
+	down(&parent->d_inode->i_sem);
+	dentry = lookup_one_len(name, parent, strlen(name));
+	if (!IS_ERR(dentry))
+		err = mknod(parent->d_inode, dentry, mode, dev);
+	else
+		err = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+
+	if (err)
+		goto error;
+
+	entry = kmalloc(sizeof(struct entry), GFP_KERNEL);
+	if (!entry) {
+		remove(dentry);
+		err = -ENOMEM;
+		goto error;
+	}
+	entry->dentry = dentry;
+	strcpy(&entry->name[0], name);
+	list_add(&entry->node, &entries);
+	return;
+
+error:
+	pr_debug("%s failed with error %d\n", __FUNCTION__, err);
+	simple_release_fs(&mount, &mount_count);
+}
+EXPORT_SYMBOL_GPL(ndevfs_create);
+
+/**
+ * ndevfs_remove - removes the node from the fs
+ *
+ * @name: the name to remove.
+ */
+void ndevfs_remove(const char *name)
+{
+	struct entry *entry;
+	struct dentry *dentry = NULL;
+
+	pr_debug("ndevfs: removing file '%s'\n", name);
+
+	list_for_each_entry(entry, &entries, node) {
+		if (strcmp(name, &entry->name[0]) == 0) {
+			dentry = entry->dentry;
+			break;
+		}
+	}
+	if (!dentry) {
+		pr_debug("%s: can't find %s\n", __FUNCTION__, name);
+		return;
+	}
+	remove (dentry);
+}
+EXPORT_SYMBOL_GPL(ndevfs_remove);
+
+static struct file_system_type fs_type = {
+	.owner =	THIS_MODULE,
+	.name =		"ndevfs",
+	.get_sb =	get_sb,
+	.kill_sb =	kill_litter_super,
+};
+
+static int __init ndevfs_init(void)
+{
+	return register_filesystem(&fs_type);
+}
+
+static void __exit ndevfs_exit(void)
+{
+	simple_release_fs(&mount, &mount_count);
+	unregister_filesystem(&fs_type);
+}
+
+core_initcall(ndevfs_init);
+module_exit(ndevfs_exit);
+MODULE_LICENSE("GPL");
+
--- gregkh-2.6.orig/fs/partitions/check.c	2005-06-24 01:05:59.000000000 -0700
+++ gregkh-2.6/fs/partitions/check.c	2005-06-24 01:06:02.000000000 -0700
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/kmod.h>
 #include <linux/ctype.h>
+#include <linux/ndevfs.h>
 
 #include "check.h"
 
@@ -273,6 +274,7 @@
 	p->start_sect = 0;
 	p->nr_sects = 0;
 	p->reads = p->writes = p->read_sectors = p->write_sectors = 0;
+	ndevfs_remove(kobject_name(&p->kobj));
 	kobject_unregister(&p->kobj);
 }
 
@@ -296,6 +298,7 @@
 	p->kobj.parent = &disk->kobj;
 	p->kobj.ktype = &ktype_part;
 	kobject_register(&p->kobj);
+	ndevfs_create(kobject_name(&p->kobj), MKDEV(disk->major, p->partno), 0);
 	disk->part[part-1] = p;
 }
 
@@ -323,6 +326,8 @@
 	if ((err = kobject_add(&disk->kobj)))
 		return;
 	disk_sysfs_symlinks(disk);
+	ndevfs_create(kobject_name(&disk->kobj),
+		      MKDEV(disk->major, disk->first_minor), 0);
 	kobject_hotplug(&disk->kobj, KOBJ_ADD);
 
 	/* No minors to use for partitions */
@@ -420,6 +425,7 @@
 		sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
 		put_device(disk->driverfs_dev);
 	}
+	ndevfs_remove(kobject_name(&disk->kobj));
 	kobject_hotplug(&disk->kobj, KOBJ_REMOVE);
 	kobject_del(&disk->kobj);
 }

             reply	other threads:[~2005-06-24  8:22 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-24  8:18 Greg KH [this message]
2005-06-24 12:23 ` [ANNOUNCE] ndevfs - a "nano" devfs Michael Tokarev
2005-06-24 15:16   ` Greg KH
2005-06-24 15:40     ` Michael Tokarev
2005-06-24 16:26       ` Greg KH
2005-06-24 14:32 ` Bill Gatliff
2005-06-24 15:17 ` Steven Rostedt
2005-06-24 15:20   ` Greg KH
2005-06-24 17:10 ` Michael Tokarev
2005-06-24 17:10 ` Bill Gatliff
2005-06-28  7:40   ` Greg KH
2005-06-24 19:05 ` Mike Bell
2005-06-24 21:55   ` J.A. Magallon
2005-06-24 19:22 ` Alexey Dobriyan
2005-06-25  0:57 ` Kyle Moffett
2005-06-25  7:37   ` Denis Vlasenko
2005-06-28  7:41   ` Greg KH
2005-06-28 19:56     ` Tom Rini
2005-06-28 21:08       ` Olaf Hering
2005-06-28 21:25         ` Tom Rini
2005-06-28 22:08           ` Michael Tokarev
2005-06-28 22:23             ` Tom Rini
2005-06-25 22:15 ` Matt Mackall
2005-06-25 23:43   ` Greg KH
2005-06-26  8:23     ` Russell King
2005-06-28  3:36       ` Greg KH
2005-06-27  7:19     ` Mike Bell
2005-06-27 22:35       ` Dmitry Torokhov
2005-06-27 23:26         ` Mike Bell
2005-06-28  7:40           ` Greg KH
2005-06-28  9:08             ` Mike Bell
2005-06-28  9:21               ` Arjan van de Ven
2005-06-28  9:40                 ` Mike Bell
2005-06-28 21:49                 ` Jim Crilly
2005-06-28 22:23                   ` Mike Bell
2005-06-28 23:43                     ` Jim Crilly
2005-06-29  0:12                       ` Mike Bell
2005-06-29  0:39                         ` David Lang
2005-06-29  0:53                           ` Mike Bell
2005-06-28 12:00             ` Oliver Neukum
2005-06-28 20:08               ` Greg KH
2005-06-29  6:41                 ` Oliver Neukum
2005-06-29 16:06                   ` Greg KH
2005-06-29 16:22                     ` Oliver Neukum
     [not found] ` <200506270819.20108.arnd@arndb.de>
2005-06-28  3:46   ` Greg KH
     [not found] <OF831AC472.851744FE-ON8025702A.004A57EC-8025702A.004B5AE9@sophos.com>
2005-06-24 15:23 ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2005-06-24 15:32 tvrtko.ursulin
2005-06-24 16:27 ` Greg KH
2005-06-27 15:21 Adam J. Richter
2005-06-27 23:27 ` J.A. Magallon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050624081808.GA26174@kroah.com \
    --to=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox