static int rtems_jffs2_rmnod( const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *loc ) { struct _inode *dir_i = rtems_jffs2_get_inode_by_location(parentloc); struct _inode *entry_i = rtems_jffs2_get_inode_by_location(loc); char *name; size_t namelen; int eno = rtems_jffs2_cache_fd_name(entry_i, &name, &namelen); if (eno == 0) { switch (dir_i->i_mode & S_IFMT) { case S_IFDIR: eno = -jffs2_rmdir(dir_i, entry_i, name, namelen); break; case S_IFREG: eno = -jffs2_unlink(dir_i, entry_i, name, namelen); break; default: eno = EINVAL; break; } } return rtems_jffs2_eno_to_rv_and_errno(eno); }
static bool rtems_jffs2_are_nodes_equal( const rtems_filesystem_location_info_t *a, const rtems_filesystem_location_info_t *b ) { struct _inode *inode_a = rtems_jffs2_get_inode_by_location(a); struct _inode *inode_b = rtems_jffs2_get_inode_by_location(b); return inode_a->i_ino == inode_b->i_ino; }
static int rtems_jffs2_link( const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *targetloc, const char *name, size_t namelen ) { struct _inode *old_d_inode = rtems_jffs2_get_inode_by_location(targetloc); struct _inode *dir_i = rtems_jffs2_get_inode_by_location(parentloc); int eno; eno = -jffs2_link(old_d_inode, dir_i, name, namelen); return rtems_jffs2_eno_to_rv_and_errno(eno); }
static int rtems_jffs2_mknod( const rtems_filesystem_location_info_t *parentloc, const char *name, size_t namelen, mode_t mode, dev_t dev ) { struct _inode *dir_i = rtems_jffs2_get_inode_by_location(parentloc); int eno; switch (mode & S_IFMT) { case S_IFDIR: eno = -jffs2_mknod(dir_i, name, namelen, mode, NULL, 0); break; case S_IFREG: eno = -jffs2_create(dir_i, name, namelen, mode); break; default: eno = EINVAL; break; } return rtems_jffs2_eno_to_rv_and_errno(eno); }
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 int rtems_jffs2_clonenode(rtems_filesystem_location_info_t *loc) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); ++inode->i_count; return 0; }
static bool rtems_jffs2_eval_is_directory( rtems_filesystem_eval_path_context_t *ctx, void *arg ) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(ctx); struct _inode *inode = rtems_jffs2_get_inode_by_location(currentloc); return S_ISDIR(inode->i_mode); }
static int rtems_jffs2_rename( const rtems_filesystem_location_info_t *oldparentloc, const rtems_filesystem_location_info_t *oldloc, const rtems_filesystem_location_info_t *newparentloc, const char *name, size_t namelen ) { struct _inode *old_dir_i = rtems_jffs2_get_inode_by_location(oldparentloc); struct _inode *new_dir_i = rtems_jffs2_get_inode_by_location(newparentloc); struct _inode *d_inode = rtems_jffs2_get_inode_by_location(oldloc); char *oldname; size_t oldnamelen; int eno = rtems_jffs2_cache_fd_name(d_inode, &oldname, &oldnamelen); if (eno == 0) { eno = -jffs2_rename(old_dir_i, d_inode, oldname, oldnamelen, new_dir_i, name, namelen); } return rtems_jffs2_eno_to_rv_and_errno(eno); }
static int rtems_jffs2_fchmod( const rtems_filesystem_location_info_t *loc, mode_t mode ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); struct iattr iattr; int eno; iattr.ia_valid = ATTR_MODE | ATTR_CTIME; iattr.ia_mode = mode; iattr.ia_ctime = get_seconds(); eno = -jffs2_do_setattr(inode, &iattr); return rtems_jffs2_eno_to_rv_and_errno(eno); }
static int rtems_jffs2_chown( const rtems_filesystem_location_info_t *loc, uid_t owner, gid_t group ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); struct iattr iattr; int eno; iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; iattr.ia_uid = owner; iattr.ia_gid = group; iattr.ia_ctime = get_seconds(); eno = -jffs2_do_setattr(inode, &iattr); return rtems_jffs2_eno_to_rv_and_errno(eno); }
static rtems_filesystem_node_types_t rtems_jffs2_node_type( const rtems_filesystem_location_info_t *loc ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); rtems_filesystem_node_types_t type; switch (inode->i_mode & S_IFMT) { case S_IFDIR: type = RTEMS_FILESYSTEM_DIRECTORY; break; case S_IFREG: type = RTEMS_FILESYSTEM_MEMORY_FILE; break; case S_IFLNK: type = RTEMS_FILESYSTEM_SYM_LINK; break; default: type = RTEMS_FILESYSTEM_INVALID_NODE_TYPE; break; } return type; }
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 void rtems_jffs2_freenode(const rtems_filesystem_location_info_t *loc) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); jffs2_iput(inode); }
static rtems_filesystem_eval_path_generic_status rtems_jffs2_eval_token( rtems_filesystem_eval_path_context_t *ctx, void *arg, const char *token, size_t tokenlen ) { rtems_filesystem_eval_path_generic_status status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE; rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(ctx); struct _inode *dir_i = rtems_jffs2_get_inode_by_location(currentloc); bool access_ok = rtems_filesystem_eval_path_check_access( ctx, RTEMS_FS_PERMS_EXEC, dir_i->i_mode, dir_i->i_uid, dir_i->i_gid ); if (access_ok) { struct _inode *entry_i; if (rtems_filesystem_is_current_directory(token, tokenlen)) { entry_i = dir_i; ++entry_i->i_count; } else if (rtems_filesystem_is_parent_directory(token, tokenlen)) { entry_i = dir_i->i_parent; ++entry_i->i_count; } else { entry_i = jffs2_lookup(dir_i, token, (int) tokenlen); } if (IS_ERR(entry_i)) { rtems_filesystem_eval_path_error(ctx, PTR_ERR(entry_i)); } else if (entry_i != NULL) { bool terminal = !rtems_filesystem_eval_path_has_path(ctx); int eval_flags = rtems_filesystem_eval_path_get_flags(ctx); bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0; rtems_filesystem_eval_path_clear_token(ctx); if (S_ISLNK(entry_i->i_mode) && (follow_sym_link || !terminal)) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(entry_i); const char *target = f->target; rtems_filesystem_eval_path_recursive(ctx, target, strlen(target)); jffs2_iput(entry_i); } else { if (S_ISDIR(entry_i->i_mode) && entry_i->i_parent == NULL) { entry_i->i_parent = dir_i; ++dir_i->i_count; } jffs2_iput(dir_i); rtems_jffs2_set_location(currentloc, entry_i); if (rtems_filesystem_eval_path_has_path(ctx)) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } } else { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; } } return status; }
size_t oldnamelen; int eno = rtems_jffs2_cache_fd_name(d_inode, &oldname, &oldnamelen); if (eno == 0) { eno = -jffs2_rename(old_dir_i, d_inode, oldname, oldnamelen, new_dir_i, name, namelen); } return rtems_jffs2_eno_to_rv_and_errno(eno); } static int rtems_jffs2_statvfs( const rtems_filesystem_location_info_t *__restrict loc, struct statvfs *__restrict buf ) { struct _inode *inode = rtems_jffs2_get_inode_by_location(loc); struct super_block *sb = inode->i_sb; struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); unsigned long avail; spin_lock(&c->erase_completion_lock); avail = c->dirty_size + c->free_size; if (avail > c->sector_size * c->resv_blocks_write) { avail -= c->sector_size * c->resv_blocks_write; } else { avail = 0; } spin_unlock(&c->erase_completion_lock); buf->f_bavail = avail >> PAGE_SHIFT; buf->f_blocks = c->flash_size >> PAGE_SHIFT;