1*dc5a79c1SDavid du Colombier typedef struct Xfs Xfs; 2*dc5a79c1SDavid du Colombier typedef struct Xfile Xfile; 3*dc5a79c1SDavid du Colombier typedef struct Iobuf Iobuf; 4*dc5a79c1SDavid du Colombier typedef struct Ext2 Ext2; 5*dc5a79c1SDavid du Colombier 6*dc5a79c1SDavid du Colombier typedef struct SuperBlock SuperBlock; 7*dc5a79c1SDavid du Colombier typedef struct GroupDesc GroupDesc; 8*dc5a79c1SDavid du Colombier typedef struct Inode Inode; 9*dc5a79c1SDavid du Colombier typedef struct DirEntry DirEntry; 10*dc5a79c1SDavid du Colombier 11*dc5a79c1SDavid du Colombier #define SECTORSIZE 512 12*dc5a79c1SDavid du Colombier #define OFFSET_SUPER_BLOCK 1024 13*dc5a79c1SDavid du Colombier 14*dc5a79c1SDavid du Colombier #define EXT2_SUPER_MAGIC 0xEF53 15*dc5a79c1SDavid du Colombier #define EXT2_MIN_BLOCK_SIZE 1024 16*dc5a79c1SDavid du Colombier #define EXT2_MAX_BLOCK_SIZE 4096 17*dc5a79c1SDavid du Colombier #define EXT2_ROOT_INODE 2 18*dc5a79c1SDavid du Colombier #define EXT2_FIRST_INO 11 19*dc5a79c1SDavid du Colombier #define EXT2_VALID_FS 0x0001 20*dc5a79c1SDavid du Colombier #define EXT2_ERROR_FS 0x0002 21*dc5a79c1SDavid du Colombier 22*dc5a79c1SDavid du Colombier /* 23*dc5a79c1SDavid du Colombier * Structure of the super block 24*dc5a79c1SDavid du Colombier */ 25*dc5a79c1SDavid du Colombier struct SuperBlock { 26*dc5a79c1SDavid du Colombier uint s_inodes_count; /* Inodes count */ 27*dc5a79c1SDavid du Colombier uint s_blocks_count; /* Blocks count */ 28*dc5a79c1SDavid du Colombier uint s_r_blocks_count; /* Reserved blocks count */ 29*dc5a79c1SDavid du Colombier uint s_free_blocks_count; /* Free blocks count */ 30*dc5a79c1SDavid du Colombier uint s_free_inodes_count; /* Free inodes count */ 31*dc5a79c1SDavid du Colombier uint s_first_data_block; /* First Data Block */ 32*dc5a79c1SDavid du Colombier uint s_log_block_size; /* Block size */ 33*dc5a79c1SDavid du Colombier int s_log_frag_size; /* Fragment size */ 34*dc5a79c1SDavid du Colombier uint s_blocks_per_group; /* # Blocks per group */ 35*dc5a79c1SDavid du Colombier uint s_frags_per_group; /* # Fragments per group */ 36*dc5a79c1SDavid du Colombier uint s_inodes_per_group; /* # Inodes per group */ 37*dc5a79c1SDavid du Colombier uint s_mtime; /* Mount time */ 38*dc5a79c1SDavid du Colombier uint s_wtime; /* Write time */ 39*dc5a79c1SDavid du Colombier ushort s_mnt_count; /* Mount count */ 40*dc5a79c1SDavid du Colombier short s_max_mnt_count; /* Maximal mount count */ 41*dc5a79c1SDavid du Colombier ushort s_magic; /* Magic signature */ 42*dc5a79c1SDavid du Colombier ushort s_state; /* File system state */ 43*dc5a79c1SDavid du Colombier ushort s_errors; /* Behaviour when detecting errors */ 44*dc5a79c1SDavid du Colombier ushort s_pad; 45*dc5a79c1SDavid du Colombier uint s_lastcheck; /* time of last check */ 46*dc5a79c1SDavid du Colombier uint s_checkinterval; /* max. time between checks */ 47*dc5a79c1SDavid du Colombier uint s_creator_os; /* OS */ 48*dc5a79c1SDavid du Colombier uint s_rev_level; /* Revision level */ 49*dc5a79c1SDavid du Colombier ushort s_def_resuid; /* Default uid for reserved blocks */ 50*dc5a79c1SDavid du Colombier ushort s_def_resgid; /* Default gid for reserved blocks */ 51*dc5a79c1SDavid du Colombier uint s_reserved[235]; /* Padding to the end of the block */ 52*dc5a79c1SDavid du Colombier }; 53*dc5a79c1SDavid du Colombier 54*dc5a79c1SDavid du Colombier /* 55*dc5a79c1SDavid du Colombier * Structure of a blocks group descriptor 56*dc5a79c1SDavid du Colombier */ 57*dc5a79c1SDavid du Colombier struct GroupDesc 58*dc5a79c1SDavid du Colombier { 59*dc5a79c1SDavid du Colombier uint bg_block_bitmap; /* Blocks bitmap block */ 60*dc5a79c1SDavid du Colombier uint bg_inode_bitmap; /* Inodes bitmap block */ 61*dc5a79c1SDavid du Colombier uint bg_inode_table; /* Inodes table block */ 62*dc5a79c1SDavid du Colombier ushort bg_free_blocks_count; /* Free blocks count */ 63*dc5a79c1SDavid du Colombier ushort bg_free_inodes_count; /* Free inodes count */ 64*dc5a79c1SDavid du Colombier ushort bg_used_dirs_count; /* Directories count */ 65*dc5a79c1SDavid du Colombier ushort bg_pad; 66*dc5a79c1SDavid du Colombier uint bg_reserved[3]; 67*dc5a79c1SDavid du Colombier }; 68*dc5a79c1SDavid du Colombier 69*dc5a79c1SDavid du Colombier /* 70*dc5a79c1SDavid du Colombier * Constants relative to the data blocks 71*dc5a79c1SDavid du Colombier */ 72*dc5a79c1SDavid du Colombier #define EXT2_NDIR_BLOCKS 12 73*dc5a79c1SDavid du Colombier #define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS 74*dc5a79c1SDavid du Colombier #define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) 75*dc5a79c1SDavid du Colombier #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) 76*dc5a79c1SDavid du Colombier #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) 77*dc5a79c1SDavid du Colombier 78*dc5a79c1SDavid du Colombier /* 79*dc5a79c1SDavid du Colombier * Structure of an inode on the disk 80*dc5a79c1SDavid du Colombier */ 81*dc5a79c1SDavid du Colombier struct Inode { 82*dc5a79c1SDavid du Colombier ushort i_mode; /* File mode */ 83*dc5a79c1SDavid du Colombier ushort i_uid; /* Owner Uid */ 84*dc5a79c1SDavid du Colombier uint i_size; /* Size in bytes */ 85*dc5a79c1SDavid du Colombier uint i_atime; /* Access time */ 86*dc5a79c1SDavid du Colombier uint i_ctime; /* Creation time */ 87*dc5a79c1SDavid du Colombier uint i_mtime; /* Modification time */ 88*dc5a79c1SDavid du Colombier uint i_dtime; /* Deletion Time */ 89*dc5a79c1SDavid du Colombier ushort i_gid; /* Group Id */ 90*dc5a79c1SDavid du Colombier ushort i_links_count; /* Links count */ 91*dc5a79c1SDavid du Colombier uint i_blocks; /* Blocks count */ 92*dc5a79c1SDavid du Colombier uint i_flags; /* File flags */ 93*dc5a79c1SDavid du Colombier uint osd1; 94*dc5a79c1SDavid du Colombier uint i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ 95*dc5a79c1SDavid du Colombier uint i_version; /* File version (for NFS) */ 96*dc5a79c1SDavid du Colombier uint i_file_acl; /* File ACL */ 97*dc5a79c1SDavid du Colombier uint i_dir_acl; /* Directory ACL */ 98*dc5a79c1SDavid du Colombier uint i_faddr; /* Fragment address */ 99*dc5a79c1SDavid du Colombier uchar osd2[12]; 100*dc5a79c1SDavid du Colombier }; 101*dc5a79c1SDavid du Colombier 102*dc5a79c1SDavid du Colombier /* 103*dc5a79c1SDavid du Colombier * Structure of a directory entry 104*dc5a79c1SDavid du Colombier */ 105*dc5a79c1SDavid du Colombier #define EXT2_NAME_LEN 255 106*dc5a79c1SDavid du Colombier #define DIR_REC_LEN(name_len) (((name_len) + 8 + 3) & ~3) 107*dc5a79c1SDavid du Colombier 108*dc5a79c1SDavid du Colombier struct DirEntry { 109*dc5a79c1SDavid du Colombier uint inode; /* Inode number */ 110*dc5a79c1SDavid du Colombier ushort rec_len; /* Directory entry length */ 111*dc5a79c1SDavid du Colombier uchar name_len; /* Name length */ 112*dc5a79c1SDavid du Colombier uchar reserved; 113*dc5a79c1SDavid du Colombier char name[EXT2_NAME_LEN]; /* File name */ 114*dc5a79c1SDavid du Colombier }; 115*dc5a79c1SDavid du Colombier 116*dc5a79c1SDavid du Colombier #define S_IFMT 00170000 117*dc5a79c1SDavid du Colombier #define S_IFLNK 0120000 118*dc5a79c1SDavid du Colombier #define S_IFREG 0100000 119*dc5a79c1SDavid du Colombier #define S_IFDIR 0040000 120*dc5a79c1SDavid du Colombier 121*dc5a79c1SDavid du Colombier #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 122*dc5a79c1SDavid du Colombier #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 123*dc5a79c1SDavid du Colombier #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 124*dc5a79c1SDavid du Colombier 125*dc5a79c1SDavid du Colombier #define DEFAULT_UID 200 126*dc5a79c1SDavid du Colombier #define DEFAULT_GID 100 127*dc5a79c1SDavid du Colombier 128*dc5a79c1SDavid du Colombier struct Iobuf 129*dc5a79c1SDavid du Colombier { 130*dc5a79c1SDavid du Colombier Xfs *dev; 131*dc5a79c1SDavid du Colombier long addr; 132*dc5a79c1SDavid du Colombier Iobuf *next; 133*dc5a79c1SDavid du Colombier Iobuf *prev; 134*dc5a79c1SDavid du Colombier Iobuf *hash; 135*dc5a79c1SDavid du Colombier int busy; 136*dc5a79c1SDavid du Colombier int dirty; 137*dc5a79c1SDavid du Colombier char *iobuf; 138*dc5a79c1SDavid du Colombier }; 139*dc5a79c1SDavid du Colombier 140*dc5a79c1SDavid du Colombier struct Xfs{ 141*dc5a79c1SDavid du Colombier Xfs *next; 142*dc5a79c1SDavid du Colombier char *name; /* of file containing external f.s. */ 143*dc5a79c1SDavid du Colombier Qid qid; /* of file containing external f.s. */ 144*dc5a79c1SDavid du Colombier long ref; /* attach count */ 145*dc5a79c1SDavid du Colombier Qid rootqid; /* of plan9 constructed root directory */ 146*dc5a79c1SDavid du Colombier short dev; 147*dc5a79c1SDavid du Colombier short fmt; 148*dc5a79c1SDavid du Colombier void *ptr; 149*dc5a79c1SDavid du Colombier 150*dc5a79c1SDavid du Colombier /* data from super block */ 151*dc5a79c1SDavid du Colombier 152*dc5a79c1SDavid du Colombier int block_size; 153*dc5a79c1SDavid du Colombier int desc_per_block; 154*dc5a79c1SDavid du Colombier int inodes_per_group; 155*dc5a79c1SDavid du Colombier int inodes_per_block; 156*dc5a79c1SDavid du Colombier int addr_per_block; 157*dc5a79c1SDavid du Colombier int blocks_per_group; 158*dc5a79c1SDavid du Colombier 159*dc5a79c1SDavid du Colombier int ngroups; 160*dc5a79c1SDavid du Colombier int superaddr, superoff; 161*dc5a79c1SDavid du Colombier int grpaddr; 162*dc5a79c1SDavid du Colombier }; 163*dc5a79c1SDavid du Colombier 164*dc5a79c1SDavid du Colombier struct Xfile{ 165*dc5a79c1SDavid du Colombier Xfile *next; /* in hash bucket */ 166*dc5a79c1SDavid du Colombier long client; 167*dc5a79c1SDavid du Colombier long fid; 168*dc5a79c1SDavid du Colombier Xfs * xf; 169*dc5a79c1SDavid du Colombier void * ptr; 170*dc5a79c1SDavid du Colombier 171*dc5a79c1SDavid du Colombier uint inbr; /* inode nbr */ 172*dc5a79c1SDavid du Colombier uint pinbr; /* parrent inode */ 173*dc5a79c1SDavid du Colombier ulong bufaddr; /* addr of inode block */ 174*dc5a79c1SDavid du Colombier ulong bufoffset; 175*dc5a79c1SDavid du Colombier int root; /* true on attach for ref count */ 176*dc5a79c1SDavid du Colombier int dirindex; /* next dir entry to read */ 177*dc5a79c1SDavid du Colombier }; 178*dc5a79c1SDavid du Colombier 179*dc5a79c1SDavid du Colombier #define EXT2_SUPER 1 180*dc5a79c1SDavid du Colombier #define EXT2_DESC 2 181*dc5a79c1SDavid du Colombier #define EXT2_BBLOCK 3 182*dc5a79c1SDavid du Colombier #define EXT2_BINODE 4 183*dc5a79c1SDavid du Colombier 184*dc5a79c1SDavid du Colombier struct Ext2{ 185*dc5a79c1SDavid du Colombier char type; 186*dc5a79c1SDavid du Colombier union{ 187*dc5a79c1SDavid du Colombier SuperBlock *sb; 188*dc5a79c1SDavid du Colombier GroupDesc *gd; 189*dc5a79c1SDavid du Colombier char *bmp; 190*dc5a79c1SDavid du Colombier }u; 191*dc5a79c1SDavid du Colombier Iobuf *buf; 192*dc5a79c1SDavid du Colombier }; 193*dc5a79c1SDavid du Colombier 194*dc5a79c1SDavid du Colombier #define DESC_ADDR(xf,n) ( (xf)->grpaddr + ((n)/(xf)->desc_per_block) ) 195*dc5a79c1SDavid du Colombier #define DESC_OFFSET(xf,d,n) ( ((GroupDesc *)(d)) + ((n)%(xf)->desc_per_block) ) 196*dc5a79c1SDavid du Colombier 197*dc5a79c1SDavid du Colombier enum{ 198*dc5a79c1SDavid du Colombier Asis, Clean, Clunk 199*dc5a79c1SDavid du Colombier }; 200*dc5a79c1SDavid du Colombier 201*dc5a79c1SDavid du Colombier enum{ 202*dc5a79c1SDavid du Colombier Enevermind, 203*dc5a79c1SDavid du Colombier Eformat, 204*dc5a79c1SDavid du Colombier Eio, 205*dc5a79c1SDavid du Colombier Enomem, 206*dc5a79c1SDavid du Colombier Enonexist, 207*dc5a79c1SDavid du Colombier Eexist, 208*dc5a79c1SDavid du Colombier Eperm, 209*dc5a79c1SDavid du Colombier Enofilsys, 210*dc5a79c1SDavid du Colombier Eauth, 211*dc5a79c1SDavid du Colombier Enospace, 212*dc5a79c1SDavid du Colombier Elink, 213*dc5a79c1SDavid du Colombier Elongname, 214*dc5a79c1SDavid du Colombier Eintern, 215*dc5a79c1SDavid du Colombier Ecorrupt, 216*dc5a79c1SDavid du Colombier Enotclean 217*dc5a79c1SDavid du Colombier }; 218*dc5a79c1SDavid du Colombier 219*dc5a79c1SDavid du Colombier extern int chatty; 220*dc5a79c1SDavid du Colombier extern int errno; 221*dc5a79c1SDavid du Colombier extern char *deffile; 222*dc5a79c1SDavid du Colombier extern int rdonly; 223