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 "sysfs.h" 13 14 DECLARE_RWSEM(sysfs_rename_sem); 15 16 static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) 17 { 18 struct sysfs_dirent * sd = dentry->d_fsdata; 19 20 if (sd) { 21 BUG_ON(sd->s_dentry != dentry); 22 sd->s_dentry = NULL; 23 sysfs_put(sd); 24 } 25 iput(inode); 26 } 27 28 static struct dentry_operations sysfs_dentry_ops = { 29 .d_iput = sysfs_d_iput, 30 }; 31 32 /* 33 * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent 34 */ 35 static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd, 36 void * element) 37 { 38 struct sysfs_dirent * sd; 39 40 sd = kmem_cache_alloc(sysfs_dir_cachep, GFP_KERNEL); 41 if (!sd) 42 return NULL; 43 44 memset(sd, 0, sizeof(*sd)); 45 atomic_set(&sd->s_count, 1); 46 atomic_set(&sd->s_event, 1); 47 INIT_LIST_HEAD(&sd->s_children); 48 list_add(&sd->s_sibling, &parent_sd->s_children); 49 sd->s_element = element; 50 51 return sd; 52 } 53 54 /* 55 * 56 * Return -EEXIST if there is already a sysfs element with the same name for 57 * the same parent. 58 * 59 * called with parent inode's i_mutex held 60 */ 61 int sysfs_dirent_exist(struct sysfs_dirent *parent_sd, 62 const unsigned char *new) 63 { 64 struct sysfs_dirent * sd; 65 66 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 67 if (sd->s_element) { 68 const unsigned char *existing = sysfs_get_name(sd); 69 if (strcmp(existing, new)) 70 continue; 71 else 72 return -EEXIST; 73 } 74 } 75 76 return 0; 77 } 78 79 80 int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, 81 void * element, umode_t mode, int type) 82 { 83 struct sysfs_dirent * sd; 84 85 sd = sysfs_new_dirent(parent_sd, element); 86 if (!sd) 87 return -ENOMEM; 88 89 sd->s_mode = mode; 90 sd->s_type = type; 91 sd->s_dentry = dentry; 92 if (dentry) { 93 dentry->d_fsdata = sysfs_get(sd); 94 dentry->d_op = &sysfs_dentry_ops; 95 } 96 97 return 0; 98 } 99 100 static int init_dir(struct inode * inode) 101 { 102 inode->i_op = &sysfs_dir_inode_operations; 103 inode->i_fop = &sysfs_dir_operations; 104 105 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 106 inc_nlink(inode); 107 return 0; 108 } 109 110 static int init_file(struct inode * inode) 111 { 112 inode->i_size = PAGE_SIZE; 113 inode->i_fop = &sysfs_file_operations; 114 return 0; 115 } 116 117 static int init_symlink(struct inode * inode) 118 { 119 inode->i_op = &sysfs_symlink_inode_operations; 120 return 0; 121 } 122 123 static int create_dir(struct kobject * k, struct dentry * p, 124 const char * n, struct dentry ** d) 125 { 126 int error; 127 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 128 129 mutex_lock(&p->d_inode->i_mutex); 130 *d = lookup_one_len(n, p, strlen(n)); 131 if (!IS_ERR(*d)) { 132 if (sysfs_dirent_exist(p->d_fsdata, n)) 133 error = -EEXIST; 134 else 135 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, 136 SYSFS_DIR); 137 if (!error) { 138 error = sysfs_create(*d, mode, init_dir); 139 if (!error) { 140 inc_nlink(p->d_inode); 141 (*d)->d_op = &sysfs_dentry_ops; 142 d_rehash(*d); 143 } 144 } 145 if (error && (error != -EEXIST)) { 146 struct sysfs_dirent *sd = (*d)->d_fsdata; 147 if (sd) { 148 list_del_init(&sd->s_sibling); 149 sysfs_put(sd); 150 } 151 d_drop(*d); 152 } 153 dput(*d); 154 } else 155 error = PTR_ERR(*d); 156 mutex_unlock(&p->d_inode->i_mutex); 157 return error; 158 } 159 160 161 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d) 162 { 163 return create_dir(k,k->dentry,n,d); 164 } 165 166 /** 167 * sysfs_create_dir - create a directory for an object. 168 * @parent: parent parent object. 169 * @kobj: object we're creating directory for. 170 */ 171 172 int sysfs_create_dir(struct kobject * kobj) 173 { 174 struct dentry * dentry = NULL; 175 struct dentry * parent; 176 int error = 0; 177 178 BUG_ON(!kobj); 179 180 if (kobj->parent) 181 parent = kobj->parent->dentry; 182 else if (sysfs_mount && sysfs_mount->mnt_sb) 183 parent = sysfs_mount->mnt_sb->s_root; 184 else 185 return -EFAULT; 186 187 error = create_dir(kobj,parent,kobject_name(kobj),&dentry); 188 if (!error) 189 kobj->dentry = dentry; 190 return error; 191 } 192 193 /* attaches attribute's sysfs_dirent to the dentry corresponding to the 194 * attribute file 195 */ 196 static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) 197 { 198 struct attribute * attr = NULL; 199 struct bin_attribute * bin_attr = NULL; 200 int (* init) (struct inode *) = NULL; 201 int error = 0; 202 203 if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) { 204 bin_attr = sd->s_element; 205 attr = &bin_attr->attr; 206 } else { 207 attr = sd->s_element; 208 init = init_file; 209 } 210 211 dentry->d_fsdata = sysfs_get(sd); 212 sd->s_dentry = dentry; 213 error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); 214 if (error) { 215 sysfs_put(sd); 216 return error; 217 } 218 219 if (bin_attr) { 220 dentry->d_inode->i_size = bin_attr->size; 221 dentry->d_inode->i_fop = &bin_fops; 222 } 223 dentry->d_op = &sysfs_dentry_ops; 224 d_rehash(dentry); 225 226 return 0; 227 } 228 229 static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry) 230 { 231 int err = 0; 232 233 dentry->d_fsdata = sysfs_get(sd); 234 sd->s_dentry = dentry; 235 err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); 236 if (!err) { 237 dentry->d_op = &sysfs_dentry_ops; 238 d_rehash(dentry); 239 } else 240 sysfs_put(sd); 241 242 return err; 243 } 244 245 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, 246 struct nameidata *nd) 247 { 248 struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; 249 struct sysfs_dirent * sd; 250 int err = 0; 251 252 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 253 if (sd->s_type & SYSFS_NOT_PINNED) { 254 const unsigned char * name = sysfs_get_name(sd); 255 256 if (strcmp(name, dentry->d_name.name)) 257 continue; 258 259 if (sd->s_type & SYSFS_KOBJ_LINK) 260 err = sysfs_attach_link(sd, dentry); 261 else 262 err = sysfs_attach_attr(sd, dentry); 263 break; 264 } 265 } 266 267 return ERR_PTR(err); 268 } 269 270 struct inode_operations sysfs_dir_inode_operations = { 271 .lookup = sysfs_lookup, 272 .setattr = sysfs_setattr, 273 }; 274 275 static void remove_dir(struct dentry * d) 276 { 277 struct dentry * parent = dget(d->d_parent); 278 struct sysfs_dirent * sd; 279 280 mutex_lock(&parent->d_inode->i_mutex); 281 d_delete(d); 282 sd = d->d_fsdata; 283 list_del_init(&sd->s_sibling); 284 sysfs_put(sd); 285 if (d->d_inode) 286 simple_rmdir(parent->d_inode,d); 287 288 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 289 atomic_read(&d->d_count)); 290 291 mutex_unlock(&parent->d_inode->i_mutex); 292 dput(parent); 293 } 294 295 void sysfs_remove_subdir(struct dentry * d) 296 { 297 remove_dir(d); 298 } 299 300 301 /** 302 * sysfs_remove_dir - remove an object's directory. 303 * @kobj: object. 304 * 305 * The only thing special about this is that we remove any files in 306 * the directory before we remove the directory, and we've inlined 307 * what used to be sysfs_rmdir() below, instead of calling separately. 308 */ 309 310 void sysfs_remove_dir(struct kobject * kobj) 311 { 312 struct dentry * dentry = dget(kobj->dentry); 313 struct sysfs_dirent * parent_sd; 314 struct sysfs_dirent * sd, * tmp; 315 316 if (!dentry) 317 return; 318 319 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); 320 mutex_lock(&dentry->d_inode->i_mutex); 321 parent_sd = dentry->d_fsdata; 322 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { 323 if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) 324 continue; 325 list_del_init(&sd->s_sibling); 326 sysfs_drop_dentry(sd, dentry); 327 sysfs_put(sd); 328 } 329 mutex_unlock(&dentry->d_inode->i_mutex); 330 331 remove_dir(dentry); 332 /** 333 * Drop reference from dget() on entrance. 334 */ 335 dput(dentry); 336 kobj->dentry = NULL; 337 } 338 339 int sysfs_rename_dir(struct kobject * kobj, const char *new_name) 340 { 341 int error = 0; 342 struct dentry * new_dentry, * parent; 343 344 if (!strcmp(kobject_name(kobj), new_name)) 345 return -EINVAL; 346 347 if (!kobj->parent) 348 return -EINVAL; 349 350 down_write(&sysfs_rename_sem); 351 parent = kobj->parent->dentry; 352 353 mutex_lock(&parent->d_inode->i_mutex); 354 355 new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); 356 if (!IS_ERR(new_dentry)) { 357 if (!new_dentry->d_inode) { 358 error = kobject_set_name(kobj, "%s", new_name); 359 if (!error) { 360 d_add(new_dentry, NULL); 361 d_move(kobj->dentry, new_dentry); 362 } 363 else 364 d_drop(new_dentry); 365 } else 366 error = -EEXIST; 367 dput(new_dentry); 368 } 369 mutex_unlock(&parent->d_inode->i_mutex); 370 up_write(&sysfs_rename_sem); 371 372 return error; 373 } 374 375 int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) 376 { 377 struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; 378 struct sysfs_dirent *new_parent_sd, *sd; 379 int error; 380 381 if (!new_parent) 382 return -EINVAL; 383 384 old_parent_dentry = kobj->parent ? 385 kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; 386 new_parent_dentry = new_parent->dentry; 387 388 again: 389 mutex_lock(&old_parent_dentry->d_inode->i_mutex); 390 if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { 391 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 392 goto again; 393 } 394 395 new_parent_sd = new_parent_dentry->d_fsdata; 396 sd = kobj->dentry->d_fsdata; 397 398 new_dentry = lookup_one_len(kobj->name, new_parent_dentry, 399 strlen(kobj->name)); 400 if (IS_ERR(new_dentry)) { 401 error = PTR_ERR(new_dentry); 402 goto out; 403 } else 404 error = 0; 405 d_add(new_dentry, NULL); 406 d_move(kobj->dentry, new_dentry); 407 dput(new_dentry); 408 409 /* Remove from old parent's list and insert into new parent's list. */ 410 list_del_init(&sd->s_sibling); 411 list_add(&sd->s_sibling, &new_parent_sd->s_children); 412 413 out: 414 mutex_unlock(&new_parent_dentry->d_inode->i_mutex); 415 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 416 417 return error; 418 } 419 420 static int sysfs_dir_open(struct inode *inode, struct file *file) 421 { 422 struct dentry * dentry = file->f_dentry; 423 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 424 425 mutex_lock(&dentry->d_inode->i_mutex); 426 file->private_data = sysfs_new_dirent(parent_sd, NULL); 427 mutex_unlock(&dentry->d_inode->i_mutex); 428 429 return file->private_data ? 0 : -ENOMEM; 430 431 } 432 433 static int sysfs_dir_close(struct inode *inode, struct file *file) 434 { 435 struct dentry * dentry = file->f_dentry; 436 struct sysfs_dirent * cursor = file->private_data; 437 438 mutex_lock(&dentry->d_inode->i_mutex); 439 list_del_init(&cursor->s_sibling); 440 mutex_unlock(&dentry->d_inode->i_mutex); 441 442 release_sysfs_dirent(cursor); 443 444 return 0; 445 } 446 447 /* Relationship between s_mode and the DT_xxx types */ 448 static inline unsigned char dt_type(struct sysfs_dirent *sd) 449 { 450 return (sd->s_mode >> 12) & 15; 451 } 452 453 static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 454 { 455 struct dentry *dentry = filp->f_dentry; 456 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 457 struct sysfs_dirent *cursor = filp->private_data; 458 struct list_head *p, *q = &cursor->s_sibling; 459 ino_t ino; 460 int i = filp->f_pos; 461 462 switch (i) { 463 case 0: 464 ino = dentry->d_inode->i_ino; 465 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) 466 break; 467 filp->f_pos++; 468 i++; 469 /* fallthrough */ 470 case 1: 471 ino = parent_ino(dentry); 472 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) 473 break; 474 filp->f_pos++; 475 i++; 476 /* fallthrough */ 477 default: 478 if (filp->f_pos == 2) 479 list_move(q, &parent_sd->s_children); 480 481 for (p=q->next; p!= &parent_sd->s_children; p=p->next) { 482 struct sysfs_dirent *next; 483 const char * name; 484 int len; 485 486 next = list_entry(p, struct sysfs_dirent, 487 s_sibling); 488 if (!next->s_element) 489 continue; 490 491 name = sysfs_get_name(next); 492 len = strlen(name); 493 if (next->s_dentry) 494 ino = next->s_dentry->d_inode->i_ino; 495 else 496 ino = iunique(sysfs_sb, 2); 497 498 if (filldir(dirent, name, len, filp->f_pos, ino, 499 dt_type(next)) < 0) 500 return 0; 501 502 list_move(q, p); 503 p = q; 504 filp->f_pos++; 505 } 506 } 507 return 0; 508 } 509 510 static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) 511 { 512 struct dentry * dentry = file->f_dentry; 513 514 mutex_lock(&dentry->d_inode->i_mutex); 515 switch (origin) { 516 case 1: 517 offset += file->f_pos; 518 case 0: 519 if (offset >= 0) 520 break; 521 default: 522 mutex_unlock(&file->f_dentry->d_inode->i_mutex); 523 return -EINVAL; 524 } 525 if (offset != file->f_pos) { 526 file->f_pos = offset; 527 if (file->f_pos >= 2) { 528 struct sysfs_dirent *sd = dentry->d_fsdata; 529 struct sysfs_dirent *cursor = file->private_data; 530 struct list_head *p; 531 loff_t n = file->f_pos - 2; 532 533 list_del(&cursor->s_sibling); 534 p = sd->s_children.next; 535 while (n && p != &sd->s_children) { 536 struct sysfs_dirent *next; 537 next = list_entry(p, struct sysfs_dirent, 538 s_sibling); 539 if (next->s_element) 540 n--; 541 p = p->next; 542 } 543 list_add_tail(&cursor->s_sibling, p); 544 } 545 } 546 mutex_unlock(&dentry->d_inode->i_mutex); 547 return offset; 548 } 549 550 const struct file_operations sysfs_dir_operations = { 551 .open = sysfs_dir_open, 552 .release = sysfs_dir_close, 553 .llseek = sysfs_dir_lseek, 554 .read = generic_read_dir, 555 .readdir = sysfs_readdir, 556 }; 557