SylixOS write 0字節問題
在移植中間件過程中,在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字節問題