static int rtems_jffs2_fstat( const rtems_filesystem_location_info_t *loc, struct stat *buf ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); struct super_block *sb = inode->i_sb; rtems_jffs2_flash_control *fc = sb->s_flash_control; rtems_jffs2_do_lock(sb); buf->st_dev = fc->device_identifier; buf->st_blksize = PAGE_SIZE; buf->st_mode = inode->i_mode; buf->st_ino = inode->i_ino; buf->st_nlink = inode->i_nlink; buf->st_uid = inode->i_uid; buf->st_gid = inode->i_gid; buf->st_size = inode->i_size; buf->st_atime = inode->i_atime; buf->st_mtime = inode->i_mtime; buf->st_ctime = inode->i_ctime; rtems_jffs2_do_unlock(sb); return 0; }
static void rtems_jffs2_unlock(const rtems_filesystem_mount_table_entry_t *mt_entry) { const rtems_jffs2_fs_info *fs_info = mt_entry->fs_info; const struct super_block *sb = &fs_info->sb; rtems_jffs2_do_unlock(sb); }
static ssize_t rtems_jffs2_dir_read(rtems_libio_t *iop, void *buf, size_t len) { struct _inode *inode = rtems_jffs2_get_inode_by_iop(iop); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct dirent *de = buf; off_t fd_off = 2; int eno = 0; struct jffs2_full_dirent *fd; off_t begin; off_t end; off_t off; rtems_jffs2_do_lock(inode->i_sb); fd = f->dents; begin = iop->offset; end = begin + len / sizeof(*de); off = begin; if (off == 0 && off < end) { eno = rtems_jffs2_fill_dirent(de, off, inode->i_ino, "."); assert(eno == 0); ++off; ++de; } if (off == 1 && off < end) { eno = rtems_jffs2_fill_dirent(de, off, inode->i_parent->i_ino, ".."); assert(eno == 0); ++off; ++de; } while (eno == 0 && off < end && fd != NULL) { if (fd->ino != 0) { if (off == fd_off) { eno = rtems_jffs2_fill_dirent(de, off, fd->ino, fd->name); ++off; ++de; } ++fd_off; } fd = fd->next; } rtems_jffs2_do_unlock(inode->i_sb); if (eno == 0) { iop->offset = off; return (off - begin) * sizeof(*de); } else { return rtems_jffs2_eno_to_rv_and_errno(eno); } }
static int rtems_jffs2_file_ftruncate(rtems_libio_t *iop, off_t length) { struct _inode *inode = rtems_jffs2_get_inode_by_iop(iop); struct iattr iattr; int eno; iattr.ia_valid = ATTR_SIZE | ATTR_MTIME | ATTR_CTIME; iattr.ia_size = length; iattr.ia_mtime = get_seconds(); iattr.ia_ctime = iattr.ia_mtime; rtems_jffs2_do_lock(inode->i_sb); eno = -jffs2_do_setattr(inode, &iattr); rtems_jffs2_do_unlock(inode->i_sb); return rtems_jffs2_eno_to_rv_and_errno(eno); }
static ssize_t rtems_jffs2_file_read(rtems_libio_t *iop, void *buf, size_t len) { struct _inode *inode = rtems_jffs2_get_inode_by_iop(iop); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); int err = 0; off_t pos; rtems_jffs2_do_lock(inode->i_sb); pos = iop->offset; if (pos >= inode->i_size) { len = 0; } else { uint32_t pos_32 = (uint32_t) pos; uint32_t max_available = inode->i_size - pos_32; if (len > max_available) { len = max_available; } err = jffs2_read_inode_range(c, f, buf, pos_32, len); } if (err == 0) { iop->offset += len; } rtems_jffs2_do_unlock(inode->i_sb); if (err == 0) { return (ssize_t) len; } else { errno = -err; return -1; } }
static int rtems_jffs2_fstat( const rtems_filesystem_location_info_t *loc, struct stat *buf ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); rtems_jffs2_do_lock(inode->i_sb); buf->st_blksize = PAGE_SIZE; buf->st_mode = inode->i_mode; buf->st_ino = inode->i_ino; buf->st_nlink = inode->i_nlink; buf->st_uid = inode->i_uid; buf->st_gid = inode->i_gid; buf->st_size = inode->i_size; buf->st_atime = inode->i_atime; buf->st_mtime = inode->i_mtime; buf->st_ctime = inode->i_ctime; rtems_jffs2_do_unlock(inode->i_sb); return 0; }
static ssize_t rtems_jffs2_file_write(rtems_libio_t *iop, const void *buf, size_t len) { struct _inode *inode = rtems_jffs2_get_inode_by_iop(iop); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_raw_inode ri; uint32_t writtenlen; off_t pos; int eno = 0; 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(get_seconds()); rtems_jffs2_do_lock(inode->i_sb); if ((iop->flags & LIBIO_FLAGS_APPEND) == 0) { pos = iop->offset; } else { pos = inode->i_size; } if (pos > inode->i_size) { ri.version = cpu_to_je32(++f->highest_version); eno = -jffs2_extend_file(inode, &ri, pos); } if (eno == 0) { ri.isize = cpu_to_je32(inode->i_size); eno = -jffs2_write_inode_range(c, f, &ri, (void *) buf, pos, len, &writtenlen); } if (eno == 0) { pos += writtenlen; inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime); if (pos > inode->i_size) { inode->i_size = pos; } iop->offset = pos; if (writtenlen != len) { eno = ENOSPC; } } rtems_jffs2_do_unlock(inode->i_sb); if (eno == 0) { return writtenlen; } else { errno = eno; return -1; } }