【已解决】各位,关于一个writev和O_DIRECT标志位冲突的文件I/O问题。

本帖最后由 almeydifer 于 2011-02-28 14:46 编辑

大家好,小的在做系统的时候碰到以下问题。具体描述如下:

1.用一个O_DIRECT标志位打开一个文件。(必须的)
2.然后write一些buffer到这个打开的文件里。

现在因为想用writev去取代write来提升一些性能,
但是发现文件在开了O_DIRECT标志位后,writev写不进去内容,终端提示“invalid argument"错误。
但是取消O_DIRECT标志位后,则没有问题,但是现在的要求就是不能去除O_DIRECT标志位。

不知道各位了解这个是什么问题引起的?如何解决?代码如下。
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. #include <string.h>  
  6. #include <sys/uio.h>  
  7.   
  8. int main()  
  9. {  
  10.     struct iovec iov[3];  
  11.     ssize_t nr;  
  12.     int fd, i;  
  13.        
  14.     char *buf[3];
  15.       
  16.         buf[0] = (char *)valloc( strlen("HI!") );
  17.         buf[1] = (char *)valloc( strlen("This is Dingdly.") );
  18.         buf[2] = (char *)valloc( strlen("Bye!") );
  19.        
  20.         memcpy( buf[0], "HI!", strlen("HI!") );
  21.         memcpy( buf[1], "This is Dingdly.", strlen("This is Dingdly.") );
  22.         memcpy( buf[2], "Bye!", strlen("Bye!") );
  23.        
  24.     fd = open("buccaneer.txt", O_WRONLY | O_CREAT | O_TRUNC);  
  25.     if( fd == -1){  
  26.         perror("open");  
  27.         return 1;  
  28.     }  
  29.       
  30.     for (i = 0; i < 3; i ++){  
  31.         iov[i].iov_base = buf[i];  
  32.         iov[i].iov_len = strlen(buf[i]);  
  33.     }  
  34.       
  35.     nr = writev(fd, iov, 3);  
  36.        
  37.     if(nr == -1){  
  38.         perror("writev");  
  39.         return 1;  
  40.     }
  41.        
  42.     if(close(fd))  
  43.     {  
  44.         perror("close");  
  45.         return 1;  
  46.     }  
  47.        
  48.     return 0;  
  49. }  
复制代码

作者: almeydifer   发布时间: 2011-02-28

惭愧,解决方法是这样的:

valloc后的内存,必须以512为单位写入到O_DIRECT标志位打开的文件,

而不是我上面的iov[i].iov_len = strlen(buf[i]); 。

作者: almeydifer   发布时间: 2011-02-28