From: Maneesh Soni <maneesh@in.ibm.com>
To: Greg KH <greg@kroah.com>
Cc: linux-kernel@vger.kernel.org, Patrick Mochel <mochel@digitalimplant.org>
Subject: Re: problem with duplicate sysfs directories and files
Date: Thu, 9 Mar 2006 08:28:24 +0530 [thread overview]
Message-ID: <20060309025824.GA4483@in.ibm.com> (raw)
In-Reply-To: <20060308075342.GA17718@kroah.com>
On Tue, Mar 07, 2006 at 11:53:42PM -0800, Greg KH wrote:
> Hi,
>
> I spent some time tonight trying to track down how to fix the issue of
> duplicate sysfs files and/or directories. This happens when you try to
> create a kobject with the same name in the same directory. The creation
> of the second kobject will fail, but the directory will remain in sysfs.
>
Let me understand this. Lets say we have sysfs directory tree like
/sys/a/b/c
and someone is trying to create one more kobject with name "c" for the
parent kobject "b" ?
And are you saying that though the new creation fails but the existing
directory remains in sysfs? I think failing the new creation and leaving
the exisiting directoy is ok. But there is sysfs_dirent leakage which
does need fixing.
> Now I know this isn't a normal operation, but it would be good to fix
> this eventually. I traced the issue down to fs/sysfs/dir.c:create_dir()
> and the check for:
> if (error && (error != -EEXIST)) {
>
> Problem is, error is set to -EEXIST, so we don't clean up properly. Now
> I know we can't just not check for this, as if you do that error
> cleanup, the original kobject's sysfs entry gets very messed up (ls -l
> does not like it at all...)
>
> But I can't seem to figure out what exactly we need to do to clean up
> properly here.
>
> Do you, or anyone else, have any pointers or ideas?
>
If you are talking about the example above, to me it appears that except
a possible sysfs_dirent leakage, we are some what ok, else there would have
been more catastrophic results because of the duplicate directory dentry/inode.
As per the current code
static int create_dir(struct kobject * k, struct dentry * p,
const char * n, struct dentry ** d)
{
int error;
umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
mutex_lock(&p->d_inode->i_mutex);
*d = lookup_one_len(n, p, strlen(n));
^^^^ lookup_one_len() will return the existing dentry corresponding to
the last component "c" in "/sys/a/b/c" without any error. Just note
that VFS is not going to allocate a new dentry for it. The existing
dentry's ref count will be increased by one.
if (!IS_ERR(*d)) {
error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
^^^^ we do have problem here, a new sysfs_dirent is allocated which
replaces the existing dentry->d_fsdata and yuk... the old sysfs_dirent
is no more linked with the existing directory, there by leaking
one sysfs_dirent.
Not only for sysfs_create_dir(), I think the problem of existing sysfs_dirent
is also there with sysfs_add_file() and sysfs_add_link(). I am working on a
patch to plug this leak.
Thanks
Maneesh
--
Maneesh Soni
Linux Technology Center,
IBM India Software Labs,
Bangalore, India
email: maneesh@in.ibm.com
Phone: 91-80-51776416
o Following patch checks for existing sysfs_dirent before allocation new one.
Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
---
linux-2.6.16-rc5-git10-maneesh/fs/sysfs/dir.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+)
diff -puN fs/sysfs/dir.c~sysfs-check-existing-dirent fs/sysfs/dir.c
--- linux-2.6.16-rc5-git10/fs/sysfs/dir.c~sysfs-check-existing-dirent 2006-03-08 17:50:00.857712216 +0530
+++ linux-2.6.16-rc5-git10-maneesh/fs/sysfs/dir.c 2006-03-08 17:50:00.864711152 +0530
@@ -50,11 +50,28 @@ static struct sysfs_dirent * sysfs_new_d
return sd;
}
+/**
+ * Initialise a newly allocated sysfs_dirent and attach it to
+ * the corresponding dentry if present.
+ *
+ * Return -EEXIST if there is already a sysfs element with the same name for
+ * the same parent.
+ *
+ * called with parent inode's i_mutex held
+ */
int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
void * element, umode_t mode, int type)
{
struct sysfs_dirent * sd;
+ list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+ const unsigned char * existing = sysfs_get_name(sd);
+ if (strcmp(existing, new))
+ continue;
+ else
+ return -EEXIST;
+ }
+
sd = sysfs_new_dirent(parent_sd, element);
if (!sd)
return -ENOMEM;
_
next prev parent reply other threads:[~2006-03-09 3:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-08 7:53 problem with duplicate sysfs directories and files Greg KH
2006-03-08 9:02 ` Andrew Morton
2006-03-09 1:03 ` Greg KH
2006-03-09 2:58 ` Maneesh Soni [this message]
2006-03-09 5:58 ` Greg KH
2006-03-09 14:10 ` Maneesh Soni
2006-03-10 0:13 ` Greg KH
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=20060309025824.GA4483@in.ibm.com \
--to=maneesh@in.ibm.com \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mochel@digitalimplant.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 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.