/filesystems/unixfs/sysvfs/sysvfs.h

http://macfuse.googlecode.com/ · C Header · 328 lines · 248 code · 43 blank · 37 comment · 8 complexity · 33321553868b1fafdb20a713f1550bc0 MD5 · raw file

  1. /*
  2. * SYSV File System Famiy for MacFUSE
  3. * Amit Singh
  4. * http://osxbook.com
  5. *
  6. * Most of the code in this file comes from the Linux kernel implementation
  7. * of sysvfs. See fs/sysv/ in the Linux kernel source tree.
  8. *
  9. * The code is Copyright (c) its various authors. It is covered by the
  10. * GNU GENERAL PUBLIC LICENSE Version 2.
  11. */
  12. #ifndef _SYSVFS_H_
  13. #define _SYSVFS_H_
  14. #include "unixfs_internal.h"
  15. #include "linux.h"
  16. #include <stdio.h>
  17. #include <sys/types.h>
  18. #include <stdint.h>
  19. #include <sys/time.h>
  20. #include <sys/errno.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <string.h>
  24. /* Heuristic timestamp used to distinguish between SVR4 and SVR2 */
  25. enum {
  26. JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60
  27. };
  28. typedef __fs16 sysv_ino_t; /* inode numbers are 16 bit */
  29. typedef __fs32 sysv_zone_t; /* block numbers are 24 bit */
  30. #define SYSV_INVAL_INO 0 /* inode 0 does not exist */
  31. #define SYSV_BADBL_INO 1 /* inode of bad blocks file */
  32. #define SYSV_ROOT_INO 2 /* inode of root directory */
  33. struct sysv_dinode { /* on disk */
  34. __fs16 di_mode;
  35. __fs16 di_nlink;
  36. __fs16 di_uid;
  37. __fs16 di_gid;
  38. __fs32 di_size;
  39. u8 di_data[3 * (10 + 1 + 1 + 1)];
  40. u8 di_gen;
  41. __fs32 di_atime;
  42. __fs32 di_mtime;
  43. __fs32 di_ctime;
  44. };
  45. struct sysv_inode_info { /* in memory */
  46. __fs32 i_data[13];
  47. u32 i_dir_start_lookup;
  48. };
  49. static inline struct sysv_inode_info*
  50. SYSV_I(struct inode* inode)
  51. {
  52. return (struct sysv_inode_info*)&(inode[1]);
  53. }
  54. #define SYSV_NAMELEN 14
  55. struct sysv_dir_entry { /* on disk */
  56. sysv_ino_t inode;
  57. char name[SYSV_NAMELEN];
  58. };
  59. #define SYSV_DIRSIZE sizeof(struct sysv_dir_entry)
  60. static inline int
  61. sysv_namecompare(int len, int maxlen, const char* name, const char* buffer)
  62. {
  63. if (len < maxlen && buffer[len])
  64. return 0;
  65. return !memcmp(name, buffer, len);
  66. }
  67. static inline unsigned long
  68. sysv_dir_pages(struct inode* inode)
  69. {
  70. return (inode->I_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  71. }
  72. struct sysv_sb_info { /* in memory */
  73. struct super_block* s_sb; /* VFS superblock */
  74. int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */
  75. char s_bytesex; /* bytesex (le/be/pdp) */
  76. char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */
  77. /* if 0: they are disallowed (ENAMETOOLONG) */
  78. nlink_t s_link_max; /* max # of hard links to a file */
  79. unsigned int s_inodes_per_block; /* # of inodes per block */
  80. unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */
  81. unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */
  82. unsigned int s_ind_per_block; /* # of indirections per block */
  83. unsigned int s_ind_per_block_bits; /* log2(ind_per_block) */
  84. unsigned int s_ind_per_block_2; /* ind_per_block ^ 2 */
  85. unsigned int s_toobig_block; /* 10 + ipb + ipb^2 + ipb^3 */
  86. unsigned int s_block_base; /* physical block # of block 0 */
  87. unsigned short s_fic_size; /* free inode cache size, NICINOD */
  88. unsigned short s_flc_size; /* free block list chunk size, NICFREE */
  89. struct buffer_head* s_bh1; /* disk buffer 1 for holding superblock */
  90. struct buffer_head* s_bh2; /* disk buffer 2 for holding superblock */
  91. char* s_sbd1; /* entire superblock data, part 1 */
  92. char* s_sbd2; /* entire superblock data, part 2 */
  93. __fs16* s_sb_fic_count; /* pointer to s_sbd->s_ninode */
  94. sysv_ino_t* s_sb_fic_inodes; /* pointer to s_sbd->s_inode */
  95. __fs16* s_sb_total_free_inodes; /* pointer to s_sbd->s_tinode */
  96. __fs16* s_bcache_count; /* pointer to s_sbd->s_nfree */
  97. sysv_zone_t* s_bcache; /* pointer to s_sbd->s_free */
  98. __fs32* s_free_blocks; /* pointer to s_sbd->s_tfree */
  99. __fs32* s_sb_time; /* pointer to s_sbd->s_time */
  100. __fs32* s_sb_state; /* pointer to s_sbd->s_state, only FSTYPE_SYSV */
  101. /* The following superblock entities don't change. */
  102. u32 s_firstinodezone; /* index of first inode zone */
  103. u32 s_firstdatazone; /* same as s_sbd->s_isize */
  104. u32 s_ninodes; /* total number of inodes */
  105. u32 s_ndatazones; /* total number of data zones */
  106. u32 s_nzones; /* same as s_sbd->s_fsize */
  107. u16 s_namelen; /* max length of dir entry */
  108. int s_forced_ro;
  109. };
  110. static inline struct sysv_sb_info*
  111. SYSV_SB(struct super_block* sb)
  112. {
  113. return (struct sysv_sb_info*)sb->s_fs_info;
  114. }
  115. static inline void
  116. sysv_read3byte(struct sysv_sb_info* sbi, unsigned char* from, unsigned char* to)
  117. {
  118. if (sbi->s_bytesex == UNIXFS_FS_PDP) {
  119. to[0] = from[0];
  120. to[1] = 0;
  121. to[2] = from[1];
  122. to[3] = from[2];
  123. } else if (sbi->s_bytesex == UNIXFS_FS_LITTLE) {
  124. to[0] = from[0];
  125. to[1] = from[1];
  126. to[2] = from[2];
  127. to[3] = 0;
  128. } else {
  129. to[0] = 0;
  130. to[1] = from[0];
  131. to[2] = from[1];
  132. to[3] = from[2];
  133. }
  134. }
  135. /* in-memory file system type identifiers */
  136. enum {
  137. FSTYPE_NONE = 0,
  138. FSTYPE_XENIX,
  139. FSTYPE_SYSV4,
  140. FSTYPE_SYSV2,
  141. FSTYPE_COH,
  142. FSTYPE_V7,
  143. FSTYPE_AFS,
  144. FSTYPE_END,
  145. };
  146. #define SYSV_MAGIC_BASE 0x012FF7B3
  147. #define XENIX_SUPER_MAGIC (SYSV_MAGIC_BASE + FSTYPE_XENIX)
  148. #define SYSV4_SUPER_MAGIC (SYSV_MAGIC_BASE + FSTYPE_SYSV4)
  149. #define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE + FSTYPE_SYSV2)
  150. #define COH_SUPER_MAGIC (SYSV_MAGIC_BASE + FSTYPE_COH)
  151. /* admissible values for i_nlink: 0.._LINK_MAX */
  152. enum {
  153. XENIX_LINK_MAX = 126, /* ?? */
  154. SYSV_LINK_MAX = 126, /* 127? 251? */
  155. V7_LINK_MAX = 126, /* ?? */
  156. COH_LINK_MAX = 10000,
  157. };
  158. /*
  159. * Xenix
  160. */
  161. #define XENIX_NICINOD 100 /* number of inode cache entries */
  162. #define XENIX_NICFREE 100 /* number of free block list chunk entries */
  163. struct xenix_super_block { /* on disk */
  164. __fs16 s_isize; /* index of first data zone */
  165. __fs32 s_fsize __packed2__; /* total number of zones of this fs */
  166. __fs16 s_nfree; /* # of free blocks in s_free, <= XENIX_NICFREE */
  167. sysv_zone_t s_free[XENIX_NICFREE]; /* first free block list chunk */
  168. __fs16 s_ninode; /* # of free inodes in s_inode, <= XENIX_NICINOD */
  169. sysv_ino_t s_inode[XENIX_NICINOD]; /* some free inodes */
  170. char s_flock; /* lock during free block list manipulation */
  171. char s_ilock; /* lock during inode cache manipulation */
  172. char s_fmod; /* super-block modified flag */
  173. char s_ronly; /* flag whether fs is mounted read-only */
  174. __fs32 s_time __packed2__; /* time of last super block update */
  175. __fs32 s_tfree __packed2__; /* total number of free zones */
  176. __fs16 s_tinode; /* total number of free inodes */
  177. __fs16 s_dinfo[4]; /* device information ?? */
  178. char s_fname[6]; /* file system volume name */
  179. char s_fpack[6]; /* file system pack name */
  180. char s_clean; /* set to 0x46 when fs was properly unmounted */
  181. char s_fill[371];
  182. s32 s_magic; /* version of file system */
  183. __fs32 s_type ; /* type of file system:
  184. 1 for 512 byte blocks
  185. 2 for 1024 byte blocks
  186. 3 for 2048 byte blocks */
  187. };
  188. /*
  189. * System V
  190. */
  191. /*
  192. * System V FS comes in two variants:
  193. * sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2).
  194. * sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4).
  195. */
  196. #define SYSV_NICINOD 100 /* number of inode cache entries */
  197. #define SYSV_NICFREE 50 /* number of free block list chunk entries */
  198. struct sysv4_super_block { /* on disk */
  199. __fs16 s_isize; /* index of first data zone */
  200. u16 s_pad0;
  201. __fs32 s_fsize; /* total number of zones of this fs */
  202. __fs16 s_nfree; /* # of free blocks in s_free, <= SYSV_NICFREE */
  203. u16 s_pad1;
  204. sysv_zone_t s_free[SYSV_NICFREE]; /* first free block list chunk */
  205. __fs16 s_ninode; /* # of free inodes in s_inode, <= SYSV_NICINOD */
  206. u16 s_pad2;
  207. sysv_ino_t s_inode[SYSV_NICINOD]; /* some free inodes */
  208. char s_flock; /* lock during free block list manipulation */
  209. char s_ilock; /* lock during inode cache manipulation */
  210. char s_fmod; /* super-block modified flag */
  211. char s_ronly; /* flag whether fs is mounted read-only */
  212. __fs32 s_time; /* time of last super block update */
  213. __fs16 s_dinfo[4]; /* device information ?? */
  214. __fs32 s_tfree; /* total number of free zones */
  215. __fs16 s_tinode; /* total number of free inodes */
  216. u16 s_pad3;
  217. char s_fname[6]; /* file system volume name */
  218. char s_fpack[6]; /* file system pack name */
  219. s32 s_fill[12];
  220. __fs32 s_state; /* state: 0x7c269d38-s_time means it is clean */
  221. s32 s_magic; /* version of file system */
  222. __fs32 s_type; /* type of file system:
  223. 1 for 512 byte blocks
  224. 2 for 1024 byte blocks */
  225. };
  226. struct sysv2_super_block { /* on disk */
  227. __fs16 s_isize; /* index of first data zone */
  228. __fs32 s_fsize __packed2__; /* total number of zones of this fs */
  229. __fs16 s_nfree; /* # of free blocks in s_free, <= SYSV_NICFREE */
  230. sysv_zone_t s_free[SYSV_NICFREE]; /* first free block list chunk */
  231. __fs16 s_ninode; /* # of free inodes in s_inode, <= SYSV_NICINOD */
  232. sysv_ino_t s_inode[SYSV_NICINOD]; /* some free inodes */
  233. char s_flock; /* lock during free block list manipulation */
  234. char s_ilock; /* lock during inode cache manipulation */
  235. char s_fmod; /* super-block modified flag */
  236. char s_ronly; /* flag whether fs is mounted read-only */
  237. __fs32 s_time __packed2__; /* time of last super block update */
  238. __fs16 s_dinfo[4]; /* device information ?? */
  239. __fs32 s_tfree __packed2__; /* total number of free zones */
  240. __fs16 s_tinode; /* total number of free inodes */
  241. char s_fname[6]; /* file system volume name */
  242. char s_fpack[6]; /* file system pack name */
  243. s32 s_fill[14];
  244. __fs32 s_state; /* file system state: 0xcb096f43 means clean */
  245. s32 s_magic; /* version of file system */
  246. __fs32 s_type; /* type of file system:
  247. 1 for 512 byte blocks
  248. 2 for 1024 byte blocks */
  249. };
  250. /*
  251. * Coherent
  252. */
  253. #define COH_NICINOD 100 /* number of inode cache entries */
  254. #define COH_NICFREE 64 /* number of free block list chunk entries */
  255. struct coh_super_block { /* on disk */
  256. __fs16 s_isize; /* index of first data zone */
  257. __fs32 s_fsize __packed2__; /* total number of zones of this fs */
  258. __fs16 s_nfree; /* # of free blocks in s_free, <= COH_NICFREE */
  259. sysv_zone_t s_free[COH_NICFREE] __packed2__; /* 1st free block list chunk */
  260. __fs16 s_ninode; /* # of free inodes in s_inode, <= COH_NICINOD */
  261. sysv_ino_t s_inode[COH_NICINOD]; /* some free inodes */
  262. char s_flock; /* lock during free block list manipulation */
  263. char s_ilock; /* lock during inode cache manipulation */
  264. char s_fmod; /* super-block modified flag */
  265. char s_ronly; /* flag whether fs is mounted read-only */
  266. __fs32 s_time __packed2__; /* time of last super block update */
  267. __fs32 s_tfree __packed2__; /* total number of free zones */
  268. __fs16 s_tinode; /* total number of free inodes */
  269. __fs16 s_interleave_m; /* interleave factor */
  270. __fs16 s_interleave_n;
  271. char s_fname[6]; /* file system volume name */
  272. char s_fpack[6]; /* file system pack name */
  273. __fs32 s_unique; /* zero, not used */
  274. };
  275. struct super_block* sysv_fill_super(int fd, void* args, int silent);
  276. const char* sysv_flavor(u_int type);
  277. u_long sysv_count_free_blocks(struct super_block* sb);
  278. u_long sysv_count_free_inodes(struct super_block* sb);
  279. struct sysv_dinode* sysv_raw_inode(struct super_block* sb, ino_t ino,
  280. struct buffer_head* bh);
  281. int sysv_next_direntry(struct inode* dp, struct unixfs_dirbuf* dirbuf,
  282. off_t* offset, struct unixfs_direntry* dent);
  283. int sysv_get_block(struct inode* ip, sector_t block, off_t* result);
  284. int sysv_get_page(struct inode* ip, sector_t index, char* pagebuf);
  285. #endif /* _SYSVFS_H_ */