Implement support for block and char dev nodes, fifos and sockets.
authorJo-Philipp Wich <jow@openwrt.org>
Sat, 4 Apr 2015 21:01:57 +0000 (23:01 +0200)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 8 Apr 2015 05:51:27 +0000 (07:51 +0200)
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
contents.c
contents.h
make_ext4fs.c

index 3144de93f4de1ae8f84f3ab2df625ed099ac33e6..bfdb657528712f52e14c85ee1074a8c5d64010fa 100644 (file)
@@ -244,6 +244,40 @@ u32 make_link(const char *link)
        return inode_num;
 }
 
+/* Creates a special file on disk.  Returns the inode number of the new file */
+u32 make_special(const char *path)
+{
+       struct ext4_inode *inode;
+       struct stat s;
+       u32 inode_num;
+
+       if (stat(path, &s)) {
+               error("failed to stat file\n");
+               return EXT4_ALLOCATE_FAILED;
+       }
+
+       inode_num = allocate_inode(info);
+       if (inode_num == EXT4_ALLOCATE_FAILED) {
+               error("failed to allocate inode\n");
+               return EXT4_ALLOCATE_FAILED;
+       }
+
+       inode = get_inode(inode_num);
+       if (inode == NULL) {
+               error("failed to get inode %u", inode_num);
+               return EXT4_ALLOCATE_FAILED;
+       }
+
+       inode->i_mode = s.st_mode & S_IFMT;
+       inode->i_links_count = 1;
+       inode->i_flags |= aux_info.default_i_flags;
+
+       ((u8 *)inode->i_block)[0] = major(s.st_rdev);
+       ((u8 *)inode->i_block)[1] = minor(s.st_rdev);
+
+       return inode_num;
+}
+
 int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime)
 {
        struct ext4_inode *inode = get_inode(inode_num);
index e57687e0af89821e7c9cdcf5670bc80fc9363434..d4f14a683ae414e4d3fec59a4c3c4a8d6aa32023 100644 (file)
@@ -37,6 +37,7 @@ u32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries,
        u32 dirs);
 u32 make_file(const char *filename, u64 len);
 u32 make_link(const char *link);
+u32 make_special(const char *path);
 int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime);
 int inode_set_selinux(u32 inode_num, const char *secon);
 int inode_set_capabilities(u32 inode_num, uint64_t capabilities);
index fa04263cb00640e3fb07ee29e548d9ee76d4c26c..3623426d03e6e653a95cad759ba77685e1ca1737 100644 (file)
@@ -44,7 +44,6 @@
 /* TODO: Not implemented:
    Allocating blocks in the same block group as the file inode
    Hash or binary tree directories
-   Special files: sockets, devices, fifos
  */
 
 static int filter_dot(const struct dirent *d)
@@ -235,6 +234,11 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path
                        free(subdir_dir_path);
                } else if (dentries[i].file_type == EXT4_FT_SYMLINK) {
                        entry_inode = make_link(dentries[i].link);
+               } else if (dentries[i].file_type == EXT4_FT_CHRDEV ||
+                          dentries[i].file_type == EXT4_FT_BLKDEV ||
+                          dentries[i].file_type == EXT4_FT_SOCK ||
+                          dentries[i].file_type == EXT4_FT_FIFO) {
+                       entry_inode = make_special(dentries[i].full_path);
                } else {
                        error("unknown file type on %s", dentries[i].path);
                        entry_inode = 0;