PageRenderTime 39ms CodeModel.GetById 14ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

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