int rtems_rfs_file_open (rtems_rfs_file_system* fs, rtems_rfs_ino ino, uint32_t flags, 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 = flags; handle->shared = shared; *file = handle; return 0; }
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 = 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; }