From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Eric W. Biederman" Subject: [PATCH 26/26] sysfs: In sysfs_add_one fail if the targe directory has been removed. Date: Fri, 29 May 2009 13:19:36 -0700 Message-ID: <1243628376-22905-26-git-send-email-ebiederm@xmission.com> References: Cc: , Tejun Heo , Cornelia Huck , , Kay Sievers , Greg KH , "Eric W. Biederman" , "Eric W. Biederman" To: Andrew Morton , Greg Kroah-Hartman Return-path: Received: from out01.mta.xmission.com ([166.70.13.231]:41842 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1763418AbZE2UT5 (ORCPT ); Fri, 29 May 2009 16:19:57 -0400 In-Reply-To: Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Eric W. Biederman If a bug in the upper layers results in someone attempting to add to a sysfs directory that has already been removed, warn about it and fail. I don't believe this has ever happened, and it certainly never should happen, but be strict to avoid errors creeping in. Acked-by: Kay Sievers Acked-by: Tejun Heo Signed-off-by: Eric W. Biederman --- fs/sysfs/dir.c | 37 +++++++++++++++++++++++-------------- 1 files changed, 23 insertions(+), 14 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 7da42fb..fda141d 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -394,21 +394,17 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) int sysfs_add_one(struct sysfs_dirent *parent_sd, struct sysfs_dirent *sd) { struct iattr *ps_iattr; + char *path; + int result; mutex_lock(&sysfs_mutex); - if (sysfs_find_dirent(parent_sd, sd->s_name)) { - char *path; - mutex_unlock(&sysfs_mutex); - path = kzalloc(PATH_MAX, GFP_KERNEL); - WARN(1, KERN_WARNING - "sysfs: cannot create duplicate filename '%s'\n", - (path == NULL) ? sd->s_name : - strcat(strcat(sysfs_pathname(parent_sd, path), "/"), - sd->s_name)); - kfree(path); - return -EEXIST; - } + result = -ENOENT; + if (parent_sd->s_flags & SYSFS_FLAG_REMOVED) + goto out_err; + + if (sysfs_find_dirent(parent_sd, sd->s_name)) + goto out_err; sd->s_parent = sysfs_get(parent_sd); sysfs_link_sibling(sd); @@ -417,9 +413,22 @@ int sysfs_add_one(struct sysfs_dirent *parent_sd, struct sysfs_dirent *sd) ps_iattr = parent_sd->s_iattr; if (ps_iattr) ps_iattr->ia_ctime = ps_iattr->ia_mtime = CURRENT_TIME; - mutex_unlock(&sysfs_mutex); return 0; + +out_err: + mutex_unlock(&sysfs_mutex); + + path = kzalloc(PATH_MAX, GFP_KERNEL); + WARN(1, KERN_WARNING "sysfs: cannot create '%s' %s\n", + (path == NULL) ? sd->s_name : + strcat(strcat(sysfs_pathname(parent_sd, path), "/"), + sd->s_name), + (result == -EEXIST ? "duplicate filename" : "no such directory") + ); + kfree(path); + + return result; } /** -- 1.6.3.1.54.g99dd.dirty