1. 程式人生 > >SylixOS write 0字節問題

SylixOS write 0字節問題

SylixOS 文件系統 writ

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字節問題