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