📄 fs-ecos.c
字号:
// Open a directory for reading.static int jffs3_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, cyg_file * file){ jffs3_dirsearch ds; int err; D2(printf("jffs3_opendir\n")); init_dirsearch(&ds, (struct _inode *) dir, name); err = jffs3_find(&ds); jffs3_iput(ds.dir); if (err != ENOERR) return err; // check it is really a directory. if (!S_ISDIR(ds.node->i_mode)) { jffs3_iput(ds.node); return ENOTDIR; } // 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 = &jffs3_dirops; file->f_offset = 0; file->f_data = (CYG_ADDRWORD) ds.node; file->f_xops = 0; return ENOERR;}// -------------------------------------------------------------------------// jffs3_chdir()// Change directory support.static int jffs3_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, cyg_dir * dir_out){ D2(printf("jffs3_chdir\n")); if (dir_out != NULL) { // This is a request to get a new directory pointer in // *dir_out. jffs3_dirsearch ds; int err; init_dirsearch(&ds, (struct _inode *) dir, name); err = jffs3_find(&ds); jffs3_iput(ds.dir); if (err != ENOERR) return err; // check it is a directory if (!S_ISDIR(ds.node->i_mode)) return ENOTDIR; // 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. jffs3_iput(node); } return ENOERR;}// -------------------------------------------------------------------------// jffs3_stat()// Get struct stat info for named object.static int jffs3_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, struct stat *buf){ jffs3_dirsearch ds; int err; D2(printf("jffs3_stat\n")); init_dirsearch(&ds, (struct _inode *) dir, name); err = jffs3_find(&ds); jffs3_iput(ds.dir); if (err != ENOERR) return err; // Fill in the status buf->st_mode = ds.node->i_mode; buf->st_ino = ds.node->i_ino; buf->st_dev = 0; buf->st_nlink = ds.node->i_nlink; buf->st_uid = ds.node->i_uid; buf->st_gid = ds.node->i_gid; 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; jffs3_iput(ds.node); return ENOERR;}// -------------------------------------------------------------------------// jffs3_getinfo()// Getinfo. Currently only support pathconf().static int jffs3_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, int key, void *buf, int len){ jffs3_dirsearch ds; int err; D2(printf("jffs3_getinfo\n")); init_dirsearch(&ds, (struct _inode *) dir, name); err = jffs3_find(&ds); jffs3_iput(ds.dir); if (err != ENOERR) return err; switch (key) { case FS_INFO_CONF: err = jffs3_pathconf(ds.node, (struct cyg_pathconf_info *) buf); break; default: err = EINVAL; } jffs3_iput(ds.node); return err;}// -------------------------------------------------------------------------// jffs3_setinfo()// Setinfo. Nothing to support here at present.static int jffs3_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("jffs3_setinfo\n")); return EINVAL;}//==========================================================================// File operations// -------------------------------------------------------------------------// jffs3_fo_read()// Read data from the file.static int jffs3_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ struct _inode *inode = (struct _inode *) fp->f_data; struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode); struct jffs3_sb_info *c = JFFS3_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("jffs3_fo_read inode size %d\n", inode->i_size)); ret = jffs3_read_inode_range(c, f, (unsigned char *) iov->iov_base, pos, len); if (ret) { D1(printf ("jffs3_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;}#ifdef CYGOPT_FS_JFFS3_WRITE// -------------------------------------------------------------------------// jffs3_fo_write()// Write data to file.static int jffs3_extend_file (struct _inode *inode, struct jffs3_raw_inode *ri, unsigned long offset){ struct jffs3_sb_info *c = JFFS3_SB_INFO(inode->i_sb); struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode); struct jffs3_full_dnode *fn; uint32_t phys_ofs, alloc_len; int ret = 0; /* Make new hole frag from old EOF to new page */ D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", (unsigned int)inode->i_size, offset)); ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL); if (ret) return ret; down(&f->sem); ri->magic = cpu_to_je16(JFFS3_MAGIC_BITMASK); ri->nodetype = cpu_to_je16(JFFS3_NODETYPE_INODE); ri->totlen = cpu_to_je32(sizeof(*ri)); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs3_unknown_node)-4)); ri->version = cpu_to_je32(++f->highest_version); ri->isize = cpu_to_je32(max((uint32_t)inode->i_size, offset)); ri->offset = cpu_to_je32(inode->i_size); ri->dsize = cpu_to_je32(offset - inode->i_size); ri->csize = cpu_to_je32(0); ri->compr = JFFS3_COMPR_ZERO; ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ri->data_crc = cpu_to_je32(0); fn = jffs3_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); jffs3_complete_reservation(c); if (IS_ERR(fn)) { ret = PTR_ERR(fn); up(&f->sem); return ret; } ret = jffs3_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { jffs3_mark_node_obsolete(c, f->metadata->raw); jffs3_free_full_dnode(f->metadata); f->metadata = NULL; } if (ret) { D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret)); jffs3_mark_node_obsolete(c, fn->raw); jffs3_free_full_dnode(fn); up(&f->sem); return ret; } inode->i_size = offset; up(&f->sem); return 0;}static int jffs3_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ struct _inode *inode = (struct _inode *) fp->f_data; off_t pos = fp->f_offset; ssize_t resid = uio->uio_resid; struct jffs3_raw_inode ri; struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode); struct jffs3_sb_info *c = JFFS3_SB_INFO(inode->i_sb); int i; // 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 = inode->i_size; if (pos < 0) return EINVAL; memset(&ri, 0, sizeof(ri)); ri.ino = cpu_to_je32(f->inocache->ino); ri.mode = cpu_to_jemode(inode->i_mode); ri.uid = cpu_to_je16(inode->i_uid); ri.gid = cpu_to_je16(inode->i_gid); ri.atime = ri.ctime = ri.mtime = cpu_to_je32(cyg_timestamp()); if (pos > inode->i_size) { int err; ri.version = cpu_to_je32(++f->highest_version); err = jffs3_extend_file(inode, &ri, pos); if (err) return -err; } ri.isize = cpu_to_je32(inode->i_size); // 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; uint32_t writtenlen; int err; D2(printf("jffs3_fo_write page_start_pos %d\n", pos)); D2(printf("jffs3_fo_write transfer size %d\n", l)); err = jffs3_write_inode_range(c, f, &ri, buf, pos, len, &writtenlen); if (err) return -err; if (writtenlen != len) return ENOSPC; pos += len; resid -= len; } // We wrote some data successfully, update the modified and access // times of the inode, increase its size appropriately, and update // the file offset and transfer residue. inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime); if (pos > inode->i_size) inode->i_size = pos; uio->uio_resid = resid; fp->f_offset = pos; return ENOERR;}#endif /* CYGOPT_FS_JFFS3_WRITE */// -------------------------------------------------------------------------// jffs3_fo_lseek()// Seek to a new file position.static int jffs3_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("jffs3_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 ) return EINVAL; // All OK, set fp offset and return new position. *apos = fp->f_offset = pos; return ENOERR;}// -------------------------------------------------------------------------// jffs3_fo_ioctl()// Handle ioctls. Currently none are defined.static int jffs3_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, CYG_ADDRWORD data){ // No Ioctls currenly defined. D2(printf("jffs3_fo_ioctl\n")); return EINVAL;}// -------------------------------------------------------------------------// jffs3_fo_fsync().// Force the file out to data storage.static int jffs3_fo_fsync(struct CYG_FILE_TAG *fp, int mode){ // Data is always permanently where it belongs, nothing to do // here. D2(printf("jffs3_fo_fsync\n")); return ENOERR;}// -------------------------------------------------------------------------// jffs3_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 jffs3_fo_close(struct CYG_FILE_TAG *fp){ struct _inode *node = (struct _inode *) fp->f_data; D2(printf("jffs3_fo_close\n")); jffs3_iput(node); fp->f_data = 0; // zero data pointer return ENOERR;}// -------------------------------------------------------------------------//jffs3_fo_fstat()// Get file status.static int jffs3_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf){ struct _inode *node = (struct _inode *) fp->f_data; D2(printf("jffs3_fo_fstat\n")); // Fill in the status buf->st_mode = node->i_mode; buf->st_ino = node->i_ino; buf->st_dev = 0; buf->st_nlink = node->i_nlink; buf->st_uid = node->i_uid; buf->st_gid = node->i_gid; 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;}// -------------------------------------------------------------------------// jffs3_fo_getinfo()// Get info. Currently only supports fpathconf().static int jffs3_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("jffs3_fo_getinfo\n")); switch (key) { case FS_INFO_CONF: err = jffs3_pathconf(node, (struct cyg_pathconf_info *) buf); break; default: err = EINVAL; } return err; return ENOERR;}// -------------------------------------------------------------------------// jffs3_fo_setinfo()// Set info. Nothing supported here.static int jffs3_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf, int len){ // No setinfo key supported at present D2(printf("jffs3_fo_setinfo\n")); return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// jffs3_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -