[关闭]
@harpsword 2015-11-04T12:44:46.000000Z 字数 4054 阅读 2291

代码分析之 blk.h

块设备


前言

代码区

  1. #ifndef _BLK_H
  2. #define _BLK_H
  3. // 块设备的种类数
  4. #define NR_BLK_DEV 7
  5. /*
  6. * NR_REQUEST is the number of entries in the request-queue.
  7. * NOTE that writes may use only the low 2/3 of these: reads
  8. * take precedence.
  9. *
  10. * 32 seems to be a reasonable number: enough to get some benefit
  11. * from the elevator-mechanism, but not so much as to lock a lot of
  12. * buffers when they are in the queue. 64 seems to be too many (easily
  13. * long pauses in reading when heavy writing/syncing is going on)
  14. */
  15. /*
  16. * 下面定义的NR_REQUEST 是请求队列中所包含的项数。
  17. * 注意,读操作仅使用这些项低端的2/3;读操作优先处理。
  18. *
  19. * 32 项好象是一个合理的数字:已经足够从电梯算法中获得好处,
  20. * 但当缓冲区在队列中而锁住时又不显得是很大的数。64 就看上
  21. * 去太大了(当大量的写/同步操作运行时很容易引起长时间的暂停)。
  22. */
  23. #define NR_REQUEST 32
  24. /*
  25. * Ok, this is an expanded form so that we can use the same
  26. * request for paging requests when that is implemented. In
  27. * paging, 'bh' is NULL, and 'waiting' is used to wait for
  28. * read/write completion.
  29. */
  30. /*
  31. * OK,下面是request 结构的一个扩展形式,因而当实现以后,我们就可以在分页请求中
  32. * 使用同样的request 结构。在分页处理中,'bh'是NULL,而'waiting'则用于等待读/写的完成。
  33. */
  34. struct request
  35. {
  36. int dev; /* -1 if no request */// 使用的设备号。
  37. int cmd; /* READ or WRITE */// 命令(READ 或WRITE)。
  38. int errors; //操作时产生的错误次数。
  39. unsigned long sector; // 起始扇区。(1 块=2 扇区)
  40. unsigned long nr_sectors; // 读/写扇区数。
  41. char *buffer; // 数据缓冲区。
  42. struct task_struct *waiting; // 任务等待操作执行完成的地方。
  43. struct buffer_head *bh; // 缓冲区头指针(include/linux/fs.h,68)。
  44. struct request *next; // 指向下一请求项。
  45. };
  46. /*
  47. * This is used in the elevator algorithm: Note that
  48. * reads always go before writes. This is natural: reads
  49. * are much more time-critical than writes.
  50. */
  51. /*
  52. * 下面的定义用于电梯算法:注意读操作总是在写操作之前进行。
  53. * 这是很自然的:读操作对时间的要求要比写严格得多。
  54. */
  55. #define IN_ORDER(s1,s2) \
  56. ((s1)->cmd<(s2)->cmd || ((s1)->cmd==(s2)->cmd && \
  57. ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \
  58. (s1)->sector < (s2)->sector))))
  59. // 块设备结构
  60. struct blk_dev_struct {
  61. void (*request_fn)(void); // 请求操作的函数指针
  62. struct request * current_request; // 请求信息结构
  63. };
  64. extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; // 块设备数组,每种块设备占用一项
  65. extern struct request request[NR_REQUEST]; // 请求队列数组
  66. extern struct task_struct * wait_for_request; // 等待请求的任务数据结构
  67. #ifdef MAJOR_NR // 主设备号
  68. /*
  69. * Add entries as needed. Currently the only block devices
  70. * supported are hard-disks and floppies.
  71. */
  72. /*
  73. * 需要时加入条目。目前块设备仅支持硬盘和软盘(还有虚拟盘)。
  74. */
  75. #if (MAJOR_NR == 1) // RAM 盘的主设备号是1。根据这里的定义可以推理内存块主设备号也为1。
  76. /* ram disk */
  77. #define DEVICE_NAME "ramdisk" // 设备名称 ramdisk
  78. #define DEVICE_REQUEST do_rd_request // 设备请求函数 do_rd_request()
  79. #define DEVICE_NR(device) ((device) & 7) // 设备号(0--7)
  80. #define DEVICE_ON(device) // 开启设备。虚拟盘无需开启和关闭
  81. #define DEVICE_OFF(device) // 关闭设备
  82. #elif (MAJOR_NR == 2)
  83. /* floppy */ // 软盘
  84. #define DEVICE_NAME "floppy"
  85. #define DEVICE_INTR do_floppy // 设备中断处理程序 do_floppy()
  86. #define DEVICE_REQUEST do_fd_request
  87. #define DEVICE_NR(device) ((device) & 3) // 设备号(0--3)
  88. #define DEVICE_ON(device) floppy_on(DEVICE_NR(device)) // 设备开启
  89. #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) // 设备关闭
  90. #elif (MAJOR_NR == 3)
  91. /* harddisk */ // 硬盘
  92. #define DEVICE_NAME "harddisk"
  93. #define DEVICE_INTR do_hd
  94. #define DEVICE_REQUEST do_hd_request
  95. #define DEVICE_NR(device) (MINOR(device)/5) // 设备号(0--1)。每个硬盘可以有4个分区
  96. #define DEVICE_ON(device) // 硬盘一直在工作, 无需开启和关闭
  97. #define DEVICE_OFF(device)
  98. #elif
  99. /* unknown blk device */ // 未知设备
  100. #error "unknown blk device"
  101. #endif
  102. #define CURRENT (blk_dev[MAJOR_NR].current_request) // CURRENT 为指定主设备号 的当前请求结构
  103. #define CURRENT_DEV DEVICE_NR(CURRENT->dev) // CURRENT_DEV 为主设备号
  104. #ifdef DEVICE_INTR
  105. void (*DEVICE_INTR)(void) = NULL; // ????????????
  106. #endif
  107. static void (DEVICE_REQUEST)(void);
  108. // 释放锁定的缓冲区。
  109. static inline void unlock_buffer(struct buffer_head * bh)
  110. {
  111. if (!bh->b_lock) // 如果指定的缓冲区 bh 没有被上锁, 则显示警告信息
  112. printk(DEVICE_NAME ": free buffer being unlocked\n");
  113. bh->b_lock=0; // 否则将该缓冲区解锁
  114. wake_up(&bh->b_wait); // 唤醒等待该缓冲区的进程
  115. }
  116. // 结束请求。
  117. static inline void end_request(int uptodate)
  118. {
  119. DEVICE_OFF(CURRENT->dev); // 关闭设备
  120. if (CURRENT->bh) { // CURRENT 为指定主设备号的当前请求结构。
  121. CURRENT->bh->b_uptodate = uptodate; // 置更新标志。
  122. unlock_buffer(CURRENT->bh); // 解锁缓冲区。
  123. }
  124. if (!uptodate) { // 如果更新标志为0 则显示设备错误信息。
  125. printk(DEVICE_NAME " I/O error\n\r");
  126. printk("dev %04x, block %d\n\r",CURRENT->dev,
  127. CURRENT->bh->b_blocknr);
  128. }
  129. wake_up(&CURRENT->waiting); // 唤醒等待该请求项的进程。
  130. wake_up(&wait_for_request); // 唤醒等待请求的进程。
  131. CURRENT->dev = -1; // 释放该请求项。
  132. CURRENT = CURRENT->next; // 从请求链表中删除该请求项。
  133. }
  134. // 定义初始化请求宏。
  135. #define INIT_REQUEST \
  136. repeat: \
  137. if (!CURRENT) \ /* 如果当前请求结构指针为null 则返回。*/
  138. return; \
  139. if (MAJOR(CURRENT->dev) != MAJOR_NR) \ /* 如果当前设备的主设备号不对则死机。*/
  140. panic(DEVICE_NAME ": request list destroyed"); \
  141. if (CURRENT->bh) { \ /* 如果在进行请求操作时缓冲区没锁定则死机。*/
  142. if (!CURRENT->bh->b_lock) \
  143. panic(DEVICE_NAME ": block not locked"); \
  144. }
  145. #endif
  146. #endif
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注