static rtems_filesystem_node_types_t rtems_rfs_rtems_node_type_by_inode (rtems_rfs_inode_handle* inode) { /* * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an * eval link which does not make sense in the case of the RFS file * system. All directory entries are links to an inode. A link such as a HARD * link is actually the normal path to a regular file, directory, device * etc's inode. Links to inodes can be considered "the real" one, yet they * are all links. */ uint16_t mode = rtems_rfs_inode_get_mode (inode); if (RTEMS_RFS_S_ISDIR (mode)) return RTEMS_FILESYSTEM_DIRECTORY; else if (RTEMS_RFS_S_ISLNK (mode)) return RTEMS_FILESYSTEM_SYM_LINK; else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode)) return RTEMS_FILESYSTEM_DEVICE; else return RTEMS_FILESYSTEM_MEMORY_FILE; }
bool rtems_rfs_rtems_set_handlers (rtems_filesystem_location_info_t* loc, rtems_rfs_inode_handle* inode) { uint16_t mode = rtems_rfs_inode_get_mode (inode); loc->handlers = NULL; if (RTEMS_RFS_S_ISDIR (mode)) loc->handlers = rtems_rfs_rtems_handlers (dir); else if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK(mode)) loc->handlers = rtems_rfs_rtems_handlers (device); else if (RTEMS_RFS_S_ISLNK (mode)) loc->handlers = rtems_rfs_rtems_handlers (link); else if (RTEMS_RFS_S_ISREG (mode)) loc->handlers = rtems_rfs_rtems_handlers (file); else { printf ("rtems-rfs: mode type unknown: %04x\n", mode); return false; } return true; }
int rtems_rfs_inode_create (rtems_rfs_file_system* fs, rtems_rfs_ino parent, const char* name, size_t length, uint16_t mode, uint16_t links, uid_t uid, gid_t gid, rtems_rfs_ino* ino) { rtems_rfs_inode_handle parent_inode; rtems_rfs_inode_handle inode; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CREATE)) { const char* type = "unknown"; int c; if (RTEMS_RFS_S_ISDIR (mode)) type = "dir"; else if (RTEMS_RFS_S_ISCHR (mode)) type = "char"; else if (RTEMS_RFS_S_ISBLK (mode)) type = "block"; else if (RTEMS_RFS_S_ISREG (mode)) type = "file"; else if (RTEMS_RFS_S_ISLNK (mode)) type = "link"; printf("rtems-rfs: inode-create: parent:%" PRIu32 " name:", parent); for (c = 0; c < length; c++) printf ("%c", name[c]); printf (" type:%s mode:%04x (%03o)\n", type, mode, mode & ((1 << 10) - 1)); } /* * The file type is field within the mode. Check we have a sane mode set. */ switch (mode & RTEMS_RFS_S_IFMT) { case RTEMS_RFS_S_IFDIR: case RTEMS_RFS_S_IFCHR: case RTEMS_RFS_S_IFBLK: case RTEMS_RFS_S_IFREG: case RTEMS_RFS_S_IFLNK: break; default: return EINVAL; } rc = rtems_rfs_inode_alloc (fs, parent, ino); if (rc > 0) return rc; rc = rtems_rfs_inode_open (fs, *ino, &inode, true); if (rc > 0) { rtems_rfs_inode_free (fs, *ino); return rc; } rc = rtems_rfs_inode_initialise (&inode, links, mode, uid, gid); if (rc > 0) { rtems_rfs_inode_close (fs, &inode); rtems_rfs_inode_free (fs, *ino); return rc; } /* * Only handle the specifics of a directory. Let caller handle the others. * * The inode delete will free the inode. */ if (RTEMS_RFS_S_ISDIR (mode)) { rc = rtems_rfs_dir_add_entry (fs, &inode, ".", 1, *ino); if (rc == 0) rc = rtems_rfs_dir_add_entry (fs, &inode, "..", 2, parent); if (rc > 0) { rtems_rfs_inode_delete (fs, &inode); rtems_rfs_inode_close (fs, &inode); return rc; } } rc = rtems_rfs_inode_open (fs, parent, &parent_inode, true); if (rc > 0) { rtems_rfs_inode_delete (fs, &inode); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_dir_add_entry (fs, &parent_inode, name, length, *ino); if (rc > 0) { rtems_rfs_inode_delete (fs, &inode); rtems_rfs_inode_close (fs, &inode); rtems_rfs_inode_close (fs, &parent_inode); return rc; } /* * If the node is a directory update the parent link count as the * new directory has the '..' link that points to the parent. */ if (RTEMS_RFS_S_ISDIR (mode)) rtems_rfs_inode_set_links (&parent_inode, rtems_rfs_inode_get_links (&parent_inode) + 1); rc = rtems_rfs_inode_close (fs, &parent_inode); if (rc > 0) { rtems_rfs_inode_delete (fs, &inode); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_inode_free (fs, *ino); return rc; } return 0; }
int rtems_rfs_symlink_read (rtems_rfs_file_system* fs, rtems_rfs_ino link, char* path, size_t size, size_t* length) { rtems_rfs_inode_handle inode; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_SYMLINK_READ)) printf ("rtems-rfs: symlink-read: link:%" PRIu32 "\n", link); rc = rtems_rfs_inode_open (fs, link, &inode, true); if (rc) return rc; if (!RTEMS_RFS_S_ISLNK (rtems_rfs_inode_get_mode (&inode))) { rtems_rfs_inode_close (fs, &inode); return EINVAL; } *length = rtems_rfs_inode_get_block_offset (&inode); if (size < *length) { *length = size; } if (rtems_rfs_inode_get_block_count (&inode) == 0) { memcpy (path, inode.node->data.name, *length); } else { rtems_rfs_block_map map; rtems_rfs_block_no block; rtems_rfs_buffer_handle buffer; char* data; rc = rtems_rfs_block_map_open (fs, &inode, &map); if (rc > 0) { rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_block_map_seek (fs, &map, 0, &block); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_buffer_handle_open (fs, &buffer); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_buffer_handle_request (fs, &buffer, block, false); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } data = rtems_rfs_buffer_data (&buffer); memcpy (path, data, *length); rc = rtems_rfs_buffer_handle_close (fs, &buffer); if (rc > 0) { rtems_rfs_block_map_close (fs, &map); rtems_rfs_inode_close (fs, &inode); return rc; } rc = rtems_rfs_block_map_close (fs, &map); if (rc > 0) { rtems_rfs_inode_close (fs, &inode); return rc; } } rc = rtems_rfs_inode_close (fs, &inode); return rc; }
static int rtems_rfs_shell_inode (rtems_rfs_file_system* fs, int argc, char *argv[]) { rtems_rfs_ino start; rtems_rfs_ino end; rtems_rfs_ino total; rtems_rfs_ino ino; bool show_all; bool error_check_only; bool forced; bool have_start; bool have_end; int arg; int b; int rc; total = fs->group_inodes * fs->group_count; start = RTEMS_RFS_ROOT_INO; end = total - 1; show_all = false; error_check_only = false; forced = false; have_start = have_end = false; for (arg = 1; arg < argc; arg++) { if (argv[arg][0] == '-') { switch (argv[arg][1]) { case 'a': show_all = true; break; case 'e': error_check_only = true; break; case 'f': forced = true; break; default: printf ("warning: option ignored: %s\n", argv[arg]); break; } } else { if (have_end && have_start) printf ("warning: option ignored: %s\n", argv[arg]); else if (!have_start) { start = end = strtoul (argv[arg], 0, 0); have_start = true; } else { end = strtoul (argv[arg], 0, 0); have_end = true; } } } if ((start >= total) || (end >= total)) { printf ("error: inode out of range (0->%" PRId32 ").\n", total - 1); return 1; } rtems_rfs_shell_lock_rfs (fs); for (ino = start; ino <= end; ino++) { rtems_rfs_inode_handle inode; bool allocated; rc = rtems_rfs_group_bitmap_test (fs, true, ino, &allocated); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: testing inode state: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } if (show_all || allocated) { uint16_t mode; bool error; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: opening inode handle: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } error = false; mode = rtems_rfs_inode_get_mode (&inode); if (error_check_only) { if (!RTEMS_RFS_S_ISDIR (mode) && !RTEMS_RFS_S_ISCHR (mode) && !RTEMS_RFS_S_ISBLK (mode) && !RTEMS_RFS_S_ISREG (mode) && !RTEMS_RFS_S_ISLNK (mode)) error = true; else { #if NEED_TO_HANDLE_DIFFERENT_TYPES int b; for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++) { uint32_t block; block = rtems_rfs_inode_get_block (&inode, b); if ((block <= RTEMS_RFS_SUPERBLOCK_SIZE) || (block >= rtems_rfs_fs_blocks (fs))) error = true; } #endif } } if (!error_check_only || error) { printf (" %5" PRIu32 ": pos=%06" PRIu32 ":%04zx %c ", ino, rtems_rfs_buffer_bnum (&inode.buffer), inode.offset * RTEMS_RFS_INODE_SIZE, allocated ? 'A' : 'F'); if (!allocated && !forced) printf (" --\n"); else { const char* type; type = "UKN"; if (RTEMS_RFS_S_ISDIR (mode)) type = "DIR"; else if (RTEMS_RFS_S_ISCHR (mode)) type = "CHR"; else if (RTEMS_RFS_S_ISBLK (mode)) type = "BLK"; else if (RTEMS_RFS_S_ISREG (mode)) type = "REG"; else if (RTEMS_RFS_S_ISLNK (mode)) type = "LNK"; printf ("links=%03i mode=%04x (%s/%03o) bo=%04u bc=%04" PRIu32 " b=[", rtems_rfs_inode_get_links (&inode), mode, type, mode & ((1 << 10) - 1), rtems_rfs_inode_get_block_offset (&inode), rtems_rfs_inode_get_block_count (&inode)); for (b = 0; b < (RTEMS_RFS_INODE_BLOCKS - 1); b++) printf ("%" PRIu32 " ", rtems_rfs_inode_get_block (&inode, b)); printf ("%" PRIu32 "]\n", rtems_rfs_inode_get_block (&inode, b)); } } rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: closing inode handle: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } } } rtems_rfs_shell_unlock_rfs (fs); return 0; }