Chinaunix

标题: 困扰了3个月的usb硬盘写操作问题,求思路 [打印本页]

作者: upcuiling    时间: 2006-11-20 17:13
标题: 困扰了3个月的usb硬盘写操作问题,求思路
平台
cpu:s3c2510
os:uclinux/linux2.4

当系统挂接ext2/3文件系统的usb硬盘时,一切对usb硬盘的写操作都正常无误!
当系统挂接fat32文件系统的usb硬盘时,对usb硬盘进行写操作时候,写数据写到
15M左右就会出现 “filesystem panic”的错误 然后就再写不进去了

求思路解决
作者: siasd    时间: 2006-11-20 18:35
你试着不通过文件系统对usb硬盘进行读写操作,如果没问题的话,很有可能是FAT32文件系统内核软件模块本身有问题,我听别人说过类似的问题。
作者: upcuiling    时间: 2006-11-20 19:59
怎么不通过文件系统来写呢,请教下!
我觉的ext2/3文件格式能写,说明usb驱动是没问题的
但是我换过能正常读写usb的内核中的vfat部分过来,  还是出现这个错误!!不过可以写多点数据进去
作者: siasd    时间: 2006-11-21 10:16
比如可以这样直接不通过文件系统访问usb disk:dd if=/dev/zero of=/dev/sda1 bs=1M count=20。
不过之前我们有人遇到过fat32 filesystem panic,估计和你的情况差不多,听说是内核中fat32 文件系统代码本身的问题
作者: upcuiling    时间: 2006-11-21 10:22
有人再提点意见吗
作者: upcuiling    时间: 2006-11-21 10:24
to siasd (灯芯)
   我改用了在linux主机上的fat32的程序,能正常使用的。还是出现这个问题
作者: upcuiling    时间: 2006-11-21 10:25
这个问题再没法解决我都要被炒了,呵呵
作者: yidou    时间: 2006-11-21 10:50
原帖由 siasd 于 2006-11-21 10:16 发表
比如可以这样直接不通过文件系统访问usb disk:dd if=/dev/zero of=/dev/sda1 bs=1M count=20。


就像上面这样

或是在其它普通硬盘上,先测试FAT32,是否存在这个问题。

[ 本帖最后由 yidou 于 2006-11-21 10:54 编辑 ]
作者: yidou    时间: 2006-11-21 10:59
原帖由 upcuiling 于 2006-11-20 19:59 发表
我觉的ext2/3文件格式能写,说明usb驱动是没问题的


并不能得出这样的结论。比如说driver中有一个潜在的bug,在fat32上会经常执行到这段代码,而EXT中很少执行。
作者: upcuiling    时间: 2006-11-21 11:44
dd if=/dev/zero of=/dev/sda1 bs=1M count=20  
dd if=/dev/zero of=/dev/sda1 bs=2M count=30

都没有出现错误,下步应该怎么排除bug

[ 本帖最后由 upcuiling 于 2006-11-21 11:46 编辑 ]
作者: upcuiling    时间: 2006-11-22 10:08
下步不知道怎么走了
作者: siasd    时间: 2006-11-23 23:14
还有几个地方需要了解的:
1. 是不是每次操作都会出现fat32 filesystem panic?
2. 在出现了panic之后,再对usb硬盘操作(读写大文件,小文件),会出现什么样的情况?
3. 在出现了panic之后,umount,然后再mount上u盘,再对其进行操作,结果是什么样的?
作者: upcuiling    时间: 2006-11-24 09:04
1,每次操作都出现这个问题
2,出现panic后,usb就被设定为read_only了,就写不进去了
3,umount后,再mount 转到第一个问题,usb为可写,但出现原来的panic
作者: initx    时间: 2006-11-24 09:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: siasd    时间: 2006-11-24 10:48
原帖由 upcuiling 于 2006-11-24 09:04 发表
1,每次操作都出现这个问题
2,出现panic后,usb就被设定为read_only了,就写不进去了
3,umount后,再mount 转到第一个问题,usb为可写,但出现原来的panic


出现了这样的错误信息了吗?
msdos_write_inode: unable to read i-node block。

如果是的话,可以尝试着这么改一改,看看行不行。
在fs/fat/inode.c中,找到函数fat_write_inode,然后找到下面这段代码
        if (!(bh = fat_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
                printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos);
                fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block";
                unlock_kernel();
                return;
        }

将这段代码改成(在函数开头定义一个变量int try_cnt = 0;):
        while(!(bh = fat_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
                if(try_cnt++ < 100) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(HZ/100 + 1);
                        continue;
                }
                printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos);
                fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block";
                unlock_kernel();
                return;
        }

然后重新编译内核,试试看(我没试过啊)
作者: siasd    时间: 2006-11-24 10:50
总感觉linux上对FAT的支持不够stable。

[ 本帖最后由 siasd 于 2006-11-24 10:54 编辑 ]
作者: upcuiling    时间: 2006-11-24 11:26
全部的出错信息:
Filesystem panic (dev 08:01).
  fat_free: deleting beyond EOF
  File system has been set read-only
file_cluster badly computed!!! 0 <> 1
file_cluster badly computed!!! 1 <> 2
Filesystem panic (dev 08:01).
  File without EOF
cp: write: No space left on device
作者: siasd    时间: 2006-11-24 12:10
有没有这样的错误信息:
bread in fat_access failed
作者: dozec    时间: 2006-11-24 17:02
原帖由 siasd 于 2006-11-21 10:16 发表
比如可以这样直接不通过文件系统访问usb disk:dd if=/dev/zero of=/dev/sda1 bs=1M count=20。
不过之前我们有人遇到过fat32 filesystem panic,估计和你的情况差不多,听说是内核中fat32 文件系统代码本身的问题


dd命令也走文件系统.
这么说也不对,应该说你操纵的对象是sda1,那么你就应该走文件系统.

我所知有3种层次上可对disk进行读写操作:
1.正常的read/write() 普通设备,那么必会走VFS->具体文件系统->PAGE转换为BUFFER->块设备层->具体驱动
2.采用raw IO方式,具体你可以自己查,调用路线是VFS->raw IO设备(存在于字符设备中)->具体驱动
3.直接从驱动的ioctl()走,通过驱动提供的IOCTL()来直接操作底层寄存器,进而发送ATAPI命令,完成设备读写.
   调用路线VFS->具体驱动->裸设备

[ 本帖最后由 dozec 于 2006-11-24 17:07 编辑 ]
作者: dozec    时间: 2006-11-24 17:16
原帖由 upcuiling 于 2006-11-24 11:26 发表
Filesystem panic (dev 08:01).
  fat_free: deleting beyond EOF
  File system has been set read-only
file_cluster badly computed!!! 0 <> 1
file_cluster badly computed!!! 1 <> 2
Filesystem panic (dev 08:01).
  File without EOF
cp: write: No space left on device.


建议你:
现在就从read/write()系统调用往下跟,一直跟到错误(看样子是FAT32本身)处附近.然后再来判定问题所在.
另外建议你查一下scsi storage驱动程序,看看有没有已说明的BUG.我的意思和上页楼上几位的一样,先确定不是底层驱动问题,然后就能确定是文件系统出问题了嘛?然后就跟.
作者: upcuiling    时间: 2006-11-24 18:40
我通过打印debug信息,发现错误是从/fs/fat/misc.c 打出的
int fat_add_cluster(struct inode *inode)
{
        [。。。。]
       
        /* We must locate the last cluster of the file to add this
           new one (nr) to the end of the link list (the FAT).
          
           Here file_cluster will be the number of the last cluster of the
           file (before we add nr).
          
           last is the corresponding cluster number on the disk. We will
           use last to plug the nr cluster. We will use file_cluster to
           update the cache.
        */
        last = file_cluster = 0;
        if ((curr = MSDOS_I(inode)->i_start) != 0) {
                fat_cache_lookup(inode, INT_MAX, &last, &curr);
                file_cluster = last;
                while (curr && curr != -1){
                        file_cluster++;
                        if (!(curr = fat_access(sb, last = curr,-1))) {
                                fat_fs_panic(sb, "File without EOF");//这里打印出出错信息
                                return res;
                        }
                }
        }
        if (last) {
                fat_access(sb, last, nr);
                fat_cache_add(inode, file_cluster, nr);
        } else {
                MSDOS_I(inode)->i_start = nr;
                MSDOS_I(inode)->i_logstart = nr;
                mark_inode_dirty(inode);
        }
        if (file_cluster
            != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
                printk ("file_cluster badly computed!!! %d <> %ld\n",   //有时候也在这里出错
                        file_cluster,
                        inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
                fat_cache_inval_inode(inode);
        }
        inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;

        return nr;
}
作者: siasd    时间: 2006-11-25 15:04
似乎是在调用fat_access函数的过程中出了问题,这个函数可能是继续往下层调用usb块设备读取FAT相关的信息。
可以这样进一步分析看看:找到fat_access这个函数的定义,在里面进一步确定到底是什么原因导致这个函数的返回值为空,当然,如果顺利的话,还可以进一步往下深入,直到最终找到根本原因。
作者: upcuiling    时间: 2006-11-27 10:36
/* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
   new_value is != -1, that FAT entry is replaced by it. */

int fat_access(struct super_block *sb,int nr,int new_value)
{
        return MSDOS_SB(sb)->cvf_format->fat_access(sb,nr,new_value);
}

这个函数返回-1说明,已经到了文件目录表的结尾了。
继续郁闷
作者: yuccc    时间: 2006-11-27 23:48
没遇见过。。。
作者: 雪飞花月    时间: 2006-11-28 11:22
提示: 作者被禁止或删除 内容自动屏蔽
作者: PCOS    时间: 2006-12-01 23:11
标题: 回复 13楼 upcuiling 的帖子
除了软件的问题,有无考虑下固件的问题!
作者: likuku    时间: 2006-12-03 12:50
换新版核心。

或者全用网络,CD-RW,DVD-RW,DVD-RAM,MO。

我很反感使用USB 存储器,因为目前很多厂商的USB设备并不是完全符合USB标准。
作者: 醉卧水云间    时间: 2006-12-04 13:22
用的是2.4核心吧,换2.6试试。
作者: crazyCat    时间: 2006-12-06 11:28
标题:
我在使用SD卡的时候也出现过类似的问题
我想是不是和mount的文件系统类型有关系呢
作者: dragon-h    时间: 2006-12-06 15:45
帮DING上去!
作者: peixubin    时间: 2006-12-07 09:28
kernel升级到2.6.10以上应该就没有问题了。
作者: upcuiling    时间: 2006-12-08 19:27
在申请一个cluster的时候,fat表中的cluster号被莫名的修改为ff了,所以导致fat表的错误 从而出现了毛病 至今没发现原因




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2