SylixOS write 0字节问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SylixOS write 0字节问题相关的知识,希望对你有一定的参考价值。

1 问题描述

在移植中间件过程中,在SylixOS调用write函数写入0字节的数据到文件中时,会导致对应的中间件测试用例失败,失败的原因是文件系统中的write函数在Linux系统和SylixOS有区别,两种实现的差别如下。

2 write函数的实现机制

2.1 SylixOS实现机制

SylixOS下通过write 函数写数据到普通文件中时,第一步会判断写入的数据是否为0,如果是0直接返回失败,具体实现如程序清单 2.1所示。

程序清单 2.1 SylixOS文件系统写函数

static ssize_t    __ramFsPWrite (PLW_FD_ENTRY    pfdentry,

                               PCHAR         pcBuffer,

                               size_t        stNBytes,

                               off_t         oftPos)

{

      PLW_FD_NODE   pfdnode     =   (PLW_FD_NODE)pfdentry->FDENTRY_pfdnode;

      PRAM_NODE     pramn       =   (PRAM_NODE)pfdnode->FDNODE_pvFile;

    ssize_t       sstWriteNum = PX_ERROR;

   

    if (!pcBuffer   || !stNBytes || (oftPos < 0)) {

          _ErrorHandle(EINVAL);

          return  (PX_ERROR);

    }

   

    if (pramn ==   LW_NULL) {

          _ErrorHandle(EISDIR);

          return  (PX_ERROR);

    }

    

    if   (__RAMFS_FILE_LOCK(pramn) != ERROR_NONE) {

          _ErrorHandle(ENXIO);

          return  (PX_ERROR);

    }

   

    if   (S_ISDIR(pramn->RAMN_mode)) {

          __RAMFS_FILE_UNLOCK(pramn);

          _ErrorHandle(EISDIR);

          return  (PX_ERROR);

    }

   

    sstWriteNum =   __ram_write(pramn, pcBuffer, stNBytes, (size_t)oftPos);

    if   (sstWriteNum > 0) {

          pfdnode->FDNODE_oftSize = (off_t)pramn->RAMN_stSize;

    }

   

      __RAMFS_FILE_UNLOCK(pramn);

   

    return  (sstWriteNum);

}

 

2.2 Linux实现机制

Linux下通过write 函数写数据到普通文件中时,第一步会判断写入的数据是否为0,如果是0直接返回0,具体实现如程序清单 2.2所示。

程序清单 2.2 Linux 文件系统写函数

ssize_t __generic_file_aio_write(struct kiocb *iocb, const   struct iovec *iov,

                 unsigned   long nr_segs, loff_t *ppos)

{

    struct file *file   = iocb->ki_filp;

    struct address_space   * mapping = file->f_mapping;

    size_t ocount;        /* original count */

    size_t count;        /* after file limit checks */

    struct inode     *inode = mapping->host;

    loff_t        pos;

    ssize_t        written;

    ssize_t        err;

 

    ocount = 0;

    err = generic_segment_checks(iov,   &nr_segs, &ocount, VERIFY_READ);

    if (err)

        return err;

 

    count = ocount;

    pos = *ppos;

 

    /* We can   write back this queue in page reclaim */

    current->backing_dev_info   = mapping->backing_dev_info;

    written = 0;

 

    err = generic_write_checks(file,   &pos, &count, S_ISBLK(inode->i_mode));

    if (err)

        goto out;

 

    if (count ==   0)

        goto out;

 

    err = file_remove_suid(file);

    if (err)

        goto out;

 

    err = file_update_time(file);

    if (err)

        goto out;

 

    /* coalesce   the iovecs and go direct-to-BIO for O_DIRECT */

    if (unlikely(file->f_flags   & O_DIRECT)) {

        loff_t endbyte;

        ssize_t written_buffered;

 

        written =   generic_file_direct_write(iocb, iov, &nr_segs, pos,

                            ppos, count, ocount);

        if (written   < 0 || written == count)

            goto out;

        /*

         *   direct-io write to a hole: fall through to buffered I/O

         * for   completing the rest of the request.

         */

        pos += written;

        count -= written;

        written_buffered   = generic_file_buffered_write(iocb, iov,

                          nr_segs, pos, ppos, count,

                          written);

        /*

         * If   generic_file_buffered_write() retuned a synchronous error

         * then   we want to return the number of bytes which were

         *   direct-written, or the error code if that was zero.  Note

         * that   this differs from normal direct-io semantics, which

         * will   return -EFOO even if some bytes were written.

         */

        if (written_buffered   < 0) {

            err =   written_buffered;

            goto out;

        }

 

        /*

         * We   need to ensure that the page cache pages are written to

         * disk   and invalidated to preserve the expected O_DIRECT

         *   semantics.

         */

        endbyte =   pos + written_buffered - written - 1;

        err = filemap_write_and_wait_range(file->f_mapping,   pos, endbyte);

        if (err   == 0) {

            written   = written_buffered;

            invalidate_mapping_pages(mapping,

                           pos >> PAGE_CACHE_SHIFT,

                           endbyte >> PAGE_CACHE_SHIFT);

        } else {

            /*

             * We   don't know how much we wrote, so just return

             *   the number of bytes which were direct-written

             */

        }

    } else {

        written =   generic_file_buffered_write(iocb, iov, nr_segs,

                pos,   ppos, count, written);

    }

out:

    current->backing_dev_info   = NULL;

    return written   ? written : err;

}


 

 


以上是关于SylixOS write 0字节问题的主要内容,如果未能解决你的问题,请参考以下文章

SylixOS块设备驱动模型

SylixOS中端模式处理方式总结

x86下SylixOS引导过程分析

SylixOS字符设备驱动框架

SylixOS SPI 总线框架浅析

SylixOS CAN总线报文浅析