/** * Get the file system data from the specific path. Checks to make sure the path is * pointing to a valid RFS file system. */ static int rtems_rfs_get_fs (const char* path, rtems_rfs_file_system** fs) { struct statvfs sb; int rc; rc = statvfs (path, &sb); if (rc < 0) { printf ("error: cannot statvfs path: %s: (%d) %s\n", path, errno, strerror (errno)); return -1; } if (sb.f_fsid != RTEMS_RFS_SB_MAGIC) { printf ("error: path '%s' is not on an RFS file system\n", path); return -1; } #if __rtems__ /* * Now find the path location on the file system. This will give the file * system data. */ { rtems_filesystem_location_info_t pathloc; rc = rtems_filesystem_evaluate_path (path, strlen (path), 0, &pathloc, true); *fs = rtems_rfs_rtems_pathloc_dev (&pathloc); rtems_filesystem_freenode (&pathloc); } #endif return rc; }
static void rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc (ctx); rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc); rtems_rfs_inode_handle inode; int rc; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc == 0) { rtems_filesystem_eval_path_generic ( ctx, &inode, &rtems_rfs_rtems_eval_config ); rc = rtems_rfs_inode_close (fs, &inode); if (rc != 0) { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: closing inode", rc) ); } } else { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: opening inode", rc) ); } }
static int rtems_rfs_rtems_utime(const rtems_filesystem_location_info_t* pathloc, time_t atime, time_t mtime) { 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; int rc; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { return rtems_rfs_rtems_error ("utime: read inode", rc); } rtems_rfs_inode_set_atime (&inode, atime); rtems_rfs_inode_set_mtime (&inode, mtime); rc = rtems_rfs_inode_close (fs, &inode); if (rc) { return rtems_rfs_rtems_error ("utime: closing inode", rc); } return 0; }
static rtems_filesystem_node_types_t rtems_rfs_rtems_node_type (const rtems_filesystem_location_info_t* pathloc) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); rtems_filesystem_node_types_t type; rtems_rfs_inode_handle inode; int rc; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { return rtems_rfs_rtems_error ("node_type: opening inode", rc); } type = rtems_rfs_rtems_node_type_by_inode (&inode); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("node_type: closing inode", rc); } return type; }
/** * This rountine will verify that the node being opened as a directory is in * fact a directory node. If it is then the offset into the directory will be * set to 0 to position to the first directory entry. */ static int rtems_rfs_rtems_dir_open (rtems_libio_t* iop, const char* pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_open: opening inode", rc); } if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode))) { rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR); } iop->offset = 0; rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return 0; }
static int rtems_rfs_rtems_dir_rmnod (rtems_filesystem_location_info_t* parent_pathloc, rtems_filesystem_location_info_t* pathloc) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); uint32_t doff = rtems_rfs_rtems_get_pathloc_doff (pathloc); int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_DIR_RMNOD)) printf ("rtems-rfs: dir-rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n", parent, doff, ino); if (ino == RTEMS_RFS_ROOT_INO) return rtems_rfs_rtems_error ("dir_rmnod: root inode", EBUSY); rtems_rfs_rtems_lock (fs); rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty); if (rc) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_rmnod: unlinking", rc); } rtems_rfs_rtems_unlock (fs); return 0; }
static int rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc, mode_t mode) { 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; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD)) printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n", ino, mode); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { return rtems_rfs_rtems_error ("fchmod: opening inode", rc); } rtems_rfs_inode_set_mode (&inode, mode); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("fchmod: closing inode", rc); } return 0; }
static int rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc, const char *name, size_t namelen, mode_t mode, dev_t dev) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parentloc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc); rtems_rfs_ino ino; rtems_rfs_inode_handle inode; uid_t uid; gid_t gid; int rc; uid = geteuid (); gid = getegid (); rc = rtems_rfs_inode_create (fs, parent, name, namelen, rtems_rfs_rtems_imode (mode), 1, uid, gid, &ino); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: inode create", rc); } rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: inode open", rc); } if (S_ISDIR(mode) || S_ISREG(mode)) { } else if (S_ISCHR (mode) || S_ISBLK (mode)) { int major; int minor; rtems_filesystem_split_dev_t (dev, major, minor); rtems_rfs_inode_set_block (&inode, 0, major); rtems_rfs_inode_set_block (&inode, 1, minor); } else { rtems_rfs_inode_close (fs, &inode); return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL); } rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("mknod: closing inode", rc); } return 0; }
/** * The following routine does a sync on an inode node. Currently it flushes * everything related to this device. * * @param iop * @return int */ int rtems_rfs_rtems_fdatasync (rtems_libio_t* iop) { int rc; rc = rtems_rfs_buffer_sync (rtems_rfs_rtems_pathloc_dev (&iop->pathinfo)); if (rc) return rtems_rfs_rtems_error ("fdatasync: sync", rc); return 0; }
static int rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc, mode_t mode) { 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; uint16_t imode; #if defined (RTEMS_POSIX_API) uid_t uid; #endif int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD)) printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n", ino, mode); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { return rtems_rfs_rtems_error ("fchmod: opening inode", rc); } imode = rtems_rfs_inode_get_mode (&inode); /* * Verify I am the owner of the node or the super user. */ #if defined (RTEMS_POSIX_API) uid = geteuid(); if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0)) { rtems_rfs_inode_close (fs, &inode); return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM); } #endif imode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); imode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); rtems_rfs_inode_set_mode (&inode, imode); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { return rtems_rfs_rtems_error ("fchmod: closing inode", rc); } return 0; }
/** * This routine will read the next directory entry based on the directory * offset. The offset should be equal to -n- time the size of an individual * dirent structure. If n is not an integer multiple of the sizeof a dirent * structure, an integer division will be performed to determine directory * entry that will be returned in the buffer. Count should reflect -m- times * the sizeof dirent bytes to be placed in the buffer. If there are not -m- * dirent elements from the current directory position to the end of the * exisiting file, the remaining entries will be placed in the buffer and the * returned value will be equal to -m actual- times the size of a directory * entry. */ static ssize_t rtems_rfs_rtems_dir_read (rtems_libio_t* iop, void* buffer, size_t count) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; struct dirent* dirent; ssize_t bytes_transferred; int d; int rc; count = count / sizeof (struct dirent); dirent = buffer; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("dir_read: read inode", rc); } bytes_transferred = 0; for (d = 0; d < count; d++, dirent++) { size_t size; rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size); if (rc == ENOENT) { rc = 0; break; } if (rc > 0) { bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc); break; } iop->offset += size; bytes_transferred += sizeof (struct dirent); } rtems_rfs_inode_close (fs, &inode); rtems_rfs_rtems_unlock (fs); return bytes_transferred; }
/** * This handler maps an open() operation onto rtems_io_open(). * * @param iop * @param pathname * @param flag * @param mode * @return int */ static int rtems_rfs_rtems_device_open ( rtems_libio_t *iop, const char *pathname, uint32_t flag, uint32_t mode) { rtems_libio_open_close_args_t args; rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; int major; int minor; rtems_status_code status; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: opening inode", rc); } major = rtems_rfs_inode_get_block (&inode, 0); minor = rtems_rfs_inode_get_block (&inode, 1); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: closing inode", rc); } rtems_rfs_rtems_unlock (fs); iop->data0 = major; iop->data1 = (void*)((intptr_t) minor); args.iop = iop; args.flags = iop->flags; args.mode = mode; status = rtems_io_open (major, minor, (void *) &args); if (status) return rtems_deviceio_errno(status); return 0; }
/** * Rename the node. */ static int rtems_rfs_rtems_rename(const rtems_filesystem_location_info_t* old_parent_loc, const rtems_filesystem_location_info_t* old_loc, const rtems_filesystem_location_info_t* new_parent_loc, const char* new_name, size_t new_name_len) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (old_loc); rtems_rfs_ino old_parent; rtems_rfs_ino new_parent; rtems_rfs_ino ino; uint32_t doff; int rc; old_parent = rtems_rfs_rtems_get_pathloc_ino (old_parent_loc); new_parent = rtems_rfs_rtems_get_pathloc_ino (new_parent_loc); ino = rtems_rfs_rtems_get_pathloc_ino (old_loc); doff = rtems_rfs_rtems_get_pathloc_doff (old_loc); if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RENAME)) printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 "\n", ino, doff, new_parent); /* * Link to the inode before unlinking so the inode is not erased when * unlinked. */ rc = rtems_rfs_link (fs, new_name, new_name_len, new_parent, ino, true); if (rc) { return rtems_rfs_rtems_error ("rename: linking", rc); } /* * Unlink all inodes even directories with the dir option as false because a * directory may not be empty. */ rc = rtems_rfs_unlink (fs, old_parent, ino, doff, rtems_rfs_unlink_dir_allowed); if (rc) { return rtems_rfs_rtems_error ("rename: unlinking", rc); } return 0; }
static int rtems_rfs_rtems_chown (const rtems_filesystem_location_info_t *pathloc, uid_t owner, gid_t group) { 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; #if defined (RTEMS_POSIX_API) uid_t uid; #endif int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_CHOWN)) printf ("rtems-rfs-rtems: chown: in: ino:%" PRId32 " uid:%d gid:%d\n", ino, owner, group); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { return rtems_rfs_rtems_error ("chown: opening inode", rc); } /* * Verify I am the owner of the node or the super user. */ #if defined (RTEMS_POSIX_API) uid = geteuid(); if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0)) { rtems_rfs_inode_close (fs, &inode); return rtems_rfs_rtems_error ("chown: not able", EPERM); } #endif rtems_rfs_inode_set_uid_gid (&inode, owner, group); rc = rtems_rfs_inode_close (fs, &inode); if (rc) { return rtems_rfs_rtems_error ("chown: closing inode", rc); } return 0; }
static int rtems_rfs_rtems_symlink (const rtems_filesystem_location_info_t* parent_loc, const char* node_name, size_t node_name_len, const char* target) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc); int rc; rc = rtems_rfs_symlink (fs, node_name, node_name_len, target, strlen (target), geteuid(), getegid(), parent); if (rc) { return rtems_rfs_rtems_error ("symlink: linking", rc); } return 0; }
static ssize_t rtems_rfs_rtems_readlink (const rtems_filesystem_location_info_t* pathloc, char* buf, size_t bufsize) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); size_t length; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_READLINK)) printf ("rtems-rfs-rtems: readlink: in: ino:%" PRId32 "\n", ino); rc = rtems_rfs_symlink_read (fs, ino, buf, bufsize, &length); if (rc) { return rtems_rfs_rtems_error ("readlink: reading link", rc); } return (ssize_t) length; }
/** * Routine to remove a node from the RFS file system. * * @param parent_pathloc * @param pathloc * @return int */ int rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc, const rtems_filesystem_location_info_t* pathloc) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc); uint32_t doff = rtems_rfs_rtems_get_pathloc_doff (pathloc); int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RMNOD)) printf ("rtems-rfs: rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n", parent, doff, ino); rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty); if (rc) { return rtems_rfs_rtems_error ("rmnod: unlinking", rc); } return 0; }
/** * This handler maps an open() operation onto rtems_io_open(). * * @param iop * @param pathname * @param flag * @param mode * @return int */ static int rtems_rfs_rtems_device_open ( rtems_libio_t *iop, const char *pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop); rtems_rfs_inode_handle inode; rtems_device_major_number major; rtems_device_minor_number minor; int rc; rtems_rfs_rtems_lock (fs); rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: opening inode", rc); } major = rtems_rfs_inode_get_block (&inode, 0); minor = rtems_rfs_inode_get_block (&inode, 1); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("device_open: closing inode", rc); } rtems_rfs_rtems_unlock (fs); iop->data0 = major; iop->data1 = (void *) (uintptr_t) minor; return rtems_deviceio_open (iop, pathname, oflag, mode, minor, major); }
static int rtems_rfs_rtems_file_open (rtems_libio_t* iop, const char* pathname, int oflag, mode_t mode) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo); rtems_rfs_ino ino; rtems_rfs_file_handle* file; int flags; int rc; flags = 0; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN)) printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04i mode:%04" PRIu32 "\n", pathname, ino, flags, mode); rtems_rfs_rtems_lock (fs); ino = rtems_rfs_rtems_get_iop_ino (iop); rc = rtems_rfs_file_open (fs, ino, flags, &file); if (rc > 0) { rtems_rfs_rtems_unlock (fs); return rtems_rfs_rtems_error ("file-open: open", rc); } if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN)) printf("rtems-rfs: file-open: handle:%p\n", file); iop->size = rtems_rfs_file_size (file); rtems_rfs_rtems_set_iop_file_handle (iop, file); rtems_rfs_rtems_unlock (fs); return 0; }
/** * Get the file system data from the specific path. Checks to make sure the path is * pointing to a valid RFS file system. */ static int rtems_rfs_get_fs (const char* path, rtems_rfs_file_system** fs) { struct statvfs sb; int rc; rc = statvfs (path, &sb); if (rc < 0) { printf ("error: cannot statvfs path: %s: (%d) %s\n", path, errno, strerror (errno)); return -1; } if (sb.f_fsid != RTEMS_RFS_SB_MAGIC) { printf ("error: path '%s' is not on an RFS file system\n", path); return -1; } #if __rtems__ /* * Now find the path location on the file system. This will give the file * system data. */ { rtems_filesystem_eval_path_context_t ctx; int eval_flags = RTEMS_FS_FOLLOW_LINK; const rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_start (&ctx, path, eval_flags); *fs = rtems_rfs_rtems_pathloc_dev (currentloc); rtems_filesystem_eval_path_cleanup (&ctx); } #endif return rc; }
/** * The following rouine creates a new link node under parent with the name * given in name. The link node is set to point to the node at targetloc. */ static int rtems_rfs_rtems_link (const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *targetloc, const char *name, size_t namelen) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (targetloc); rtems_rfs_ino target = rtems_rfs_rtems_get_pathloc_ino (targetloc); rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc); int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_LINK)) printf ("rtems-rfs-rtems: link: in: parent:%" PRId32 " target:%" PRId32 "\n", parent, target); rc = rtems_rfs_link (fs, name, namelen, parent, target, false); if (rc) { return rtems_rfs_rtems_error ("link: linking", rc); } return 0; }
/** * Return the file system stat data. * * @param pathloc * @param sb * @return int */ static int rtems_rfs_rtems_statvfs (const rtems_filesystem_location_info_t* pathloc, struct statvfs* sb) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); size_t blocks; size_t inodes; rtems_rfs_group_usage (fs, &blocks, &inodes); sb->f_bsize = rtems_rfs_fs_block_size (fs); sb->f_frsize = rtems_rfs_fs_media_block_size (fs); sb->f_blocks = rtems_rfs_fs_media_blocks (fs); sb->f_bfree = rtems_rfs_fs_blocks (fs) - blocks; sb->f_bavail = sb->f_bfree; sb->f_files = rtems_rfs_fs_inodes (fs); sb->f_ffree = rtems_rfs_fs_inodes (fs) - inodes; sb->f_favail = sb->f_ffree; sb->f_fsid = RTEMS_RFS_SB_MAGIC; sb->f_flag = rtems_rfs_fs_flags (fs); sb->f_namemax = rtems_rfs_fs_max_name (fs); return 0; }
return 0; } /** * Return the file system stat data. * * @param pathloc * @param sb * @return int */ static int rtems_rfs_rtems_statvfs ( const rtems_filesystem_location_info_t *__restrict pathloc, struct statvfs *__restrict sb) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); size_t blocks; size_t inodes; rtems_rfs_group_usage (fs, &blocks, &inodes); sb->f_bsize = rtems_rfs_fs_block_size (fs); sb->f_frsize = rtems_rfs_fs_media_block_size (fs); sb->f_blocks = rtems_rfs_fs_media_blocks (fs); sb->f_bfree = rtems_rfs_fs_blocks (fs) - blocks - 1; /* do not count the superblock */ sb->f_bavail = sb->f_bfree; sb->f_files = rtems_rfs_fs_inodes (fs); sb->f_ffree = rtems_rfs_fs_inodes (fs) - inodes; sb->f_favail = sb->f_ffree; sb->f_fsid = RTEMS_RFS_SB_MAGIC; sb->f_flag = rtems_rfs_fs_flags (fs);
static rtems_filesystem_eval_path_generic_status rtems_rfs_rtems_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_rfs_inode_handle* inode = arg; bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_FS_PERMS_EXEC, inode); if (access_ok) { if (rtems_filesystem_is_current_directory (token, tokenlen)) { rtems_filesystem_eval_path_clear_token (ctx); } else { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); rtems_rfs_ino entry_ino; uint32_t entry_doff; int rc = rtems_rfs_dir_lookup_ino ( fs, inode, token, tokenlen, &entry_ino, &entry_doff ); if (rc == 0) { rc = rtems_rfs_inode_close (fs, inode); if (rc == 0) { rc = rtems_rfs_inode_open (fs, entry_ino, inode, true); } if (rc != 0) { /* * This prevents the rtems_rfs_inode_close() from doing something in * rtems_rfs_rtems_eval_path(). */ memset (inode, 0, sizeof(*inode)); } } else { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; rc = -1; } if (rc == 0) { bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode) == RTEMS_FILESYSTEM_SYM_LINK; int eval_flags = rtems_filesystem_eval_path_get_flags (ctx); bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0; bool terminal = !rtems_filesystem_eval_path_has_path (ctx); rtems_filesystem_eval_path_clear_token (ctx); if (is_sym_link && (follow_sym_link || !terminal)) { rtems_rfs_rtems_follow_link (ctx, fs, entry_ino); } else { rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO; if (rc == 0) { rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino); rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff); if (!terminal) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } else { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: set handlers", rc) ); } } } } } return status; }
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; }