📄 fs-ecos.c
字号:
}// -------------------------------------------------------------------------// 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; init_dirsearch(&ds, (struct _inode *) dir, (const unsigned char *) name); err = jffs2_find(&ds); jffs2_iput(ds.dir); if (err != ENOERR) return err; // check it is a directory if (!S_ISDIR(ds.node->i_mode)) { jffs2_iput(ds.node); 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. jffs2_iput(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")); init_dirsearch(&ds, (struct _inode *) dir, (const unsigned char *) name); err = jffs2_find(&ds); jffs2_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; jffs2_iput(ds.node); 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")); init_dirsearch(&ds, (struct _inode *) dir, (const unsigned char *) name); err = jffs2_find(&ds); jffs2_iput(ds.dir); 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; } jffs2_iput(ds.node); return err;}// -------------------------------------------------------------------------// 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;}#ifdef CYGOPT_FS_JFFS2_WRITE// -------------------------------------------------------------------------// jffs2_fo_write()// Write data to file.static int jffs2_extend_file (struct _inode *inode, struct jffs2_raw_inode *ri, unsigned long offset){ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_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 = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL); if (ret) return ret; down(&f->sem); ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ri->totlen = cpu_to_je32(sizeof(*ri)); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_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 = JFFS2_COMPR_ZERO; ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ri->data_crc = cpu_to_je32(0); fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); jffs2_complete_reservation(c); if (IS_ERR(fn)) { ret = PTR_ERR(fn); up(&f->sem); return ret; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { jffs2_mark_node_obsolete(c, f->metadata->raw); jffs2_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)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); up(&f->sem); return ret; } inode->i_size = offset; up(&f->sem); return 0;}// jffs2_fo_open()// Truncate a filestatic int jffs2_truncate_file (struct _inode *inode){ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_full_dnode *new_metadata, * old_metadata; struct jffs2_raw_inode *ri; uint32_t phys_ofs, alloclen; int err; ri = jffs2_alloc_raw_inode(); if (!ri) { return ENOMEM; } err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); if (err) { jffs2_free_raw_inode(ri); return err; } down(&f->sem); ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ri->totlen = cpu_to_je32(sizeof(*ri)); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ri->ino = cpu_to_je32(inode->i_ino); ri->version = cpu_to_je32(++f->highest_version); ri->uid = cpu_to_je16(inode->i_uid); ri->gid = cpu_to_je16(inode->i_gid); ri->mode = cpu_to_jemode(inode->i_mode); ri->isize = cpu_to_je32(0); ri->atime = cpu_to_je32(inode->i_atime); ri->mtime = cpu_to_je32(cyg_timestamp()); ri->offset = cpu_to_je32(0); ri->csize = ri->dsize = cpu_to_je32(0); ri->compr = JFFS2_COMPR_NONE; ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ri->data_crc = cpu_to_je32(0); new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); if (IS_ERR(new_metadata)) { jffs2_complete_reservation(c); jffs2_free_raw_inode(ri); up(&f->sem); return PTR_ERR(new_metadata); } /* It worked. Update the inode */ inode->i_mtime = cyg_timestamp(); inode->i_size = 0; old_metadata = f->metadata; jffs2_truncate_fragtree (c, &f->fragtree, 0); f->metadata = new_metadata; if (old_metadata) { jffs2_mark_node_obsolete(c, old_metadata->raw); jffs2_free_full_dnode(old_metadata); } jffs2_free_raw_inode(ri); up(&f->sem); jffs2_complete_reservation(c); return 0;}static int jffs2_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 jffs2_raw_inode ri; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_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 = jffs2_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]; unsigned char *buf = iov->iov_base; off_t len = iov->iov_len; uint32_t writtenlen; int err; D2(printf("jffs2_fo_write page_start_pos %d\n", pos)); D2(printf("jffs2_fo_write transfer size %d\n", len)); err = jffs2_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_JFFS2_WRITE */// -------------------------------------------------------------------------// 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; } if (pos < 0 ) 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")); jffs2_iput(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 = 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;}// -------------------------------------------------------------------------// 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -