📄 fs-ecos.c
字号:
if (err == 0) ds1.node->i_ctime = ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp(); return err;}// -------------------------------------------------------------------------// jffs2_opendir()// Open a directory for reading.static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, cyg_file * file){ jffs2_dirsearch ds; int err; D2(printf("jffs2_opendir\n")); icache_evict((struct inode *) mte->root, (struct inode *) dir); init_dirsearch(&ds, (struct inode *) dir, name); err = jffs2_find(&ds); if (err != ENOERR) return err; // check it is really a directory. if (!S_ISDIR(ds.node->i_mode)) return ENOTDIR; ds.node->i_count++; // Count successful open // Initialize the file object, setting the f_ops field to a // special set of file ops. file->f_type = CYG_FILE_TYPE_FILE; file->f_ops = &jffs2_dirops; file->f_offset = 0; file->f_data = (CYG_ADDRWORD) ds.node; file->f_xops = 0; return ENOERR;}// -------------------------------------------------------------------------// jffs2_chdir()// Change directory support.static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, cyg_dir * dir_out){ D2(printf("jffs2_chdir\n")); if (dir_out != NULL) { // This is a request to get a new directory pointer in // *dir_out. jffs2_dirsearch ds; int err; icache_evict((struct inode *) mte->root, (struct inode *) dir); init_dirsearch(&ds, (struct inode *) dir, name); err = jffs2_find(&ds); if (err != ENOERR) return err; // check it is a directory if (!S_ISDIR(ds.node->i_mode)) return ENOTDIR; // Increment ref count to keep this directory in existance // while it is the current cdir. ds.node->i_count++; // Pass it out *dir_out = (cyg_dir) ds.node; } else { // If no output dir is required, this means that the mte and // dir arguments are the current cdir setting and we should // forget this fact. struct inode *node = (struct inode *) dir; // Just decrement directory reference count. dec_refcnt(node); } return ENOERR;}// -------------------------------------------------------------------------// jffs2_stat()// Get struct stat info for named object.static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, struct stat *buf){ jffs2_dirsearch ds; int err; D2(printf("jffs2_stat\n")); icache_evict((struct inode *) mte->root, (struct inode *) dir); init_dirsearch(&ds, (struct inode *) dir, name); err = jffs2_find(&ds); if (err != ENOERR) return err; // Fill in the status buf->st_mode = ds.node->i_mode; buf->st_ino = (ino_t) ds.node; buf->st_dev = 0; buf->st_nlink = ds.node->i_nlink; buf->st_uid = 0; buf->st_gid = 0; buf->st_size = ds.node->i_size; buf->st_atime = ds.node->i_atime; buf->st_mtime = ds.node->i_mtime; buf->st_ctime = ds.node->i_ctime; return err; return ENOERR;}// -------------------------------------------------------------------------// jffs2_getinfo()// Getinfo. Currently only support pathconf().static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, int key, void *buf, int len){ jffs2_dirsearch ds; int err; D2(printf("jffs2_getinfo\n")); icache_evict((struct inode *) mte->root, (struct inode *) dir); init_dirsearch(&ds, (struct inode *) dir, name); err = jffs2_find(&ds); if (err != ENOERR) return err; switch (key) { case FS_INFO_CONF: err = jffs2_pathconf(ds.node, (struct cyg_pathconf_info *) buf); break; default: err = EINVAL; } return err; return ENOERR;}// -------------------------------------------------------------------------// jffs2_setinfo()// Setinfo. Nothing to support here at present.static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, int key, void *buf, int len){ // No setinfo keys supported at present D2(printf("jffs2_setinfo\n")); return EINVAL;}//==========================================================================// File operations// -------------------------------------------------------------------------// jffs2_fo_read()// Read data from the file.static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ struct inode *inode = (struct inode *) fp->f_data; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); int i; ssize_t resid = uio->uio_resid; off_t pos = fp->f_offset; down(&f->sem); // Loop over the io vectors until there are none left for (i = 0; i < uio->uio_iovcnt && pos < inode->i_size; i++) { int ret; cyg_iovec *iov = &uio->uio_iov[i]; off_t len = min(iov->iov_len, inode->i_size - pos); D2(printf("jffs2_fo_read inode size %d\n", inode->i_size)); ret = jffs2_read_inode_range(c, f, (unsigned char *) iov->iov_base, pos, len); if (ret) { D1(printf ("jffs2_fo_read(): read_inode_range failed %d\n", ret)); uio->uio_resid = resid; up(&f->sem); return -ret; } resid -= len; pos += len; } // We successfully read some data, update the node's access time // and update the file offset and transfer residue. inode->i_atime = cyg_timestamp(); uio->uio_resid = resid; fp->f_offset = pos; up(&f->sem); return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_write()// Write data to file.static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ struct page write_page; off_t page_start_pos; struct inode *node = (struct inode *) fp->f_data; off_t pos = fp->f_offset; ssize_t resid = uio->uio_resid; int i; memset(&read_write_buffer, 0, PAGE_CACHE_SIZE); write_page.virtual = &read_write_buffer; // If the APPEND mode bit was supplied, force all writes to // the end of the file. if (fp->f_flag & CYG_FAPPEND) pos = fp->f_offset = node->i_size; // Check that pos is within current file size, or at the very end. if (pos < 0 || pos > node->i_size) return EINVAL; // Now loop over the iovecs until they are all done, or // we get an error. for (i = 0; i < uio->uio_iovcnt; i++) { cyg_iovec *iov = &uio->uio_iov[i]; char *buf = (char *) iov->iov_base; off_t len = iov->iov_len; // loop over the vector writing it to the file until it has // all been done. while (len > 0) { //cyg_uint8 *fbuf; //size_t bsize; size_t writtenlen; off_t l = len; int err; write_page.index = 0; page_start_pos = pos; while (page_start_pos >= (PAGE_CACHE_SIZE)) { write_page.index++; page_start_pos -= PAGE_CACHE_SIZE; } if (l > PAGE_CACHE_SIZE - page_start_pos) l = PAGE_CACHE_SIZE - page_start_pos; D2(printf ("jffs2_fo_write write_page.index %d\n", write_page.index)); D2(printf ("jffs2_fo_write page_start_pos %d\n", page_start_pos)); D2(printf("jffs2_fo_write transfer size %d\n", l)); err = jffs2_prepare_write(node, &write_page, page_start_pos, page_start_pos + l); if (err != 0) return err; // copy data in memcpy(&read_write_buffer[page_start_pos], buf, l); writtenlen = jffs2_commit_write(node, &write_page, page_start_pos, page_start_pos + l); if (writtenlen != l) return ENOSPC; // Update working vars len -= l; buf += l; pos += l; resid -= l; } } // We wrote some data successfully, update the modified and access // times of the node, increase its size appropriately, and update // the file offset and transfer residue. node->i_mtime = node->i_ctime = cyg_timestamp(); if (pos > node->i_size) node->i_size = pos; uio->uio_resid = resid; fp->f_offset = pos; return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_lseek()// Seek to a new file position.static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * apos, int whence){ struct inode *node = (struct inode *) fp->f_data; off_t pos = *apos; D2(printf("jffs2_fo_lseek\n")); switch (whence) { case SEEK_SET: // Pos is already where we want to be. break; case SEEK_CUR: // Add pos to current offset. pos += fp->f_offset; break; case SEEK_END: // Add pos to file size. pos += node->i_size; break; default: return EINVAL; } // Check that pos is still within current file size, or at the // very end. if (pos < 0 || pos > node->i_size) return EINVAL; // All OK, set fp offset and return new position. *apos = fp->f_offset = pos; return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_ioctl()// Handle ioctls. Currently none are defined.static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, CYG_ADDRWORD data){ // No Ioctls currenly defined. D2(printf("jffs2_fo_ioctl\n")); return EINVAL;}// -------------------------------------------------------------------------// jffs2_fo_fsync().// Force the file out to data storage.static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode){ // Data is always permanently where it belongs, nothing to do // here. D2(printf("jffs2_fo_fsync\n")); return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_close()// Close a file. We just decrement the refcnt and let it go away if// that is all that is keeping it here.static int jffs2_fo_close(struct CYG_FILE_TAG *fp){ struct inode *node = (struct inode *) fp->f_data; D2(printf("jffs2_fo_close\n")); dec_refcnt(node); fp->f_data = 0; // zero data pointer return ENOERR;}// -------------------------------------------------------------------------//jffs2_fo_fstat()// Get file status.static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf){ struct inode *node = (struct inode *) fp->f_data; D2(printf("jffs2_fo_fstat\n")); // Fill in the status buf->st_mode = node->i_mode; buf->st_ino = (ino_t) node; buf->st_dev = 0; buf->st_nlink = node->i_nlink; buf->st_uid = 0; buf->st_gid = 0; buf->st_size = node->i_size; buf->st_atime = node->i_atime; buf->st_mtime = node->i_mtime; buf->st_ctime = node->i_ctime; return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_getinfo()// Get info. Currently only supports fpathconf().static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf, int len){ struct inode *node = (struct inode *) fp->f_data; int err; D2(printf("jffs2_fo_getinfo\n")); switch (key) { case FS_INFO_CONF: err = jffs2_pathconf(node, (struct cyg_pathconf_info *) buf); break; default: err = EINVAL; } return err; return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_setinfo()// Set info. Nothing supported here.static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf, int len){ // No setinfo key supported at present D2(printf("jffs2_fo_setinfo\n")); return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// jffs2_fo_dirread()// Read a single directory entry from a file.static __inline void filldir(char *nbuf, int nlen, const char *name, int namlen){ int len = nlen < namlen ? nlen : namlen; memcpy(nbuf, name, len); nbuf[len] = '\0';}static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ struct inode *d_inode = (struct inode *) fp->f_data; struct dirent *ent = (struct dirent *) uio->uio_iov[0].iov_base; char *nbuf = ent->d_name; int nlen = sizeof (ent->d_name) - 1; off_t len = uio->uio_iov[0].iov_len; struct jffs2_inode_info *f; struct jffs2_sb_info *c; struct inode *inode = d_inode; struct jffs2_full_dirent *fd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -