您的位置:首页 > 运维架构 > Linux

Linux那些事儿之我是Block层(3)驱动不过一出戏,内存申请为哪般?

2010-08-08 22:05 453 查看
下一个函数

,alloc_disk().


sd.c
中咱们传递进来的参数是

16.

720 struct gendisk *alloc_disk(int minors)

721 {

722
return alloc_disk_node(minors, -1);

723 }

724

725 struct gendisk *alloc_disk_node(int minors, int node_id)

726 {

727
struct gendisk *disk;

728

729
disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);

730
if (disk) {

731
memset(disk, 0, sizeof(struct gendisk));

732
if (!init_disk_stats(disk)) {

733
kfree(disk);

734
return NULL;

735
}

736
if (minors > 1) {

737
int size = (minors - 1) * sizeof(struct hd_struct *);

738

disk->part = kmalloc_node(size, GFP_KERNEL, node_id);

739
if (!disk->part) {

740
kfree(disk);

741
return NULL;

742
}

743
memset(disk->part, 0, size);

744
}

745
disk->minors = minors;

746
kobj_set_kset_s(disk,block_subsys);

747
kobject_init(&disk->kobj);

748

rand_initialize_disk(disk);

749
INIT_WORK(&disk->async_notify,

750
media_change_notify_thread);

751
}

752
return disk;

753 }

因此我们做的事情就是申请了一个

struct gendisk
结构体

.
毫无疑问

,
这个结构体是我们这个故事中最重要的结构体之一

,
来自

include/linux/genhd.h:

113 struct gendisk {

114
int major;
/* major number of driver */

115
int first_minor;

116
int minors;
/* maximum number of minors, =1 for

117
* disks that can't be partitioned. */

118
char disk_name[32];
/* name of major driver */

119
struct hd_struct **part;
/* [indexed by minor] */

120

int part_uevent_suppress;

121
struct block_device_operations *fops;

122
struct request_queue *queue;

123
void *private_data;

124
sector_t capacity;

125

126
int flags;

127
struct device *driverfs_dev;

128
struct kobject kobj;

129
struct kobject *holder_dir;

130
struct kobject *slave_dir;

131

132
struct timer_rand_state *random;

133
int policy;

134

135

atomic_t sync_io;
/* RAID */

136
unsigned long stamp;

137
int in_flight;

138 #ifdef
CONFIG_SMP

139
struct disk_stats *dkstats;

140 #else

141
struct disk_stats dkstats;

142 #endif

143
struct work_struct async_notify;

144 };

因为

minors
我们给的是

16,
所以

736
行的

if
语句肯定是满足的

.
于是

size
等于

15


sizeof(struct hd_struct *),


part
我们看到是

struct hd_struct
的二级指针

,
这里我们看到

kmalloc_node(),
这个函数中的

node/node_id
这些概念指的是

NUMA
技术中的节点

,
对于咱们这些根本就不会接触

NUMA
的人来说

kmalloc_node()
就等于

kmalloc(),
因此这里做的就是申请内存并且初始化为

0.
要说明的一点是

,part
就是

partition
的意思

,
日后它将扮演我们常说的分区的角色

.

然后

,disk->minors
设置为了

16.

746


,kobj_set_kset_s(),block_subsys
是我们前面注册的子系统

,
从数据结构来说

,
它的定义如下

,
来自

block/genhd.c:

20 struct kset block_subsys;

其实也就是一个

struct kset.
而这里的

kobj_set_kset_s
的作用就是让

disk
对应

kobject


kset
等于

block_subsys.
也就是说让

kobject
找到它的

kset.(
如果你还记得当初我们在我是

Sysfs
中分析的

kobject


kset
的那套理论的话

,
你不会不明白这里的意图

.)


kobject_init()
初始化一个

kobject,
这个函数通常就是出现在设置了

kobject


kset
之后

.

网友


暗恋未遂


打断了我

,
他说这行代码并不是定义一个结构体

.
它更像是一个声明

,
而不像是定义

.
我仔细一看

,
似乎真的是的

,
这里的确是声明

,
而定义并不在这里

,Linux
内核代码的确是虚虚实实真真假假

,
一不小心就会看走眼

,
写代码的哥们儿果然是深谙兵不厌诈的道理

.但愿
他们只是借此表达他们对现实社会的不满吧

,
毕竟在这年头

,
只有假货是真的

,
别的都是假的

.
那么定义在哪里呢

?
同一个文件中

:

610 decl_subsys(block, &ktype_block, &block_uevent_ops);

这个

decl_subsys
来自

include/linux/kobject.h:

173 #define decl_subsys(_name,_type,_uevent_ops) /

174 struct kset _name##_subsys = { /

175
.kobj = { .name = __stringify(_name) }, /

176
.ktype = _type, /

177
.uevent_ops =_uevent_ops, /

178 }

结合这个宏的定义

,
我们知道

,
我们等效于做了下面这么一件事情

:

174 struct kset block_subsys = { /

175
.kobj = { .name = __stringify(block) }, /

176
.ktype = &ktype_block, /

177
.uevent_ops = &block_uevent_ops, /

178 }

正是因为有了这么一个定义

,
正是因为这里我们把

”block”
给了

block_subsys


kobj


name
成员

,
所以当我们在

block
子系统初始化的时候调用

subsystem_register(&block_subsys)
之后

,
我们才会在

/sys/
目录下面看到

”block”
子目录

.

localhost:~ # ls /sys/

block
bus
class
devices
firmware
fs
kernel
module
power

749


,
初始化一个工作队列

.
到时候用到了再来看

.

至此

,alloc_disk_node
就将返回

,
从而

alloc_disk
也就返回了

.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: