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 old_parent_dentry = kobj->parent ? 382 kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; 383 new_parent_dentry = new_parent ? 384 new_parent->dentry : sysfs_mount->mnt_sb->s_root; 385 386 again: 387 mutex_lock(&old_parent_dentry->d_inode->i_mutex); 388 if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { 389 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 390 goto again; 391 } 392 393 new_parent_sd = new_parent_dentry->d_fsdata; 394 sd = kobj->dentry->d_fsdata; 395 396 new_dentry = lookup_one_len(kobj->name, new_parent_dentry, 397 strlen(kobj->name)); 398 if (IS_ERR(new_dentry)) { 399 error = PTR_ERR(new_dentry); 400 goto out; 401 } else 402 error = 0; 403 d_add(new_dentry, NULL); 404 d_move(kobj->dentry, new_dentry); 405 dput(new_dentry); 406 407 /* Remove from old parent's list and insert into new parent's list. */ 408 list_del_init(&sd->s_sibling); 409 list_add(&sd->s_sibling, &new_parent_sd->s_children); 410 411 out: 412 mutex_unlock(&new_parent_dentry->d_inode->i_mutex); 413 mutex_unlock(&old_parent_dentry->d_inode->i_mutex); 414 415 return error; 416 } 417 418 static int sysfs_dir_open(struct inode *inode, struct file *file) 419 { 420 struct dentry * dentry = file->f_path.dentry; 421 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 422 423 mutex_lock(&dentry->d_inode->i_mutex); 424 file->private_data = sysfs_new_dirent(parent_sd, NULL); 425 mutex_unlock(&dentry->d_inode->i_mutex); 426 427 return file->private_data ? 0 : -ENOMEM; 428 429 } 430 431 static int sysfs_dir_close(struct inode *inode, struct file *file) 432 { 433 struct dentry * dentry = file->f_path.dentry; 434 struct sysfs_dirent * cursor = file->private_data; 435 436 mutex_lock(&dentry->d_inode->i_mutex); 437 list_del_init(&cursor->s_sibling); 438 mutex_unlock(&dentry->d_inode->i_mutex); 439 440 release_sysfs_dirent(cursor); 441 442 return 0; 443 } 444 445 /* Relationship between s_mode and the DT_xxx types */ 446 static inline unsigned char dt_type(struct sysfs_dirent *sd) 447 { 448 return (sd->s_mode >> 12) & 15; 449 } 450 451 static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 452 { 453 struct dentry *dentry = filp->f_path.dentry; 454 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 455 struct sysfs_dirent *cursor = filp->private_data; 456 struct list_head *p, *q = &cursor->s_sibling; 457 ino_t ino; 458 int i = filp->f_pos; 459 460 switch (i) { 461 case 0: 462 ino = dentry->d_inode->i_ino; 463 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) 464 break; 465 filp->f_pos++; 466 i++; 467 /* fallthrough */ 468 case 1: 469 ino = parent_ino(dentry); 470 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) 471 break; 472 filp->f_pos++; 473 i++; 474 /* fallthrough */ 475 default: 476 if (filp->f_pos == 2) 477 list_move(q, &parent_sd->s_children); 478 479 for (p=q->next; p!= &parent_sd->s_children; p=p->next) { 480 struct sysfs_dirent *next; 481 const char * name; 482 int len; 483 484 next = list_entry(p, struct sysfs_dirent, 485 s_sibling); 486 if (!next->s_element) 487 continue; 488 489 name = sysfs_get_name(next); 490 len = strlen(name); 491 if (next->s_dentry) 492 ino = next->s_dentry->d_inode->i_ino; 493 else 494 ino = iunique(sysfs_sb, 2); 495 496 if (filldir(dirent, name, len, filp->f_pos, ino, 497 dt_type(next)) < 0) 498 return 0; 499 500 list_move(q, p); 501 p = q; 502 filp->f_pos++; 503 } 504 } 505 return 0; 506 } 507 508 static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) 509 { 510 struct dentry * dentry = file->f_path.dentry; 511 512 mutex_lock(&dentry->d_inode->i_mutex); 513 switch (origin) { 514 case 1: 515 offset += file->f_pos; 516 case 0: 517 if (offset >= 0) 518 break; 519 default: 520 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); 521 return -EINVAL; 522 } 523 if (offset != file->f_pos) { 524 file->f_pos = offset; 525 if (file->f_pos >= 2) { 526 struct sysfs_dirent *sd = dentry->d_fsdata; 527 struct sysfs_dirent *cursor = file->private_data; 528 struct list_head *p; 529 loff_t n = file->f_pos - 2; 530 531 list_del(&cursor->s_sibling); 532 p = sd->s_children.next; 533 while (n && p != &sd->s_children) { 534 struct sysfs_dirent *next; 535 next = list_entry(p, struct sysfs_dirent, 536 s_sibling); 537 if (next->s_element) 538 n--; 539 p = p->next; 540 } 541 list_add_tail(&cursor->s_sibling, p); 542 } 543 } 544 mutex_unlock(&dentry->d_inode->i_mutex); 545 return offset; 546 } 547 548 const struct file_operations sysfs_dir_operations = { 549 .open = sysfs_dir_open, 550 .release = sysfs_dir_close, 551 .llseek = sysfs_dir_lseek, 552 .read = generic_read_dir, 553 .readdir = sysfs_readdir, 554 }; 555