aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/bin.c76
-rw-r--r--fs/sysfs/dir.c224
-rw-r--r--fs/sysfs/file.c64
-rw-r--r--fs/sysfs/group.c6
-rw-r--r--fs/sysfs/inode.c63
-rw-r--r--fs/sysfs/mount.c100
-rw-r--r--fs/sysfs/symlink.c93
-rw-r--r--fs/sysfs/sysfs.h51
8 files changed, 485 insertions, 192 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index a0a500af24a1..4e321f7353fa 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -46,22 +46,22 @@ struct bin_buffer {
46}; 46};
47 47
48static int 48static int
49fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) 49fill_read(struct file *file, char *buffer, loff_t off, size_t count)
50{ 50{
51 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 51 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
52 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; 52 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
53 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 53 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
54 int rc; 54 int rc;
55 55
56 /* need attr_sd for attr, its parent for kobj */ 56 /* need attr_sd for attr, its parent for kobj */
57 if (!sysfs_get_active_two(attr_sd)) 57 if (!sysfs_get_active(attr_sd))
58 return -ENODEV; 58 return -ENODEV;
59 59
60 rc = -EIO; 60 rc = -EIO;
61 if (attr->read) 61 if (attr->read)
62 rc = attr->read(kobj, attr, buffer, off, count); 62 rc = attr->read(file, kobj, attr, buffer, off, count);
63 63
64 sysfs_put_active_two(attr_sd); 64 sysfs_put_active(attr_sd);
65 65
66 return rc; 66 return rc;
67} 67}
@@ -70,8 +70,7 @@ static ssize_t
70read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) 70read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
71{ 71{
72 struct bin_buffer *bb = file->private_data; 72 struct bin_buffer *bb = file->private_data;
73 struct dentry *dentry = file->f_path.dentry; 73 int size = file->f_path.dentry->d_inode->i_size;
74 int size = dentry->d_inode->i_size;
75 loff_t offs = *off; 74 loff_t offs = *off;
76 int count = min_t(size_t, bytes, PAGE_SIZE); 75 int count = min_t(size_t, bytes, PAGE_SIZE);
77 char *temp; 76 char *temp;
@@ -92,7 +91,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
92 91
93 mutex_lock(&bb->mutex); 92 mutex_lock(&bb->mutex);
94 93
95 count = fill_read(dentry, bb->buffer, offs, count); 94 count = fill_read(file, bb->buffer, offs, count);
96 if (count < 0) { 95 if (count < 0) {
97 mutex_unlock(&bb->mutex); 96 mutex_unlock(&bb->mutex);
98 goto out_free; 97 goto out_free;
@@ -117,22 +116,22 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
117} 116}
118 117
119static int 118static int
120flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) 119flush_write(struct file *file, char *buffer, loff_t offset, size_t count)
121{ 120{
122 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 121 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
123 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; 122 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
124 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 123 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
125 int rc; 124 int rc;
126 125
127 /* need attr_sd for attr, its parent for kobj */ 126 /* need attr_sd for attr, its parent for kobj */
128 if (!sysfs_get_active_two(attr_sd)) 127 if (!sysfs_get_active(attr_sd))
129 return -ENODEV; 128 return -ENODEV;
130 129
131 rc = -EIO; 130 rc = -EIO;
132 if (attr->write) 131 if (attr->write)
133 rc = attr->write(kobj, attr, buffer, offset, count); 132 rc = attr->write(file, kobj, attr, buffer, offset, count);
134 133
135 sysfs_put_active_two(attr_sd); 134 sysfs_put_active(attr_sd);
136 135
137 return rc; 136 return rc;
138} 137}
@@ -141,8 +140,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
141 size_t bytes, loff_t *off) 140 size_t bytes, loff_t *off)
142{ 141{
143 struct bin_buffer *bb = file->private_data; 142 struct bin_buffer *bb = file->private_data;
144 struct dentry *dentry = file->f_path.dentry; 143 int size = file->f_path.dentry->d_inode->i_size;
145 int size = dentry->d_inode->i_size;
146 loff_t offs = *off; 144 loff_t offs = *off;
147 int count = min_t(size_t, bytes, PAGE_SIZE); 145 int count = min_t(size_t, bytes, PAGE_SIZE);
148 char *temp; 146 char *temp;
@@ -165,7 +163,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
165 163
166 memcpy(bb->buffer, temp, count); 164 memcpy(bb->buffer, temp, count);
167 165
168 count = flush_write(dentry, bb->buffer, offs, count); 166 count = flush_write(file, bb->buffer, offs, count);
169 mutex_unlock(&bb->mutex); 167 mutex_unlock(&bb->mutex);
170 168
171 if (count > 0) 169 if (count > 0)
@@ -184,12 +182,12 @@ static void bin_vma_open(struct vm_area_struct *vma)
184 if (!bb->vm_ops || !bb->vm_ops->open) 182 if (!bb->vm_ops || !bb->vm_ops->open)
185 return; 183 return;
186 184
187 if (!sysfs_get_active_two(attr_sd)) 185 if (!sysfs_get_active(attr_sd))
188 return; 186 return;
189 187
190 bb->vm_ops->open(vma); 188 bb->vm_ops->open(vma);
191 189
192 sysfs_put_active_two(attr_sd); 190 sysfs_put_active(attr_sd);
193} 191}
194 192
195static void bin_vma_close(struct vm_area_struct *vma) 193static void bin_vma_close(struct vm_area_struct *vma)
@@ -201,12 +199,12 @@ static void bin_vma_close(struct vm_area_struct *vma)
201 if (!bb->vm_ops || !bb->vm_ops->close) 199 if (!bb->vm_ops || !bb->vm_ops->close)
202 return; 200 return;
203 201
204 if (!sysfs_get_active_two(attr_sd)) 202 if (!sysfs_get_active(attr_sd))
205 return; 203 return;
206 204
207 bb->vm_ops->close(vma); 205 bb->vm_ops->close(vma);
208 206
209 sysfs_put_active_two(attr_sd); 207 sysfs_put_active(attr_sd);
210} 208}
211 209
212static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 210static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -219,12 +217,12 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
219 if (!bb->vm_ops || !bb->vm_ops->fault) 217 if (!bb->vm_ops || !bb->vm_ops->fault)
220 return VM_FAULT_SIGBUS; 218 return VM_FAULT_SIGBUS;
221 219
222 if (!sysfs_get_active_two(attr_sd)) 220 if (!sysfs_get_active(attr_sd))
223 return VM_FAULT_SIGBUS; 221 return VM_FAULT_SIGBUS;
224 222
225 ret = bb->vm_ops->fault(vma, vmf); 223 ret = bb->vm_ops->fault(vma, vmf);
226 224
227 sysfs_put_active_two(attr_sd); 225 sysfs_put_active(attr_sd);
228 return ret; 226 return ret;
229} 227}
230 228
@@ -241,12 +239,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
241 if (!bb->vm_ops->page_mkwrite) 239 if (!bb->vm_ops->page_mkwrite)
242 return 0; 240 return 0;
243 241
244 if (!sysfs_get_active_two(attr_sd)) 242 if (!sysfs_get_active(attr_sd))
245 return VM_FAULT_SIGBUS; 243 return VM_FAULT_SIGBUS;
246 244
247 ret = bb->vm_ops->page_mkwrite(vma, vmf); 245 ret = bb->vm_ops->page_mkwrite(vma, vmf);
248 246
249 sysfs_put_active_two(attr_sd); 247 sysfs_put_active(attr_sd);
250 return ret; 248 return ret;
251} 249}
252 250
@@ -261,12 +259,12 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
261 if (!bb->vm_ops || !bb->vm_ops->access) 259 if (!bb->vm_ops || !bb->vm_ops->access)
262 return -EINVAL; 260 return -EINVAL;
263 261
264 if (!sysfs_get_active_two(attr_sd)) 262 if (!sysfs_get_active(attr_sd))
265 return -EINVAL; 263 return -EINVAL;
266 264
267 ret = bb->vm_ops->access(vma, addr, buf, len, write); 265 ret = bb->vm_ops->access(vma, addr, buf, len, write);
268 266
269 sysfs_put_active_two(attr_sd); 267 sysfs_put_active(attr_sd);
270 return ret; 268 return ret;
271} 269}
272 270
@@ -281,12 +279,12 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
281 if (!bb->vm_ops || !bb->vm_ops->set_policy) 279 if (!bb->vm_ops || !bb->vm_ops->set_policy)
282 return 0; 280 return 0;
283 281
284 if (!sysfs_get_active_two(attr_sd)) 282 if (!sysfs_get_active(attr_sd))
285 return -EINVAL; 283 return -EINVAL;
286 284
287 ret = bb->vm_ops->set_policy(vma, new); 285 ret = bb->vm_ops->set_policy(vma, new);
288 286
289 sysfs_put_active_two(attr_sd); 287 sysfs_put_active(attr_sd);
290 return ret; 288 return ret;
291} 289}
292 290
@@ -301,12 +299,12 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
301 if (!bb->vm_ops || !bb->vm_ops->get_policy) 299 if (!bb->vm_ops || !bb->vm_ops->get_policy)
302 return vma->vm_policy; 300 return vma->vm_policy;
303 301
304 if (!sysfs_get_active_two(attr_sd)) 302 if (!sysfs_get_active(attr_sd))
305 return vma->vm_policy; 303 return vma->vm_policy;
306 304
307 pol = bb->vm_ops->get_policy(vma, addr); 305 pol = bb->vm_ops->get_policy(vma, addr);
308 306
309 sysfs_put_active_two(attr_sd); 307 sysfs_put_active(attr_sd);
310 return pol; 308 return pol;
311} 309}
312 310
@@ -321,12 +319,12 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
321 if (!bb->vm_ops || !bb->vm_ops->migrate) 319 if (!bb->vm_ops || !bb->vm_ops->migrate)
322 return 0; 320 return 0;
323 321
324 if (!sysfs_get_active_two(attr_sd)) 322 if (!sysfs_get_active(attr_sd))
325 return 0; 323 return 0;
326 324
327 ret = bb->vm_ops->migrate(vma, from, to, flags); 325 ret = bb->vm_ops->migrate(vma, from, to, flags);
328 326
329 sysfs_put_active_two(attr_sd); 327 sysfs_put_active(attr_sd);
330 return ret; 328 return ret;
331} 329}
332#endif 330#endif
@@ -356,14 +354,14 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
356 354
357 /* need attr_sd for attr, its parent for kobj */ 355 /* need attr_sd for attr, its parent for kobj */
358 rc = -ENODEV; 356 rc = -ENODEV;
359 if (!sysfs_get_active_two(attr_sd)) 357 if (!sysfs_get_active(attr_sd))
360 goto out_unlock; 358 goto out_unlock;
361 359
362 rc = -EINVAL; 360 rc = -EINVAL;
363 if (!attr->mmap) 361 if (!attr->mmap)
364 goto out_put; 362 goto out_put;
365 363
366 rc = attr->mmap(kobj, attr, vma); 364 rc = attr->mmap(file, kobj, attr, vma);
367 if (rc) 365 if (rc)
368 goto out_put; 366 goto out_put;
369 367
@@ -384,7 +382,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
384 bb->vm_ops = vma->vm_ops; 382 bb->vm_ops = vma->vm_ops;
385 vma->vm_ops = &bin_vm_ops; 383 vma->vm_ops = &bin_vm_ops;
386out_put: 384out_put:
387 sysfs_put_active_two(attr_sd); 385 sysfs_put_active(attr_sd);
388out_unlock: 386out_unlock:
389 mutex_unlock(&bb->mutex); 387 mutex_unlock(&bb->mutex);
390 388
@@ -399,7 +397,7 @@ static int open(struct inode * inode, struct file * file)
399 int error; 397 int error;
400 398
401 /* binary file operations requires both @sd and its parent */ 399 /* binary file operations requires both @sd and its parent */
402 if (!sysfs_get_active_two(attr_sd)) 400 if (!sysfs_get_active(attr_sd))
403 return -ENODEV; 401 return -ENODEV;
404 402
405 error = -EACCES; 403 error = -EACCES;
@@ -426,11 +424,11 @@ static int open(struct inode * inode, struct file * file)
426 mutex_unlock(&sysfs_bin_lock); 424 mutex_unlock(&sysfs_bin_lock);
427 425
428 /* open succeeded, put active references */ 426 /* open succeeded, put active references */
429 sysfs_put_active_two(attr_sd); 427 sysfs_put_active(attr_sd);
430 return 0; 428 return 0;
431 429
432 err_out: 430 err_out:
433 sysfs_put_active_two(attr_sd); 431 sysfs_put_active(attr_sd);
434 kfree(bb); 432 kfree(bb);
435 return error; 433 return error;
436} 434}
@@ -501,7 +499,7 @@ int sysfs_create_bin_file(struct kobject *kobj,
501void sysfs_remove_bin_file(struct kobject *kobj, 499void sysfs_remove_bin_file(struct kobject *kobj,
502 const struct bin_attribute *attr) 500 const struct bin_attribute *attr)
503{ 501{
504 sysfs_hash_and_remove(kobj->sd, attr->attr.name); 502 sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
505} 503}
506 504
507EXPORT_SYMBOL_GPL(sysfs_create_bin_file); 505EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 699f371b9f12..7e54bac8c4b0 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -93,7 +93,7 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
93 * RETURNS: 93 * RETURNS:
94 * Pointer to @sd on success, NULL on failure. 94 * Pointer to @sd on success, NULL on failure.
95 */ 95 */
96static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) 96struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
97{ 97{
98 if (unlikely(!sd)) 98 if (unlikely(!sd))
99 return NULL; 99 return NULL;
@@ -124,7 +124,7 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
124 * Put an active reference to @sd. This function is noop if @sd 124 * Put an active reference to @sd. This function is noop if @sd
125 * is NULL. 125 * is NULL.
126 */ 126 */
127static void sysfs_put_active(struct sysfs_dirent *sd) 127void sysfs_put_active(struct sysfs_dirent *sd)
128{ 128{
129 struct completion *cmpl; 129 struct completion *cmpl;
130 int v; 130 int v;
@@ -145,45 +145,6 @@ static void sysfs_put_active(struct sysfs_dirent *sd)
145} 145}
146 146
147/** 147/**
148 * sysfs_get_active_two - get active references to sysfs_dirent and parent
149 * @sd: sysfs_dirent of interest
150 *
151 * Get active reference to @sd and its parent. Parent's active
152 * reference is grabbed first. This function is noop if @sd is
153 * NULL.
154 *
155 * RETURNS:
156 * Pointer to @sd on success, NULL on failure.
157 */
158struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
159{
160 if (sd) {
161 if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
162 return NULL;
163 if (unlikely(!sysfs_get_active(sd))) {
164 sysfs_put_active(sd->s_parent);
165 return NULL;
166 }
167 }
168 return sd;
169}
170
171/**
172 * sysfs_put_active_two - put active references to sysfs_dirent and parent
173 * @sd: sysfs_dirent of interest
174 *
175 * Put active references to @sd and its parent. This function is
176 * noop if @sd is NULL.
177 */
178void sysfs_put_active_two(struct sysfs_dirent *sd)
179{
180 if (sd) {
181 sysfs_put_active(sd);
182 sysfs_put_active(sd->s_parent);
183 }
184}
185
186/**
187 * sysfs_deactivate - deactivate sysfs_dirent 148 * sysfs_deactivate - deactivate sysfs_dirent
188 * @sd: sysfs_dirent to deactivate 149 * @sd: sysfs_dirent to deactivate
189 * 150 *
@@ -195,6 +156,10 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
195 int v; 156 int v;
196 157
197 BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); 158 BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
159
160 if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
161 return;
162
198 sd->s_sibling = (void *)&wait; 163 sd->s_sibling = (void *)&wait;
199 164
200 rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); 165 rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
@@ -354,7 +319,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
354 319
355 atomic_set(&sd->s_count, 1); 320 atomic_set(&sd->s_count, 1);
356 atomic_set(&sd->s_active, 0); 321 atomic_set(&sd->s_active, 0);
357 sysfs_dirent_init_lockdep(sd);
358 322
359 sd->s_name = name; 323 sd->s_name = name;
360 sd->s_mode = mode; 324 sd->s_mode = mode;
@@ -416,7 +380,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
416{ 380{
417 struct sysfs_inode_attrs *ps_iattr; 381 struct sysfs_inode_attrs *ps_iattr;
418 382
419 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) 383 if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
420 return -EEXIST; 384 return -EEXIST;
421 385
422 sd->s_parent = sysfs_get(acxt->parent_sd); 386 sd->s_parent = sysfs_get(acxt->parent_sd);
@@ -569,13 +533,17 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
569 * Pointer to sysfs_dirent if found, NULL if not. 533 * Pointer to sysfs_dirent if found, NULL if not.
570 */ 534 */
571struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, 535struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
536 const void *ns,
572 const unsigned char *name) 537 const unsigned char *name)
573{ 538{
574 struct sysfs_dirent *sd; 539 struct sysfs_dirent *sd;
575 540
576 for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) 541 for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
542 if (ns && sd->s_ns && (sd->s_ns != ns))
543 continue;
577 if (!strcmp(sd->s_name, name)) 544 if (!strcmp(sd->s_name, name))
578 return sd; 545 return sd;
546 }
579 return NULL; 547 return NULL;
580} 548}
581 549
@@ -594,12 +562,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
594 * Pointer to sysfs_dirent if found, NULL if not. 562 * Pointer to sysfs_dirent if found, NULL if not.
595 */ 563 */
596struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, 564struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
565 const void *ns,
597 const unsigned char *name) 566 const unsigned char *name)
598{ 567{
599 struct sysfs_dirent *sd; 568 struct sysfs_dirent *sd;
600 569
601 mutex_lock(&sysfs_mutex); 570 mutex_lock(&sysfs_mutex);
602 sd = sysfs_find_dirent(parent_sd, name); 571 sd = sysfs_find_dirent(parent_sd, ns, name);
603 sysfs_get(sd); 572 sysfs_get(sd);
604 mutex_unlock(&sysfs_mutex); 573 mutex_unlock(&sysfs_mutex);
605 574
@@ -608,7 +577,8 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
608EXPORT_SYMBOL_GPL(sysfs_get_dirent); 577EXPORT_SYMBOL_GPL(sysfs_get_dirent);
609 578
610static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, 579static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
611 const char *name, struct sysfs_dirent **p_sd) 580 enum kobj_ns_type type, const void *ns, const char *name,
581 struct sysfs_dirent **p_sd)
612{ 582{
613 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 583 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
614 struct sysfs_addrm_cxt acxt; 584 struct sysfs_addrm_cxt acxt;
@@ -619,6 +589,9 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
619 sd = sysfs_new_dirent(name, mode, SYSFS_DIR); 589 sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
620 if (!sd) 590 if (!sd)
621 return -ENOMEM; 591 return -ENOMEM;
592
593 sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);
594 sd->s_ns = ns;
622 sd->s_dir.kobj = kobj; 595 sd->s_dir.kobj = kobj;
623 596
624 /* link in */ 597 /* link in */
@@ -637,7 +610,33 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
637int sysfs_create_subdir(struct kobject *kobj, const char *name, 610int sysfs_create_subdir(struct kobject *kobj, const char *name,
638 struct sysfs_dirent **p_sd) 611 struct sysfs_dirent **p_sd)
639{ 612{
640 return create_dir(kobj, kobj->sd, name, p_sd); 613 return create_dir(kobj, kobj->sd,
614 KOBJ_NS_TYPE_NONE, NULL, name, p_sd);
615}
616
617/**
618 * sysfs_read_ns_type: return associated ns_type
619 * @kobj: the kobject being queried
620 *
621 * Each kobject can be tagged with exactly one namespace type
622 * (i.e. network or user). Return the ns_type associated with
623 * this object if any
624 */
625static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
626{
627 const struct kobj_ns_type_operations *ops;
628 enum kobj_ns_type type;
629
630 ops = kobj_child_ns_ops(kobj);
631 if (!ops)
632 return KOBJ_NS_TYPE_NONE;
633
634 type = ops->type;
635 BUG_ON(type <= KOBJ_NS_TYPE_NONE);
636 BUG_ON(type >= KOBJ_NS_TYPES);
637 BUG_ON(!kobj_ns_type_registered(type));
638
639 return type;
641} 640}
642 641
643/** 642/**
@@ -646,7 +645,9 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
646 */ 645 */
647int sysfs_create_dir(struct kobject * kobj) 646int sysfs_create_dir(struct kobject * kobj)
648{ 647{
648 enum kobj_ns_type type;
649 struct sysfs_dirent *parent_sd, *sd; 649 struct sysfs_dirent *parent_sd, *sd;
650 const void *ns = NULL;
650 int error = 0; 651 int error = 0;
651 652
652 BUG_ON(!kobj); 653 BUG_ON(!kobj);
@@ -656,7 +657,11 @@ int sysfs_create_dir(struct kobject * kobj)
656 else 657 else
657 parent_sd = &sysfs_root; 658 parent_sd = &sysfs_root;
658 659
659 error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd); 660 if (sysfs_ns_type(parent_sd))
661 ns = kobj->ktype->namespace(kobj);
662 type = sysfs_read_ns_type(kobj);
663
664 error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
660 if (!error) 665 if (!error)
661 kobj->sd = sd; 666 kobj->sd = sd;
662 return error; 667 return error;
@@ -666,13 +671,19 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
666 struct nameidata *nd) 671 struct nameidata *nd)
667{ 672{
668 struct dentry *ret = NULL; 673 struct dentry *ret = NULL;
669 struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata; 674 struct dentry *parent = dentry->d_parent;
675 struct sysfs_dirent *parent_sd = parent->d_fsdata;
670 struct sysfs_dirent *sd; 676 struct sysfs_dirent *sd;
671 struct inode *inode; 677 struct inode *inode;
678 enum kobj_ns_type type;
679 const void *ns;
672 680
673 mutex_lock(&sysfs_mutex); 681 mutex_lock(&sysfs_mutex);
674 682
675 sd = sysfs_find_dirent(parent_sd, dentry->d_name.name); 683 type = sysfs_ns_type(parent_sd);
684 ns = sysfs_info(dir->i_sb)->ns[type];
685
686 sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name);
676 687
677 /* no such entry */ 688 /* no such entry */
678 if (!sd) { 689 if (!sd) {
@@ -681,7 +692,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
681 } 692 }
682 693
683 /* attach dentry and inode */ 694 /* attach dentry and inode */
684 inode = sysfs_get_inode(sd); 695 inode = sysfs_get_inode(dir->i_sb, sd);
685 if (!inode) { 696 if (!inode) {
686 ret = ERR_PTR(-ENOMEM); 697 ret = ERR_PTR(-ENOMEM);
687 goto out_unlock; 698 goto out_unlock;
@@ -771,7 +782,8 @@ void sysfs_remove_dir(struct kobject * kobj)
771} 782}
772 783
773int sysfs_rename(struct sysfs_dirent *sd, 784int sysfs_rename(struct sysfs_dirent *sd,
774 struct sysfs_dirent *new_parent_sd, const char *new_name) 785 struct sysfs_dirent *new_parent_sd, const void *new_ns,
786 const char *new_name)
775{ 787{
776 const char *dup_name = NULL; 788 const char *dup_name = NULL;
777 int error; 789 int error;
@@ -779,12 +791,12 @@ int sysfs_rename(struct sysfs_dirent *sd,
779 mutex_lock(&sysfs_mutex); 791 mutex_lock(&sysfs_mutex);
780 792
781 error = 0; 793 error = 0;
782 if ((sd->s_parent == new_parent_sd) && 794 if ((sd->s_parent == new_parent_sd) && (sd->s_ns == new_ns) &&
783 (strcmp(sd->s_name, new_name) == 0)) 795 (strcmp(sd->s_name, new_name) == 0))
784 goto out; /* nothing to rename */ 796 goto out; /* nothing to rename */
785 797
786 error = -EEXIST; 798 error = -EEXIST;
787 if (sysfs_find_dirent(new_parent_sd, new_name)) 799 if (sysfs_find_dirent(new_parent_sd, new_ns, new_name))
788 goto out; 800 goto out;
789 801
790 /* rename sysfs_dirent */ 802 /* rename sysfs_dirent */
@@ -806,6 +818,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
806 sd->s_parent = new_parent_sd; 818 sd->s_parent = new_parent_sd;
807 sysfs_link_sibling(sd); 819 sysfs_link_sibling(sd);
808 } 820 }
821 sd->s_ns = new_ns;
809 822
810 error = 0; 823 error = 0;
811 out: 824 out:
@@ -816,19 +829,28 @@ int sysfs_rename(struct sysfs_dirent *sd,
816 829
817int sysfs_rename_dir(struct kobject *kobj, const char *new_name) 830int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
818{ 831{
819 return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name); 832 struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
833 const void *new_ns = NULL;
834
835 if (sysfs_ns_type(parent_sd))
836 new_ns = kobj->ktype->namespace(kobj);
837
838 return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
820} 839}
821 840
822int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) 841int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
823{ 842{
824 struct sysfs_dirent *sd = kobj->sd; 843 struct sysfs_dirent *sd = kobj->sd;
825 struct sysfs_dirent *new_parent_sd; 844 struct sysfs_dirent *new_parent_sd;
845 const void *new_ns = NULL;
826 846
827 BUG_ON(!sd->s_parent); 847 BUG_ON(!sd->s_parent);
848 if (sysfs_ns_type(sd->s_parent))
849 new_ns = kobj->ktype->namespace(kobj);
828 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? 850 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
829 new_parent_kobj->sd : &sysfs_root; 851 new_parent_kobj->sd : &sysfs_root;
830 852
831 return sysfs_rename(sd, new_parent_sd, sd->s_name); 853 return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name);
832} 854}
833 855
834/* Relationship between s_mode and the DT_xxx types */ 856/* Relationship between s_mode and the DT_xxx types */
@@ -837,13 +859,56 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
837 return (sd->s_mode >> 12) & 15; 859 return (sd->s_mode >> 12) & 15;
838} 860}
839 861
862static int sysfs_dir_release(struct inode *inode, struct file *filp)
863{
864 sysfs_put(filp->private_data);
865 return 0;
866}
867
868static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
869 struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
870{
871 if (pos) {
872 int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
873 pos->s_parent == parent_sd &&
874 ino == pos->s_ino;
875 sysfs_put(pos);
876 if (!valid)
877 pos = NULL;
878 }
879 if (!pos && (ino > 1) && (ino < INT_MAX)) {
880 pos = parent_sd->s_dir.children;
881 while (pos && (ino > pos->s_ino))
882 pos = pos->s_sibling;
883 }
884 while (pos && pos->s_ns && pos->s_ns != ns)
885 pos = pos->s_sibling;
886 return pos;
887}
888
889static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
890 struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
891{
892 pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
893 if (pos)
894 pos = pos->s_sibling;
895 while (pos && pos->s_ns && pos->s_ns != ns)
896 pos = pos->s_sibling;
897 return pos;
898}
899
840static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 900static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
841{ 901{
842 struct dentry *dentry = filp->f_path.dentry; 902 struct dentry *dentry = filp->f_path.dentry;
843 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 903 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
844 struct sysfs_dirent *pos; 904 struct sysfs_dirent *pos = filp->private_data;
905 enum kobj_ns_type type;
906 const void *ns;
845 ino_t ino; 907 ino_t ino;
846 908
909 type = sysfs_ns_type(parent_sd);
910 ns = sysfs_info(dentry->d_sb)->ns[type];
911
847 if (filp->f_pos == 0) { 912 if (filp->f_pos == 0) {
848 ino = parent_sd->s_ino; 913 ino = parent_sd->s_ino;
849 if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) 914 if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
@@ -857,29 +922,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
857 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) 922 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
858 filp->f_pos++; 923 filp->f_pos++;
859 } 924 }
860 if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) { 925 mutex_lock(&sysfs_mutex);
861 mutex_lock(&sysfs_mutex); 926 for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
862 927 pos;
863 /* Skip the dentries we have already reported */ 928 pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) {
864 pos = parent_sd->s_dir.children; 929 const char * name;
865 while (pos && (filp->f_pos > pos->s_ino)) 930 unsigned int type;
866 pos = pos->s_sibling; 931 int len, ret;
867 932
868 for ( ; pos; pos = pos->s_sibling) { 933 name = pos->s_name;
869 const char * name; 934 len = strlen(name);
870 int len; 935 ino = pos->s_ino;
871 936 type = dt_type(pos);
872 name = pos->s_name; 937 filp->f_pos = ino;
873 len = strlen(name); 938 filp->private_data = sysfs_get(pos);
874 filp->f_pos = ino = pos->s_ino;
875 939
876 if (filldir(dirent, name, len, filp->f_pos, ino,
877 dt_type(pos)) < 0)
878 break;
879 }
880 if (!pos)
881 filp->f_pos = INT_MAX;
882 mutex_unlock(&sysfs_mutex); 940 mutex_unlock(&sysfs_mutex);
941 ret = filldir(dirent, name, len, filp->f_pos, ino, type);
942 mutex_lock(&sysfs_mutex);
943 if (ret < 0)
944 break;
945 }
946 mutex_unlock(&sysfs_mutex);
947 if ((filp->f_pos > 1) && !pos) { /* EOF */
948 filp->f_pos = INT_MAX;
949 filp->private_data = NULL;
883 } 950 }
884 return 0; 951 return 0;
885} 952}
@@ -888,5 +955,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
888const struct file_operations sysfs_dir_operations = { 955const struct file_operations sysfs_dir_operations = {
889 .read = generic_read_dir, 956 .read = generic_read_dir,
890 .readdir = sysfs_readdir, 957 .readdir = sysfs_readdir,
958 .release = sysfs_dir_release,
891 .llseek = generic_file_llseek, 959 .llseek = generic_file_llseek,
892}; 960};
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index dc30d9e31683..1beaa739d0a6 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -53,7 +53,7 @@ struct sysfs_buffer {
53 size_t count; 53 size_t count;
54 loff_t pos; 54 loff_t pos;
55 char * page; 55 char * page;
56 struct sysfs_ops * ops; 56 const struct sysfs_ops * ops;
57 struct mutex mutex; 57 struct mutex mutex;
58 int needs_read_fill; 58 int needs_read_fill;
59 int event; 59 int event;
@@ -75,7 +75,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
75{ 75{
76 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 76 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
77 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 77 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
78 struct sysfs_ops * ops = buffer->ops; 78 const struct sysfs_ops * ops = buffer->ops;
79 int ret = 0; 79 int ret = 0;
80 ssize_t count; 80 ssize_t count;
81 81
@@ -85,13 +85,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
85 return -ENOMEM; 85 return -ENOMEM;
86 86
87 /* need attr_sd for attr and ops, its parent for kobj */ 87 /* need attr_sd for attr and ops, its parent for kobj */
88 if (!sysfs_get_active_two(attr_sd)) 88 if (!sysfs_get_active(attr_sd))
89 return -ENODEV; 89 return -ENODEV;
90 90
91 buffer->event = atomic_read(&attr_sd->s_attr.open->event); 91 buffer->event = atomic_read(&attr_sd->s_attr.open->event);
92 count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); 92 count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
93 93
94 sysfs_put_active_two(attr_sd); 94 sysfs_put_active(attr_sd);
95 95
96 /* 96 /*
97 * The code works fine with PAGE_SIZE return but it's likely to 97 * The code works fine with PAGE_SIZE return but it's likely to
@@ -199,16 +199,16 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
199{ 199{
200 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 200 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
201 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 201 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
202 struct sysfs_ops * ops = buffer->ops; 202 const struct sysfs_ops * ops = buffer->ops;
203 int rc; 203 int rc;
204 204
205 /* need attr_sd for attr and ops, its parent for kobj */ 205 /* need attr_sd for attr and ops, its parent for kobj */
206 if (!sysfs_get_active_two(attr_sd)) 206 if (!sysfs_get_active(attr_sd))
207 return -ENODEV; 207 return -ENODEV;
208 208
209 rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); 209 rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
210 210
211 sysfs_put_active_two(attr_sd); 211 sysfs_put_active(attr_sd);
212 212
213 return rc; 213 return rc;
214} 214}
@@ -335,7 +335,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
335 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 335 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
336 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 336 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
337 struct sysfs_buffer *buffer; 337 struct sysfs_buffer *buffer;
338 struct sysfs_ops *ops; 338 const struct sysfs_ops *ops;
339 int error = -EACCES; 339 int error = -EACCES;
340 char *p; 340 char *p;
341 341
@@ -344,7 +344,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
344 memmove(last_sysfs_file, p, strlen(p) + 1); 344 memmove(last_sysfs_file, p, strlen(p) + 1);
345 345
346 /* need attr_sd for attr and ops, its parent for kobj */ 346 /* need attr_sd for attr and ops, its parent for kobj */
347 if (!sysfs_get_active_two(attr_sd)) 347 if (!sysfs_get_active(attr_sd))
348 return -ENODEV; 348 return -ENODEV;
349 349
350 /* every kobject with an attribute needs a ktype assigned */ 350 /* every kobject with an attribute needs a ktype assigned */
@@ -393,13 +393,13 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
393 goto err_free; 393 goto err_free;
394 394
395 /* open succeeded, put active references */ 395 /* open succeeded, put active references */
396 sysfs_put_active_two(attr_sd); 396 sysfs_put_active(attr_sd);
397 return 0; 397 return 0;
398 398
399 err_free: 399 err_free:
400 kfree(buffer); 400 kfree(buffer);
401 err_out: 401 err_out:
402 sysfs_put_active_two(attr_sd); 402 sysfs_put_active(attr_sd);
403 return error; 403 return error;
404} 404}
405 405
@@ -437,12 +437,12 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
437 struct sysfs_open_dirent *od = attr_sd->s_attr.open; 437 struct sysfs_open_dirent *od = attr_sd->s_attr.open;
438 438
439 /* need parent for the kobj, grab both */ 439 /* need parent for the kobj, grab both */
440 if (!sysfs_get_active_two(attr_sd)) 440 if (!sysfs_get_active(attr_sd))
441 goto trigger; 441 goto trigger;
442 442
443 poll_wait(filp, &od->poll, wait); 443 poll_wait(filp, &od->poll, wait);
444 444
445 sysfs_put_active_two(attr_sd); 445 sysfs_put_active(attr_sd);
446 446
447 if (buffer->event != atomic_read(&od->event)) 447 if (buffer->event != atomic_read(&od->event))
448 goto trigger; 448 goto trigger;
@@ -478,9 +478,12 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
478 mutex_lock(&sysfs_mutex); 478 mutex_lock(&sysfs_mutex);
479 479
480 if (sd && dir) 480 if (sd && dir)
481 sd = sysfs_find_dirent(sd, dir); 481 /* Only directories are tagged, so no need to pass
482 * a tag explicitly.
483 */
484 sd = sysfs_find_dirent(sd, NULL, dir);
482 if (sd && attr) 485 if (sd && attr)
483 sd = sysfs_find_dirent(sd, attr); 486 sd = sysfs_find_dirent(sd, NULL, attr);
484 if (sd) 487 if (sd)
485 sysfs_notify_dirent(sd); 488 sysfs_notify_dirent(sd);
486 489
@@ -509,6 +512,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
509 if (!sd) 512 if (!sd)
510 return -ENOMEM; 513 return -ENOMEM;
511 sd->s_attr.attr = (void *)attr; 514 sd->s_attr.attr = (void *)attr;
515 sysfs_dirent_init_lockdep(sd);
512 516
513 sysfs_addrm_start(&acxt, dir_sd); 517 sysfs_addrm_start(&acxt, dir_sd);
514 rc = sysfs_add_one(&acxt, sd); 518 rc = sysfs_add_one(&acxt, sd);
@@ -542,6 +546,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
542 546
543} 547}
544 548
549int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
550{
551 int err = 0;
552 int i;
553
554 for (i = 0; ptr[i] && !err; i++)
555 err = sysfs_create_file(kobj, ptr[i]);
556 if (err)
557 while (--i >= 0)
558 sysfs_remove_file(kobj, ptr[i]);
559 return err;
560}
545 561
546/** 562/**
547 * sysfs_add_file_to_group - add an attribute file to a pre-existing group. 563 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
@@ -556,7 +572,7 @@ int sysfs_add_file_to_group(struct kobject *kobj,
556 int error; 572 int error;
557 573
558 if (group) 574 if (group)
559 dir_sd = sysfs_get_dirent(kobj->sd, group); 575 dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
560 else 576 else
561 dir_sd = sysfs_get(kobj->sd); 577 dir_sd = sysfs_get(kobj->sd);
562 578
@@ -586,7 +602,7 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
586 mutex_lock(&sysfs_mutex); 602 mutex_lock(&sysfs_mutex);
587 603
588 rc = -ENOENT; 604 rc = -ENOENT;
589 sd = sysfs_find_dirent(kobj->sd, attr->name); 605 sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
590 if (!sd) 606 if (!sd)
591 goto out; 607 goto out;
592 608
@@ -611,9 +627,15 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
611 627
612void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) 628void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
613{ 629{
614 sysfs_hash_and_remove(kobj->sd, attr->name); 630 sysfs_hash_and_remove(kobj->sd, NULL, attr->name);
615} 631}
616 632
633void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
634{
635 int i;
636 for (i = 0; ptr[i]; i++)
637 sysfs_remove_file(kobj, ptr[i]);
638}
617 639
618/** 640/**
619 * sysfs_remove_file_from_group - remove an attribute file from a group. 641 * sysfs_remove_file_from_group - remove an attribute file from a group.
@@ -627,11 +649,11 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
627 struct sysfs_dirent *dir_sd; 649 struct sysfs_dirent *dir_sd;
628 650
629 if (group) 651 if (group)
630 dir_sd = sysfs_get_dirent(kobj->sd, group); 652 dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
631 else 653 else
632 dir_sd = sysfs_get(kobj->sd); 654 dir_sd = sysfs_get(kobj->sd);
633 if (dir_sd) { 655 if (dir_sd) {
634 sysfs_hash_and_remove(dir_sd, attr->name); 656 sysfs_hash_and_remove(dir_sd, NULL, attr->name);
635 sysfs_put(dir_sd); 657 sysfs_put(dir_sd);
636 } 658 }
637} 659}
@@ -732,3 +754,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
732 754
733EXPORT_SYMBOL_GPL(sysfs_create_file); 755EXPORT_SYMBOL_GPL(sysfs_create_file);
734EXPORT_SYMBOL_GPL(sysfs_remove_file); 756EXPORT_SYMBOL_GPL(sysfs_remove_file);
757EXPORT_SYMBOL_GPL(sysfs_remove_files);
758EXPORT_SYMBOL_GPL(sysfs_create_files);
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index fe611949a7f7..23c1e598792a 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -23,7 +23,7 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
23 int i; 23 int i;
24 24
25 for (i = 0, attr = grp->attrs; *attr; i++, attr++) 25 for (i = 0, attr = grp->attrs; *attr; i++, attr++)
26 sysfs_hash_and_remove(dir_sd, (*attr)->name); 26 sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
27} 27}
28 28
29static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, 29static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
@@ -39,7 +39,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
39 * visibility. Do this by first removing then 39 * visibility. Do this by first removing then
40 * re-adding (if required) the file */ 40 * re-adding (if required) the file */
41 if (update) 41 if (update)
42 sysfs_hash_and_remove(dir_sd, (*attr)->name); 42 sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
43 if (grp->is_visible) { 43 if (grp->is_visible) {
44 mode = grp->is_visible(kobj, *attr, i); 44 mode = grp->is_visible(kobj, *attr, i);
45 if (!mode) 45 if (!mode)
@@ -132,7 +132,7 @@ void sysfs_remove_group(struct kobject * kobj,
132 struct sysfs_dirent *sd; 132 struct sysfs_dirent *sd;
133 133
134 if (grp->name) { 134 if (grp->name) {
135 sd = sysfs_get_dirent(dir_sd, grp->name); 135 sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
136 if (!sd) { 136 if (!sd) {
137 WARN(!sd, KERN_WARNING "sysfs group %p not found for " 137 WARN(!sd, KERN_WARNING "sysfs group %p not found for "
138 "kobject '%s'\n", grp, kobject_name(kobj)); 138 "kobject '%s'\n", grp, kobject_name(kobj));
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 220b758523ae..0835a3b70e03 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -18,6 +18,7 @@
18#include <linux/capability.h> 18#include <linux/capability.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/slab.h>
21#include <linux/xattr.h> 22#include <linux/xattr.h>
22#include <linux/security.h> 23#include <linux/security.h>
23#include "sysfs.h" 24#include "sysfs.h"
@@ -81,24 +82,23 @@ int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
81 if (!sd_attrs) 82 if (!sd_attrs)
82 return -ENOMEM; 83 return -ENOMEM;
83 sd->s_iattr = sd_attrs; 84 sd->s_iattr = sd_attrs;
84 } else { 85 }
85 /* attributes were changed at least once in past */ 86 /* attributes were changed at least once in past */
86 iattrs = &sd_attrs->ia_iattr; 87 iattrs = &sd_attrs->ia_iattr;
87 88
88 if (ia_valid & ATTR_UID) 89 if (ia_valid & ATTR_UID)
89 iattrs->ia_uid = iattr->ia_uid; 90 iattrs->ia_uid = iattr->ia_uid;
90 if (ia_valid & ATTR_GID) 91 if (ia_valid & ATTR_GID)
91 iattrs->ia_gid = iattr->ia_gid; 92 iattrs->ia_gid = iattr->ia_gid;
92 if (ia_valid & ATTR_ATIME) 93 if (ia_valid & ATTR_ATIME)
93 iattrs->ia_atime = iattr->ia_atime; 94 iattrs->ia_atime = iattr->ia_atime;
94 if (ia_valid & ATTR_MTIME) 95 if (ia_valid & ATTR_MTIME)
95 iattrs->ia_mtime = iattr->ia_mtime; 96 iattrs->ia_mtime = iattr->ia_mtime;
96 if (ia_valid & ATTR_CTIME) 97 if (ia_valid & ATTR_CTIME)
97 iattrs->ia_ctime = iattr->ia_ctime; 98 iattrs->ia_ctime = iattr->ia_ctime;
98 if (ia_valid & ATTR_MODE) { 99 if (ia_valid & ATTR_MODE) {
99 umode_t mode = iattr->ia_mode; 100 umode_t mode = iattr->ia_mode;
100 iattrs->ia_mode = sd->s_mode = mode; 101 iattrs->ia_mode = sd->s_mode = mode;
101 }
102 } 102 }
103 return 0; 103 return 0;
104} 104}
@@ -112,20 +112,20 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
112 if (!sd) 112 if (!sd)
113 return -EINVAL; 113 return -EINVAL;
114 114
115 mutex_lock(&sysfs_mutex);
115 error = inode_change_ok(inode, iattr); 116 error = inode_change_ok(inode, iattr);
116 if (error) 117 if (error)
117 return error; 118 goto out;
118
119 iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
120 119
121 error = inode_setattr(inode, iattr); 120 error = sysfs_sd_setattr(sd, iattr);
122 if (error) 121 if (error)
123 return error; 122 goto out;
124 123
125 mutex_lock(&sysfs_mutex); 124 /* this ignores size changes */
126 error = sysfs_sd_setattr(sd, iattr); 125 generic_setattr(inode, iattr);
127 mutex_unlock(&sysfs_mutex);
128 126
127out:
128 mutex_unlock(&sysfs_mutex);
129 return error; 129 return error;
130} 130}
131 131
@@ -284,6 +284,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
284 284
285/** 285/**
286 * sysfs_get_inode - get inode for sysfs_dirent 286 * sysfs_get_inode - get inode for sysfs_dirent
287 * @sb: super block
287 * @sd: sysfs_dirent to allocate inode for 288 * @sd: sysfs_dirent to allocate inode for
288 * 289 *
289 * Get inode for @sd. If such inode doesn't exist, a new inode 290 * Get inode for @sd. If such inode doesn't exist, a new inode
@@ -296,11 +297,11 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
296 * RETURNS: 297 * RETURNS:
297 * Pointer to allocated inode on success, NULL on failure. 298 * Pointer to allocated inode on success, NULL on failure.
298 */ 299 */
299struct inode * sysfs_get_inode(struct sysfs_dirent *sd) 300struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
300{ 301{
301 struct inode *inode; 302 struct inode *inode;
302 303
303 inode = iget_locked(sysfs_sb, sd->s_ino); 304 inode = iget_locked(sb, sd->s_ino);
304 if (inode && (inode->i_state & I_NEW)) 305 if (inode && (inode->i_state & I_NEW))
305 sysfs_init_inode(sd, inode); 306 sysfs_init_inode(sd, inode);
306 307
@@ -323,7 +324,7 @@ void sysfs_delete_inode(struct inode *inode)
323 sysfs_put(sd); 324 sysfs_put(sd);
324} 325}
325 326
326int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name) 327int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name)
327{ 328{
328 struct sysfs_addrm_cxt acxt; 329 struct sysfs_addrm_cxt acxt;
329 struct sysfs_dirent *sd; 330 struct sysfs_dirent *sd;
@@ -333,7 +334,9 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
333 334
334 sysfs_addrm_start(&acxt, dir_sd); 335 sysfs_addrm_start(&acxt, dir_sd);
335 336
336 sd = sysfs_find_dirent(dir_sd, name); 337 sd = sysfs_find_dirent(dir_sd, ns, name);
338 if (sd && (sd->s_ns != ns))
339 sd = NULL;
337 if (sd) 340 if (sd)
338 sysfs_remove_one(&acxt, sd); 341 sysfs_remove_one(&acxt, sd);
339 342
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 49749955ccaf..281c0c9bc39f 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -18,12 +18,12 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/magic.h> 20#include <linux/magic.h>
21#include <linux/slab.h>
21 22
22#include "sysfs.h" 23#include "sysfs.h"
23 24
24 25
25static struct vfsmount *sysfs_mount; 26static struct vfsmount *sysfs_mount;
26struct super_block * sysfs_sb = NULL;
27struct kmem_cache *sysfs_dir_cachep; 27struct kmem_cache *sysfs_dir_cachep;
28 28
29static const struct super_operations sysfs_ops = { 29static const struct super_operations sysfs_ops = {
@@ -35,7 +35,7 @@ static const struct super_operations sysfs_ops = {
35struct sysfs_dirent sysfs_root = { 35struct sysfs_dirent sysfs_root = {
36 .s_name = "", 36 .s_name = "",
37 .s_count = ATOMIC_INIT(1), 37 .s_count = ATOMIC_INIT(1),
38 .s_flags = SYSFS_DIR, 38 .s_flags = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),
39 .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 39 .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
40 .s_ino = 1, 40 .s_ino = 1,
41}; 41};
@@ -50,11 +50,10 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
50 sb->s_magic = SYSFS_MAGIC; 50 sb->s_magic = SYSFS_MAGIC;
51 sb->s_op = &sysfs_ops; 51 sb->s_op = &sysfs_ops;
52 sb->s_time_gran = 1; 52 sb->s_time_gran = 1;
53 sysfs_sb = sb;
54 53
55 /* get root inode, initialize and unlock it */ 54 /* get root inode, initialize and unlock it */
56 mutex_lock(&sysfs_mutex); 55 mutex_lock(&sysfs_mutex);
57 inode = sysfs_get_inode(&sysfs_root); 56 inode = sysfs_get_inode(sb, &sysfs_root);
58 mutex_unlock(&sysfs_mutex); 57 mutex_unlock(&sysfs_mutex);
59 if (!inode) { 58 if (!inode) {
60 pr_debug("sysfs: could not get root inode\n"); 59 pr_debug("sysfs: could not get root inode\n");
@@ -73,18 +72,107 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
73 return 0; 72 return 0;
74} 73}
75 74
75static int sysfs_test_super(struct super_block *sb, void *data)
76{
77 struct sysfs_super_info *sb_info = sysfs_info(sb);
78 struct sysfs_super_info *info = data;
79 enum kobj_ns_type type;
80 int found = 1;
81
82 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
83 if (sb_info->ns[type] != info->ns[type])
84 found = 0;
85 }
86 return found;
87}
88
89static int sysfs_set_super(struct super_block *sb, void *data)
90{
91 int error;
92 error = set_anon_super(sb, data);
93 if (!error)
94 sb->s_fs_info = data;
95 return error;
96}
97
76static int sysfs_get_sb(struct file_system_type *fs_type, 98static int sysfs_get_sb(struct file_system_type *fs_type,
77 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 99 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
78{ 100{
79 return get_sb_single(fs_type, flags, data, sysfs_fill_super, mnt); 101 struct sysfs_super_info *info;
102 enum kobj_ns_type type;
103 struct super_block *sb;
104 int error;
105
106 error = -ENOMEM;
107 info = kzalloc(sizeof(*info), GFP_KERNEL);
108 if (!info)
109 goto out;
110
111 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
112 info->ns[type] = kobj_ns_current(type);
113
114 sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info);
115 if (IS_ERR(sb) || sb->s_fs_info != info)
116 kfree(info);
117 if (IS_ERR(sb)) {
118 error = PTR_ERR(sb);
119 goto out;
120 }
121 if (!sb->s_root) {
122 sb->s_flags = flags;
123 error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
124 if (error) {
125 deactivate_locked_super(sb);
126 goto out;
127 }
128 sb->s_flags |= MS_ACTIVE;
129 }
130
131 simple_set_mnt(mnt, sb);
132 error = 0;
133out:
134 return error;
135}
136
137static void sysfs_kill_sb(struct super_block *sb)
138{
139 struct sysfs_super_info *info = sysfs_info(sb);
140
141 /* Remove the superblock from fs_supers/s_instances
142 * so we can't find it, before freeing sysfs_super_info.
143 */
144 kill_anon_super(sb);
145 kfree(info);
80} 146}
81 147
82static struct file_system_type sysfs_fs_type = { 148static struct file_system_type sysfs_fs_type = {
83 .name = "sysfs", 149 .name = "sysfs",
84 .get_sb = sysfs_get_sb, 150 .get_sb = sysfs_get_sb,
85 .kill_sb = kill_anon_super, 151 .kill_sb = sysfs_kill_sb,
86}; 152};
87 153
154void sysfs_exit_ns(enum kobj_ns_type type, const void *ns)
155{
156 struct super_block *sb;
157
158 mutex_lock(&sysfs_mutex);
159 spin_lock(&sb_lock);
160 list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) {
161 struct sysfs_super_info *info = sysfs_info(sb);
162 /*
163 * If we see a superblock on the fs_supers/s_instances
164 * list the unmount has not completed and sb->s_fs_info
165 * points to a valid struct sysfs_super_info.
166 */
167 /* Ignore superblocks with the wrong ns */
168 if (info->ns[type] != ns)
169 continue;
170 info->ns[type] = NULL;
171 }
172 spin_unlock(&sb_lock);
173 mutex_unlock(&sysfs_mutex);
174}
175
88int __init sysfs_init(void) 176int __init sysfs_init(void)
89{ 177{
90 int err = -ENOMEM; 178 int err = -ENOMEM;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5eff49fa41b..a7ac78f8e67a 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/gfp.h>
14#include <linux/mount.h> 15#include <linux/mount.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/kobject.h> 17#include <linux/kobject.h>
@@ -27,6 +28,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
27 struct sysfs_dirent *target_sd = NULL; 28 struct sysfs_dirent *target_sd = NULL;
28 struct sysfs_dirent *sd = NULL; 29 struct sysfs_dirent *sd = NULL;
29 struct sysfs_addrm_cxt acxt; 30 struct sysfs_addrm_cxt acxt;
31 enum kobj_ns_type ns_type;
30 int error; 32 int error;
31 33
32 BUG_ON(!name); 34 BUG_ON(!name);
@@ -57,14 +59,29 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
57 if (!sd) 59 if (!sd)
58 goto out_put; 60 goto out_put;
59 61
62 ns_type = sysfs_ns_type(parent_sd);
63 if (ns_type)
64 sd->s_ns = target->ktype->namespace(target);
60 sd->s_symlink.target_sd = target_sd; 65 sd->s_symlink.target_sd = target_sd;
61 target_sd = NULL; /* reference is now owned by the symlink */ 66 target_sd = NULL; /* reference is now owned by the symlink */
62 67
63 sysfs_addrm_start(&acxt, parent_sd); 68 sysfs_addrm_start(&acxt, parent_sd);
64 if (warn) 69 /* Symlinks must be between directories with the same ns_type */
65 error = sysfs_add_one(&acxt, sd); 70 if (!ns_type ||
66 else 71 (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent))) {
67 error = __sysfs_add_one(&acxt, sd); 72 if (warn)
73 error = sysfs_add_one(&acxt, sd);
74 else
75 error = __sysfs_add_one(&acxt, sd);
76 } else {
77 error = -EINVAL;
78 WARN(1, KERN_WARNING
79 "sysfs: symlink across ns_types %s/%s -> %s/%s\n",
80 parent_sd->s_name,
81 sd->s_name,
82 sd->s_symlink.target_sd->s_parent->s_name,
83 sd->s_symlink.target_sd->s_name);
84 }
68 sysfs_addrm_finish(&acxt); 85 sysfs_addrm_finish(&acxt);
69 86
70 if (error) 87 if (error)
@@ -106,6 +123,26 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,
106} 123}
107 124
108/** 125/**
126 * sysfs_delete_link - remove symlink in object's directory.
127 * @kobj: object we're acting for.
128 * @targ: object we're pointing to.
129 * @name: name of the symlink to remove.
130 *
131 * Unlike sysfs_remove_link sysfs_delete_link has enough information
132 * to successfully delete symlinks in tagged directories.
133 */
134void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
135 const char *name)
136{
137 const void *ns = NULL;
138 spin_lock(&sysfs_assoc_lock);
139 if (targ->sd && sysfs_ns_type(kobj->sd))
140 ns = targ->sd->s_ns;
141 spin_unlock(&sysfs_assoc_lock);
142 sysfs_hash_and_remove(kobj->sd, ns, name);
143}
144
145/**
109 * sysfs_remove_link - remove symlink in object's directory. 146 * sysfs_remove_link - remove symlink in object's directory.
110 * @kobj: object we're acting for. 147 * @kobj: object we're acting for.
111 * @name: name of the symlink to remove. 148 * @name: name of the symlink to remove.
@@ -120,7 +157,52 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
120 else 157 else
121 parent_sd = kobj->sd; 158 parent_sd = kobj->sd;
122 159
123 sysfs_hash_and_remove(parent_sd, name); 160 sysfs_hash_and_remove(parent_sd, NULL, name);
161}
162
163/**
164 * sysfs_rename_link - rename symlink in object's directory.
165 * @kobj: object we're acting for.
166 * @targ: object we're pointing to.
167 * @old: previous name of the symlink.
168 * @new: new name of the symlink.
169 *
170 * A helper function for the common rename symlink idiom.
171 */
172int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
173 const char *old, const char *new)
174{
175 struct sysfs_dirent *parent_sd, *sd = NULL;
176 const void *old_ns = NULL, *new_ns = NULL;
177 int result;
178
179 if (!kobj)
180 parent_sd = &sysfs_root;
181 else
182 parent_sd = kobj->sd;
183
184 if (targ->sd)
185 old_ns = targ->sd->s_ns;
186
187 result = -ENOENT;
188 sd = sysfs_get_dirent(parent_sd, old_ns, old);
189 if (!sd)
190 goto out;
191
192 result = -EINVAL;
193 if (sysfs_type(sd) != SYSFS_KOBJ_LINK)
194 goto out;
195 if (sd->s_symlink.target_sd->s_dir.kobj != targ)
196 goto out;
197
198 if (sysfs_ns_type(parent_sd))
199 new_ns = targ->ktype->namespace(targ);
200
201 result = sysfs_rename(sd, parent_sd, new_ns, new);
202
203out:
204 sysfs_put(sd);
205 return result;
124} 206}
125 207
126static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, 208static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
@@ -222,3 +304,4 @@ const struct inode_operations sysfs_symlink_inode_operations = {
222 304
223EXPORT_SYMBOL_GPL(sysfs_create_link); 305EXPORT_SYMBOL_GPL(sysfs_create_link);
224EXPORT_SYMBOL_GPL(sysfs_remove_link); 306EXPORT_SYMBOL_GPL(sysfs_remove_link);
307EXPORT_SYMBOL_GPL(sysfs_rename_link);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index cdd9377a6e06..6a13105b5594 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -58,6 +58,7 @@ struct sysfs_dirent {
58 struct sysfs_dirent *s_sibling; 58 struct sysfs_dirent *s_sibling;
59 const char *s_name; 59 const char *s_name;
60 60
61 const void *s_ns; /* namespace tag */
61 union { 62 union {
62 struct sysfs_elem_dir s_dir; 63 struct sysfs_elem_dir s_dir;
63 struct sysfs_elem_symlink s_symlink; 64 struct sysfs_elem_symlink s_symlink;
@@ -66,8 +67,8 @@ struct sysfs_dirent {
66 }; 67 };
67 68
68 unsigned int s_flags; 69 unsigned int s_flags;
70 unsigned short s_mode;
69 ino_t s_ino; 71 ino_t s_ino;
70 umode_t s_mode;
71 struct sysfs_inode_attrs *s_iattr; 72 struct sysfs_inode_attrs *s_iattr;
72}; 73};
73 74
@@ -79,21 +80,38 @@ struct sysfs_dirent {
79#define SYSFS_KOBJ_BIN_ATTR 0x0004 80#define SYSFS_KOBJ_BIN_ATTR 0x0004
80#define SYSFS_KOBJ_LINK 0x0008 81#define SYSFS_KOBJ_LINK 0x0008
81#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) 82#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
83#define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
82 84
83#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK 85/* identify any namespace tag on sysfs_dirents */
84#define SYSFS_FLAG_REMOVED 0x0200 86#define SYSFS_NS_TYPE_MASK 0xff00
87#define SYSFS_NS_TYPE_SHIFT 8
88
89#define SYSFS_FLAG_MASK ~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK)
90#define SYSFS_FLAG_REMOVED 0x020000
85 91
86static inline unsigned int sysfs_type(struct sysfs_dirent *sd) 92static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
87{ 93{
88 return sd->s_flags & SYSFS_TYPE_MASK; 94 return sd->s_flags & SYSFS_TYPE_MASK;
89} 95}
90 96
97/*
98 * Return any namespace tags on this dirent.
99 * enum kobj_ns_type is defined in linux/kobject.h
100 */
101static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd)
102{
103 return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT;
104}
105
91#ifdef CONFIG_DEBUG_LOCK_ALLOC 106#ifdef CONFIG_DEBUG_LOCK_ALLOC
92#define sysfs_dirent_init_lockdep(sd) \ 107#define sysfs_dirent_init_lockdep(sd) \
93do { \ 108do { \
94 static struct lock_class_key __key; \ 109 struct attribute *attr = sd->s_attr.attr; \
110 struct lock_class_key *key = attr->key; \
111 if (!key) \
112 key = &attr->skey; \
95 \ 113 \
96 lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ 114 lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
97} while(0) 115} while(0)
98#else 116#else
99#define sysfs_dirent_init_lockdep(sd) do {} while(0) 117#define sysfs_dirent_init_lockdep(sd) do {} while(0)
@@ -110,8 +128,17 @@ struct sysfs_addrm_cxt {
110/* 128/*
111 * mount.c 129 * mount.c
112 */ 130 */
131
132/*
133 * Each sb is associated with a set of namespace tags (i.e.
134 * the network namespace of the task which mounted this sysfs
135 * instance).
136 */
137struct sysfs_super_info {
138 const void *ns[KOBJ_NS_TYPES];
139};
140#define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info))
113extern struct sysfs_dirent sysfs_root; 141extern struct sysfs_dirent sysfs_root;
114extern struct super_block *sysfs_sb;
115extern struct kmem_cache *sysfs_dir_cachep; 142extern struct kmem_cache *sysfs_dir_cachep;
116 143
117/* 144/*
@@ -124,8 +151,8 @@ extern const struct file_operations sysfs_dir_operations;
124extern const struct inode_operations sysfs_dir_inode_operations; 151extern const struct inode_operations sysfs_dir_inode_operations;
125 152
126struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); 153struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
127struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd); 154struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
128void sysfs_put_active_two(struct sysfs_dirent *sd); 155void sysfs_put_active(struct sysfs_dirent *sd);
129void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 156void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
130 struct sysfs_dirent *parent_sd); 157 struct sysfs_dirent *parent_sd);
131int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 158int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
@@ -134,8 +161,10 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
134void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); 161void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
135 162
136struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, 163struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
164 const void *ns,
137 const unsigned char *name); 165 const unsigned char *name);
138struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, 166struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
167 const void *ns,
139 const unsigned char *name); 168 const unsigned char *name);
140struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); 169struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
141 170
@@ -146,7 +175,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
146void sysfs_remove_subdir(struct sysfs_dirent *sd); 175void sysfs_remove_subdir(struct sysfs_dirent *sd);
147 176
148int sysfs_rename(struct sysfs_dirent *sd, 177int sysfs_rename(struct sysfs_dirent *sd,
149 struct sysfs_dirent *new_parent_sd, const char *new_name); 178 struct sysfs_dirent *new_parent_sd, const void *ns, const char *new_name);
150 179
151static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) 180static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
152{ 181{
@@ -168,7 +197,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
168/* 197/*
169 * inode.c 198 * inode.c
170 */ 199 */
171struct inode *sysfs_get_inode(struct sysfs_dirent *sd); 200struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
172void sysfs_delete_inode(struct inode *inode); 201void sysfs_delete_inode(struct inode *inode);
173int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); 202int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
174int sysfs_permission(struct inode *inode, int mask); 203int sysfs_permission(struct inode *inode, int mask);
@@ -176,7 +205,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
176int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); 205int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
177int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, 206int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
178 size_t size, int flags); 207 size_t size, int flags);
179int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); 208int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name);
180int sysfs_inode_init(void); 209int sysfs_inode_init(void);
181 210
182/* 211/*