1/* 2 * dir.c - Operations for sysfs directories. 3 */ 4 5#undef DEBUG 6 7#include <linux/fs.h> 8#include <linux/mount.h> 9#include <linux/module.h> 10#include <linux/kobject.h> 11#include <linux/namei.h> 12#include <asm/semaphore.h> 13#include "sysfs.h" 14 15DECLARE_RWSEM(sysfs_rename_sem); 16spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED; 17 18static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) 19{ 20 struct sysfs_dirent * sd = dentry->d_fsdata; 21 22 if (sd) { 23 /* sd->s_dentry is protected with sysfs_lock. This 24 * allows sysfs_drop_dentry() to dereference it. 25 */ 26 spin_lock(&sysfs_lock); 27 28 /* The dentry might have been deleted or another 29 * lookup could have happened updating sd->s_dentry to 30 * point the new dentry. Ignore if it isn't pointing 31 * to this dentry. 32 */ 33 if (sd->s_dentry == dentry) 34 sd->s_dentry = NULL; 35 spin_unlock(&sysfs_lock); 36 sysfs_put(sd); 37 } 38 iput(inode); 39} 40 41static struct dentry_operations sysfs_dentry_ops = { 42 .d_iput = sysfs_d_iput, 43}; 44 45static unsigned int sysfs_inode_counter; 46ino_t sysfs_get_inum(void) 47{ 48 if (unlikely(sysfs_inode_counter < 3)) 49 sysfs_inode_counter = 3; 50 return sysfs_inode_counter++; 51} 52 53/* 54 * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent 55 */ 56static struct sysfs_dirent * __sysfs_new_dirent(void * element) 57{ 58 struct sysfs_dirent * sd; 59 60 sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); 61 if (!sd) 62 return NULL; 63 64 sd->s_ino = sysfs_get_inum(); 65 atomic_set(&sd->s_count, 1); 66 atomic_set(&sd->s_event, 1); 67 INIT_LIST_HEAD(&sd->s_children); 68 INIT_LIST_HEAD(&sd->s_sibling); 69 sd->s_element = element; 70 71 return sd; 72} 73 74static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd, 75 struct sysfs_dirent *sd) 76{ 77 if (sd) 78 list_add(&sd->s_sibling, &parent_sd->s_children); 79} 80 81static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd, 82 void * element) 83{ 84 struct sysfs_dirent *sd; 85 sd = __sysfs_new_dirent(element); 86 __sysfs_list_dirent(parent_sd, sd); 87 return sd; 88} 89 90/* 91 * 92 * Return -EEXIST if there is already a sysfs element with the same name for 93 * the same parent. 94 * 95 * called with parent inode's i_mutex held 96 */ 97int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, 98 const unsigned char *new) 99{ 100 struct sysfs_dirent * sd; 101 102 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 103 if (sd->s_element) { 104 const unsigned char *existing = sysfs_get_name(sd); 105 if (strcmp(existing, new)) 106 continue; 107 else 108 return -EEXIST; 109 } 110 } 111 112 return 0; 113} 114 115 116static struct sysfs_dirent * 117__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type) 118{ 119 struct sysfs_dirent * sd; 120 121 sd = __sysfs_new_dirent(element); 122 if (!sd) 123 goto out; 124 125 sd->s_mode = mode; 126 sd->s_type = type; 127 sd->s_dentry = dentry; 128 if (dentry) { 129 dentry->d_fsdata = sysfs_get(sd); 130 dentry->d_op = &sysfs_dentry_ops; 131 } 132 133out: 134 return sd; 135} 136 137int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, 138 void * element, umode_t mode, int type) 139{ 140 struct sysfs_dirent *sd; 141 142 sd = __sysfs_make_dirent(dentry, element, mode, type); 143 __sysfs_list_dirent(parent_sd, sd); 144 145 return sd ? 0 : -ENOMEM; 146} 147 148static int init_dir(struct inode * inode) 149{ 150 inode->i_op = &sysfs_dir_inode_operations; 151 inode->i_fop = &sysfs_dir_operations; 152 153 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 154 inc_nlink(inode); 155 return 0; 156} 157 158static int init_file(struct inode * inode) 159{ 160 inode->i_size = PAGE_SIZE; 161 inode->i_fop = &sysfs_file_operations; 162 return 0; 163} 164 165static int init_symlink(struct inode * inode) 166{ 167 inode->i_op = &sysfs_symlink_inode_operations; 168 return 0; 169} 170 171static int create_dir(struct kobject * k, struct dentry * p, 172 const char * n, struct dentry ** d) 173{ 174 int error; 175 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 176 177 mutex_lock(&p->d_inode->i_mutex); 178 *d = lookup_one_len(n, p, strlen(n)); 179 if (!IS_ERR(*d)) { 180 if (sysfs_dirent_exist(p->d_fsdata, n)) 181 error = -EEXIST; 182 else 183 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, 184 SYSFS_DIR); 185 if (!error) { 186 error = sysfs_create(*d, mode, init_dir); 187 if (!error) { 188 inc_nlink(p->d_inode); 189 (*d)->d_op = &sysfs_dentry_ops; 190 d_rehash(*d); 191 } 192 } 193 if (error && (error != -EEXIST)) { 194 struct sysfs_dirent *sd = (*d)->d_fsdata; 195 if (sd) { 196 list_del_init(&sd->s_sibling); 197 sysfs_put(sd); 198 } 199 d_drop(*d); 200 } 201 dput(*d); 202 } else 203 error = PTR_ERR(*d); 204 mutex_unlock(&p->d_inode->i_mutex); 205 return error; 206} 207 208 209int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d) 210{ 211 return create_dir(k,k->dentry,n,d); 212} 213 214/** 215 * sysfs_create_dir - create a directory for an object. 216 * @kobj: object we're creating directory for. 217 * @shadow_parent: parent parent object. 218 */ 219 220int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent) 221{ 222 struct dentry * dentry = NULL; 223 struct dentry * parent; 224 int error = 0; 225 226 BUG_ON(!kobj); 227 228 if (shadow_parent) 229 parent = shadow_parent; 230 else if (kobj->parent) 231 parent = kobj->parent->dentry; 232 else if (sysfs_mount && sysfs_mount->mnt_sb) 233 parent = sysfs_mount->mnt_sb->s_root; 234 else 235 return -EFAULT; 236 237 error = create_dir(kobj,parent,kobject_name(kobj),&dentry); 238 if (!error) 239 kobj->dentry = dentry; 240 return error; 241} 242 243/* attaches attribute's sysfs_dirent to the dentry corresponding to the 244 * attribute file 245 */ 246static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) 247{ 248 struct attribute * attr = NULL; 249 struct bin_attribute * bin_attr = NULL; 250 int (* init) (struct inode *) = NULL; 251 int error = 0; 252 253 if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) { 254 bin_attr = sd->s_element; 255 attr = &bin_attr->attr; 256 } else { 257 attr = sd->s_element; 258 init = init_file; 259 } 260 261 dentry->d_fsdata = sysfs_get(sd); 262 /* protect sd->s_dentry against sysfs_d_iput */ 263 spin_lock(&sysfs_lock); 264 sd->s_dentry = dentry; 265 spin_unlock(&sysfs_lock); 266 error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); 267 if (error) { 268 sysfs_put(sd); 269 return error; 270 } 271 272 if (bin_attr) { 273 dentry->d_inode->i_size = bin_attr->size; 274 dentry->d_inode->i_fop = &bin_fops; 275 } 276 dentry->d_op = &sysfs_dentry_ops; 277 d_rehash(dentry); 278 279 return 0; 280} 281 282static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry) 283{ 284 int err = 0; 285 286 dentry->d_fsdata = sysfs_get(sd); 287 /* protect sd->s_dentry against sysfs_d_iput */ 288 spin_lock(&sysfs_lock); 289 sd->s_dentry = dentry; 290 spin_unlock(&sysfs_lock); 291 err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); 292 if (!err) { 293 dentry->d_op = &sysfs_dentry_ops; 294 d_rehash(dentry); 295 } else 296 sysfs_put(sd); 297 298 return err; 299} 300 301static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, 302 struct nameidata *nd) 303{ 304 struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; 305 struct sysfs_dirent * sd; 306 int err = 0; 307 308 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 309 if (sd->s_type & SYSFS_NOT_PINNED) { 310 const unsigned char * name = sysfs_get_name(sd); 311 312 if (strcmp(name, dentry->d_name.name)) 313 continue; 314 315 if (sd->s_type & SYSFS_KOBJ_LINK) 316 err = sysfs_attach_link(sd, dentry); 317 else 318 err = sysfs_attach_attr(sd, dentry); 319 break; 320 } 321 } 322 323 return ERR_PTR(err); 324} 325 326const struct inode_operations sysfs_dir_inode_operations = { 327 .lookup = sysfs_lookup, 328 .setattr = sysfs_setattr, 329}; 330 331static void remove_dir(struct dentry * d) 332{ 333 struct dentry * parent = dget(d->d_parent); 334 struct sysfs_dirent * sd; 335 336 mutex_lock(&parent->d_inode->i_mutex); 337 d_delete(d); 338 sd = d->d_fsdata; 339 list_del_init(&sd->s_sibling); 340 sysfs_put(sd); 341 if (d->d_inode) 342 simple_rmdir(parent->d_inode,d); 343 344 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 345 atomic_read(&d->d_count)); 346 347 mutex_unlock(&parent->d_inode->i_mutex); 348 dput(parent); 349} 350 351void sysfs_remove_subdir(struct dentry * d) 352{ 353 remove_dir(d); 354} 355 356 357static void __sysfs_remove_dir(struct dentry *dentry) 358{ 359 struct sysfs_dirent * parent_sd; 360 struct sysfs_dirent * sd, * tmp; 361 362 dget(dentry); 363 if (!dentry) 364 return; 365 366 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); 367 mutex_lock(&dentry->d_inode->i_mutex); 368 parent_sd = dentry->d_fsdata; 369 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { 370 if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) 371 continue; 372 list_del_init(&sd->s_sibling); 373 sysfs_drop_dentry(sd, dentry); 374 sysfs_put(sd); 375 } 376 mutex_unlock(&dentry->d_inode->i_mutex); 377 378 remove_dir(dentry); 379 /** 380 * Drop reference from dget() on entrance. 381 */ 382 dput(dentry); 383} 384 385/** 386 * sysfs_remove_dir - remove an object's directory. 387 * @kobj: object. 388 * 389 * The only thing special about this is that we remove any files in 390 * the directory before we remove the directory, and we've inlined 391 * what used to be sysfs_rmdir() below, instead of calling separately. 392 */ 393 394void sysfs_remove_dir(struct kobject * kobj) 395{ 396 __sysfs_remove_dir(kobj->dentry); 397 kobj->dentry = NULL; 398} 399 400int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent, 401 const char *new_name) 402{ 403 int error = 0; 404 struct dentry * new_dentry; 405 406 if (!new_parent) 407 return -EFAULT; 408 409 down_write(&sysfs_rename_sem); 410 mutex_lock(&new_parent->d_inode->i_mutex); 411 412 new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name)); 413 if (!IS_ERR(new_dentry)) { 414 /* By allowing two different directories with the 415 * same d_parent we allow this routine to move 416 * between different shadows of the same directory 417 */ 418 if (kobj->dentry->d_parent->d_inode != new_parent->d_inode) 419 return -EINVAL; 420 else if (new_dentry->d_parent->d_inode != new_parent->d_inode) 421 error = -EINVAL; 422 else if (new_dentry == kobj->dentry) 423 error = -EINVAL; 424 else if (!new_dentry->d_inode) { 425 error = kobject_set_name(kobj, "%s", new_name); 426 if (!error) { 427 struct sysfs_dirent *sd, *parent_sd; 428 429 d_add(new_dentry, NULL); 430 d_move(kobj->dentry, new_dentry); 431 432 sd = kobj->dentry->d_fsdata; 433 parent_sd = new_parent->d_fsdata; 434 435 list_del_init(&sd->s_sibling); 436 list_add(&sd->s_sibling, &parent_sd->s_children); 437 } 438 else 439 d_drop(new_dentry); 440 } else 441 error = -EEXIST; 442 dput(new_dentry); 443 } 444 mutex_unlock(&new_parent->d_inode->i_mutex); 445 up_write(&sysfs_rename_sem); 446 447 return error; 448} 449 450int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) 451{ 452 struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; 453 struct sysfs_dirent *new_parent_sd, *sd; 454 int error; 455 456 old_parent_dentry = kobj->parent ? 457 kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; 458 new_parent_dentry = new_parent ? 459 new_parent->dentry : sysfs_mount->mnt_sb->s_root; 460 461 if (old_parent_dentry->d_inode == new_parent_dentry->d_inode) 462 return 0; /* nothing to move */ 463again: 464 mutex_lock(&old_parent_dentry->d_inode->i_mutex); 465 if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { 466 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 467 goto again; 468 } 469 470 new_parent_sd = new_parent_dentry->d_fsdata; 471 sd = kobj->dentry->d_fsdata; 472 473 new_dentry = lookup_one_len(kobj->name, new_parent_dentry, 474 strlen(kobj->name)); 475 if (IS_ERR(new_dentry)) { 476 error = PTR_ERR(new_dentry); 477 goto out; 478 } else 479 error = 0; 480 d_add(new_dentry, NULL); 481 d_move(kobj->dentry, new_dentry); 482 dput(new_dentry); 483 484 /* Remove from old parent's list and insert into new parent's list. */ 485 list_del_init(&sd->s_sibling); 486 list_add(&sd->s_sibling, &new_parent_sd->s_children); 487 488out: 489 mutex_unlock(&new_parent_dentry->d_inode->i_mutex); 490 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 491 492 return error; 493} 494 495static int sysfs_dir_open(struct inode *inode, struct file *file) 496{ 497 struct dentry * dentry = file->f_path.dentry; 498 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 499 500 mutex_lock(&dentry->d_inode->i_mutex); 501 file->private_data = sysfs_new_dirent(parent_sd, NULL); 502 mutex_unlock(&dentry->d_inode->i_mutex); 503 504 return file->private_data ? 0 : -ENOMEM; 505 506} 507 508static int sysfs_dir_close(struct inode *inode, struct file *file) 509{ 510 struct dentry * dentry = file->f_path.dentry; 511 struct sysfs_dirent * cursor = file->private_data; 512 513 mutex_lock(&dentry->d_inode->i_mutex); 514 list_del_init(&cursor->s_sibling); 515 mutex_unlock(&dentry->d_inode->i_mutex); 516 517 release_sysfs_dirent(cursor); 518 519 return 0; 520} 521 522/* Relationship between s_mode and the DT_xxx types */ 523static inline unsigned char dt_type(struct sysfs_dirent *sd) 524{ 525 return (sd->s_mode >> 12) & 15; 526} 527 528static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 529{ 530 struct dentry *dentry = filp->f_path.dentry; 531 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 532 struct sysfs_dirent *cursor = filp->private_data; 533 struct list_head *p, *q = &cursor->s_sibling; 534 ino_t ino; 535 int i = filp->f_pos; 536 537 switch (i) { 538 case 0: 539 ino = parent_sd->s_ino; 540 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) 541 break; 542 filp->f_pos++; 543 i++; 544 /* fallthrough */ 545 case 1: 546 ino = parent_ino(dentry); 547 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) 548 break; 549 filp->f_pos++; 550 i++; 551 /* fallthrough */ 552 default: 553 if (filp->f_pos == 2) 554 list_move(q, &parent_sd->s_children); 555 556 for (p=q->next; p!= &parent_sd->s_children; p=p->next) { 557 struct sysfs_dirent *next; 558 const char * name; 559 int len; 560 561 next = list_entry(p, struct sysfs_dirent, 562 s_sibling); 563 if (!next->s_element) 564 continue; 565 566 name = sysfs_get_name(next); 567 len = strlen(name); 568 ino = next->s_ino; 569 570 if (filldir(dirent, name, len, filp->f_pos, ino, 571 dt_type(next)) < 0) 572 return 0; 573 574 list_move(q, p); 575 p = q; 576 filp->f_pos++; 577 } 578 } 579 return 0; 580} 581 582static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) 583{ 584 struct dentry * dentry = file->f_path.dentry; 585 586 mutex_lock(&dentry->d_inode->i_mutex); 587 switch (origin) { 588 case 1: 589 offset += file->f_pos; 590 case 0: 591 if (offset >= 0) 592 break; 593 default: 594 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); 595 return -EINVAL; 596 } 597 if (offset != file->f_pos) { 598 file->f_pos = offset; 599 if (file->f_pos >= 2) { 600 struct sysfs_dirent *sd = dentry->d_fsdata; 601 struct sysfs_dirent *cursor = file->private_data; 602 struct list_head *p; 603 loff_t n = file->f_pos - 2; 604 605 list_del(&cursor->s_sibling); 606 p = sd->s_children.next; 607 while (n && p != &sd->s_children) { 608 struct sysfs_dirent *next; 609 next = list_entry(p, struct sysfs_dirent, 610 s_sibling); 611 if (next->s_element) 612 n--; 613 p = p->next; 614 } 615 list_add_tail(&cursor->s_sibling, p); 616 } 617 } 618 mutex_unlock(&dentry->d_inode->i_mutex); 619 return offset; 620} 621 622 623/** 624 * sysfs_make_shadowed_dir - Setup so a directory can be shadowed 625 * @kobj: object we're creating shadow of. 626 */ 627 628int sysfs_make_shadowed_dir(struct kobject *kobj, 629 void * (*follow_link)(struct dentry *, struct nameidata *)) 630{ 631 struct inode *inode; 632 struct inode_operations *i_op; 633 634 inode = kobj->dentry->d_inode; 635 if (inode->i_op != &sysfs_dir_inode_operations) 636 return -EINVAL; 637 638 i_op = kmalloc(sizeof(*i_op), GFP_KERNEL); 639 if (!i_op) 640 return -ENOMEM; 641 642 memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op)); 643 i_op->follow_link = follow_link; 644 645 /* Locking of inode->i_op? 646 * Since setting i_op is a single word write and they 647 * are atomic we should be ok here. 648 */ 649 inode->i_op = i_op; 650 return 0; 651} 652 653/** 654 * sysfs_create_shadow_dir - create a shadow directory for an object. 655 * @kobj: object we're creating directory for. 656 * 657 * sysfs_make_shadowed_dir must already have been called on this 658 * directory. 659 */ 660 661struct dentry *sysfs_create_shadow_dir(struct kobject *kobj) 662{ 663 struct sysfs_dirent *sd; 664 struct dentry *parent, *dir, *shadow; 665 struct inode *inode; 666 667 dir = kobj->dentry; 668 inode = dir->d_inode; 669 parent = dir->d_parent; 670 shadow = ERR_PTR(-EINVAL); 671 if (!sysfs_is_shadowed_inode(inode)) 672 goto out; 673 674 shadow = d_alloc(parent, &dir->d_name); 675 if (!shadow) 676 goto nomem; 677 678 sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR); 679 if (!sd) 680 goto nomem; 681 682 d_instantiate(shadow, igrab(inode)); 683 inc_nlink(inode); 684 inc_nlink(parent->d_inode); 685 shadow->d_op = &sysfs_dentry_ops; 686 687 dget(shadow); /* Extra count - pin the dentry in core */ 688 689out: 690 return shadow; 691nomem: 692 dput(shadow); 693 shadow = ERR_PTR(-ENOMEM); 694 goto out; 695} 696 697/** 698 * sysfs_remove_shadow_dir - remove an object's directory. 699 * @shadow: dentry of shadow directory 700 * 701 * The only thing special about this is that we remove any files in 702 * the directory before we remove the directory, and we've inlined 703 * what used to be sysfs_rmdir() below, instead of calling separately. 704 */ 705 706void sysfs_remove_shadow_dir(struct dentry *shadow) 707{ 708 __sysfs_remove_dir(shadow); 709} 710 711const struct file_operations sysfs_dir_operations = { 712 .open = sysfs_dir_open, 713 .release = sysfs_dir_close, 714 .llseek = sysfs_dir_lseek, 715 .read = generic_read_dir, 716 .readdir = sysfs_readdir, 717}; 718