1.5.3 关联block_device结构
接下来是register_disk函数,来自fs/partitions/check.c:
473 /* Not exported, helper to add_disk(). */ 474 void register_disk(struct gendisk *disk) 475 { 476 struct block_device *bdev; 477 char *s; 478 int i; 479 struct hd_struct *p; 480 int err; 481 482 strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); 483 /* ewww... some of these buggers have / in name... */ 484 s = strchr(disk->kobj.name, '/'); 485 if (s) 486 *s = '!'; 487 if ((err = kobject_add(&disk->kobj))) 488 return; 489 err = disk_sysfs_symlinks(disk); 490 if (err) { 491 kobject_del(&disk->kobj); 492 return; 493 } 494 disk_sysfs_add_subdirs(disk); 495 496 /* No minors to use for partitions */ 497 if (disk->minors == 1) 498 goto exit; 499 500 /* No such device (e.g., media were just removed) */ 501 if (!get_capacity(disk)) 502 goto exit; 503 504 bdev = bdget_disk(disk, 0); 505 if (!bdev) 506 goto exit; 507 508 /* scan partition table, but suppress uevents */ 509 bdev->bd_invalidated = 1; 510 disk->part_uevent_suppress = 1; 511 err = blkdev_get(bdev, FMODE_READ, 0); 512 disk->part_uevent_suppress = 0; 513 if (err < 0) 514 goto exit; 515 blkdev_put(bdev); 516 517 exit: 518 /* announce disk after possible partitions are already created */ 519 kobject_uevent(&disk->kobj, KOBJ_ADD); 520 521 /* announce possible partitions */ 522 for (i = 1; i < disk->minors; i++) { 523 p = disk->part[i-1]; 524 if (!p || !p->nr_sects) 525 continue; 526 kobject_uevent(&p->kobj, KOBJ_ADD); 527 } 528 } |
首先487行这个kobject_add的作用是很直观的,在Sysfs中为这块磁盘建一个子目录,例如我们为的硬盘建立一个块设备驱动,则会在/sys/block/目录中看到一个sdf,要是把这个调用kobject_add函数这行注释掉,肯定就看不到这个sdf目录。这里有两个问题:
第一,为什么kobject_add这么一调用,生成的这个子目录的名字就叫做“sdf”,而不叫做别的呢?其实在sd_probe中做过这么一件事情,通过精心计算得到disk_name的,而这个disk_name正是struct gendisk的一个成员,这里我们看到482行我们把disk_name给了kobj.name,这就是为什么我们调用kobject_add添加一个kobject的时候,它的名字就是我们当时的disk_name。
第二,为什么生成的这个子目录是在/sys/block目录下面,而不是在别的位置呢?还记得在alloc_disk_node中我们申请struct gendisk的情景么?kobj_set_kset_s(disk,block_subsys)做的就是让disk对应的kobject从属于block_subsys对应的kobject下面。这就是为什么我们现在添加这个kobject的时候,它很自然的就会在/sys/block子目录下面建立文件。
继续走,disk_sysfs_symlinks来自fs/partitions/check.c,这个函数虽然不短