From: Dan Williams <dan.j.williams@intel.com>
To: gregkh@suse.de
Cc: linux-kernel@vger.kernel.org, kay.sievers@vrfy.org,
neilb@suse.de, htejun@gmail.com, hpa@zytor.com, lkml@rtr.ca
Subject: [PATCH] sysfs: add /sys/dev/{char, block} to lookup sysfs path by major:minor
Date: Mon, 14 Apr 2008 09:57:48 -0700 [thread overview]
Message-ID: <20080414165036.13697.6532.stgit@dwillia2-linux.ch.intel.com> (raw)
Why?:
There are occasions where userspace would like to access sysfs
attributes for a device but it may not know how sysfs has named the
device or the path. For example what is the sysfs path for
/dev/disk/by-id/ata-ST3160827AS_5MT004CK? With this change a call to
stat(2) returns the major:minor then userspace can see that
/sys/dev/block/8:32 links to /sys/block/sdc.
What are the alternatives?:
1/ Add an ioctl to return the path: Doable, but sysfs is meant to reduce
the need to proliferate ioctl interfaces into the kernel, so this
seems counter productive.
2/ Use udev to create these symlinks: Also doable, but it adds a
udev dependency to utilities that might be running in a limited
environment like an initramfs.
Cc: NeilBrown <neilb@suse.de>
Cc: Tejun Heo <htejun@gmail.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Greg KH <gregkh@suse.de>
Cc: Mark Lord <lkml@rtr.ca>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
This is the second revision of the patch originally posted here:
http://marc.info/?l=linux-kernel&m=120795638915272&w=2
* Fixed up ENOMEM handling in devices_init()
* Added a short blurb in Documentation/filesystems/sysfs.txt
Documentation/filesystems/sysfs.txt | 6 +++++
drivers/base/core.c | 46 ++++++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 7f27b8f..9e9c348 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -248,6 +248,7 @@ The top level sysfs directory looks like:
block/
bus/
class/
+dev/
devices/
firmware/
net/
@@ -274,6 +275,11 @@ fs/ contains a directory for some filesystems. Currently each
filesystem wanting to export attributes must create its own hierarchy
below fs/ (see ./fuse.txt for an example).
+dev/ contains two directories char/ and block/. Inside these two
+directories there are symlinks named <major>:<minor>. These symlinks
+point to the sysfs directory for the given device. /sys/dev provides a
+quick way to lookup the sysfs interface for a device from the result of
+a stat(2) operation.
More information can driver-model specific features can be found in
Documentation/driver-model/.
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 24198ad..39db294 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -27,6 +27,9 @@
int (*platform_notify)(struct device *dev) = NULL;
int (*platform_notify_remove)(struct device *dev) = NULL;
+static struct kobject *dev_kobj;
+static struct kobject *char_kobj;
+static struct kobject *block_kobj;
#ifdef CONFIG_BLOCK
static inline int device_is_not_partition(struct device *dev)
@@ -759,6 +762,11 @@ static void device_remove_class_symlinks(struct device *dev)
sysfs_remove_link(&dev->kobj, "subsystem");
}
+static struct kobject *device_to_dev_kobj(struct device *dev)
+{
+ return dev->class == &block_class ? block_kobj : char_kobj;
+}
+
/**
* device_add - add device to device hierarchy.
* @dev: device.
@@ -775,6 +783,7 @@ int device_add(struct device *dev)
struct device *parent = NULL;
struct class_interface *class_intf;
int error;
+ char devt_str[25];
dev = get_device(dev);
if (!dev || !strlen(dev->bus_id)) {
@@ -806,9 +815,16 @@ int device_add(struct device *dev)
goto attrError;
if (MAJOR(dev->devt)) {
+ struct kobject *kobj = device_to_dev_kobj(dev);
+
error = device_create_file(dev, &devt_attr);
if (error)
goto ueventattrError;
+
+ format_dev_t(devt_str, dev->devt);
+ error = sysfs_create_link(kobj, &dev->kobj, devt_str);
+ if (error)
+ goto devtattrError;
}
error = device_add_class_symlinks(dev);
@@ -854,6 +870,9 @@ int device_add(struct device *dev)
device_remove_class_symlinks(dev);
SymlinkError:
if (MAJOR(dev->devt))
+ sysfs_remove_link(device_to_dev_kobj(dev), devt_str);
+ devtattrError:
+ if (MAJOR(dev->devt))
device_remove_file(dev, &devt_attr);
ueventattrError:
device_remove_file(dev, &uevent_attr);
@@ -925,12 +944,16 @@ void device_del(struct device *dev)
{
struct device *parent = dev->parent;
struct class_interface *class_intf;
+ char devt_str[25];
device_pm_remove(dev);
if (parent)
klist_del(&dev->knode_parent);
- if (MAJOR(dev->devt))
+ if (MAJOR(dev->devt)) {
+ format_dev_t(devt_str, dev->devt);
+ sysfs_remove_link(device_to_dev_kobj(dev), devt_str);
device_remove_file(dev, &devt_attr);
+ }
if (dev->class) {
device_remove_class_symlinks(dev);
@@ -1055,7 +1078,25 @@ int __init devices_init(void)
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
if (!devices_kset)
return -ENOMEM;
+ dev_kobj = kobject_create_and_add("dev", NULL);
+ if (!dev_kobj)
+ goto dev_kobj_err;
+ block_kobj = kobject_create_and_add("block", dev_kobj);
+ if (!block_kobj)
+ goto block_kobj_err;
+ char_kobj = kobject_create_and_add("char", dev_kobj);
+ if (!char_kobj)
+ goto char_kobj_err;
+
return 0;
+
+ char_kobj_err:
+ kobject_put(block_kobj);
+ block_kobj_err:
+ kobject_put(dev_kobj);
+ dev_kobj_err:
+ kset_unregister(devices_kset);
+ return -ENOMEM;
}
EXPORT_SYMBOL_GPL(device_for_each_child);
@@ -1380,4 +1421,7 @@ void device_shutdown(void)
dev->driver->shutdown(dev);
}
}
+ kobject_put(char_kobj);
+ kobject_put(block_kobj);
+ kobject_put(dev_kobj);
}
next reply other threads:[~2008-04-14 16:57 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-14 16:57 Dan Williams [this message]
2008-04-14 17:00 ` [PATCH] sysfs: add /sys/dev/{char, block} to lookup sysfs path by major:minor H. Peter Anvin
2008-04-15 3:13 ` SL Baur
2008-04-15 4:46 ` Dan Williams
2008-04-15 7:08 ` SL Baur
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=20080414165036.13697.6532.stgit@dwillia2-linux.ch.intel.com \
--to=dan.j.williams@intel.com \
--cc=gregkh@suse.de \
--cc=hpa@zytor.com \
--cc=htejun@gmail.com \
--cc=kay.sievers@vrfy.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lkml@rtr.ca \
--cc=neilb@suse.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.