summaryrefslogtreecommitdiff
path: root/ufs/ufs.h
diff options
context:
space:
mode:
Diffstat (limited to 'ufs/ufs.h')
-rw-r--r--ufs/ufs.h289
1 files changed, 289 insertions, 0 deletions
diff --git a/ufs/ufs.h b/ufs/ufs.h
new file mode 100644
index 00000000..5d823ebc
--- /dev/null
+++ b/ufs/ufs.h
@@ -0,0 +1,289 @@
+/*
+ Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <mach.h>
+#include <hurd.h>
+#include <sys/mman.h>
+#include <hurd/ports.h>
+#include <hurd/pager.h>
+#include <hurd/fshelp.h>
+#include <hurd/iohelp.h>
+#include <hurd/diskfs.h>
+#include <sys/mman.h>
+#include <assert.h>
+#include "fs.h"
+#include "dinode.h"
+
+/* Define this if memory objects should not be cached by the kernel.
+ Normally, don't define it, but defining it causes a much greater rate
+ of paging requests, which may be helpful in catching bugs. */
+
+/* #undef DONT_CACHE_MEMORY_OBJECTS */
+
+struct disknode
+{
+ ino_t number;
+
+ int dir_idx;
+
+ /* For a directory, this array holds the number of directory entries in
+ each DIRBLKSIZE piece of the directory. */
+ int *dirents;
+
+ /* Links on hash list. */
+ struct node *hnext, **hprevp;
+
+ struct rwlock allocptrlock;
+
+ struct dirty_indir *dirty;
+
+ struct user_pager_info *fileinfo;
+};
+
+/* Identifies a particular block and where it's found
+ when interpreting indirect block structure. */
+struct iblock_spec
+{
+ /* Disk address of block */
+ daddr_t bno;
+
+ /* Offset in next block up; -1 if it's in the inode itself. */
+ int offset;
+};
+
+/* Identifies an indirect block owned by this file which
+ might be dirty. */
+struct dirty_indir
+{
+ daddr_t bno; /* Disk address of block. */
+ struct dirty_indir *next;
+};
+
+struct user_pager_info
+{
+ struct node *np;
+ enum pager_type
+ {
+ DISK,
+ FILE_DATA,
+ } type;
+ struct pager *p;
+ vm_prot_t max_prot;
+
+ vm_offset_t allow_unlocked_pagein;
+ vm_size_t unlocked_pagein_length;
+};
+
+#include <hurd/diskfs-pager.h>
+
+/* The physical media. */
+extern struct store *store;
+/* What the user specified. */
+extern struct store_parsed *store_parsed;
+
+/* Mapped image of the disk. */
+extern void *disk_image;
+
+extern void *zeroblock;
+
+extern struct fs *sblock;
+extern struct csum *csum;
+int sblock_dirty;
+int csum_dirty;
+
+spin_lock_t node2pagelock;
+
+spin_lock_t alloclock;
+
+spin_lock_t gennumberlock;
+u_long nextgennumber;
+
+spin_lock_t unlocked_pagein_lock;
+
+/* The compat_mode specifies whether or not we write
+ extensions onto the disk. */
+enum compat_mode
+{
+ COMPAT_GNU = 0,
+ COMPAT_BSD42 = 1,
+ COMPAT_BSD44 = 2,
+} compat_mode;
+
+/* If this is set, then this filesystem has two extensions:
+ 1) directory entries include the type field.
+ 2) symlink targets might be written directly in the di_db field
+ of the dinode. */
+int direct_symlink_extension;
+
+/* If this is set, then the disk is byteswapped from native order. */
+int swab_disk;
+
+/* Number of device blocks per DEV_BSIZE block. */
+unsigned log2_dev_blocks_per_dev_bsize;
+
+/* Handy macros */
+#define DEV_BSIZE 512
+#define NBBY 8
+#define btodb(n) ((n) / DEV_BSIZE)
+#define howmany(x,y) (((x)+((y)-1))/(y))
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#define isclr(a, i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<(i)%NBBY))
+#define fsaddr(fs,n) (fsbtodb(fs,n)*DEV_BSIZE)
+
+
+/* Functions for looking inside disk_image */
+
+/* Convert an inode number to the dinode on disk. */
+extern inline struct dinode *
+dino (ino_t inum)
+{
+ return (struct dinode *)
+ (disk_image
+ + fsaddr (sblock, ino_to_fsba (sblock, inum))
+ + ino_to_fsbo (sblock, inum) * sizeof (struct dinode));
+}
+
+/* Convert a indirect block number to a daddr_t table. */
+extern inline daddr_t *
+indir_block (daddr_t bno)
+{
+ return (daddr_t *) (disk_image + fsaddr (sblock, bno));
+}
+
+/* Convert a cg number to the cylinder group. */
+extern inline struct cg *
+cg_locate (int ncg)
+{
+ return (struct cg *) (disk_image + fsaddr (sblock, cgtod (sblock, ncg)));
+}
+
+/* Sync part of the disk */
+extern inline void
+sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait)
+{
+ pager_sync_some (diskfs_disk_pager, fsaddr (sblock, blkno), nbytes, wait);
+}
+
+/* Sync an disk inode */
+extern inline void
+sync_dinode (int inum, int wait)
+{
+ sync_disk_blocks (ino_to_fsba (sblock, inum), sblock->fs_fsize, wait);
+}
+
+
+/* Functions for byte swapping */
+extern inline short
+swab_short (short arg)
+{
+ return (((arg & 0xff) << 8)
+ | ((arg & 0xff00) >> 8));
+}
+
+extern inline long
+swab_long (long arg)
+{
+ return (((long) swab_short (arg & 0xffff) << 16)
+ | swab_short ((arg & 0xffff0000) >> 16));
+}
+
+extern inline long long
+swab_long_long (long long arg)
+{
+ return (((long long) swab_long (arg & 0xffffffff) << 32)
+ | swab_long ((arg & 0xffffffff00000000LL) >> 32));
+}
+
+/* Return ENTRY, after byteswapping it if necessary */
+#define read_disk_entry(entry) \
+({ \
+ typeof (entry) ret; \
+ if (!swab_disk || sizeof (entry) == 1) \
+ ret = (entry); \
+ else if (sizeof (entry) == 2) \
+ ret = swab_short (entry); \
+ else if (sizeof (entry) == 4) \
+ ret = swab_long (entry); \
+ else \
+ abort (); \
+ ret; \
+})
+
+/* Execute A = B, but byteswap it along the way if necessary */
+#define write_disk_entry(a,b) \
+({ \
+ if (!swab_disk || sizeof (a) == 1) \
+ ((a) = (b)); \
+ else if (sizeof (a) == 2) \
+ ((a) = (swab_short (b))); \
+ else if (sizeof (a) == 4) \
+ ((a) = (swab_long (b))); \
+ else \
+ abort (); \
+})
+
+
+
+
+
+/* From alloc.c: */
+error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *,
+ struct protid *);
+void ffs_blkfree(struct node *, daddr_t bno, long size);
+daddr_t ffs_blkpref (struct node *, daddr_t, int, daddr_t *);
+error_t ffs_realloccg(struct node *, daddr_t, daddr_t,
+ int, int, daddr_t *, struct protid *);
+
+/* From bmap.c */
+error_t fetch_indir_spec (struct node *, daddr_t, struct iblock_spec *);
+void mark_indir_dirty (struct node *, daddr_t);
+
+/* From hyper.c: */
+void get_hypermetadata (void);
+void copy_sblock (void);
+
+/* From inode.c: */
+struct node *ifind (ino_t ino);
+void inode_init (void);
+void write_all_disknodes (void);
+
+/* From pager.c: */
+void create_disk_pager (void);
+void din_map (struct node *);
+void sin_map (struct node *);
+void sin_remap (struct node *, int);
+void sin_unmap (struct node *);
+void din_unmap (struct node *);
+void drop_pager_softrefs (struct node *);
+void allow_pager_softrefs (struct node *);
+void flush_node_pager (struct node *);
+
+/* From subr.c: */
+void ffs_fragacct (struct fs *, int, long [], int);
+int ffs_isblock(struct fs *, u_char *, daddr_t);
+void ffs_clrblock(struct fs *, u_char *, daddr_t);
+void ffs_setblock (struct fs *, u_char *, daddr_t);
+int skpc (int, int, char *);
+int scanc (u_int, u_char *, u_char [], int);
+
+/* From pokeloc.c: */
+void record_poke (void *, vm_size_t);
+void sync_disk (int);
+void flush_pokes ();