root/include/linux/sysv_fs.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. to_coh_ulong
  2. from_coh_ulong
  3. from_coh_imode
  4. to_coh_imode
  5. sysv_bread
  6. coh_wait_on_inode
  7. coh_lock_inode
  8. coh_unlock_inode

   1 #ifndef _LINUX_SYSV_FS_H
   2 #define _LINUX_SYSV_FS_H
   3 
   4 /*
   5  * The SystemV/Coherent filesystem constants/structures/macros
   6  */
   7 
   8 
   9 /* This code assumes
  10    - a little endian processor like 386,
  11    - sizeof(short) = 2, sizeof(int) = 4, sizeof(long) = 4,
  12    - alignof(short) = 2, alignof(long) = 4.
  13 */
  14 
  15 #ifdef __GNUC__
  16 #define __packed2__  __attribute__ ((packed, aligned(2)))
  17 #else
  18 #error I want gcc!
  19 #endif
  20 
  21 #include <linux/stat.h>         /* declares S_IFLNK etc. */
  22 #include <linux/sched.h>        /* declares wake_up() */
  23 #include <linux/sysv_fs_sb.h>   /* defines the sv_... shortcuts */
  24 
  25 
  26 /* Layout on disk */
  27 /* ============== */
  28 
  29 
  30 /* The block size is sb->sv_block_size which may be smaller than BLOCK_SIZE. */
  31 
  32 /* zones (= data allocation units) are blocks */
  33 
  34 /* On Coherent FS, 32 bit quantities are stored using (I quote the Coherent
  35    manual) a "canonical byte ordering". This is the PDP-11 byte ordering:
  36    x = 2^24 * byte3 + 2^16 * byte2 + 2^8 * byte1 + byte0 is stored
  37    as { byte2, byte3, byte0, byte1 }. We need conversions.
  38 */
  39 
  40 typedef unsigned long coh_ulong;
  41 
  42 static inline coh_ulong to_coh_ulong (unsigned long x)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
  45 }
  46 
  47 static inline unsigned long from_coh_ulong (coh_ulong x)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
  50 }
  51 
  52 /* inode numbers are 16 bit */
  53 
  54 typedef unsigned short sysv_ino_t;
  55 
  56 /* Block numbers are 24 bit, sometimes stored in 32 bit.
  57    On Coherent FS, they are always stored in PDP-11 manner: the least
  58    significant 16 bits come last.
  59 */
  60 
  61 typedef unsigned long sysv_zone_t;
  62 
  63 /* Among the blocks ... */
  64 /* Xenix FS, Coherent FS: block 0 is the boot block, block 1 the super-block.
  65    SystemV FS: block 0 contains both the boot sector and the super-block. */
  66 /* The first inode zone is sb->sv_firstinodezone (1 or 2). */
  67 
  68 /* Among the inodes ... */
  69 /* 0 is non-existent */
  70 #define SYSV_BADBL_INO  1       /* inode of bad blocks file */
  71 #define SYSV_ROOT_INO   2       /* inode of root directory */
  72 
  73 
  74 /* Xenix super-block data on disk */
  75 #define XENIX_NICINOD   100     /* number of inode cache entries */
  76 #define XENIX_NICFREE   100     /* number of free block list chunk entries */
  77 struct xenix_super_block {
  78         unsigned short s_isize; /* index of first data zone */
  79         unsigned long  s_fsize __packed2__; /* total number of zones of this fs */
  80         /* the start of the free block list: */
  81         unsigned short s_nfree; /* number of free blocks in s_free, <= XENIX_NICFREE */
  82         unsigned long  s_free[XENIX_NICFREE]; /* first free block list chunk */
  83         /* the cache of free inodes: */
  84         unsigned short s_ninode; /* number of free inodes in s_inode, <= XENIX_NICINOD */
  85         sysv_ino_t     s_inode[XENIX_NICINOD]; /* some free inodes */
  86         /* locks, not used by Linux: */
  87         char           s_flock; /* lock during free block list manipulation */
  88         char           s_ilock; /* lock during inode cache manipulation */
  89         char           s_fmod;  /* super-block modified flag */
  90         char           s_ronly; /* flag whether fs is mounted read-only */
  91         unsigned long  s_time __packed2__; /* time of last super block update */
  92         unsigned long  s_tfree __packed2__; /* total number of free zones */
  93         unsigned short s_tinode;        /* total number of free inodes */
  94         short          s_dinfo[4];      /* device information ?? */
  95         char           s_fname[6];      /* file system volume name */
  96         char           s_fpack[6];      /* file system pack name */
  97         char           s_clean;         /* set to 0x46 when filesystem is properly unmounted */
  98         char           s_fill[371];
  99         long           s_magic;         /* version of file system */
 100         long           s_type;          /* type of file system: 1 for 512 byte blocks
 101                                                                 2 for 1024 byte blocks */
 102 };
 103 
 104 /* Xenix free list block on disk */
 105 struct xenix_freelist_chunk {
 106         unsigned short fl_nfree;        /* number of free blocks in fl_free, <= XENIX_NICFREE] */
 107         unsigned long  fl_free[XENIX_NICFREE] __packed2__;
 108 };
 109 
 110 /* SystemV FS comes in two variants:
 111  * sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2).
 112  * sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4).
 113  */
 114 #define SYSV_NICINOD    100     /* number of inode cache entries */
 115 #define SYSV_NICFREE    50      /* number of free block list chunk entries */
 116 
 117 /* SystemV4 super-block data on disk */
 118 struct sysv4_super_block {
 119         unsigned short s_isize; /* index of first data zone */
 120         unsigned long  s_fsize; /* total number of zones of this fs */
 121         /* the start of the free block list: */
 122         unsigned short s_nfree; /* number of free blocks in s_free, <= SYSV_NICFREE */
 123         unsigned long  s_free[SYSV_NICFREE]; /* first free block list chunk */
 124         /* the cache of free inodes: */
 125         unsigned short s_ninode; /* number of free inodes in s_inode, <= SYSV_NICINOD */
 126         sysv_ino_t     s_inode[SYSV_NICINOD]; /* some free inodes */
 127         /* locks, not used by Linux: */
 128         char           s_flock; /* lock during free block list manipulation */
 129         char           s_ilock; /* lock during inode cache manipulation */
 130         char           s_fmod;  /* super-block modified flag */
 131         char           s_ronly; /* flag whether fs is mounted read-only */
 132         unsigned long  s_time;  /* time of last super block update */
 133         short          s_dinfo[4];      /* device information ?? */
 134         unsigned long  s_tfree; /* total number of free zones */
 135         unsigned short s_tinode;        /* total number of free inodes */
 136         char           s_fname[6];      /* file system volume name */
 137         char           s_fpack[6];      /* file system pack name */
 138         long           s_fill[12];
 139         long           s_state;         /* file system state */
 140         long           s_magic;         /* version of file system */
 141         long           s_type;          /* type of file system: 1 for 512 byte blocks
 142                                                                 2 for 1024 byte blocks */
 143 };
 144 
 145 /* SystemV4 free list block on disk */
 146 struct sysv4_freelist_chunk {
 147         unsigned short fl_nfree;        /* number of free blocks in fl_free, <= SYSV_NICFREE] */
 148         unsigned long  fl_free[SYSV_NICFREE];
 149 };
 150 
 151 /* SystemV2 super-block data on disk */
 152 struct sysv2_super_block {
 153         unsigned short s_isize; /* index of first data zone */
 154         unsigned long  s_fsize __packed2__; /* total number of zones of this fs */
 155         /* the start of the free block list: */
 156         unsigned short s_nfree; /* number of free blocks in s_free, <= SYSV_NICFREE */
 157         unsigned long  s_free[SYSV_NICFREE]; /* first free block list chunk */
 158         /* the cache of free inodes: */
 159         unsigned short s_ninode; /* number of free inodes in s_inode, <= SYSV_NICINOD */
 160         sysv_ino_t     s_inode[SYSV_NICINOD]; /* some free inodes */
 161         /* locks, not used by Linux: */
 162         char           s_flock; /* lock during free block list manipulation */
 163         char           s_ilock; /* lock during inode cache manipulation */
 164         char           s_fmod;  /* super-block modified flag */
 165         char           s_ronly; /* flag whether fs is mounted read-only */
 166         unsigned long  s_time __packed2__; /* time of last super block update */
 167         short          s_dinfo[4];      /* device information ?? */
 168         unsigned long  s_tfree __packed2__; /* total number of free zones */
 169         unsigned short s_tinode;        /* total number of free inodes */
 170         char           s_fname[6];      /* file system volume name */
 171         char           s_fpack[6];      /* file system pack name */
 172         long           s_fill[14];
 173         long           s_state;         /* file system state */
 174         long           s_magic;         /* version of file system */
 175         long           s_type;          /* type of file system: 1 for 512 byte blocks
 176                                                                 2 for 1024 byte blocks */
 177 };
 178 
 179 /* SystemV2 free list block on disk */
 180 struct sysv2_freelist_chunk {
 181         unsigned short fl_nfree;        /* number of free blocks in fl_free, <= SYSV_NICFREE] */
 182         unsigned long  fl_free[SYSV_NICFREE] __packed2__;
 183 };
 184 
 185 /* Coherent super-block data on disk */
 186 #define COH_NICINOD     100     /* number of inode cache entries */
 187 #define COH_NICFREE     64      /* number of free block list chunk entries */
 188 struct coh_super_block {
 189         unsigned short s_isize; /* index of first data zone */
 190         coh_ulong      s_fsize __packed2__; /* total number of zones of this fs */
 191         /* the start of the free block list: */
 192         unsigned short s_nfree; /* number of free blocks in s_free, <= COH_NICFREE */
 193         coh_ulong      s_free[COH_NICFREE] __packed2__; /* first free block list chunk */
 194         /* the cache of free inodes: */
 195         unsigned short s_ninode; /* number of free inodes in s_inode, <= COH_NICINOD */
 196         sysv_ino_t     s_inode[COH_NICINOD]; /* some free inodes */
 197         /* locks, not used by Linux: */
 198         char           s_flock; /* lock during free block list manipulation */
 199         char           s_ilock; /* lock during inode cache manipulation */
 200         char           s_fmod;  /* super-block modified flag */
 201         char           s_ronly; /* flag whether fs is mounted read-only */
 202         coh_ulong      s_time __packed2__; /* time of last super block update */
 203         coh_ulong      s_tfree __packed2__; /* total number of free zones */
 204         unsigned short s_tinode;        /* total number of free inodes */
 205         unsigned short s_interleave_m;  /* interleave factor */
 206         unsigned short s_interleave_n;
 207         char           s_fname[6];      /* file system volume name */
 208         char           s_fpack[6];      /* file system pack name */
 209         unsigned long  s_unique;        /* zero, not used */
 210 };
 211 
 212 /* Coherent free list block on disk */
 213 struct coh_freelist_chunk {
 214         unsigned short fl_nfree;        /* number of free blocks in fl_free, <= COH_NICFREE] */
 215         unsigned long  fl_free[COH_NICFREE] __packed2__;
 216 };
 217 
 218 
 219 /* SystemV/Coherent inode data on disk */
 220 
 221 struct sysv_inode {
 222         unsigned short i_mode;
 223         unsigned short i_nlink;
 224         unsigned short i_uid;
 225         unsigned short i_gid;
 226         unsigned long  i_size;
 227         union { /* directories, regular files, ... */
 228                 char i_addb[3*(10+1+1+1)+1]; /* zone numbers: max. 10 data blocks,
 229                                               * then 1 indirection block,
 230                                               * then 1 double indirection block,
 231                                               * then 1 triple indirection block.
 232                                               * Then maybe a "file generation number" ??
 233                                               */
 234                 /* devices */
 235                 dev_t i_rdev;
 236                 /* named pipes on Coherent */
 237                 struct {
 238                         char p_addp[30];
 239                         short p_pnc;
 240                         short p_prx;
 241                         short p_pwx;
 242                 } i_p;
 243         } i_a;
 244         unsigned long i_atime;  /* time of last access */
 245         unsigned long i_mtime;  /* time of last modification */
 246         unsigned long i_ctime;  /* time of creation */
 247 };
 248 
 249 /* The admissible values for i_mode are listed in <linux/stat.h> :
 250  * #define S_IFMT  00170000  mask for type
 251  * #define S_IFREG  0100000  type = regular file
 252  * #define S_IFBLK  0060000  type = block device
 253  * #define S_IFDIR  0040000  type = directory
 254  * #define S_IFCHR  0020000  type = character device
 255  * #define S_IFIFO  0010000  type = named pipe
 256  * #define S_ISUID  0004000  set user id
 257  * #define S_ISGID  0002000  set group id
 258  * #define S_ISVTX  0001000  save swapped text even after use
 259  * Additionally for SystemV:
 260  * #define S_IFLNK  0120000  type = symbolic link
 261  * #define S_IFNAM  0050000  type = XENIX special named file ??
 262  * Additionally for Coherent:
 263  * #define S_IFMPB  0070000  type = multiplexed block device ??
 264  * #define S_IFMPC  0030000  type = multiplexed character device ??
 265  *
 266  * Since Coherent doesn't know about symbolic links, we use a kludgey
 267  * implementation of symbolic links: i_mode = COH_KLUDGE_SYMLINK_MODE
 268  * denotes a symbolic link. When a regular file should get this mode by
 269  * accident, it is automatically converted to COH_KLUDGE_NOT_SYMLINK.
 270  * We use S_IFREG because only regular files (and Coherent pipes...) can have
 271  * data blocks with arbitrary contents associated with them, and S_ISVTX
 272  * ("save swapped text after use") because it is unused on both Linux and
 273  * Coherent: Linux does much more intelligent paging, and Coherent hasn't
 274  * virtual memory at all.
 275  * Same trick for Xenix.
 276  */
 277 #define COH_KLUDGE_SYMLINK_MODE (S_IFREG | S_ISVTX)
 278 #define COH_KLUDGE_NOT_SYMLINK  (S_IFREG | S_ISVTX | S_IRUSR) /* force read access */
 279 extern inline mode_t from_coh_imode(unsigned short mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         if (mode == COH_KLUDGE_SYMLINK_MODE)
 282                 return (S_IFLNK | 0777);
 283         else
 284                 return mode;
 285 }
 286 extern inline unsigned short to_coh_imode(mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         if (S_ISLNK(mode))
 289                 return COH_KLUDGE_SYMLINK_MODE;
 290         else if (mode == COH_KLUDGE_SYMLINK_MODE)
 291                 return COH_KLUDGE_NOT_SYMLINK;
 292         else
 293                 return mode;
 294 }
 295 
 296 /* Admissible values for i_nlink: 0.._LINK_MAX */
 297 #define XENIX_LINK_MAX  126     /* ?? */
 298 #define SYSV_LINK_MAX   126     /* 127? 251? */
 299 #define COH_LINK_MAX    10000   /* max number of hard links to an inode */
 300 
 301 /* The number of inodes per block is
 302    sb->sv_inodes_per_block = block_size / sizeof(struct sysv_inode) */
 303 /* The number of indirect pointers per block is
 304    sb->sv_ind_per_block = block_size / sizeof(unsigned long) */
 305 
 306 
 307 /* SystemV/Coherent directory entry on disk */
 308 
 309 #define SYSV_NAMELEN    14      /* max size of name in struct sysv_dir_entry */
 310 
 311 struct sysv_dir_entry {
 312         sysv_ino_t inode;
 313         char name[SYSV_NAMELEN]; /* up to 14 characters, the rest are zeroes */
 314 };
 315 
 316 #define SYSV_DIRSIZE    sizeof(struct sysv_dir_entry)   /* size of every directory entry */
 317 
 318 
 319 #ifdef __KERNEL__
 320 
 321 /* Operations */
 322 /* ========== */
 323 
 324 
 325 /* identify the FS in memory */
 326 #define FSTYPE_XENIX    1
 327 #define FSTYPE_SYSV4    2
 328 #define FSTYPE_SYSV2    3
 329 #define FSTYPE_COH      4
 330 
 331 #define SYSV_MAGIC_BASE         0x012FF7B3
 332 
 333 #define XENIX_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_XENIX)
 334 #define SYSV4_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_SYSV4)
 335 #define SYSV2_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_SYSV2)
 336 #define COH_SUPER_MAGIC         (SYSV_MAGIC_BASE+FSTYPE_COH)
 337 
 338 /* Because the block size may be smaller than 1024 (which is the unit used by
 339    the disk drivers and the buffer code), many functions must return a pointer
 340    to the buffer data additionally to the buffer head pointer.
 341 */
 342 #if 0
 343 struct bh_data {
 344         struct buffer_head * bh;
 345         char * bh_data;
 346 };
 347 #endif
 348 
 349 /* sysv_bread(sb,dev,block,...) would be equivalent to
 350    bread(dev,block,BLOCK_SIZE)
 351    if the block size were always 1024, which is the only one bread() supports.
 352 */
 353 static inline struct buffer_head *
 354 sysv_bread (struct super_block *sb, int dev, unsigned int block, char* * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 355 {
 356         struct buffer_head *bh;
 357 
 358         if (!(bh = bread (dev, (block >> sb->sv_block_size_ratio_bits) + sb->sv_block_base, BLOCK_SIZE)))
 359                 return NULL;
 360         *data = bh->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits);
 361         return bh;
 362 }
 363 
 364 
 365 /* locks - protect against simultaneous write and truncate */
 366 
 367 extern void _coh_wait_on_inode (struct inode * inode);
 368 
 369 extern inline void coh_wait_on_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 370 {
 371         if (inode->u.sysv_i.i_lock)
 372                 _coh_wait_on_inode(inode);
 373 }
 374 
 375 extern inline void coh_lock_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 376 {
 377         if (inode->u.sysv_i.i_lock)
 378                 _coh_wait_on_inode(inode);
 379         inode->u.sysv_i.i_lock = 1;
 380 }
 381 
 382 extern inline void coh_unlock_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 383 {
 384         inode->u.sysv_i.i_lock = 0;
 385         wake_up(&inode->u.sysv_i.i_wait);
 386 }
 387 
 388 
 389 /*
 390  * Function prototypes
 391  */
 392 
 393 extern int sysv_lookup(struct inode * dir,const char * name, int len,
 394         struct inode ** result);
 395 extern int sysv_create(struct inode * dir,const char * name, int len, int mode,
 396         struct inode ** result);
 397 extern int sysv_mkdir(struct inode * dir, const char * name, int len, int mode);
 398 extern int sysv_rmdir(struct inode * dir, const char * name, int len);
 399 extern int sysv_unlink(struct inode * dir, const char * name, int len);
 400 extern int sysv_symlink(struct inode * inode, const char * name, int len,
 401         const char * symname);
 402 extern int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, int len);
 403 extern int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rdev);
 404 extern int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
 405         struct inode * new_dir, const char * new_name, int new_len);
 406 extern struct inode * sysv_new_inode(const struct inode * dir);
 407 extern void sysv_free_inode(struct inode * inode);
 408 extern unsigned long sysv_count_free_inodes(struct super_block *sb);
 409 extern int sysv_new_block(struct super_block * sb);
 410 extern void sysv_free_block(struct super_block * sb, unsigned int block);
 411 extern unsigned long sysv_count_free_blocks(struct super_block *sb);
 412 
 413 extern int sysv_bmap(struct inode *,int);
 414 
 415 extern struct buffer_head * sysv_getblk(struct inode *, unsigned int, int, char* *);
 416 extern struct buffer_head * sysv_file_bread(struct inode *, int, int, char* *);
 417 
 418 extern void sysv_truncate(struct inode *);
 419 extern void sysv_put_super(struct super_block *);
 420 extern struct super_block *sysv_read_super(struct super_block *,void *,int);
 421 extern void sysv_write_super(struct super_block *);
 422 extern void sysv_read_inode(struct inode *);
 423 extern int sysv_notify_change(int,struct inode *);
 424 extern void sysv_write_inode(struct inode *);
 425 extern void sysv_put_inode(struct inode *);
 426 extern void sysv_statfs(struct super_block *, struct statfs *);
 427 extern int sysv_sync_inode(struct inode *);
 428 extern int sysv_sync_file(struct inode *, struct file *);
 429 #if 0
 430 extern int sysv_mmap(struct inode *, struct file *, unsigned long, size_t, int, unsigned long);
 431 #endif
 432 
 433 extern struct inode_operations sysv_file_inode_operations;
 434 extern struct inode_operations sysv_file_inode_operations_with_bmap;
 435 extern struct inode_operations sysv_dir_inode_operations;
 436 extern struct inode_operations sysv_symlink_inode_operations;
 437 
 438 #endif /* __KERNEL__ */
 439 
 440 #endif
 441 

/* [previous][next][first][last][top][bottom][index][help] */