Chinaunix首页 | 论坛 | 博客
  • 博客访问: 227504
  • 博文数量: 42
  • 博客积分: 2618
  • 博客等级: 少校
  • 技术积分: 385
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-26 10:04
文章分类

全部博文(42)

文章存档

2013年(2)

2012年(2)

2011年(3)

2010年(17)

2009年(18)

我的朋友

分类: LINUX

2009-11-01 14:23:00

    最近碰到sata类型的多家厂商硬盘读写问题,大概是在128G的地方读写失败,问题查了很久,不过最终还是解决了。问题大概是是ata协议的部分漏洞吧,针对于lba28模式和lba48模式的区分太模糊,例如对于DMA方式的写命令有两种:WRITE DMA、WRITE DMA EXT,前者基于lba28、后者基于lba48;命令格式如下:
lba28:
lba48:
两种命令在sata规范里面并没有确切的区分,在linux2.4.17内核里面,libata判断如果硬盘支持lba48模式,那么优先使用lba48模式的命令;但是在linux2.6.24内核里面,libata在将scsi命令转换为ata命令时并没有这么优先考虑,而是使用了
 

static inline int lba_28_ok(u64 block, u32 n_block)
{
         /* check the ending block number */
         return ((block + n_block - 1) < ((u64)1 << 28))

                && (n_block <= 256);
}
 
static inline int lba_48_ok(u64 block, u32 n_block)
{
       /* check the ending block number */
        return ((block + n_block - 1) < ((u64)1 << 48))

               && (n_block <= 65536);
}

这两个内联函数来区分lba28和lba48模式,问题也就出在这里,(( + n_block - 1) < (()1 << 28)) && (n_block <= 256)并没有严格的区分两种类型命令的临界状态,去掉-1问题就能够解决;在linux2.6.30里面已经做了这样的修改,所以如果你依旧使用2.6.30以前的内核,需要修改这个地方。

顺便记录下来,希望对看我博客的朋友有帮助。

阅读(3114) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-10 14:50:57

哥们怎么联系你呢?