Chinaunix

标题: kernel中读取文件,只读取到文件部分内容(前1013个字节) [打印本页]

作者: wokao112358    时间: 2013-11-25 17:34
标题: kernel中读取文件,只读取到文件部分内容(前1013个字节)
本帖最后由 wokao112358 于 2013-11-28 12:23 编辑

  filp=filp_open(filename,O_RDONLY,0);
  inode=filp->f_dentry->d_inode;   
  magic=inode->i_sb->s_magic;
  printk("<1>file system magic:%li \n",magic);
  printk("<1>super blocksize:%li \n",inode->i_sb->s_blocksize);//----->here is 4096
  printk("<1>inode %li \n",inode->i_ino); //----->here is 4904

  fsize=inode->i_size;
  printk("<1>file size:%i \n",(int)fsize);  //---->here is 4336 bytes
  buf=(char *) kmalloc(fsize+1,GFP_ATOMIC);

  fs=get_fs();
  set_fs(KERNEL_DS);
  filp->f_op->read(filp,buf,fsize,&(filp->f_pos));
  set_fs(fs);

  buf[fsize]='\0';
  printk("<1>The File Content is:\n");
  printk("<1>%s",buf); //---->only 1013 bytes printed

上述代码是在内核中编写,我希望是一次性把文件(4336字节)内容读取出来,但是实际打印的情况是只有文件的前1013个字节,
大神们,请问是操作系统有限制么?如果有限制的话,能告诉我是设置在什么地方么?
我上网没找到关于限制的信息,先谢谢各位了!
作者: firkraag    时间: 2013-11-26 10:03
check the value of buf[1048] and the return value of the filp->f_op->read.
作者: wokao112358    时间: 2013-11-26 13:07
本帖最后由 wokao112358 于 2013-11-26 14:09 编辑

read的返回值就是文件大小.
之前我犯了个错误,将log从linux下拷贝到window下时,'0A'被替换成了'0D0A';实际的打印的buf只有1013个字节,之后的就没打印出来
buf[1012]确实是被读取文件的第1023个字节,buf[1013]也不是'\0', 而是空格;buf[1014]我也打印了,不是'\0';
照理说不会打印到这里就停止了,所以我猜测可能是内核有限制,但是我查了printk的ring buf,即使整个文件的size也没有超;
#define CONFIG_LOG_BUF_SHIFT  14
#define __LOG_BUF_LEN(1 << CONFIG_LOG_BUF_SHIFT)

回复 2# firkraag


   
作者: Godbach    时间: 2013-11-26 15:04
回复 3# wokao112358


这个好验证,你先把文件全部读到 buffer,然后再打印 buffer,比如按照 hex 打印之类的。

此外,read 返回的长度总共有多少呢。

   
作者: wokao112358    时间: 2013-11-26 16:05
我贴出来的代码就是这么做的,先全部读到buf,然后打印buf;
但是发现只打印了部分(打印了1013个字节),但是read返回值确实是文件的大小;
我也选择性的打印了一些字节,如buf[2040], 和文件内容也是一致的。
回复 4# Godbach


   
作者: firkraag    时间: 2013-11-26 16:13
回复 5# wokao112358
Can you upload you file?
作者: asuka2001    时间: 2013-11-26 16:29
回复 5# wokao112358


printk("<1>%s",buf); //---->only 1048 bytes printed


你按字符串打印,万一 buf里读的文件内容里有个0x00那当然printk就罢工了!

你确定你的文件内容里不可能有0x00?


   
作者: asuka2001    时间: 2013-11-26 16:30
回复 5# wokao112358

printk("<1>%s",buf); //---->only 1048 bytes printed

你是按字符串进行打印的,除非你的文件内容里不会有0x00,否则一遇上0x00 printk就要罢工!


   
作者: Godbach    时间: 2013-11-26 19:02
回复 5# wokao112358

第一个问题: 你应该打印一下 read 的返回值。

第二个问题: read 的执行的时候应该是可以判断什么时候结束的,你没有判断 read 结束的逻辑。你就调用了一次 read,感觉应该是仅仅读取了一块。
filp->f_op->read(filp,buf,fsize,&(filp->f_pos));


   
作者: asuka2001    时间: 2013-11-26 19:07
回复 1# wokao112358


printk("<1>%s",buf); //---->only 1048 bytes printed

你确定文件内容中没有0x00?

   
作者: wokao112358    时间: 2013-11-27 10:22
配置文件由于保密问题没法上传。。。
read返回值是文件的长度;
我一次读取了buf中的每个字节,发现只有buf最后一个字节是‘\0’;
但是打印的时候确实没有打印完全。回复 6# firkraag


   
作者: wokao112358    时间: 2013-11-27 10:23
这个可以确定的;
read返回值是文件的长度;
我依次读取了buf中的每个字节,发现只有buf最后一个字节是‘\0’;
但是打印的时候确实没有打印完全。
回复 10# asuka2001


   
作者: wokao112358    时间: 2013-11-27 10:25
本帖最后由 wokao112358 于 2013-11-27 10:31 编辑

1、 read返回值是文件的长度;
2、read结束的条件就是入参fsize或者读到文件末尾,可以这么理解吧?
3、我依次读取了buf中的每个字节,发现只有buf最后一个字节是‘\0’;
     我也选取了buf中靠后的一些字节进行打印,发现跟文件内容也是一致的;
但是整个打印buf的时候没有打印完全。
回复 9# Godbach


   
作者: Godbach    时间: 2013-11-27 10:29
回复 13# wokao112358

可能和 printk 自身 buffer 有关系。

你这样打印吧,每 1K 字节,调用一次 printk 试试


   
作者: wokao112358    时间: 2013-11-27 10:31
嗯,好的,我先试试你说的这个回复 14# Godbach


   
作者: asuka2001    时间: 2013-11-27 11:32
回复 12# wokao112358

那问题就是printk了,printk()调用vprintk_emit()

vprintk_emit()
{
        static char textbuf[LOG_LINE_MAX];
        ......
        text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
}
   
作者: asuka2001    时间: 2013-11-27 11:35
回复 16# asuka2001

只不过为什么是1048个字节我觉得有点奇怪。。。

#define PREFIX_MAX                32
#define LOG_LINE_MAX                1024 - PREFIX_MAX

明显 LOG_LINE_MAX是小于1024字节的。。。


   
作者: firkraag    时间: 2013-11-27 12:13
回复 11# wokao112358

printk_buf overflow as asuka2001 said.
   
作者: wokao112358    时间: 2013-11-27 20:05
是我刚发帖的时候搞错了,其实是1013个字节,之前打印的log文件在win下‘0A’被转成了'0D0A',所以字节数变多了;我马上改下帖子回复 17# asuka2001


   
作者: wokao112358    时间: 2013-11-27 20:07
谢谢各位的帮助,我再看看源码!!!




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