Currently sysfs_new_dirent() takes @mode and @type.  @mode contains
S_IF* mask which is also duplicately indicated by @type.  This patch
sysfs_new_dirent() determine S_IF* mask and normalize @mode such that
only bits from S_IALLUGO is taken as @mode.

This is to allow later use of unused @mode bits as special flags.

Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
---
 fs/sysfs/dir.c     |   36 +++++++++++++++++++++++++++++++++++-
 fs/sysfs/file.c    |    2 +-
 fs/sysfs/symlink.c |    2 +-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index ba631eb..02918d3 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -298,17 +298,51 @@ static struct dentry_operations sysfs_dentry_ops = {
        .d_iput         = sysfs_d_iput,
 };
 
+/**
+ *     sysfs_new_dirent - allocate and initialize sysfs_dirent
+ *     @name: name for the new sysfs_dirent
+ *     @mode: mask of bits from S_IRWXUGO
+ *     @type: one of SYSFS_{DIR|FILE|BIN|LINK}
+ *
+ *     Allocate and initialize a sysfs_dirent with the specified
+ *     parameters.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     Pointer to the new sysfs_dirent on success, NULL on allocation
+ *     failure.
+ */
 struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
 {
        char *dup_name = NULL;
        struct sysfs_dirent *sd;
 
+       /* need to copy name? */
        if (type & SYSFS_COPY_NAME) {
                name = dup_name = kstrdup(name, GFP_KERNEL);
                if (!name)
                        return NULL;
        }
 
+       /* normalize mode */
+       mode &= S_IALLUGO;
+
+       switch (type) {
+       case SYSFS_DIR:
+               mode |= S_IFDIR;
+               break;
+       case SYSFS_KOBJ_ATTR:
+       case SYSFS_KOBJ_BIN_ATTR:
+               mode |= S_IFREG;
+               break;
+       case SYSFS_KOBJ_LINK:
+               mode |= S_IFLNK;
+               break;
+       }
+
+       /* allocate and initialize */
        sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
        if (!sd)
                goto err_out1;
@@ -607,7 +641,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent 
*parent_sd,
 static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
                      const char *name, struct sysfs_dirent **p_sd)
 {
-       umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+       umode_t mode = S_IRWXU | S_IRUGO | S_IXUGO;
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
        int rc;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 5d708ff..8d8e1ee 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -571,7 +571,7 @@ const struct file_operations sysfs_file_operations = {
 int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
                   int type)
 {
-       umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
+       umode_t mode = attr->mode & S_IALLUGO;
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
        int rc;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 6b3358e..bf96bcd 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -82,7 +82,7 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * 
target, const char
                goto out_put;
 
        error = -ENOMEM;
-       sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+       sd = sysfs_new_dirent(name, S_IRWXUGO, SYSFS_KOBJ_LINK);
        if (!sd)
                goto out_put;
 
-- 
1.5.0.3


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to