You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Disk /dev/sda: 146.1 GB, 146163105792 bytes<br />
255 heads, 63 sectors/track, 17769 cylinders<br />
Units = cylinders <strong>of</strong> 16065 * 512 = 8225280 bytes<br />
Device Boot Start End Blocks Id System<br />
/dev/sda1 1 266 2136613+ 83 Linux<br />
/dev/sda2 2879 17769 119611957+ 83 Linux<br />
/dev/sda3 * 267 1572 10490445 83 Linux<br />
/dev/sda4 1573 2878 10490445 82 Linux swap / Solaris<br />
myhost: #<br />
看出sg_readcap 读出来的信息了吗?我们可以传递不同的参数,如果像我们这里-b 参数,那么将获得<br />
block 数以及每个block 的字节数.我们来计算一下,我们这里返回的两个值分别是0x11040000 和<br />
0x200,0x11040000 对应于十进制285474816,0x200 就是十进制的512,N 多设备的block 大小都<br />
是<br />
512.这两个相乘就是我们的容量,相乘的结果是146163105792,看到了吗?和fdisk 命令显示出来的一模<br />
一样,呵呵,其实fdisk 就是这么干的.不一样就见鬼了.Ok,有了直观的印象可以继续往下看了.刚才我们知<br />
道对于有设置US_FL_FIX_CAPACITY 这个flag 的设备,就会执行fix_read_capacity(),这个函数定义<br />
于drivers/usb/storage/protocol.c 中,所谓的这个bug 在这个注释里说得很清楚.明明容量是N,偏偏要<br />
汇报说自己是N+1,你说这不是找抽么?当然这也很简单,我们处理起来不难.<br />
60 /*<br />
61 * Fix-up the return data from a READ CAPACITY command. My Feiya reader<br />
62 * returns a value that is 1 too large.<br />
63 */<br />
64 static void fix_read_capacity(struct scsi_cmnd *srb)<br />
181<br />
65 {<br />
66 unsigned int index, <strong>of</strong>fset;<br />
67 __be32 c;<br />
68 unsigned long capacity;<br />
69<br />
70 /* verify that it's a READ CAPACITY command */<br />
71 if (srb->cmnd[0] != READ_CAPACITY)<br />
72 return;<br />
73<br />
74 index = <strong>of</strong>fset = 0;<br />
75 if (usb_stor_access_xfer_buf((unsigned char *) &c, 4, srb,<br />
76 &index, &<strong>of</strong>fset, FROM_XFER_BUF) != 4)<br />
77 return;<br />
78<br />
79 capacity = be32_to_cpu(c);<br />
80 US_DEBUGP("US: Fixing capacity: from %ld to %ld\n",<br />
81 capacity+1, capacity);<br />
82 c = cpu_to_be32(capacity - 1);<br />
83<br />
84 index = <strong>of</strong>fset = 0;