【问题标题】:EINVAL with gpfs_fcntl带有 gpfs​​_fcntl 的 EINVAL
【发布时间】:2013-04-22 11:26:41
【问题描述】:

我正在尝试对 IO 繁重的代码使用预取提示。我根据我对 gpfs​​_fcntl() 手册页的理解设置了代码,但确实得到了 EINVAL。我现在有点迷茫我做错了什么 - 任何提示都表示赞赏。

挂载:/dev/scratch16 on /bgscratch type gpfs (rw,dev=cadmos-gss.gss1a:scratch16,ldev=scratch16)

Error: Prefetch using gpfs_fcntl failed: Invalid argument (22), 32768b at 7713095680 from /bgscratch/foo.dat

文件:-rw-rw-r-- 1 delalond bbp 14739308544 Jul 25 2012 /bgscratch/foo.dat

来源:

void BufferedFile::prefetch( const uint64_t offset, const uint64_t size )
{
   if( file_.fd == -1 )
       file_.fd = ::open( filename.c_str(), O_RDONLY );
   if( file_.fd == -1 )
   {
       LBWARN << "open() failed: " << lunchbox::sysError << std::endl;
       return;
   }
   struct
   {
       gpfsFcntlHeader_t hdr;
       gpfsAccessRange_t acc;
   } arg;
   arg.hdr.totalLength = sizeof(arg);
   arg.hdr.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
   arg.hdr.fcntlReserved = 0;
   arg.acc.structLen = sizeof(arg.acc);
   arg.acc.structType = GPFS_ACCESS_RANGE;
   arg.acc.start = offset;
   arg.acc.length = size;
   arg.acc.isWrite = 0;
   if( gpfs_fcntl( file_.fd, &arg ) != 0 )
        LBWARN << "Prefetch using gpfs_fcntl failed: " << lunchbox::sysError
               << ", " << size << "b at " << offset << " from " << filename
               << std::endl;
}

编辑:我可以在独立的应用程序中重现该问题,并且一旦启动大于 4GB 就会发生错误,即使它是一个很长的 64 位系统。

【问题讨论】:

  • 您应该添加语言标签,以便更多人看到它。不确定是 c 还是 c++,所以我没有添加任何内容
  • 您是否将 file_.fd 初始化为 -1 ?
  • 是的,fd在构造函数中被初始化为-1。
  • 我的猜测是您需要使用除沼泽标准“open”以外的其他东西打开文件句柄......不过只是猜测,抱歉:(
  • 查看gpfsAccessRange_t 元素startlength 的类型为offset_t,这是否等同于您平台上的uint64_t

标签: c++ c filesystems


【解决方案1】:

您正在尝试在文件结束后读取。

鉴于fileSize,尝试类似

arg.acc.length = fileSize > offset + size ? size : fileSize - offset;

【讨论】:

  • 32768b at 7713095680 长度为 14739308544 的文件应该在文件中!?
  • 据我从文档中可以看出,文件的大小应该在 ia_size 字段中的gpfs_iattr_t 结构(或 x64 的gpfs_iattr64_t 结构)中读取。
  • 不确定你得到了什么。我没有使用 gpfs​​_iattr_t。我的代码非常接近 gpfs​​_fcntl.h 顶部给出的示例
  • 您是否尝试比较ls返回的大小和gpfs_iattr_t提供的大小?
【解决方案2】:

您的offsetsizeuint64_t,无符号整数。虽然结构gpfsAccessRange_t 的文档将元素startlength 视为offset_t,但它们可能是有符号整数。你知道offset_t是怎么定义的吗?

我还注意到 HDF5 使用 off_t

【讨论】:

  • 开始和长度在我的 gpfs​​_fcntl.h 中很长
【解决方案3】:

我忍不住注意到/bgscratch:如果您使用的是蓝色基因 /Q 系统,除非您运行 V1R2M1 或更新版本,否则 gpfs​​_fcntl() 将无法工作。较旧的驱动程序版本不会将 gpfs​​_fcntl 系统调用中继到 i/o 节点。

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2018-08-19
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多