Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196053
b: refs/heads/master
c: 3ff195b
h: refs/heads/master
i:
  196051: 8067c8e
v: v3
  • Loading branch information
Eric W. Biederman authored and Greg Kroah-Hartman committed May 21, 2010
1 parent 01ce34a commit 1832c0e
Show file tree
Hide file tree
Showing 14 changed files with 182 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc451f2058238013e1cdf4acd443c01734d332f0
refs/heads/master: 3ff195b011d7decf501a4d55aeed312731094796
2 changes: 1 addition & 1 deletion trunk/drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
goto free_id;
}

pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");
if (!pdesc->value_sd) {
ret = -ENODEV;
goto free_id;
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/md/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1678,9 +1678,9 @@ int bitmap_create(mddev_t *mddev)

bitmap->mddev = mddev;

bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
bm = sysfs_get_dirent(mddev->kobj.sd, NULL, "bitmap");
if (bm) {
bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear");
bitmap->sysfs_can_clear = sysfs_get_dirent(bm, NULL, "can_clear");
sysfs_put(bm);
} else
bitmap->sysfs_can_clear = NULL;
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
kobject_del(&rdev->kobj);
goto fail;
}
rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, "state");
rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, NULL, "state");

list_add_rcu(&rdev->same_set, &mddev->disks);
bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk);
Expand Down Expand Up @@ -4189,7 +4189,7 @@ static int md_alloc(dev_t dev, char *name)
mutex_unlock(&disks_mutex);
if (!error) {
kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state");
mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, NULL, "array_state");
}
mddev_put(mddev);
return error;
Expand Down Expand Up @@ -4398,7 +4398,7 @@ static int do_md_run(mddev_t * mddev)
printk(KERN_WARNING
"md: cannot register extra attributes for %s\n",
mdname(mddev));
mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, NULL, "sync_action");
} else if (mddev->ro == 2) /* auto-readonly not meaningful */
mddev->ro = 0;

Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/sysfs/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ int sysfs_create_bin_file(struct kobject *kobj,
void sysfs_remove_bin_file(struct kobject *kobj,
const struct bin_attribute *attr)
{
sysfs_hash_and_remove(kobj->sd, attr->attr.name);
sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
}

EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
Expand Down
112 changes: 88 additions & 24 deletions trunk/fs/sysfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,15 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
{
struct sysfs_inode_attrs *ps_iattr;

if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
return -EEXIST;

if (sysfs_ns_type(acxt->parent_sd) && !sd->s_ns) {
WARN(1, KERN_WARNING "sysfs: ns required in '%s' for '%s'\n",
acxt->parent_sd->s_name, sd->s_name);
return -EINVAL;
}

sd->s_parent = sysfs_get(acxt->parent_sd);

sysfs_link_sibling(sd);
Expand Down Expand Up @@ -533,13 +539,17 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
* Pointer to sysfs_dirent if found, NULL if not.
*/
struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
const void *ns,
const unsigned char *name)
{
struct sysfs_dirent *sd;

for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling)
for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
if (sd->s_ns != ns)
continue;
if (!strcmp(sd->s_name, name))
return sd;
}
return NULL;
}

Expand All @@ -558,12 +568,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
* Pointer to sysfs_dirent if found, NULL if not.
*/
struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
const void *ns,
const unsigned char *name)
{
struct sysfs_dirent *sd;

mutex_lock(&sysfs_mutex);
sd = sysfs_find_dirent(parent_sd, name);
sd = sysfs_find_dirent(parent_sd, ns, name);
sysfs_get(sd);
mutex_unlock(&sysfs_mutex);

Expand All @@ -572,7 +583,8 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
EXPORT_SYMBOL_GPL(sysfs_get_dirent);

static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
const char *name, struct sysfs_dirent **p_sd)
enum kobj_ns_type type, const void *ns, const char *name,
struct sysfs_dirent **p_sd)
{
umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
struct sysfs_addrm_cxt acxt;
Expand All @@ -583,6 +595,9 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
if (!sd)
return -ENOMEM;

sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);
sd->s_ns = ns;
sd->s_dir.kobj = kobj;

/* link in */
Expand All @@ -601,7 +616,25 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
int sysfs_create_subdir(struct kobject *kobj, const char *name,
struct sysfs_dirent **p_sd)
{
return create_dir(kobj, kobj->sd, name, p_sd);
return create_dir(kobj, kobj->sd,
KOBJ_NS_TYPE_NONE, NULL, name, p_sd);
}

static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
{
const struct kobj_ns_type_operations *ops;
enum kobj_ns_type type;

ops = kobj_child_ns_ops(kobj);
if (!ops)
return KOBJ_NS_TYPE_NONE;

type = ops->type;
BUG_ON(type <= KOBJ_NS_TYPE_NONE);
BUG_ON(type >= KOBJ_NS_TYPES);
BUG_ON(!kobj_ns_type_registered(type));

return type;
}

/**
Expand All @@ -610,7 +643,9 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
*/
int sysfs_create_dir(struct kobject * kobj)
{
enum kobj_ns_type type;
struct sysfs_dirent *parent_sd, *sd;
const void *ns = NULL;
int error = 0;

BUG_ON(!kobj);
Expand All @@ -620,7 +655,11 @@ int sysfs_create_dir(struct kobject * kobj)
else
parent_sd = &sysfs_root;

error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
if (sysfs_ns_type(parent_sd))
ns = kobj->ktype->namespace(kobj);
type = sysfs_read_ns_type(kobj);

error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
if (!error)
kobj->sd = sd;
return error;
Expand All @@ -630,13 +669,19 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
struct dentry *ret = NULL;
struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata;
struct dentry *parent = dentry->d_parent;
struct sysfs_dirent *parent_sd = parent->d_fsdata;
struct sysfs_dirent *sd;
struct inode *inode;
enum kobj_ns_type type;
const void *ns;

mutex_lock(&sysfs_mutex);

sd = sysfs_find_dirent(parent_sd, dentry->d_name.name);
type = sysfs_ns_type(parent_sd);
ns = sysfs_info(dir->i_sb)->ns[type];

sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name);

/* no such entry */
if (!sd) {
Expand Down Expand Up @@ -735,20 +780,21 @@ void sysfs_remove_dir(struct kobject * kobj)
}

int sysfs_rename(struct sysfs_dirent *sd,
struct sysfs_dirent *new_parent_sd, const char *new_name)
struct sysfs_dirent *new_parent_sd, const void *new_ns,
const char *new_name)
{
const char *dup_name = NULL;
int error;

mutex_lock(&sysfs_mutex);

error = 0;
if ((sd->s_parent == new_parent_sd) &&
if ((sd->s_parent == new_parent_sd) && (sd->s_ns == new_ns) &&
(strcmp(sd->s_name, new_name) == 0))
goto out; /* nothing to rename */

error = -EEXIST;
if (sysfs_find_dirent(new_parent_sd, new_name))
if (sysfs_find_dirent(new_parent_sd, new_ns, new_name))
goto out;

/* rename sysfs_dirent */
Expand All @@ -770,6 +816,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
sd->s_parent = new_parent_sd;
sysfs_link_sibling(sd);
}
sd->s_ns = new_ns;

error = 0;
out:
Expand All @@ -780,19 +827,28 @@ int sysfs_rename(struct sysfs_dirent *sd,

int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
{
return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name);
struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
const void *new_ns = NULL;

if (sysfs_ns_type(parent_sd))
new_ns = kobj->ktype->namespace(kobj);

return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
}

int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
{
struct sysfs_dirent *sd = kobj->sd;
struct sysfs_dirent *new_parent_sd;
const void *new_ns = NULL;

BUG_ON(!sd->s_parent);
if (sysfs_ns_type(sd->s_parent))
new_ns = kobj->ktype->namespace(kobj);
new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
new_parent_kobj->sd : &sysfs_root;

return sysfs_rename(sd, new_parent_sd, sd->s_name);
return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name);
}

/* Relationship between s_mode and the DT_xxx types */
Expand All @@ -807,32 +863,35 @@ static int sysfs_dir_release(struct inode *inode, struct file *filp)
return 0;
}

static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd,
ino_t ino, struct sysfs_dirent *pos)
static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
{
if (pos) {
int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
pos->s_parent == parent_sd &&
ino == pos->s_ino;
sysfs_put(pos);
if (valid)
return pos;
if (!valid)
pos = NULL;
}
pos = NULL;
if ((ino > 1) && (ino < INT_MAX)) {
if (!pos && (ino > 1) && (ino < INT_MAX)) {
pos = parent_sd->s_dir.children;
while (pos && (ino > pos->s_ino))
pos = pos->s_sibling;
}
while (pos && pos->s_ns != ns)
pos = pos->s_sibling;
return pos;
}

static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd,
ino_t ino, struct sysfs_dirent *pos)
static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
{
pos = sysfs_dir_pos(parent_sd, ino, pos);
pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
if (pos)
pos = pos->s_sibling;
while (pos && pos->s_ns != ns)
pos = pos->s_sibling;
return pos;
}

Expand All @@ -841,8 +900,13 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
struct dentry *dentry = filp->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata;
struct sysfs_dirent *pos = filp->private_data;
enum kobj_ns_type type;
const void *ns;
ino_t ino;

type = sysfs_ns_type(parent_sd);
ns = sysfs_info(dentry->d_sb)->ns[type];

if (filp->f_pos == 0) {
ino = parent_sd->s_ino;
if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
Expand All @@ -857,9 +921,9 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
filp->f_pos++;
}
mutex_lock(&sysfs_mutex);
for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos);
for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
pos;
pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) {
pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) {
const char * name;
unsigned int type;
int len, ret;
Expand Down
17 changes: 10 additions & 7 deletions trunk/fs/sysfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,12 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
mutex_lock(&sysfs_mutex);

if (sd && dir)
sd = sysfs_find_dirent(sd, dir);
/* Only directories are tagged, so no need to pass
* a tag explicitly.
*/
sd = sysfs_find_dirent(sd, NULL, dir);
if (sd && attr)
sd = sysfs_find_dirent(sd, attr);
sd = sysfs_find_dirent(sd, NULL, attr);
if (sd)
sysfs_notify_dirent(sd);

Expand Down Expand Up @@ -569,7 +572,7 @@ int sysfs_add_file_to_group(struct kobject *kobj,
int error;

if (group)
dir_sd = sysfs_get_dirent(kobj->sd, group);
dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
else
dir_sd = sysfs_get(kobj->sd);

Expand Down Expand Up @@ -599,7 +602,7 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
mutex_lock(&sysfs_mutex);

rc = -ENOENT;
sd = sysfs_find_dirent(kobj->sd, attr->name);
sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
if (!sd)
goto out;

Expand All @@ -624,7 +627,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);

void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
{
sysfs_hash_and_remove(kobj->sd, attr->name);
sysfs_hash_and_remove(kobj->sd, NULL, attr->name);
}

void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
Expand All @@ -646,11 +649,11 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
struct sysfs_dirent *dir_sd;

if (group)
dir_sd = sysfs_get_dirent(kobj->sd, group);
dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
else
dir_sd = sysfs_get(kobj->sd);
if (dir_sd) {
sysfs_hash_and_remove(dir_sd, attr->name);
sysfs_hash_and_remove(dir_sd, NULL, attr->name);
sysfs_put(dir_sd);
}
}
Expand Down
Loading

0 comments on commit 1832c0e

Please sign in to comment.