From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: Tejun Heo <htejun@gmail.com>, Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 65/75] sysfs: implement sysfs_open_dirent
Date: Fri, 12 Oct 2007 15:17:09 -0700 [thread overview]
Message-ID: <11922277441791-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <11922277403355-git-send-email-gregkh@suse.de>
From: Tejun Heo <htejun@gmail.com>
Implement sysfs_open_dirent which represents an open file (attribute)
sysfs_dirent. A file sysfs_dirent with one or more open files have
one sysfs_dirent and all sysfs_buffers (one for each open instance)
are linked to it.
sysfs_open_dirent doesn't actually do anything yet but will be used to
off-load things which are specific for open file sysfs_dirent from it.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/sysfs/file.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
fs/sysfs/sysfs.h | 3 +
2 files changed, 111 insertions(+), 1 deletions(-)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 3c91a57..b13ba94 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -49,6 +49,22 @@ static struct sysfs_ops subsys_sysfs_ops = {
.store = subsys_attr_store,
};
+/*
+ * There's one sysfs_buffer for each open file and one
+ * sysfs_open_dirent for each sysfs_dirent with one or more open
+ * files.
+ *
+ * filp->private_data points to sysfs_buffer and
+ * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open
+ * is protected by sysfs_open_dirent_lock.
+ */
+static spinlock_t sysfs_open_dirent_lock = SPIN_LOCK_UNLOCKED;
+
+struct sysfs_open_dirent {
+ atomic_t refcnt;
+ struct list_head buffers; /* goes through sysfs_buffer.list */
+};
+
struct sysfs_buffer {
size_t count;
loff_t pos;
@@ -57,6 +73,7 @@ struct sysfs_buffer {
struct mutex mutex;
int needs_read_fill;
int event;
+ struct list_head list;
};
/**
@@ -237,6 +254,86 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
return len;
}
+/**
+ * sysfs_get_open_dirent - get or create sysfs_open_dirent
+ * @sd: target sysfs_dirent
+ * @buffer: sysfs_buffer for this instance of open
+ *
+ * If @sd->s_attr.open exists, increment its reference count;
+ * otherwise, create one. @buffer is chained to the buffers
+ * list.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
+ struct sysfs_buffer *buffer)
+{
+ struct sysfs_open_dirent *od, *new_od = NULL;
+
+ retry:
+ spin_lock(&sysfs_open_dirent_lock);
+
+ if (!sd->s_attr.open && new_od) {
+ sd->s_attr.open = new_od;
+ new_od = NULL;
+ }
+
+ od = sd->s_attr.open;
+ if (od) {
+ atomic_inc(&od->refcnt);
+ list_add_tail(&buffer->list, &od->buffers);
+ }
+
+ spin_unlock(&sysfs_open_dirent_lock);
+
+ if (od) {
+ kfree(new_od);
+ return 0;
+ }
+
+ /* not there, initialize a new one and retry */
+ new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
+ if (!new_od)
+ return -ENOMEM;
+
+ atomic_set(&new_od->refcnt, 0);
+ INIT_LIST_HEAD(&new_od->buffers);
+ goto retry;
+}
+
+/**
+ * sysfs_put_open_dirent - put sysfs_open_dirent
+ * @sd: target sysfs_dirent
+ * @buffer: associated sysfs_buffer
+ *
+ * Put @sd->s_attr.open and unlink @buffer from the buffers list.
+ * If reference count reaches zero, disassociate and free it.
+ *
+ * LOCKING:
+ * None.
+ */
+static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
+ struct sysfs_buffer *buffer)
+{
+ struct sysfs_open_dirent *od = sd->s_attr.open;
+
+ spin_lock(&sysfs_open_dirent_lock);
+
+ list_del(&buffer->list);
+ if (atomic_dec_and_test(&od->refcnt))
+ sd->s_attr.open = NULL;
+ else
+ od = NULL;
+
+ spin_unlock(&sysfs_open_dirent_lock);
+
+ kfree(od);
+}
+
static int sysfs_open_file(struct inode *inode, struct file *file)
{
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
@@ -298,19 +395,29 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
buffer->ops = ops;
file->private_data = buffer;
+ /* make sure we have open dirent struct */
+ error = sysfs_get_open_dirent(attr_sd, buffer);
+ if (error)
+ goto err_free;
+
/* open succeeded, put active references */
sysfs_put_active_two(attr_sd);
return 0;
+ err_free:
+ kfree(buffer);
err_out:
sysfs_put_active_two(attr_sd);
return error;
}
-static int sysfs_release(struct inode * inode, struct file * filp)
+static int sysfs_release(struct inode *inode, struct file *filp)
{
+ struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
struct sysfs_buffer *buffer = filp->private_data;
+ sysfs_put_open_dirent(sd, buffer);
+
if (buffer->page)
free_page((unsigned long)buffer->page);
kfree(buffer);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 42b0327..3adce7d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -1,3 +1,5 @@
+struct sysfs_open_dirent;
+
/* type-specific structures for sysfs_dirent->s_* union members */
struct sysfs_elem_dir {
struct kobject *kobj;
@@ -11,6 +13,7 @@ struct sysfs_elem_symlink {
struct sysfs_elem_attr {
struct attribute *attr;
+ struct sysfs_open_dirent *open;
};
struct sysfs_elem_bin_attr {
--
1.5.3.4
next prev parent reply other threads:[~2007-10-12 22:56 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20071012221251.GB4559@kroah.com\>
2007-10-12 22:16 ` [PATCH 01/75] platform: prefix MODALIAS with "platform:" Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 02/75] HOWTO: update ja_JP/HOWTO with latest changes Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 03/75] Driver core: make sysfs uevent-attributes static Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 04/75] Driver core: change add_uevent_var to use a struct Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 05/75] Driver core: add CONFIG_UEVENT_HELPER_PATH Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 06/75] Driver core: remove subsys_set_kset Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 07/75] Driver core: remove kset_set_kset_s Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 08/75] Driver core: remove subsys_put() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 09/75] Driver core: remove subsys_get() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 10/75] Driver core: remove put_bus() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 11/75] Driver core: remove get_bus() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 12/75] kobjects: fix up improper use of the kobject name field Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 13/75] cdev: remove unneeded setting of cdev names Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 14/75] Drivers: clean up direct setting of the name of a kset Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 15/75] kobject: remove the static array for the name Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 16/75] Driver core: clean up removed functions from the documentation Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 17/75] debugfs: helper for decimal challenged Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 18/75] sysfs/file.c - use mutex instead of semaphore Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 19/75] sysfs: cleanup semaphore.h Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 20/75] sysfs: Remove first pass at shadow directory support Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 21/75] sysfs: cosmetic changes in sysfs_lookup() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 22/75] sysfs: simplify sysfs_rename_dir() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 23/75] sysfs: make sysfs_add/remove_one() call link/unlink_sibling() implictly Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 24/75] sysfs: make sysfs_add_one() automatically check for duplicate entry Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 25/75] sysfs: make sysfs_addrm_finish() return void Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 26/75] dmi-id: Use dynamic sysfs attributes Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 27/75] dmi-id: Possible cleanup Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 28/75] Convert from class_device to device for drivers/video Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 29/75] Convert from class_device to device in drivers/char Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 30/75] Driver core: exclude kobject_uevent.c for !CONFIG_HOTPLUG Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 31/75] Driver core: add uevent file for bus and driver Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 32/75] Driver core: kerneldoc - kobject_uevent_env is not "usually KOBJ_MOVE" Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 33/75] Fix Firmware class name collision Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 34/75] drivers/base/power/: make 2 functions static Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 35/75] sysfs: Fix typos in fs/sysfs/file.c Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 36/75] sysdev: remove global sysdev drivers list Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 37/75] Driver core: Make platform_device.id an int Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 38/75] sysfs: fix i_mutex locking in sysfs_get_dentry() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 39/75] sysfs: Move all of inode initialization into sysfs_init_inode Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 40/75] sysfs: Remove sysfs_instantiate Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 41/75] sysfs: Use kill_anon_super Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 42/75] sysfs: Make sysfs_mount static Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 43/75] sysfs: In sysfs_lookup don't open code sysfs_find_dirent Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 44/75] sysfs: Simplify readdir Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 45/75] sysfs: Rewrite sysfs_drop_dentry Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 46/75] sysfs: Introduce sysfs_rename_mutex Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 47/75] sysfs: simply sysfs_get_dentry Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 48/75] sysfs: Remove s_dentry Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 49/75] sysfs: Rewrite rename in terms of sysfs dirents Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 50/75] sysfs: Rewrite sysfs_move_dir " Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 51/75] PTY: add kernel parameter to overwrite legacy pty count Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 52/75] sysfs: spit a warning to users when they try to create a duplicate sysfs file Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 53/75] sysfs: fix comments of sysfs_add/remove_one() Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 54/75] sysfs: fix sysfs_chmod_file() such that it updates sd->s_mode too Greg Kroah-Hartman
2007-10-12 22:16 ` [PATCH 55/75] sysfs: clean up header files Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 56/75] sysfs: kill sysfs_update_file() Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 57/75] sysfs: reposition sysfs_dirent->s_mode Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 58/75] sysfs: kill unnecessary sysfs_get() in open paths Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 59/75] sysfs: kill unnecessary NULL pointer check in sysfs_release() Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 60/75] sysfs: make bin attr open get active reference of parent too Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 61/75] sysfs: make s_elem an anonymous union Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 62/75] sysfs: open code sysfs_attach_dentry() Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 63/75] sysfs: make sysfs_root a regular directory dirent Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 64/75] sysfs: move sysfs_dirent->s_children into sysfs_dirent->s_dir Greg Kroah-Hartman
2007-10-12 22:17 ` Greg Kroah-Hartman [this message]
2007-10-12 22:17 ` [PATCH 66/75] sysfs: move sysfs file poll implementation to sysfs_open_dirent Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 67/75] driver core: remove subsystem_init() Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 68/75] Driver core: rename ktype_class Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 69/75] Driver core: rename ktype_device Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 70/75] Driver core: rename ktype_driver Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 71/75] Driver core: rename ktype_edd and ktype_efivar Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 72/75] kset: add some kerneldoc to help describe what these strange things are Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 73/75] kobject: update the copyrights Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 74/75] sysfs: add copyrights Greg Kroah-Hartman
2007-10-12 22:17 ` [PATCH 75/75] PM: merge device power-management source files Greg Kroah-Hartman
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=11922277441791-git-send-email-gregkh@suse.de \
--to=gregkh@suse.de \
--cc=htejun@gmail.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