1 /* 2 * gendisk handling 3 */ 4 5 #include <linux/module.h> 6 #include <linux/fs.h> 7 #include <linux/genhd.h> 8 #include <linux/kdev_t.h> 9 #include <linux/kernel.h> 10 #include <linux/blkdev.h> 11 #include <linux/init.h> 12 #include <linux/spinlock.h> 13 #include <linux/seq_file.h> 14 #include <linux/slab.h> 15 #include <linux/kmod.h> 16 #include <linux/kobj_map.h> 17 #include <linux/buffer_head.h> 18 #include <linux/mutex.h> 19 20 struct kset block_subsys; 21 static DEFINE_MUTEX(block_subsys_lock); 22 23 /* 24 * Can be deleted altogether. Later. 25 * 26 */ 27 static struct blk_major_name { 28 struct blk_major_name *next; 29 int major; 30 char name[16]; 31 } *major_names[BLKDEV_MAJOR_HASH_SIZE]; 32 33 /* index in the above - for now: assume no multimajor ranges */ 34 static inline int major_to_index(int major) 35 { 36 return major % BLKDEV_MAJOR_HASH_SIZE; 37 } 38 39 #ifdef CONFIG_PROC_FS 40 41 void blkdev_show(struct seq_file *f, off_t offset) 42 { 43 struct blk_major_name *dp; 44 45 if (offset < BLKDEV_MAJOR_HASH_SIZE) { 46 mutex_lock(&block_subsys_lock); 47 for (dp = major_names[offset]; dp; dp = dp->next) 48 seq_printf(f, "%3d %s\n", dp->major, dp->name); 49 mutex_unlock(&block_subsys_lock); 50 } 51 } 52 53 #endif /* CONFIG_PROC_FS */ 54 55 int register_blkdev(unsigned int major, const char *name) 56 { 57 struct blk_major_name **n, *p; 58 int index, ret = 0; 59 60 mutex_lock(&block_subsys_lock); 61 62 /* temporary */ 63 if (major == 0) { 64 for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) { 65 if (major_names[index] == NULL) 66 break; 67 } 68 69 if (index == 0) { 70 printk("register_blkdev: failed to get major for %s\n", 71 name); 72 ret = -EBUSY; 73 goto out; 74 } 75 major = index; 76 ret = major; 77 } 78 79 p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL); 80 if (p == NULL) { 81 ret = -ENOMEM; 82 goto out; 83 } 84 85 p->major = major; 86 strlcpy(p->name, name, sizeof(p->name)); 87 p->next = NULL; 88 index = major_to_index(major); 89 90 for (n = &major_names[index]; *n; n = &(*n)->next) { 91 if ((*n)->major == major) 92 break; 93 } 94 if (!*n) 95 *n = p; 96 else 97 ret = -EBUSY; 98 99 if (ret < 0) { 100 printk("register_blkdev: cannot get major %d for %s\n", 101 major, name); 102 kfree(p); 103 } 104 out: 105 mutex_unlock(&block_subsys_lock); 106 return ret; 107 } 108 109 EXPORT_SYMBOL(register_blkdev); 110 111 void unregister_blkdev(unsigned int major, const char *name) 112 { 113 struct blk_major_name **n; 114 struct blk_major_name *p = NULL; 115 int index = major_to_index(major); 116 117 mutex_lock(&block_subsys_lock); 118 for (n = &major_names[index]; *n; n = &(*n)->next) 119 if ((*n)->major == major) 120 break; 121 if (!*n || strcmp((*n)->name, name)) { 122 WARN_ON(1); 123 } else { 124 p = *n; 125 *n = p->next; 126 } 127 mutex_unlock(&block_subsys_lock); 128 kfree(p); 129 } 130 131 EXPORT_SYMBOL(unregister_blkdev); 132 133 static struct kobj_map *bdev_map; 134 135 /* 136 * Register device numbers dev..(dev+range-1) 137 * range must be nonzero 138 * The hash chain is sorted on range, so that subranges can override. 139 */ 140 void blk_register_region(dev_t dev, unsigned long range, struct module *module, 141 struct kobject *(*probe)(dev_t, int *, void *), 142 int (*lock)(dev_t, void *), void *data) 143 { 144 kobj_map(bdev_map, dev, range, module, probe, lock, data); 145 } 146 147 EXPORT_SYMBOL(blk_register_region); 148 149 void blk_unregister_region(dev_t dev, unsigned long range) 150 { 151 kobj_unmap(bdev_map, dev, range); 152 } 153 154 EXPORT_SYMBOL(blk_unregister_region); 155 156 static struct kobject *exact_match(dev_t dev, int *part, void *data) 157 { 158 struct gendisk *p = data; 159 return &p->kobj; 160 } 161 162 static int exact_lock(dev_t dev, void *data) 163 { 164 struct gendisk *p = data; 165 166 if (!get_disk(p)) 167 return -1; 168 return 0; 169 } 170 171 /** 172 * add_disk - add partitioning information to kernel list 173 * @disk: per-device partitioning information 174 * 175 * This function registers the partitioning information in @disk 176 * with the kernel. 177 */ 178 void add_disk(struct gendisk *disk) 179 { 180 disk->flags |= GENHD_FL_UP; 181 blk_register_region(MKDEV(disk->major, disk->first_minor), 182 disk->minors, NULL, exact_match, exact_lock, disk); 183 register_disk(disk); 184 blk_register_queue(disk); 185 } 186 187 EXPORT_SYMBOL(add_disk); 188 EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */ 189 190 void unlink_gendisk(struct gendisk *disk) 191 { 192 blk_unregister_queue(disk); 193 blk_unregister_region(MKDEV(disk->major, disk->first_minor), 194 disk->minors); 195 } 196 197 #define to_disk(obj) container_of(obj,struct gendisk,kobj) 198 199 /** 200 * get_gendisk - get partitioning information for a given device 201 * @dev: device to get partitioning information for 202 * 203 * This function gets the structure containing partitioning 204 * information for the given device @dev. 205 */ 206 struct gendisk *get_gendisk(dev_t dev, int *part) 207 { 208 struct kobject *kobj = kobj_lookup(bdev_map, dev, part); 209 return kobj ? to_disk(kobj) : NULL; 210 } 211 212 /* 213 * print a full list of all partitions - intended for places where the root 214 * filesystem can't be mounted and thus to give the victim some idea of what 215 * went wrong 216 */ 217 void __init printk_all_partitions(void) 218 { 219 int n; 220 struct gendisk *sgp; 221 222 mutex_lock(&block_subsys_lock); 223 /* For each block device... */ 224 list_for_each_entry(sgp, &block_subsys.list, kobj.entry) { 225 char buf[BDEVNAME_SIZE]; 226 /* 227 * Don't show empty devices or things that have been surpressed 228 */ 229 if (get_capacity(sgp) == 0 || 230 (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) 231 continue; 232 233 /* 234 * Note, unlike /proc/partitions, I am showing the numbers in 235 * hex - the same format as the root= option takes. 236 */ 237 printk("%02x%02x %10llu %s", 238 sgp->major, sgp->first_minor, 239 (unsigned long long)get_capacity(sgp) >> 1, 240 disk_name(sgp, 0, buf)); 241 if (sgp->driverfs_dev != NULL && 242 sgp->driverfs_dev->driver != NULL) 243 printk(" driver: %s\n", 244 sgp->driverfs_dev->driver->name); 245 else 246 printk(" (driver?)\n"); 247 248 /* now show the partitions */ 249 for (n = 0; n < sgp->minors - 1; ++n) { 250 if (sgp->part[n] == NULL) 251 continue; 252 if (sgp->part[n]->nr_sects == 0) 253 continue; 254 printk(" %02x%02x %10llu %s\n", 255 sgp->major, n + 1 + sgp->first_minor, 256 (unsigned long long)sgp->part[n]->nr_sects >> 1, 257 disk_name(sgp, n + 1, buf)); 258 } /* partition subloop */ 259 } /* Block device loop */ 260 261 mutex_unlock(&block_subsys_lock); 262 return; 263 } 264 265 #ifdef CONFIG_PROC_FS 266 /* iterator */ 267 static void *part_start(struct seq_file *part, loff_t *pos) 268 { 269 struct list_head *p; 270 loff_t l = *pos; 271 272 mutex_lock(&block_subsys_lock); 273 list_for_each(p, &block_subsys.list) 274 if (!l--) 275 return list_entry(p, struct gendisk, kobj.entry); 276 return NULL; 277 } 278 279 static void *part_next(struct seq_file *part, void *v, loff_t *pos) 280 { 281 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 282 ++*pos; 283 return p==&block_subsys.list ? NULL : 284 list_entry(p, struct gendisk, kobj.entry); 285 } 286 287 static void part_stop(struct seq_file *part, void *v) 288 { 289 mutex_unlock(&block_subsys_lock); 290 } 291 292 static int show_partition(struct seq_file *part, void *v) 293 { 294 struct gendisk *sgp = v; 295 int n; 296 char buf[BDEVNAME_SIZE]; 297 298 if (&sgp->kobj.entry == block_subsys.list.next) 299 seq_puts(part, "major minor #blocks name\n\n"); 300 301 /* Don't show non-partitionable removeable devices or empty devices */ 302 if (!get_capacity(sgp) || 303 (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE))) 304 return 0; 305 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) 306 return 0; 307 308 /* show the full disk and all non-0 size partitions of it */ 309 seq_printf(part, "%4d %4d %10llu %s\n", 310 sgp->major, sgp->first_minor, 311 (unsigned long long)get_capacity(sgp) >> 1, 312 disk_name(sgp, 0, buf)); 313 for (n = 0; n < sgp->minors - 1; n++) { 314 if (!sgp->part[n]) 315 continue; 316 if (sgp->part[n]->nr_sects == 0) 317 continue; 318 seq_printf(part, "%4d %4d %10llu %s\n", 319 sgp->major, n + 1 + sgp->first_minor, 320 (unsigned long long)sgp->part[n]->nr_sects >> 1 , 321 disk_name(sgp, n + 1, buf)); 322 } 323 324 return 0; 325 } 326 327 struct seq_operations partitions_op = { 328 .start =part_start, 329 .next = part_next, 330 .stop = part_stop, 331 .show = show_partition 332 }; 333 #endif 334 335 336 extern int blk_dev_init(void); 337 338 static struct kobject *base_probe(dev_t dev, int *part, void *data) 339 { 340 if (request_module("block-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0) 341 /* Make old-style 2.4 aliases work */ 342 request_module("block-major-%d", MAJOR(dev)); 343 return NULL; 344 } 345 346 static int __init genhd_device_init(void) 347 { 348 int err; 349 350 bdev_map = kobj_map_init(base_probe, &block_subsys_lock); 351 blk_dev_init(); 352 err = subsystem_register(&block_subsys); 353 if (err < 0) 354 printk(KERN_WARNING "%s: subsystem_register error: %d\n", 355 __FUNCTION__, err); 356 return err; 357 } 358 359 subsys_initcall(genhd_device_init); 360 361 362 363 /* 364 * kobject & sysfs bindings for block devices 365 */ 366 static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr, 367 char *page) 368 { 369 struct gendisk *disk = to_disk(kobj); 370 struct disk_attribute *disk_attr = 371 container_of(attr,struct disk_attribute,attr); 372 ssize_t ret = -EIO; 373 374 if (disk_attr->show) 375 ret = disk_attr->show(disk,page); 376 return ret; 377 } 378 379 static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr, 380 const char *page, size_t count) 381 { 382 struct gendisk *disk = to_disk(kobj); 383 struct disk_attribute *disk_attr = 384 container_of(attr,struct disk_attribute,attr); 385 ssize_t ret = 0; 386 387 if (disk_attr->store) 388 ret = disk_attr->store(disk, page, count); 389 return ret; 390 } 391 392 static struct sysfs_ops disk_sysfs_ops = { 393 .show = &disk_attr_show, 394 .store = &disk_attr_store, 395 }; 396 397 static ssize_t disk_uevent_store(struct gendisk * disk, 398 const char *buf, size_t count) 399 { 400 kobject_uevent(&disk->kobj, KOBJ_ADD); 401 return count; 402 } 403 static ssize_t disk_dev_read(struct gendisk * disk, char *page) 404 { 405 dev_t base = MKDEV(disk->major, disk->first_minor); 406 return print_dev_t(page, base); 407 } 408 static ssize_t disk_range_read(struct gendisk * disk, char *page) 409 { 410 return sprintf(page, "%d\n", disk->minors); 411 } 412 static ssize_t disk_removable_read(struct gendisk * disk, char *page) 413 { 414 return sprintf(page, "%d\n", 415 (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0)); 416 417 } 418 static ssize_t disk_size_read(struct gendisk * disk, char *page) 419 { 420 return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk)); 421 } 422 static ssize_t disk_capability_read(struct gendisk *disk, char *page) 423 { 424 return sprintf(page, "%x\n", disk->flags); 425 } 426 static ssize_t disk_stats_read(struct gendisk * disk, char *page) 427 { 428 preempt_disable(); 429 disk_round_stats(disk); 430 preempt_enable(); 431 return sprintf(page, 432 "%8lu %8lu %8llu %8u " 433 "%8lu %8lu %8llu %8u " 434 "%8u %8u %8u" 435 "\n", 436 disk_stat_read(disk, ios[READ]), 437 disk_stat_read(disk, merges[READ]), 438 (unsigned long long)disk_stat_read(disk, sectors[READ]), 439 jiffies_to_msecs(disk_stat_read(disk, ticks[READ])), 440 disk_stat_read(disk, ios[WRITE]), 441 disk_stat_read(disk, merges[WRITE]), 442 (unsigned long long)disk_stat_read(disk, sectors[WRITE]), 443 jiffies_to_msecs(disk_stat_read(disk, ticks[WRITE])), 444 disk->in_flight, 445 jiffies_to_msecs(disk_stat_read(disk, io_ticks)), 446 jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); 447 } 448 static struct disk_attribute disk_attr_uevent = { 449 .attr = {.name = "uevent", .mode = S_IWUSR }, 450 .store = disk_uevent_store 451 }; 452 static struct disk_attribute disk_attr_dev = { 453 .attr = {.name = "dev", .mode = S_IRUGO }, 454 .show = disk_dev_read 455 }; 456 static struct disk_attribute disk_attr_range = { 457 .attr = {.name = "range", .mode = S_IRUGO }, 458 .show = disk_range_read 459 }; 460 static struct disk_attribute disk_attr_removable = { 461 .attr = {.name = "removable", .mode = S_IRUGO }, 462 .show = disk_removable_read 463 }; 464 static struct disk_attribute disk_attr_size = { 465 .attr = {.name = "size", .mode = S_IRUGO }, 466 .show = disk_size_read 467 }; 468 static struct disk_attribute disk_attr_capability = { 469 .attr = {.name = "capability", .mode = S_IRUGO }, 470 .show = disk_capability_read 471 }; 472 static struct disk_attribute disk_attr_stat = { 473 .attr = {.name = "stat", .mode = S_IRUGO }, 474 .show = disk_stats_read 475 }; 476 477 #ifdef CONFIG_FAIL_MAKE_REQUEST 478 479 static ssize_t disk_fail_store(struct gendisk * disk, 480 const char *buf, size_t count) 481 { 482 int i; 483 484 if (count > 0 && sscanf(buf, "%d", &i) > 0) { 485 if (i == 0) 486 disk->flags &= ~GENHD_FL_FAIL; 487 else 488 disk->flags |= GENHD_FL_FAIL; 489 } 490 491 return count; 492 } 493 static ssize_t disk_fail_read(struct gendisk * disk, char *page) 494 { 495 return sprintf(page, "%d\n", disk->flags & GENHD_FL_FAIL ? 1 : 0); 496 } 497 static struct disk_attribute disk_attr_fail = { 498 .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, 499 .store = disk_fail_store, 500 .show = disk_fail_read 501 }; 502 503 #endif 504 505 static struct attribute * default_attrs[] = { 506 &disk_attr_uevent.attr, 507 &disk_attr_dev.attr, 508 &disk_attr_range.attr, 509 &disk_attr_removable.attr, 510 &disk_attr_size.attr, 511 &disk_attr_stat.attr, 512 &disk_attr_capability.attr, 513 #ifdef CONFIG_FAIL_MAKE_REQUEST 514 &disk_attr_fail.attr, 515 #endif 516 NULL, 517 }; 518 519 static void disk_release(struct kobject * kobj) 520 { 521 struct gendisk *disk = to_disk(kobj); 522 kfree(disk->random); 523 kfree(disk->part); 524 free_disk_stats(disk); 525 kfree(disk); 526 } 527 528 static struct kobj_type ktype_block = { 529 .release = disk_release, 530 .sysfs_ops = &disk_sysfs_ops, 531 .default_attrs = default_attrs, 532 }; 533 534 extern struct kobj_type ktype_part; 535 536 static int block_uevent_filter(struct kset *kset, struct kobject *kobj) 537 { 538 struct kobj_type *ktype = get_ktype(kobj); 539 540 return ((ktype == &ktype_block) || (ktype == &ktype_part)); 541 } 542 543 static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp, 544 int num_envp, char *buffer, int buffer_size) 545 { 546 struct kobj_type *ktype = get_ktype(kobj); 547 struct device *physdev; 548 struct gendisk *disk; 549 struct hd_struct *part; 550 int length = 0; 551 int i = 0; 552 553 if (ktype == &ktype_block) { 554 disk = container_of(kobj, struct gendisk, kobj); 555 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 556 &length, "MINOR=%u", disk->first_minor); 557 } else if (ktype == &ktype_part) { 558 disk = container_of(kobj->parent, struct gendisk, kobj); 559 part = container_of(kobj, struct hd_struct, kobj); 560 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 561 &length, "MINOR=%u", 562 disk->first_minor + part->partno); 563 } else 564 return 0; 565 566 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 567 "MAJOR=%u", disk->major); 568 569 /* add physical device, backing this device */ 570 physdev = disk->driverfs_dev; 571 if (physdev) { 572 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); 573 574 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 575 &length, "PHYSDEVPATH=%s", path); 576 kfree(path); 577 578 if (physdev->bus) 579 add_uevent_var(envp, num_envp, &i, 580 buffer, buffer_size, &length, 581 "PHYSDEVBUS=%s", 582 physdev->bus->name); 583 584 if (physdev->driver) 585 add_uevent_var(envp, num_envp, &i, 586 buffer, buffer_size, &length, 587 "PHYSDEVDRIVER=%s", 588 physdev->driver->name); 589 } 590 591 /* terminate, set to next free slot, shrink available space */ 592 envp[i] = NULL; 593 envp = &envp[i]; 594 num_envp -= i; 595 buffer = &buffer[length]; 596 buffer_size -= length; 597 598 return 0; 599 } 600 601 static struct kset_uevent_ops block_uevent_ops = { 602 .filter = block_uevent_filter, 603 .uevent = block_uevent, 604 }; 605 606 decl_subsys(block, &ktype_block, &block_uevent_ops); 607 608 /* 609 * aggregate disk stat collector. Uses the same stats that the sysfs 610 * entries do, above, but makes them available through one seq_file. 611 * Watching a few disks may be efficient through sysfs, but watching 612 * all of them will be more efficient through this interface. 613 * 614 * The output looks suspiciously like /proc/partitions with a bunch of 615 * extra fields. 616 */ 617 618 /* iterator */ 619 static void *diskstats_start(struct seq_file *part, loff_t *pos) 620 { 621 loff_t k = *pos; 622 struct list_head *p; 623 624 mutex_lock(&block_subsys_lock); 625 list_for_each(p, &block_subsys.list) 626 if (!k--) 627 return list_entry(p, struct gendisk, kobj.entry); 628 return NULL; 629 } 630 631 static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) 632 { 633 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 634 ++*pos; 635 return p==&block_subsys.list ? NULL : 636 list_entry(p, struct gendisk, kobj.entry); 637 } 638 639 static void diskstats_stop(struct seq_file *part, void *v) 640 { 641 mutex_unlock(&block_subsys_lock); 642 } 643 644 static int diskstats_show(struct seq_file *s, void *v) 645 { 646 struct gendisk *gp = v; 647 char buf[BDEVNAME_SIZE]; 648 int n = 0; 649 650 /* 651 if (&sgp->kobj.entry == block_subsys.kset.list.next) 652 seq_puts(s, "major minor name" 653 " rio rmerge rsect ruse wio wmerge " 654 "wsect wuse running use aveq" 655 "\n\n"); 656 */ 657 658 preempt_disable(); 659 disk_round_stats(gp); 660 preempt_enable(); 661 seq_printf(s, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", 662 gp->major, n + gp->first_minor, disk_name(gp, n, buf), 663 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]), 664 (unsigned long long)disk_stat_read(gp, sectors[0]), 665 jiffies_to_msecs(disk_stat_read(gp, ticks[0])), 666 disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]), 667 (unsigned long long)disk_stat_read(gp, sectors[1]), 668 jiffies_to_msecs(disk_stat_read(gp, ticks[1])), 669 gp->in_flight, 670 jiffies_to_msecs(disk_stat_read(gp, io_ticks)), 671 jiffies_to_msecs(disk_stat_read(gp, time_in_queue))); 672 673 /* now show all non-0 size partitions of it */ 674 for (n = 0; n < gp->minors - 1; n++) { 675 struct hd_struct *hd = gp->part[n]; 676 677 if (hd && hd->nr_sects) 678 seq_printf(s, "%4d %4d %s %u %u %u %u\n", 679 gp->major, n + gp->first_minor + 1, 680 disk_name(gp, n + 1, buf), 681 hd->ios[0], hd->sectors[0], 682 hd->ios[1], hd->sectors[1]); 683 } 684 685 return 0; 686 } 687 688 struct seq_operations diskstats_op = { 689 .start = diskstats_start, 690 .next = diskstats_next, 691 .stop = diskstats_stop, 692 .show = diskstats_show 693 }; 694 695 static void media_change_notify_thread(struct work_struct *work) 696 { 697 struct gendisk *gd = container_of(work, struct gendisk, async_notify); 698 char event[] = "MEDIA_CHANGE=1"; 699 char *envp[] = { event, NULL }; 700 701 /* 702 * set enviroment vars to indicate which event this is for 703 * so that user space will know to go check the media status. 704 */ 705 kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); 706 put_device(gd->driverfs_dev); 707 } 708 709 void genhd_media_change_notify(struct gendisk *disk) 710 { 711 get_device(disk->driverfs_dev); 712 schedule_work(&disk->async_notify); 713 } 714 EXPORT_SYMBOL_GPL(genhd_media_change_notify); 715 716 struct gendisk *alloc_disk(int minors) 717 { 718 return alloc_disk_node(minors, -1); 719 } 720 721 struct gendisk *alloc_disk_node(int minors, int node_id) 722 { 723 struct gendisk *disk; 724 725 disk = kmalloc_node(sizeof(struct gendisk), 726 GFP_KERNEL | __GFP_ZERO, node_id); 727 if (disk) { 728 if (!init_disk_stats(disk)) { 729 kfree(disk); 730 return NULL; 731 } 732 if (minors > 1) { 733 int size = (minors - 1) * sizeof(struct hd_struct *); 734 disk->part = kmalloc_node(size, 735 GFP_KERNEL | __GFP_ZERO, node_id); 736 if (!disk->part) { 737 kfree(disk); 738 return NULL; 739 } 740 } 741 disk->minors = minors; 742 kobj_set_kset_s(disk,block_subsys); 743 kobject_init(&disk->kobj); 744 rand_initialize_disk(disk); 745 INIT_WORK(&disk->async_notify, 746 media_change_notify_thread); 747 } 748 return disk; 749 } 750 751 EXPORT_SYMBOL(alloc_disk); 752 EXPORT_SYMBOL(alloc_disk_node); 753 754 struct kobject *get_disk(struct gendisk *disk) 755 { 756 struct module *owner; 757 struct kobject *kobj; 758 759 if (!disk->fops) 760 return NULL; 761 owner = disk->fops->owner; 762 if (owner && !try_module_get(owner)) 763 return NULL; 764 kobj = kobject_get(&disk->kobj); 765 if (kobj == NULL) { 766 module_put(owner); 767 return NULL; 768 } 769 return kobj; 770 771 } 772 773 EXPORT_SYMBOL(get_disk); 774 775 void put_disk(struct gendisk *disk) 776 { 777 if (disk) 778 kobject_put(&disk->kobj); 779 } 780 781 EXPORT_SYMBOL(put_disk); 782 783 void set_device_ro(struct block_device *bdev, int flag) 784 { 785 if (bdev->bd_contains != bdev) 786 bdev->bd_part->policy = flag; 787 else 788 bdev->bd_disk->policy = flag; 789 } 790 791 EXPORT_SYMBOL(set_device_ro); 792 793 void set_disk_ro(struct gendisk *disk, int flag) 794 { 795 int i; 796 disk->policy = flag; 797 for (i = 0; i < disk->minors - 1; i++) 798 if (disk->part[i]) disk->part[i]->policy = flag; 799 } 800 801 EXPORT_SYMBOL(set_disk_ro); 802 803 int bdev_read_only(struct block_device *bdev) 804 { 805 if (!bdev) 806 return 0; 807 else if (bdev->bd_contains != bdev) 808 return bdev->bd_part->policy; 809 else 810 return bdev->bd_disk->policy; 811 } 812 813 EXPORT_SYMBOL(bdev_read_only); 814 815 int invalidate_partition(struct gendisk *disk, int index) 816 { 817 int res = 0; 818 struct block_device *bdev = bdget_disk(disk, index); 819 if (bdev) { 820 fsync_bdev(bdev); 821 res = __invalidate_device(bdev); 822 bdput(bdev); 823 } 824 return res; 825 } 826 827 EXPORT_SYMBOL(invalidate_partition); 828