[alibaba/tengine]开启directio后fcntl(O_DIRECT)错误

2024-07-10 382 views
4

我的配置为:

directio 1m;
directio_alignment 4K;

错误为:2016/12/02 08:57:50 [alert] 30440#30440: *1621 fcntl(O_DIRECT) "/datatest/01.png" failed (22: Invalid argument), ... 测试了几次发现符合下面的条件即报错 1、被访问的文件大小大于directio设置的大小(directio设置为1m,01.png为1.73m,directio改为2m不报错) 2、root设置mount挂载的磁盘的文件报错,root本地磁盘目录不报错,或由upstream上游服务器提供的不报错(mount方式为cifs) 这个报错并未对访问产生影响,响应为200,且md5校验正确。

回答

2

1、被访问的文件大小大于directio设置的大小(directio设置为1m,01.png为1.73m,directio改为2m不报错)

文件大于directio设置的大小时候,才会对read的文件fd设置O_DIRECTIO。所以当你将directio改为2m时,实际是没有对文件设置directio的,所以也就没有报错

2、root设置mount挂载的磁盘的文件报错,root本地磁盘目录不报错,或由upstream上游服务器提供的不报错(mount方式为cifs)

directio设置失败不会影响文件读,改为正常读文件(cache模式)

我不是很熟悉cifs文件系统格式,我查阅文档,在linux-3.7上,cifs对directio支持已被废弃,文档截取如下:

directio Do not do inode data caching on files opened on this mount. This precludes mmaping files on this mount. In some cases with fast networks and little or no caching benefits on the client (e.g. when the application is doing large sequential reads bigger than page size without rereading the same data) this can provide better performance than the default behavior which caches reads (readahead) and writes (writebehind) through the local Linux client pagecache if oplock (caching token) is granted and held. Note that direct allows write operations larger than page size to be sent to the server. On some kernels this requires the cifs.ko module to be built with the CIFS_EXPERIMENTAL configure option.

This option is will be deprecated in 3.7. Users should use cache=none instead on more recent kernels.

0

查看linus的内核树,目前CIFS对O_DIRECTIO也是不支持的,如果设置该标记会直接返回EINVAL (对应错误原因 Invalid argument): here

/*
 * The presence of cifs_direct_io() in the address space ops vector
 * allowes open() O_DIRECT flags which would have failed otherwise.
 *
 * In the non-cached mode (mount with cache=none), we shunt off direct read and write requests
 * so this method should never be called.
 *
 * Direct IO is not yet supported in the cached mode. 
 */
static ssize_t
cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter)
{
        /*
         * FIXME
         * Eventually need to support direct IO for non forcedirectio mounts
         */
        return -EINVAL;
}
6

我把这几个都注释了,nas既要被linux访问又要被windows访问(cms是基于.net部署在windows上的),所以暂时没办法只能用cifs。

#aio threads
#directio 1m;
#directio_alignment 4K;

我设置了sendfile_max_chunk 256K;可以解决大文件请求量较大时,对页面请求阻塞的问题。大文件请求量较大时对/us /nginx_status等状态查看的请求都会阻塞。