sqfs_filesystem.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020 Bootlin
  4. *
  5. * Author: Joao Marcos Costa <joaomarcos.costa@bootlin.com>
  6. */
  7. #ifndef SQFS_FILESYSTEM_H
  8. #define SQFS_FILESYSTEM_H
  9. #include <asm/unaligned.h>
  10. #include <fs.h>
  11. #include <part.h>
  12. #include <stdint.h>
  13. #define SQFS_UNCOMPRESSED_DATA 0x0002
  14. #define SQFS_MAGIC_NUMBER 0x73717368
  15. /* The three first members of squashfs_dir_index make a total of 12 bytes */
  16. #define SQFS_DIR_INDEX_BASE_LENGTH 12
  17. /* size of metadata (inode and directory) blocks */
  18. #define SQFS_METADATA_BLOCK_SIZE 8192
  19. /* Max. number of fragment entries in a metadata block is 512 */
  20. #define SQFS_MAX_ENTRIES 512
  21. /* Metadata blocks start by a 2-byte length header */
  22. #define SQFS_HEADER_SIZE 2
  23. #define SQFS_LREG_INODE_MIN_SIZE 56
  24. #define SQFS_DIR_HEADER_SIZE 12
  25. #define SQFS_MISC_ENTRY_TYPE -1
  26. #define SQFS_EMPTY_FILE_SIZE 3
  27. #define SQFS_STOP_READDIR 1
  28. #define SQFS_EMPTY_DIR -1
  29. /*
  30. * A directory entry object has a fixed length of 8 bytes, corresponding to its
  31. * first four members, plus the size of the entry name, which is equal to
  32. * 'entry_name' + 1 bytes.
  33. */
  34. #define SQFS_ENTRY_BASE_LENGTH 8
  35. /* Inode types */
  36. #define SQFS_DIR_TYPE 1
  37. #define SQFS_REG_TYPE 2
  38. #define SQFS_SYMLINK_TYPE 3
  39. #define SQFS_BLKDEV_TYPE 4
  40. #define SQFS_CHRDEV_TYPE 5
  41. #define SQFS_FIFO_TYPE 6
  42. #define SQFS_SOCKET_TYPE 7
  43. #define SQFS_LDIR_TYPE 8
  44. #define SQFS_LREG_TYPE 9
  45. #define SQFS_LSYMLINK_TYPE 10
  46. #define SQFS_LBLKDEV_TYPE 11
  47. #define SQFS_LCHRDEV_TYPE 12
  48. #define SQFS_LFIFO_TYPE 13
  49. #define SQFS_LSOCKET_TYPE 14
  50. struct squashfs_super_block {
  51. __le32 s_magic;
  52. __le32 inodes;
  53. __le32 mkfs_time;
  54. __le32 block_size;
  55. __le32 fragments;
  56. __le16 compression;
  57. __le16 block_log;
  58. __le16 flags;
  59. __le16 no_ids;
  60. __le16 s_major;
  61. __le16 s_minor;
  62. __le64 root_inode;
  63. __le64 bytes_used;
  64. __le64 id_table_start;
  65. __le64 xattr_id_table_start;
  66. __le64 inode_table_start;
  67. __le64 directory_table_start;
  68. __le64 fragment_table_start;
  69. __le64 export_table_start;
  70. };
  71. struct squashfs_ctxt {
  72. struct disk_partition cur_part_info;
  73. struct blk_desc *cur_dev;
  74. struct squashfs_super_block *sblk;
  75. #if IS_ENABLED(CONFIG_ZSTD)
  76. void *zstd_workspace;
  77. #endif
  78. };
  79. struct squashfs_directory_index {
  80. u32 index;
  81. u32 start;
  82. u32 size;
  83. char name[0];
  84. };
  85. struct squashfs_base_inode {
  86. __le16 inode_type;
  87. __le16 mode;
  88. __le16 uid;
  89. __le16 guid;
  90. __le32 mtime;
  91. __le32 inode_number;
  92. };
  93. struct squashfs_ipc_inode {
  94. __le16 inode_type;
  95. __le16 mode;
  96. __le16 uid;
  97. __le16 guid;
  98. __le32 mtime;
  99. __le32 inode_number;
  100. __le32 nlink;
  101. };
  102. struct squashfs_lipc_inode {
  103. __le16 inode_type;
  104. __le16 mode;
  105. __le16 uid;
  106. __le16 guid;
  107. __le32 mtime;
  108. __le32 inode_number;
  109. __le32 nlink;
  110. __le32 xattr;
  111. };
  112. struct squashfs_dev_inode {
  113. __le16 inode_type;
  114. __le16 mode;
  115. __le16 uid;
  116. __le16 guid;
  117. __le32 mtime;
  118. __le32 inode_number;
  119. __le32 nlink;
  120. __le32 rdev;
  121. };
  122. struct squashfs_ldev_inode {
  123. __le16 inode_type;
  124. __le16 mode;
  125. __le16 uid;
  126. __le16 guid;
  127. __le32 mtime;
  128. __le32 inode_number;
  129. __le32 nlink;
  130. __le32 rdev;
  131. __le32 xattr;
  132. };
  133. struct squashfs_symlink_inode {
  134. __le16 inode_type;
  135. __le16 mode;
  136. __le16 uid;
  137. __le16 guid;
  138. __le32 mtime;
  139. __le32 inode_number;
  140. __le32 nlink;
  141. __le32 symlink_size;
  142. char symlink[0];
  143. };
  144. struct squashfs_reg_inode {
  145. __le16 inode_type;
  146. __le16 mode;
  147. __le16 uid;
  148. __le16 guid;
  149. __le32 mtime;
  150. __le32 inode_number;
  151. __le32 start_block;
  152. __le32 fragment;
  153. __le32 offset;
  154. __le32 file_size;
  155. __le32 block_list[0];
  156. };
  157. struct squashfs_lreg_inode {
  158. __le16 inode_type;
  159. __le16 mode;
  160. __le16 uid;
  161. __le16 guid;
  162. __le32 mtime;
  163. __le32 inode_number;
  164. __le64 start_block;
  165. __le64 file_size;
  166. __le64 sparse;
  167. __le32 nlink;
  168. __le32 fragment;
  169. __le32 offset;
  170. __le32 xattr;
  171. __le32 block_list[0];
  172. };
  173. struct squashfs_dir_inode {
  174. __le16 inode_type;
  175. __le16 mode;
  176. __le16 uid;
  177. __le16 guid;
  178. __le32 mtime;
  179. __le32 inode_number;
  180. __le32 start_block;
  181. __le32 nlink;
  182. __le16 file_size;
  183. __le16 offset;
  184. __le32 parent_inode;
  185. };
  186. struct squashfs_ldir_inode {
  187. __le16 inode_type;
  188. __le16 mode;
  189. __le16 uid;
  190. __le16 guid;
  191. __le32 mtime;
  192. __le32 inode_number;
  193. __le32 nlink;
  194. __le32 file_size;
  195. __le32 start_block;
  196. __le32 parent_inode;
  197. __le16 i_count;
  198. __le16 offset;
  199. __le32 xattr;
  200. struct squashfs_directory_index index[0];
  201. };
  202. union squashfs_inode {
  203. struct squashfs_base_inode *base;
  204. struct squashfs_dev_inode *dev;
  205. struct squashfs_ldev_inode *ldev;
  206. struct squashfs_symlink_inode *symlink;
  207. struct squashfs_reg_inode *reg;
  208. struct squashfs_lreg_inode *lreg;
  209. struct squashfs_dir_inode *dir;
  210. struct squashfs_ldir_inode *ldir;
  211. struct squashfs_ipc_inode *ipc;
  212. struct squashfs_lipc_inode *lipc;
  213. };
  214. struct squashfs_directory_entry {
  215. u16 offset;
  216. s16 inode_offset;
  217. u16 type;
  218. u16 name_size;
  219. char name[0];
  220. };
  221. struct squashfs_directory_header {
  222. u32 count;
  223. u32 start;
  224. u32 inode_number;
  225. };
  226. struct squashfs_fragment_block_entry {
  227. u64 start;
  228. u32 size;
  229. u32 _unused;
  230. };
  231. struct squashfs_dir_stream {
  232. struct fs_dir_stream fs_dirs;
  233. struct fs_dirent dentp;
  234. /*
  235. * 'size' is the uncompressed size of the entire listing, including
  236. * headers. 'entry_count' is the number of entries following a
  237. * specific header. Both variables are decremented in sqfs_readdir() so
  238. * the function knows when the end of the directory is reached.
  239. */
  240. size_t size;
  241. int entry_count;
  242. /* SquashFS structures */
  243. struct squashfs_directory_header *dir_header;
  244. struct squashfs_directory_entry *entry;
  245. /*
  246. * 'table' points to a position into the directory table. Both 'table'
  247. * and 'inode' are defined for the first time in sqfs_opendir().
  248. * 'table's value changes in sqfs_readdir().
  249. */
  250. unsigned char *table;
  251. union squashfs_inode i;
  252. struct squashfs_dir_inode i_dir;
  253. struct squashfs_ldir_inode i_ldir;
  254. /*
  255. * References to the tables' beginnings. They are assigned in
  256. * sqfs_opendir() and freed in sqfs_closedir().
  257. */
  258. unsigned char *inode_table;
  259. unsigned char *dir_table;
  260. };
  261. struct squashfs_file_info {
  262. /* File size in bytes (uncompressed) */
  263. size_t size;
  264. /* Reference to list of data blocks's sizes */
  265. u32 *blk_sizes;
  266. /* Offset into the fragment block */
  267. u32 offset;
  268. /* Offset in which the data blocks begin */
  269. u64 start;
  270. /* Is file fragmented? */
  271. bool frag;
  272. /* Compressed fragment */
  273. bool comp;
  274. };
  275. void *sqfs_find_inode(void *inode_table, int inode_number, __le32 inode_count,
  276. __le32 block_size);
  277. int sqfs_dir_offset(void *dir_i, u32 *m_list, int m_count);
  278. int sqfs_read_metablock(unsigned char *file_mapping, int offset,
  279. bool *compressed, u32 *data_size);
  280. bool sqfs_is_empty_dir(void *dir_i);
  281. bool sqfs_is_dir(u16 type);
  282. #endif /* SQFS_FILESYSTEM_H */