Blame view
fs/sysfs/group.c
3.81 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * fs/sysfs/group.c - Operations for adding/removing multiple files at once. * * Copyright (c) 2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Lab * * This file is released undert the GPL v2. * */ #include <linux/kobject.h> #include <linux/module.h> #include <linux/dcache.h> |
5f45f1a78 [PATCH] remove du... |
14 |
#include <linux/namei.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 |
#include <linux/err.h> #include "sysfs.h" |
d4acd722b [SCSI] sysfs: add... |
17 |
static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
608e266a2 sysfs: make kobj ... |
18 |
const struct attribute_group *grp) |
1da177e4c Linux-2.6.12-rc2 |
19 20 |
{ struct attribute *const* attr; |
d4acd722b [SCSI] sysfs: add... |
21 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
d4acd722b [SCSI] sysfs: add... |
23 |
for (i = 0, attr = grp->attrs; *attr; i++, attr++) |
0f4238958 [SCSI] sysfs: mak... |
24 |
sysfs_hash_and_remove(dir_sd, (*attr)->name); |
1da177e4c Linux-2.6.12-rc2 |
25 |
} |
d4acd722b [SCSI] sysfs: add... |
26 |
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
0f4238958 [SCSI] sysfs: mak... |
27 |
const struct attribute_group *grp, int update) |
1da177e4c Linux-2.6.12-rc2 |
28 29 |
{ struct attribute *const* attr; |
d4acd722b [SCSI] sysfs: add... |
30 |
int error = 0, i; |
1da177e4c Linux-2.6.12-rc2 |
31 |
|
0f4238958 [SCSI] sysfs: mak... |
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { mode_t mode = 0; /* in update mode, we're changing the permissions or * visibility. Do this by first removing then * re-adding (if required) the file */ if (update) sysfs_hash_and_remove(dir_sd, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, (*attr)->mode | mode); if (unlikely(error)) break; } |
1da177e4c Linux-2.6.12-rc2 |
50 |
if (error) |
d4acd722b [SCSI] sysfs: add... |
51 |
remove_files(dir_sd, kobj, grp); |
1da177e4c Linux-2.6.12-rc2 |
52 53 |
return error; } |
0f4238958 [SCSI] sysfs: mak... |
54 55 |
static int internal_create_group(struct kobject *kobj, int update, const struct attribute_group *grp) |
1da177e4c Linux-2.6.12-rc2 |
56 |
{ |
608e266a2 sysfs: make kobj ... |
57 |
struct sysfs_dirent *sd; |
1da177e4c Linux-2.6.12-rc2 |
58 |
int error; |
0f4238958 [SCSI] sysfs: mak... |
59 60 61 62 63 |
BUG_ON(!kobj || (!update && !kobj->sd)); /* Updates may happen before the object has been instantiated */ if (unlikely(update && !kobj->sd)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
64 65 |
if (grp->name) { |
608e266a2 sysfs: make kobj ... |
66 |
error = sysfs_create_subdir(kobj, grp->name, &sd); |
1da177e4c Linux-2.6.12-rc2 |
67 68 69 |
if (error) return error; } else |
608e266a2 sysfs: make kobj ... |
70 71 |
sd = kobj->sd; sysfs_get(sd); |
0f4238958 [SCSI] sysfs: mak... |
72 |
error = create_files(sd, kobj, grp, update); |
608e266a2 sysfs: make kobj ... |
73 |
if (error) { |
1da177e4c Linux-2.6.12-rc2 |
74 |
if (grp->name) |
608e266a2 sysfs: make kobj ... |
75 |
sysfs_remove_subdir(sd); |
1da177e4c Linux-2.6.12-rc2 |
76 |
} |
608e266a2 sysfs: make kobj ... |
77 |
sysfs_put(sd); |
1da177e4c Linux-2.6.12-rc2 |
78 79 |
return error; } |
0f4238958 [SCSI] sysfs: mak... |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
/** * sysfs_create_group - given a directory kobject, create an attribute group * @kobj: The kobject to create the group on * @grp: The attribute group to create * * This function creates a group for the first time. It will explicitly * warn and error if any of the attribute files being created already exist. * * Returns 0 on success or error. */ int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) { return internal_create_group(kobj, 0, grp); } /** * sysfs_update_group - given a directory kobject, create an attribute group * @kobj: The kobject to create the group on * @grp: The attribute group to create * * This function updates an attribute group. Unlike * sysfs_create_group(), it will explicitly not warn or error if any * of the attribute files being created already exist. Furthermore, * if the visibility of the files has changed through the is_visible() * callback, it will update the permissions and add or remove the * relevant files. * * The primary use for this function is to call it after making a change * that affects group visibility. * * Returns 0 on success or error. */ int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp) { return internal_create_group(kobj, 1, grp); } |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 |
void sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) { |
608e266a2 sysfs: make kobj ... |
121 122 |
struct sysfs_dirent *dir_sd = kobj->sd; struct sysfs_dirent *sd; |
1da177e4c Linux-2.6.12-rc2 |
123 |
|
057f6c019 security: prevent... |
124 |
if (grp->name) { |
608e266a2 sysfs: make kobj ... |
125 |
sd = sysfs_get_dirent(dir_sd, grp->name); |
969affd27 sysfs: remove BUG... |
126 |
if (!sd) { |
99fcd77d1 Use WARN() in fs/... |
127 |
WARN(!sd, KERN_WARNING "sysfs group %p not found for " |
969affd27 sysfs: remove BUG... |
128 129 |
"kobject '%s' ", grp, kobject_name(kobj)); |
969affd27 sysfs: remove BUG... |
130 131 |
return; } |
608e266a2 sysfs: make kobj ... |
132 133 |
} else sd = sysfs_get(dir_sd); |
1da177e4c Linux-2.6.12-rc2 |
134 |
|
d4acd722b [SCSI] sysfs: add... |
135 |
remove_files(sd, kobj, grp); |
1da177e4c Linux-2.6.12-rc2 |
136 |
if (grp->name) |
608e266a2 sysfs: make kobj ... |
137 138 139 |
sysfs_remove_subdir(sd); sysfs_put(sd); |
1da177e4c Linux-2.6.12-rc2 |
140 141 142 143 |
} EXPORT_SYMBOL_GPL(sysfs_create_group); |
0f4238958 [SCSI] sysfs: mak... |
144 |
EXPORT_SYMBOL_GPL(sysfs_update_group); |
1da177e4c Linux-2.6.12-rc2 |
145 |
EXPORT_SYMBOL_GPL(sysfs_remove_group); |