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; }
int rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc, struct stat* buf) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); rtems_rfs_inode_handle inode; rtems_rfs_file_shared* shared; uint16_t mode; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT)) printf ("rtems-rfs-rtems: stat: in: ino:%" PRId32 "\n", ino); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { return rtems_rfs_rtems_error ("stat: opening inode", rc); } mode = rtems_rfs_inode_get_mode (&inode); if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK (mode)) { buf->st_rdev = rtems_filesystem_make_dev_t (rtems_rfs_inode_get_block (&inode, 0), rtems_rfs_inode_get_block (&inode, 1)); } buf->st_dev = (dev_t) (uintptr_t)rtems_rfs_fs_device (fs); buf->st_ino = rtems_rfs_inode_ino (&inode); buf->st_mode = rtems_rfs_rtems_mode (mode); buf->st_nlink = rtems_rfs_inode_get_links (&inode); buf->st_uid = rtems_rfs_inode_get_uid (&inode); buf->st_gid = rtems_rfs_inode_get_gid (&inode); /* * Need to check is the ino is an open file. If so we take the values from * the open file rather than the inode. */ shared = rtems_rfs_file_get_shared (fs, rtems_rfs_inode_ino (&inode)); if (shared) { buf->st_atime = rtems_rfs_file_shared_get_atime (shared); buf->st_mtime = rtems_rfs_file_shared_get_mtime (shared); buf->st_ctime = rtems_rfs_file_shared_get_ctime (shared); buf->st_blocks = rtems_rfs_file_shared_get_block_count (shared); if (S_ISLNK (buf->st_mode)) buf->st_size = rtems_rfs_file_shared_get_block_offset (shared); else buf->st_size = rtems_rfs_file_shared_get_size (fs, shared); } else { buf->st_atime = rtems_rfs_inode_get_atime (&inode); buf->st_mtime = rtems_rfs_inode_get_mtime (&inode); buf->st_ctime = rtems_rfs_inode_get_ctime (&inode); buf->st_blocks = rtems_rfs_inode_get_block_count (&inode); if (S_ISLNK (buf->st_mode)) buf->st_size = rtems_rfs_inode_get_block_offset (&inode); else buf->st_size = rtems_rfs_inode_get_size (fs, &inode); } buf->st_blksize = rtems_rfs_fs_block_size (fs); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("stat: closing inode", rc); } return 0; }
int rtems_rfs_file_open (rtems_rfs_file_system* fs, rtems_rfs_ino ino, int oflag, rtems_rfs_file_handle** file) { rtems_rfs_file_handle* handle; rtems_rfs_file_shared* shared; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: ino=%" PRId32 "\n", ino); *file = NULL; /* * Allocate a new handle and initialise it. Do this before we deal with the * shared node data so we do not have to be concerned with reference * counting. */ handle = malloc (sizeof (rtems_rfs_file_handle)); if (!handle) return ENOMEM; memset (handle, 0, sizeof (rtems_rfs_file_handle)); rc = rtems_rfs_buffer_handle_open (fs, &handle->buffer); if (rc > 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: buffer handle open failed: %d: %s\n", rc, strerror (rc)); free (handle); return rc; } /* * Scan the file system data list of open files for this ino. If found up * the reference count and return the pointer to the data. */ shared = rtems_rfs_file_get_shared (fs, ino); if (shared) { shared->references++; if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: ino=%" PRId32 " shared\n", ino); } else { /* * None exists so create. Copy in the shared parts of the inode we hold in * memory. */ shared = malloc (sizeof (rtems_rfs_file_shared)); if (!shared) { rtems_rfs_buffer_handle_close (fs, &handle->buffer); free (handle); return ENOMEM; } memset (shared, 0, sizeof (rtems_rfs_file_shared)); rc = rtems_rfs_inode_open (fs, ino, &shared->inode, true); if (rc > 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: inode open failed: %d: %s\n", rc, strerror (rc)); free (shared); rtems_rfs_buffer_handle_close (fs, &handle->buffer); free (handle); return rc; } rc = rtems_rfs_block_map_open (fs, &shared->inode, &shared->map); if (rc > 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: block map open failed: %d: %s\n", rc, strerror (rc)); rtems_rfs_inode_close (fs, &shared->inode); free (shared); rtems_rfs_buffer_handle_close (fs, &handle->buffer); free (handle); return rc; } shared->references = 1; shared->size.count = rtems_rfs_inode_get_block_count (&shared->inode); shared->size.offset = rtems_rfs_inode_get_block_offset (&shared->inode); shared->atime = rtems_rfs_inode_get_atime (&shared->inode); shared->mtime = rtems_rfs_inode_get_mtime (&shared->inode); shared->ctime = rtems_rfs_inode_get_ctime (&shared->inode); shared->fs = fs; rtems_chain_append (&fs->file_shares, &shared->link); rtems_rfs_inode_unload (fs, &shared->inode, false); if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN)) printf ("rtems-rfs: file-open: ino=%" PRId32 " share created\n", ino); } handle->flags = oflag; handle->shared = shared; *file = handle; return 0; }
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; }