int rtems_rfs_link (rtems_rfs_file_system* fs, const char* name, int length, rtems_rfs_ino parent, rtems_rfs_ino target, bool link_dir) { rtems_rfs_inode_handle parent_inode; rtems_rfs_inode_handle target_inode; uint16_t links; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_LINK)) { int c; printf ("rtems-rfs: link: parent(%" PRIu32 ") -> ", parent); for (c = 0; c < length; c++) printf ("%c", name[c]); printf ("(%" PRIu32 ")\n", target); } rc = rtems_rfs_inode_open (fs, target, &target_inode, true); if (rc) return rc; /* * If the target inode is a directory and we cannot link directories * return a not supported error code. */ if (!link_dir && S_ISDIR (rtems_rfs_inode_get_mode (&target_inode))) { rtems_rfs_inode_close (fs, &target_inode); return ENOTSUP; } rc = rtems_rfs_inode_open (fs, parent, &parent_inode, true); if (rc) { rtems_rfs_inode_close (fs, &target_inode); return rc; } rc = rtems_rfs_dir_add_entry (fs, &parent_inode, name, length, target); if (rc > 0) { rtems_rfs_inode_close (fs, &parent_inode); rtems_rfs_inode_close (fs, &target_inode); return rc; } links = rtems_rfs_inode_get_links (&target_inode) + 1; rtems_rfs_inode_set_links (&target_inode, links); rc = rtems_rfs_inode_time_stamp_now (&parent_inode, true, true); if (rc > 0) { rtems_rfs_inode_close (fs, &parent_inode); rtems_rfs_inode_close (fs, &target_inode); return rc; } rc = rtems_rfs_inode_close (fs, &parent_inode); if (rc > 0) { rtems_rfs_inode_close (fs, &target_inode); return rc; } rc = rtems_rfs_inode_close (fs, &target_inode); return rc; }
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; }
static int rtems_rfs_write_root_dir (const char* name) { rtems_rfs_file_system* fs; rtems_rfs_inode_handle inode; rtems_rfs_ino ino; int rc; /* * External API so returns -1. */ rc = rtems_rfs_fs_open (name, NULL, RTEMS_RFS_FS_FORCE_OPEN, &fs); if (rc < 0) { printf ("rtems-rfs: format: file system open failed: %d: %s\n", errno, strerror (errno)); return -1; } rc = rtems_rfs_inode_alloc (fs, RTEMS_RFS_ROOT_INO, &ino); if (rc > 0) { printf ("rtems-rfs: format: inode allocation failed: %d: %s\n", rc, strerror (rc)); rtems_rfs_fs_close (fs); return rc; } if (ino != RTEMS_RFS_ROOT_INO) { printf ("rtems-rfs: format: allocated inode not root ino: %" PRId32 "\n", ino); rtems_rfs_fs_close (fs); return rc; } rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { printf ("rtems-rfs: format: inode open failed: %d: %s\n", rc, strerror (rc)); rtems_rfs_group_bitmap_free (fs, true, ino); rtems_rfs_fs_close (fs); return rc; } rc = rtems_rfs_inode_initialise (&inode, 0, (RTEMS_RFS_S_IFDIR | RTEMS_RFS_S_IRWXU | RTEMS_RFS_S_IXGRP | RTEMS_RFS_S_IXOTH), 0, 0); if (rc > 0) printf ("rtems-rfs: format: inode initialise failed: %d: %s\n", rc, strerror (rc)); rc = rtems_rfs_dir_add_entry (fs, &inode, ".", 1, ino); if (rc > 0) printf ("rtems-rfs: format: directory add failed: %d: %s\n", rc, strerror (rc)); rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) printf ("rtems-rfs: format: inode close failed: %d: %s\n", rc, strerror (rc)); rc = rtems_rfs_fs_close (fs); if (rc < 0) printf ("rtems-rfs: format: file system close failed: %d: %s\n", errno, strerror (errno)); return rc; }