diff -u --recursive --new-file linux-1.3.10/drivers/block/Makefile linux/drivers/block/Makefile --- linux-1.3.10/drivers/block/Makefile Sun Jul 16 13:48:26 1995 +++ linux/drivers/block/Makefile Sun Jul 16 13:50:39 1995 @@ -19,8 +19,8 @@ # In the future, some of these should be built conditionally. # -OBJS := ll_rw_blk.o ramdisk.o genhd.o -SRCS := ll_rw_blk.c ramdisk.c genhd.c +OBJS := ll_rw_blk.o rd.o rd_gz_inflate.o rd_gz_unzip.o genhd.o +SRCS := ll_rw_blk.c rd.c rd_gz_inflate.c rd_gz_unzip.c genhd.c BLOCK_MODULE_OBJS = ifdef CONFIG_BLK_DEV_FD diff -u --recursive --new-file linux-1.3.10/drivers/block/README.ramdisk linux/drivers/block/README.ramdisk --- linux-1.3.10/drivers/block/README.ramdisk Wed Dec 31 17:00:00 1969 +++ linux/drivers/block/README.ramdisk Sun Jul 16 18:30:47 1995 @@ -0,0 +1,34 @@ +New RAMDISK driver README +------------------------- + + This improved version of the ramdisk driver contains two major +enhancements to the older ramdisk driver : + + 1. It supports gzipped ramdisk images. This, for example, makes +the standard 1.44MB rootdisk shipped with Slackware 2.2 take up only 544K +of disk space. This feature can be used easily by gziping a standard +rootdisk (or creating a larger one in a ramdisk), and copying it down to +the floppy. + + This can be extremely useful for certain rare situations (like if +you only have a 720K disk to put a rootdisk on - using this ramdisk +driver, you can put a full rootdisk on it...) + +(TODO: Make the gzip loader read at 384K and 512K into the disk, so a +kernel and a rootdisk can both be used.) + + 2. It also supports multiple ramdisk devices (referencing +straight to the buffer cache). A buffer protection scheme has been added +to the buffer.c system, which should keep the buffers safe. + + You can create the devices by doing : + + mknod /dev/ramX b 33 X + + (X is the minor number - it can be up to 255. Note that minor #0 +can be the static ramdisk as well, so I suggest that it not be mknoded.) + + Enjoy! + + - Chad Page + (cpage@best.com) diff -u --recursive --new-file linux-1.3.10/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-1.3.10/drivers/block/ll_rw_blk.c Sun Jul 16 18:36:47 1995 +++ linux/drivers/block/ll_rw_blk.c Sun Jul 16 18:37:27 1995 @@ -21,6 +21,24 @@ #include #include "blk.h" +/* The following #define, when uncommented, adds a penalty to the current + processes priority (actually, it's dynamic count variable), which should + discourage excessive i/o... it only does anything when it gets to low-level + code, since the buffers go pretty fast anyway... + + These changes do *nothing* if COUNTER_DEC is not defined. +*/ + +/* #define COUNTER_DEC */ + +#ifdef COUNTER_DEC + #define COUNTER_DEC_BLOCK 50 + #define COUNTER_DEC_PAGE 200 +#else + #define COUNTER_DEC_BLOCK 0 + #define COUNTER_DEC_PAGE 0 +#endif + /* * The request-struct contains all necessary data * to load a nr of sectors into memory @@ -423,6 +441,11 @@ printk("Can't page to read-only device 0x%X\n",dev); return; } + + current->counter -= COUNTER_DEC_PAGE; + if (current->counter < 0) + current->counter = 0; + req = get_request_wait(NR_REQUEST, dev); /* fill up the request-info, and add it to the queue */ req->cmd = rw; @@ -490,6 +513,13 @@ goto sorry; } + /* At this point, let's change current->counter so the program won't go + straight for the block device again - if things are loaded... */ + + current->counter -= COUNTER_DEC_BLOCK; + if (current->counter < 0) + current->counter = 0; + /* If there are no pending requests for this device, then we insert a dummy request for that device. This will prevent the request from starting until we have shoved all of the blocks into the @@ -627,7 +657,6 @@ #ifdef CONFIG_SJCD mem_start = sjcd_init(mem_start,mem_end); #endif CONFIG_SJCD - if (ramdisk_size) - mem_start += rd_init(mem_start, ramdisk_size*1024); + mem_start += rd_init(mem_start, ramdisk_size*1024); return mem_start; } diff -u --recursive --new-file linux-1.3.10/drivers/block/rd.c linux/drivers/block/rd.c --- linux-1.3.10/drivers/block/rd.c Wed Dec 31 17:00:00 1969 +++ linux/drivers/block/rd.c Sun Jul 16 14:20:05 1995 @@ -0,0 +1,613 @@ +/* + * ramdisk.c - Multiple ramdisk driver - gzip-loading version - v. 0.8 beta. + * + * (C) Chad Page et. al, 1995. + * + * This ramdisk is designed to have filesystems created on it and mounted + * just like a regular floppy disk. + * + * It also does something suggested by Linus : use the buffer cache as the + * ramdisk data. This makes it possible to dynamically allocate the ramdisk + * buffer - with some consequences I have to deal with as I write this. + * + * This version is bimodal in that it supports BOTH static allocation and + * dynamic allocation. I added that because of unforseen bugs (as in, it + * wouldn't boot!), and I've used a mmap call to do this. + * + * Based on the original ramdisk.c, written mostly by Theodore Ts'o in 1991. + * + * The gzip loader is self-activating, and automatically switches between + * the two loading methods on whether or not get_method says it's a gzip file + * or not (note : this isin't a clean printout yet!) + * + */ + +#include +#ifdef MODULE +#include +#include + +static char kernel_version[] = UTS_RELEASE; +#endif +#define DEVICE_NAME "ramdisk" +#define DEVICE_REQUEST rd_request +#define DEVICE_NR(device) (MINOR(device)) +#define DEVICE_ON(device) +#define DEVICE_OFF(device) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern void wait_for_keypress(void); + +#define MAJOR_NR 33 /* This is an official major number */ + +#ifdef MODULE + #include "/usr/src/linux/drivers/block/blk.h" +#else + #include "blk.h" + #define BUILD_CRAMDISK + + void rd_load(void); + int crd_load(struct inode *finode, struct file * fflip); +#endif + +/* Various static variables go here... mostly used within the ramdisk code only. */ + +unsigned long rd_addr[256] = {0, }; + +int rd_length[256]; +int rd_blocksizes[256] = {1024, }; + +/* This is the size of the rootdisk-loading ramdisk. If it is 0, don't load + the rootdisk... */ + +int rd_param; + +/* + * Basically, my strategy here is to set up a buffer-head which can't be + * deleted, and make that my Ramdisk. If the request is outside of the + * allocated size, we must get rid of it... + * + */ + +static void rd_request(void) +{ + unsigned int minor; + int offset, len; + +repeat: + INIT_REQUEST; + + minor = MINOR(CURRENT->dev); + + if ((rd_addr[minor] < 4096) && (minor == 0)) { + end_request(0); + goto repeat; + } + + offset = CURRENT->sector << 9; + len = CURRENT->current_nr_sectors << 9; + + if ((offset + len) > rd_length[minor]) { + end_request(0); + goto repeat; + } + + if (rd_addr[minor] < 4096) /* This is a buffer-cache-disk */ + { + if (CURRENT->cmd == READ) + { + memset(CURRENT->buffer, 0, len); + } + CURRENT->bh->b_prot = 1; + } + else /* Conventional ramdisk */ + { + if (CURRENT->cmd == READ) + { + memcpy(CURRENT->buffer, (char *)(rd_addr[minor] + offset), len); + } + if (CURRENT->cmd == WRITE) + { + memcpy((char *)(rd_addr[minor] + offset), CURRENT->buffer, len); + } + } + end_request(1); + goto repeat; +} + +/* The implementation of BLKFLSBUF is stolen from ide.c. Hopefully it's + a good hack... */ + +static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + if (!inode || !inode->i_rdev) + return -EINVAL; + + switch (cmd) { + case BLKFLSBUF: + if (!suser()) return -EACCES; + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + break; + default: + break; + }; + + return 0; +} + +static struct file_operations fd_fops = { + NULL, /* lseek - default */ + block_read, /* read - block dev write */ + block_write, /* write - block dev write */ + NULL, /* readdir - not here! */ + NULL, /* select */ + rd_ioctl, /* ioctl */ + NULL, /* mmap */ + NULL, /* no special open code... there should be! */ + NULL, /* no special release code... */ + block_fsync /* fsync */ +}; + +/* This is the registration and initialization section of the ramdisk driver */ + +int main_rd_init(void) +{ + int count; + + if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) { + printk("RAMDISK2 : Could not get major %d", MAJOR_NR); + return -EIO; + } + + blk_dev[MAJOR_NR].request_fn = &rd_request; + + for (count = 0; count < 256; count++) { + rd_length[count] = (16384 * 1024); + rd_blocksizes[count] = 1024; + } + + blksize_size[MAJOR_NR] = rd_blocksizes; + + return 0; +} + +/* Module init */ +#ifdef MODULE +int init_module(void) +{ + return main_rd_init(); +} + +void cleanup_module(void) +{ + unregister_blkdev(MAJOR_NR, "ramdisk"); +} +#else +/* Non-modular init... */ + +long rd_init(long mem_start, int length) +{ + main_rd_init(); + + rd_param = length; + rd_addr[0] = mem_start; + rd_length[0] = length; + + return length; +} +#endif +/* This is the non-modular section of the driver. This is changed + from the original in that the ramdisk blindly loads from block 0 without + a filesystem check. Peter Anvin told me that he and Linus agreed that it + was no longer necessary, and that it took up space (which I am using to + write all these comments :) + + As usual, I am trying to maintain compatibility with the older ramdisk in + the function calls used by the other parts of the kernel, to prevent + kernel patching. + + This code is diabled when this is compiled into modular form. +*/ + +#ifndef MODULE + +void rd_load() +{ + struct inode inode; + struct file flip; + int device; + + device = ROOT_DEV; + + printk(KERN_NOTICE "VFS: Insert ramdisk floppy and press ENTER\n"); + wait_for_keypress(); + + if (MAJOR(device) != FLOPPY_MAJOR) return; + + memset(&flip, 0, sizeof(flip)); + memset(&inode, 0, sizeof(inode)); + inode.i_rdev = device; + flip.f_mode = 1; /* read only */ + flip.f_inode = &inode; + + if (blkdev_open(&inode, &flip) != 0) return; + +#ifdef BUILD_CRAMDISK + if (crd_load(&inode, &flip) == 1) { + if (flip.f_op -> release) flip.f_op -> release(&inode, &flip); + return; + } + + if (flip.f_op -> lseek) flip.f_op -> lseek(&inode, &flip, 0, 0); +#endif + + /* Now, copy the data... */ + + flip.f_op -> read(&inode, &flip, (char *)rd_addr[0], rd_param); + + if (flip.f_op -> release) flip.f_op -> release(&inode, &flip); + + invalidate_buffers(ROOT_DEV); + ROOT_DEV = (MAJOR_NR << 8); +} + +#ifdef BUILD_CRAMDISK + +/* + * From linux/kernel/blk_drv/cramdisk.c + * + * Written/adapted by Richard Lyons, 1FEB94, and hacked by Chad Page Apr. 95 + * to work with the new ramdisk driver. + * + * Parts of this file are copyright Jean-loup Gailly. + * Parts of this file are not copyright Mark Adler. + * + */ + +#include +#include + +#define EOF -1 + +DECLARE(uch, inbuf, INBUFSIZ); +unsigned char *outbuf; +DECLARE(uch, window, WSIZE); +DECLARE(ulg, crc_32_tab, 256); + +#define fcalloc(a,b) malloc((a) * (b)) +#define fcfree(p) free(p) +#define to_stdout 0 + +unsigned int insize; +unsigned int inptr; + +unsigned char *output_data; +unsigned long output_ptr; +unsigned int outcnt; + +int method, exit_code, part_nb, last_member; +int test = 0; +int force = 0; +int verbose = 1; +long bytes_out; + +void makecrc(void); +void allocbufs(void); +void freebufs(void); +local int get_method(int in); +void (*work)(int inf, int outf); + +struct inode *inode; +struct file *flip; + +/* + * Unlike cramdisk, I use get_method to decide whether or not the rootdisk + * is gzipped, and if it is I go here... + */ + +int crd_load(struct inode * finode, struct file * fflip) +{ + inode = finode; + flip = fflip; + + exit_code = OK; + test = 0; + part_nb = 0; + allocbufs(); + clear_bufs(); + makecrc(); + method = get_method(0); + if (method < 0) + { + printk("RAMDISK : gzip header not found - continuing with conventional load.\n"); + return 0; + } + printk("RAMDISK : starting gunzip of rootdisk image... "); + work(0, 0); + printk("done.\n"); + freebufs(); + invalidate_buffers(ROOT_DEV); + if (exit_code == OK) + ROOT_DEV = (MAJOR_NR << 8); + return 1; +} + +void +allocbufs(void) +{ + ALLOC(uch, inbuf, INBUFSIZ); + outbuf = (unsigned char *)rd_addr[0]; + ALLOC(uch, window, WSIZE); + ALLOC(ulg, crc_32_tab, 256); +} + +void +freebufs(void) +{ + FREE(crc_32_tab); + FREE(window); + FREE(inbuf); +} + + +/* =========================================================================== + * Clear input and output buffers + */ +void clear_bufs() +{ + output_data = (unsigned char *)rd_addr[0]; + outcnt = output_ptr = 0; + insize = inptr = 0; + bytes_out = 0L; +} + +/* + * Code to compute the CRC-32 table. Borrowed from + * gzip-1.0.3/makecrc.c. + */ + +void +makecrc(void) +{ +/* Not copyrighted 1990 Mark Adler */ + + unsigned long c; /* crc shift register */ + unsigned long e; /* polynomial exclusive-or pattern */ + int i; /* counter for all possible eight bit values */ + int k; /* byte being shifted into crc apparatus */ + + /* terms of polynomial defining this crc (except x^32): */ + static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* Make exclusive-or pattern from polynomial */ + e = 0; + for (i = 0; i < sizeof(p)/sizeof(int); i++) + e |= 1L << (31 - p[i]); + + crc_32_tab[0] = 0; + + for (i = 1; i < 256; i++) + { + c = 0; + for (k = i | 256; k != 1; k >>= 1) + { + c = c & 1 ? (c >> 1) ^ e : c >> 1; + if (k & 1) + c ^= e; + } + crc_32_tab[i] = c; + } +} + +/* =========================================================================== + * Run a set of bytes through the crc shift register. If s is a NULL + * pointer, then initialize the crc shift register contents instead. + * Return the current crc in either case. + */ +ulg updcrc(s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + while (n--) { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } + } + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} + +void +error(char *s) +{ + printk("%s", s); + exit_code = ERROR; +} + +/* ======================================================================== + * Check the magic number of the input file and update ofname if an + * original name was given and to_stdout is not set. + * Return the compression method, -1 for error, -2 for warning. + * Set inptr to the offset of the next byte to be processed. + * This function may be called repeatedly for an input file consisting + * of several contiguous gzip'ed members. + * IN assertions: there is at least one remaining compressed member. + * If the member is a zip file, it must be the only one. + */ +local int get_method(in) + int in; /* input file descriptor */ +{ + uch flags; + char magic[2]; /* magic header */ + + magic[0] = (char)get_byte(); + magic[1] = (char)get_byte(); + + method = -1; /* unknown yet */ + part_nb++; /* number of parts in gzip file */ + last_member = 0; + /* assume multiple members in gzip file except for record oriented I/O */ + + if (memcmp(magic, GZIP_MAGIC, 2) == 0 + || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) { + + work = unzip; + method = (int)get_byte(); + flags = (uch)get_byte(); + if ((flags & ENCRYPTED) != 0) { + error("Input is encrypted\n"); + exit_code = ERROR; + return -1; + } + if ((flags & CONTINUATION) != 0) { + error("Multi part input\n"); + exit_code = ERROR; + if (force <= 1) return -1; + } + if ((flags & RESERVED) != 0) { + error("Input has invalid flags\n"); + exit_code = ERROR; + if (force <= 1) return -1; + } + inptr += 6; + + if ((flags & CONTINUATION) != 0) { + unsigned part = (unsigned)get_byte(); + part |= ((unsigned)get_byte())<<8; + if (verbose) { + error("Input is not part number 1\n"); + } + } + if ((flags & EXTRA_FIELD) != 0) { + unsigned len = (unsigned)get_byte(); + len |= ((unsigned)get_byte())<<8; + while (len--) (void)get_byte(); + } + + /* Get original file name if it was truncated */ + if ((flags & ORIG_NAME) != 0) { + if (to_stdout || part_nb > 1) { + /* Discard the old name */ + while (get_byte() != 0) /* null */ ; + } else { + +/* You won't believe how long not having this line in messed me up... + in the gzip loader used by the kernel and cramdisk, it does not take + into account the original file name, causing me literally hours of grief + until I reverse-engineered gzip-1.0.3 from my Linux CD set to figure out + how my gzip adaption was broken... then I put this line in, and presto! + */ + while (get_byte() != 0); + } /* to_stdout */ + } /* orig_name */ + + /* Discard file comment if any */ + if ((flags & COMMENT) != 0) { + while (get_byte() != 0) /* null */ ; + } + + } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2 + && memcmp(inbuf, PKZIP_MAGIC, 4) == 0) { + /* To simplify the code, we support a zip file when alone only. + * We are thus guaranteed that the entire local header fits in inbuf. + */ + inptr = 0; + work = unzip; + if (check_zipfile(in) == -1) return -1; + /* check_zipfile may get ofname from the local header */ + last_member = 1; + + } else if (memcmp(magic, PACK_MAGIC, 2) == 0) { + error("packed input"); + } else if (memcmp(magic, LZW_MAGIC, 2) == 0) { + error("compressed input"); + last_member = 1; + } + if (method == -1) { + error("Corrupted input\n"); + if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING; + return part_nb == 1 ? -1 : -2; + } + + return method; +} + +/* I made this a real function while trying to debug this. It isin't needed, +and will go away in alpha 4/beta-test 1. */ + +int get_byte(void) +{ + if (inptr < insize) { + return inbuf[inptr++]; + } + else + return fill_inbuf(); +} + +int +fill_inbuf(void) +{ + if (exit_code != OK) return EOF; + + insize = flip -> f_op -> read(inode, flip, inbuf, INBUFSIZ); + if (insize == 0) return EOF; + + inptr = 1; + + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +void flush_window() +{ + if (outcnt == 0) + return; + if ((output_ptr + outcnt) > rd_length[0]) + error("CRAMDISK: compressed image too long\n"); + else { + updcrc(window, outcnt); + + memcpy(output_data + output_ptr, (char *)window, outcnt); + + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + } + outcnt = 0; +} + + +typedef struct { + unsigned long start; + unsigned long pages; +} chain; + +#define MAX_MISSES (PAGE_SIZE/sizeof(chain)) + +#endif + +#endif /* Non-modular portions */ + diff -u --recursive --new-file linux-1.3.10/drivers/block/rd_gz_inflate.c linux/drivers/block/rd_gz_inflate.c --- linux-1.3.10/drivers/block/rd_gz_inflate.c Wed Dec 31 17:00:00 1969 +++ linux/drivers/block/rd_gz_inflate.c Sun Jul 16 14:22:03 1995 @@ -0,0 +1,812 @@ +#define DEBG(x) +#define DEBG1(x) +/* inflate.c -- Not copyrighted 1992 by Mark Adler + version c10p1, 10 January 1993 */ + +/* + * Adapted for booting Linux by Hannu Savolainen 1993 + * based on gzip-1.0.3 + */ + +#ifndef lint +static char rcsid[] = "$Id: inflate.c,v 0.10 1993/02/04 13:21:06 jloup Exp $"; +#endif + +#include + +#include +#define slide window + +#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) +# include +# include +#endif + +struct huft { + uch e; /* number of extra bits or operation */ + uch b; /* number of bits in this code or subcode */ + union { + ush n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; +}; + + +/* Function prototypes */ +int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, + struct huft **, int *)); +int huft_free OF((struct huft *)); +int inflate_codes OF((struct huft *, struct huft *, int, int)); +int inflate_stored OF((void)); +int inflate_fixed OF((void)); +int inflate_dynamic OF((void)); +int inflate_block OF((int *)); +int inflate OF((void)); + + +#define wp outcnt +#define flush_output(w) (wp=(w),flush_window()) + +/* Tables for deflate from PKZIP's appnote.txt. */ +static unsigned border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +static ush cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +static ush cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + +ulg bb; /* bit buffer */ +unsigned bk; /* bits in bit buffer */ + +ush mask_bits[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +#ifdef CRYPT + uch cc; +# define NEXTBYTE() \ + (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte()) +#else +# define NEXTBYTE() (uch)get_byte() +#endif +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} + +int lbits = 9; /* bits in base literal/length lookup table */ +int dbits = 6; /* bits in base distance lookup table */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + + +unsigned hufts; /* track memory usage */ + + +int huft_build(b, n, s, d, e, t, m) +unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ +unsigned n; /* number of codes (assumed <= N_MAX) */ +unsigned s; /* number of simple-valued codes (0..s-1) */ +ush *d; /* list of base values for non-simple codes */ +ush *e; /* list of extra bits for non-simple codes */ +struct huft **t; /* result: starting table */ +int *m; /* maximum lookup bits, returns actual */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. */ +{ + unsigned a; /* counter for codes of length k */ + unsigned c[BMAX+1]; /* bit length count table */ + unsigned f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + unsigned x[BMAX+1]; /* bit offsets, then code stack */ + unsigned *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + unsigned z; /* number of entries in current table */ + +DEBG("huft1 "); + + /* Generate counts for each bit length */ + memzero(c, sizeof(c)); + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (struct huft *)NULL; + *m = 0; + return 0; + } + +DEBG("huft2 "); + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((unsigned)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((unsigned)l > i) + l = i; + *m = l; + +DEBG("huft3 "); + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= c[i]) < 0) + return 2; + c[i] += y; + +DEBG("huft4 "); + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + +DEBG("huft5 "); + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + +DEBG("h6 "); + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (struct huft *)NULL; /* just to keep compilers happy */ + q = (struct huft *)NULL; /* ditto */ + z = 0; /* ditto */ +DEBG("h6a "); + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { +DEBG("h6b "); + a = c[k]; + while (a--) + { +DEBG("h6b1 "); + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { +DEBG1("1 "); + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ +DEBG1("2 "); + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } +DEBG1("3 "); + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + q = (struct huft *)malloc((z + 1)*sizeof(struct huft)); +DEBG1("4 "); + hufts += z + 1; /* track memory usage */ + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = (struct huft *)NULL; + u[h] = ++q; /* table starts after link */ + +DEBG1("5 "); + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.b = (uch)l; /* bits to dump before this table */ + r.e = (uch)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } +DEBG1("6 "); + } +DEBG("h6c "); + + /* set up table entry in r */ + r.b = (uch)(k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = *p++; /* simple code is just the value */ + } + else + { + r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } +DEBG("h6d "); + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } +DEBG("h6e "); + } +DEBG("h6f "); + } + +DEBG("huft7 "); + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + + + +int huft_free(t) +struct huft *t; /* table to free */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register struct huft *p, *q; + + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != (struct huft *)NULL) + { + q = (--p)->v.t; + free(p); + p = q; + } + return 0; +} + + +int inflate_codes(tl, td, bl, bd) +struct huft *tl, *td; /* literal/length and distance decoder tables */ +int bl, bd; /* number of bits decoded by tl[] and td[] */ +/* inflate (decompress) the codes in a deflated (compressed) block. + Return an error code or zero if it all goes ok. */ +{ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + + /* make local copies of globals */ + b = bb; /* initialize bit buffer */ + k = bk; + w = wp; /* initialize window position */ + + /* inflate the coded data */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + for (;;) /* do until end of block */ + { + NEEDBITS((unsigned)bl) + if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + if (e == 16) /* then it's a literal */ + { + slide[w++] = (uch)t->v.n; + if (w == WSIZE) + { + flush_output(w); + w = 0; + } + } + else /* it's an EOB or a length */ + { + /* exit if end of block */ + if (e == 15) + break; + + /* get length of block to copy */ + NEEDBITS(e) + n = t->v.n + ((unsigned)b & mask_bits[e]); + DUMPBITS(e); + + /* decode distance of block to copy */ + NEEDBITS((unsigned)bd) + if ((e = (t = td + ((unsigned)b & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + NEEDBITS(e) + d = w - t->v.n - ((unsigned)b & mask_bits[e]); + DUMPBITS(e) + + /* do the copy */ + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); +#if !defined(NOMEMCPY) && !defined(DEBUG) + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(slide + w, slide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + slide[w++] = slide[d++]; + } while (--e); + if (w == WSIZE) + { + flush_output(w); + w = 0; + } + } while (n); + } + } + + + /* restore the globals from the locals */ + wp = w; /* restore global window pointer */ + bb = b; /* restore global bit buffer */ + bk = k; + + /* done */ + return 0; +} + + + +int inflate_stored() +/* "decompress" an inflated type 0 (stored) block. */ +{ + unsigned n; /* number of bytes in block */ + unsigned w; /* current window position */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + +DEBG(""); + return 0; +} + + + +int inflate_fixed() +/* decompress an inflated type 1 (fixed Huffman codes) block. We should + either replace this with a custom decoder, or at least precompute the + Huffman tables. */ +{ + int i; /* temporary variable */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned l[288]; /* length list for huft_build */ + +DEBG(" 1) + { + huft_free(tl); + + DEBG(">"); + return i; + } + + + /* decompress until an end-of-block code */ + if (inflate_codes(tl, td, bl, bd)) + return 1; + + + /* free the decoding tables, return */ + huft_free(tl); + huft_free(td); + return 0; +} + + + +int inflate_dynamic() +/* decompress an inflated type 2 (dynamic Huffman codes) block. */ +{ + int i; /* temporary variables */ + unsigned j; + unsigned l; /* last length */ + unsigned m; /* mask for bit lengths table */ + unsigned n; /* number of lengths to get */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned nb; /* number of bit length codes */ + unsigned nl; /* number of literal/length codes */ + unsigned nd; /* number of distance codes */ +#ifdef PKZIP_BUG_WORKAROUND + unsigned ll[288+32]; /* literal/length and distance code lengths */ +#else + unsigned ll[286+30]; /* literal/length and distance code lengths */ +#endif + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + +DEBG(" 288 || nd > 32) +#else + if (nl > 286 || nd > 30) +#endif + return 1; /* bad lengths */ + +DEBG("dyn1 "); + + /* read in bit-length-code lengths */ + for (j = 0; j < nb; j++) + { + NEEDBITS(3) + ll[border[j]] = (unsigned)b & 7; + DUMPBITS(3) + } + for (; j < 19; j++) + ll[border[j]] = 0; + +DEBG("dyn2 "); + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) + { + if (i == 1) + huft_free(tl); + return i; /* incomplete code set */ + } + +DEBG("dyn3 "); + + /* read in literal and distance code lengths */ + n = nl + nd; + m = mask_bits[bl]; + i = l = 0; + while ((unsigned)i < n) + { + NEEDBITS((unsigned)bl) + j = (td = tl + ((unsigned)b & m))->b; + DUMPBITS(j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + NEEDBITS(2) + j = 3 + ((unsigned)b & 3); + DUMPBITS(2) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + NEEDBITS(3) + j = 3 + ((unsigned)b & 7); + DUMPBITS(3) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + else /* j == 18: 11 to 138 zero length codes */ + { + NEEDBITS(7) + j = 11 + ((unsigned)b & 0x7f); + DUMPBITS(7) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + +DEBG("dyn4 "); + + /* free decoding table for trees */ + huft_free(tl); + +DEBG("dyn5 "); + + /* restore the global bit buffer */ + bb = b; + bk = k; + +DEBG("dyn5a "); + + /* build the decoding tables for literal/length and distance codes */ + bl = lbits; + if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) + { +DEBG("dyn5b "); + if (i == 1) { + error(" incomplete literal tree\n"); + huft_free(tl); + } + return i; /* incomplete code set */ + } +DEBG("dyn5c "); + bd = dbits; + if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) + { +DEBG("dyn5d "); + if (i == 1) { + error(" incomplete distance tree\n"); +#ifdef PKZIP_BUG_WORKAROUND + i = 0; + } +#else + huft_free(td); + } + huft_free(tl); + return i; /* incomplete code set */ +#endif + } + +DEBG("dyn6 "); + + /* decompress until an end-of-block code */ + if (inflate_codes(tl, td, bl, bd)) + return 1; + +DEBG("dyn7 "); + + /* free the decoding tables, return */ + huft_free(tl); + huft_free(td); + + DEBG(">"); + return 0; +} + + + +int inflate_block(e) +int *e; /* last block flag */ +/* decompress an inflated block */ +{ + unsigned t; /* block type */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + DEBG(""); + + /* bad block type */ + return 2; +} + + + +int inflate() +/* decompress an inflated entry */ +{ + int e; /* last block flag */ + int r; /* result code */ + unsigned h; /* maximum struct huft's malloc'ed */ + + + /* initialize window, bit buffer */ + wp = 0; + bk = 0; + bb = 0; + + + /* decompress until the last block */ + h = 0; + do { + hufts = 0; + if ((r = inflate_block(&e)) != 0) + return r; + if (hufts > h) + h = hufts; + } while (!e); + + /* Undo too much lookahead. The next read will be byte aligned so we + * can discard unused bits in the last meaningful byte. + */ + while (bk >= 8) { + bk -= 8; + inptr--; + } + + /* flush out slide */ + flush_output(wp); + + + /* return success */ +#ifdef DEBUG + fprintf(stderr, "<%u> ", h); +#endif /* DEBUG */ + return 0; +} diff -u --recursive --new-file linux-1.3.10/drivers/block/rd_gz_unzip.c linux/drivers/block/rd_gz_unzip.c --- linux-1.3.10/drivers/block/rd_gz_unzip.c Wed Dec 31 17:00:00 1969 +++ linux/drivers/block/rd_gz_unzip.c Sun Jul 16 14:22:59 1995 @@ -0,0 +1,185 @@ +/* unzip.c -- decompress files in gzip or pkzip format. + * Copyright (C) 1992-1993 Jean-loup Gailly + * + * Adapted for Linux booting by Hannu Savolainen 1993 + * + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License, see the file COPYING. + * + * The code in this file is derived from the file funzip.c written + * and put in the public domain by Mark Adler. + */ + +/* + This version can extract files in gzip or pkzip format. + For the latter, only the first entry is extracted, and it has to be + either deflated or stored. + */ + +#ifndef lint +static char rcsid[] = "$Id: unzip.c,v 0.9 1993/02/10 16:07:22 jloup Exp $"; +#endif + +#include +#include + +#include +#include + +#include + +/* PKZIP header definitions */ +#define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ +#define LOCFLG 6 /* offset of bit flag */ +#define CRPFLG 1 /* bit for encrypted entry */ +#define EXTFLG 8 /* bit for extended local header */ +#define LOCHOW 8 /* offset of compression method */ +#define LOCTIM 10 /* file mod time (for decryption) */ +#define LOCCRC 14 /* offset of crc */ +#define LOCSIZ 18 /* offset of compressed size */ +#define LOCLEN 22 /* offset of uncompressed length */ +#define LOCFIL 26 /* offset of file name field length */ +#define LOCEXT 28 /* offset of extra field length */ +#define LOCHDR 30 /* size of local header, including sig */ +#define EXTHDR 16 /* size of extended local header, inc sig */ + + +/* Globals */ + +int decrypt; /* flag to turn on decryption */ +char *key; /* not used--needed to link crypt.c */ +int pkzip = 0; /* set for a pkzip file */ +int extended = 0; /* set if extended local header */ + +/* =========================================================================== + * Check zip file and advance inptr to the start of the compressed data. + * Get ofname from the local header if necessary. + */ +int check_zipfile(in) + int in; /* input file descriptors */ +{ + uch *h = inbuf + inptr; /* first local header */ + + /* ifd = in; */ + + /* Check validity of local header, and skip name and extra fields */ + inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT); + + if (inptr > insize || LG(h) != LOCSIG) { + error("input not a zip"); + } + method = h[LOCHOW]; + if (method != STORED && method != DEFLATED) { + error("first entry not deflated or stored--can't extract"); + } + + /* If entry encrypted, decrypt and validate encryption header */ + if ((decrypt = h[LOCFLG] & CRPFLG) != 0) { + error("encrypted file\n"); + exit_code = ERROR; + return -1; + } + + /* Save flags for unzip() */ + extended = (h[LOCFLG] & EXTFLG) != 0; + pkzip = 1; + + /* Get ofname and time stamp from local header (to be done) */ + return 0; +} + +/* =========================================================================== + * Unzip in to out. This routine works on both gzip and pkzip files. + * + * IN assertions: the buffer inbuf contains already the beginning of + * the compressed data, from offsets inptr to insize-1 included. + * The magic header has already been checked. The output buffer is cleared. + */ +void unzip(in, out) + int in, out; /* input and output file descriptors */ +{ + ulg orig_crc = 0; /* original crc */ + ulg orig_len = 0; /* original uncompressed length */ + int n; + uch buf[EXTHDR]; /* extended local header */ + + /* ifd = in; + ofd = out; */ + + updcrc(NULL, 0); /* initialize crc */ + + if (pkzip && !extended) { /* crc and length at the end otherwise */ + orig_crc = LG(inbuf + LOCCRC); + orig_len = LG(inbuf + LOCLEN); + } + + printk("%d\n", inptr); + + /* Decompress */ + if (method == DEFLATED) { + + int res = inflate(); + + if (res == 3) { + error("out of memory"); + } else if (res != 0) { + error("invalid compressed format"); + } + + } else if (pkzip && method == STORED) { + + register ulg n = LG(inbuf + LOCLEN); + + if (n != LG(inbuf + LOCSIZ) - (decrypt ? RAND_HEAD_LEN : 0)) { + + error("length mismatch"); + } + while (n--) { + uch c = (uch)get_byte(); +#ifdef CRYPT + if (decrypt) zdecode(c); +#endif + if (!test) put_char(c); + } + } else { + error("internal error, invalid method"); + } + + /* Get the crc and original length */ + if (!pkzip) { + /* crc32 (see algorithm.doc) + * uncompressed input size modulo 2^32 + */ + for (n = 0; n < 8; n++) { + buf[n] = (uch)get_byte(); /* may cause an error if EOF */ + } + orig_crc = LG(buf); + orig_len = LG(buf+4); + + } else if (extended) { /* If extended header, check it */ + /* signature - 4bytes: 0x50 0x4b 0x07 0x08 + * CRC-32 value + * compressed size 4-bytes + * uncompressed size 4-bytes + */ + for (n = 0; n < EXTHDR; n++) { + buf[n] = (uch)get_byte(); /* may cause an error if EOF */ + } + orig_crc = LG(buf+4); + orig_len = LG(buf+12); + } + + /* Validate decompression */ + if (orig_crc != updcrc(outbuf, 0)) { + error("crc error"); + } + if (orig_len != bytes_out) { + error("length error"); + } + + /* Check if there are more entries in a pkzip file */ + if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) { + error("zip file has more than one entry"); + } + extended = pkzip = 0; /* for next file */ +} diff -u --recursive --new-file linux-1.3.10/fs/buffer.c linux/fs/buffer.c --- linux-1.3.10/fs/buffer.c Sun Jul 16 13:48:42 1995 +++ linux/fs/buffer.c Sun Jul 16 13:54:32 1995 @@ -185,7 +185,7 @@ if (!bh->b_dirt || pass>=2) continue; /* don't bother about locked buffers */ - if (bh->b_lock) + if (bh->b_lock || bh->b_prot) continue; bh->b_count++; bh->b_flushtime = 0; @@ -262,6 +262,8 @@ for (i = nr_buffers_type[nlist]*2 ; --i > 0 ; bh = bh->b_next_free) { if (bh->b_dev != dev) continue; + if (bh->b_prot) + continue; wait_on_buffer(bh); if (bh->b_dev != dev) continue; @@ -563,7 +565,7 @@ continue; }; - if (bh->b_count || bh->b_size != size) + if (bh->b_prot || bh->b_count || bh->b_size != size) continue; /* Buffers are written in the order they are placed @@ -605,6 +607,8 @@ if(candidate[i] == bh) candidate[i] = NULL; /* Got last one */ if (bh->b_count || bh->b_size != size) panic("Busy buffer in candidate list\n"); + if (bh->b_prot) + panic ("Protected buffer in candidate list\n"); if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1) panic("Shared buffer in candidate list\n"); if (BADNESS(bh)) panic("Buffer in candidate list with BADNESS != 0\n"); @@ -634,7 +638,7 @@ continue; }; - if (bh->b_count || bh->b_size != size) + if (bh->b_prot || bh->b_count || bh->b_size != size) continue; /* Buffers are written in the order they are @@ -1064,6 +1068,7 @@ while (1) { arr[block++] = bh; bh->b_count = 1; + bh->b_prot = 0; bh->b_dirt = 0; bh->b_flushtime = 0; bh->b_uptodate = 0; @@ -1259,7 +1264,7 @@ do { if (!tmp) return 0; - if (tmp->b_count || tmp->b_dirt || tmp->b_lock || tmp->b_wait) + if (tmp->b_prot || tmp->b_count || tmp->b_dirt || tmp->b_lock || tmp->b_wait) return 0; tmp = tmp->b_this_page; } while (tmp != bh); @@ -1377,7 +1382,7 @@ bh = free_list[isize]; if(!bh) continue; for (i=0 ; !i || bh != free_list[isize]; bh = bh->b_next_free, i++) { - if (bh->b_count || !bh->b_this_page) + if (bh->b_count || bh->b_prot || !bh->b_this_page) continue; if (try_to_free(bh, &bh)) return 1; @@ -1397,7 +1402,7 @@ for ( ; i-- > 0 ; bh = bh->b_next_free) { /* We may have stalled while waiting for I/O to complete. */ if(bh->b_list != nlist) goto repeat1; - if (bh->b_count || !bh->b_this_page) + if (bh->b_prot || bh->b_count || !bh->b_this_page) continue; if(size && bh->b_size != size) continue; if (bh->b_lock) @@ -1426,7 +1431,7 @@ void show_buffers(void) { struct buffer_head * bh; - int found = 0, locked = 0, dirty = 0, used = 0, lastused = 0; + int found = 0, locked = 0, protected = 0, dirty = 0, used = 0, lastused = 0; int shared; int nlist, isize; @@ -1435,13 +1440,15 @@ printk("Buffer blocks: %6d\n",nr_buffers); for(nlist = 0; nlist < NR_LIST; nlist++) { - shared = found = locked = dirty = used = lastused = 0; + shared = found = locked = dirty = used = protected = lastused = 0; bh = lru_list[nlist]; if(!bh) continue; do { found++; if (bh->b_lock) locked++; + if (bh->b_prot) + protected++; if (bh->b_dirt) dirty++; if(mem_map[MAP_NR(((unsigned long) bh->b_data))] !=1) shared++; @@ -1449,8 +1456,8 @@ used++, lastused = found; bh = bh->b_next_free; } while (bh != lru_list[nlist]); - printk("Buffer[%d] mem: %d buffers, %d used (last=%d), %d locked, %d dirty %d shrd\n", - nlist, found, used, lastused, locked, dirty, shared); + printk("Buffer[%d] mem: %d buffers, %d used (last=%d), %d locked, %d protected %d dirty %d shrd\n", + nlist, found, used, lastused, locked, protected, dirty, shared); }; printk("Size [LAV] Free Clean Unshar Lck Lck1 Dirty Shared\n"); for(isize = 0; isizeb_count || tmp->b_dirt || tmp->b_lock) + if (tmp->b_prot || tmp->b_count || tmp->b_dirt || tmp->b_lock) return 0; tmp = tmp->b_this_page; } while (tmp != bh); @@ -1578,6 +1584,7 @@ bh->b_dirt = 0; bh->b_flushtime = 0; bh->b_lock = 0; + bh->b_prot = 0; bh->b_uptodate = 0; bh->b_req = 0; bh->b_dev = dev; @@ -1749,7 +1756,7 @@ continue; } - if (bh->b_lock || !bh->b_dirt) + if (bh->b_lock || !bh->b_dirt || bh->b_prot) continue; ndirty++; if(bh->b_flushtime > jiffies) continue; diff -u --recursive --new-file linux-1.3.10/include/linux/fs.h linux/include/linux/fs.h --- linux-1.3.10/include/linux/fs.h Sun Jul 16 13:48:52 1995 +++ linux/include/linux/fs.h Sun Jul 16 13:55:31 1995 @@ -135,6 +135,7 @@ unsigned short b_count; /* users using this block */ unsigned char b_uptodate; unsigned char b_dirt; /* 0-clean,1-dirty */ + unsigned char b_prot; /* 0-regular,1-protected */ unsigned char b_lock; /* 0 - ok, 1 -locked */ unsigned char b_req; /* 0 if the buffer has been invalidated */ unsigned char b_list; /* List that this buffer appears */ diff -u --recursive --new-file linux-1.3.10/include/linux/rd_gz_crypt.h linux/include/linux/rd_gz_crypt.h --- linux-1.3.10/include/linux/rd_gz_crypt.h Wed Dec 31 17:00:00 1969 +++ linux/include/linux/rd_gz_crypt.h Sun Jul 16 14:18:11 1995 @@ -0,0 +1,12 @@ +/* crypt.h (dummy version) -- do not perform encryption + * Hardly worth copyrighting :-) + */ + +#ifdef CRYPT +# undef CRYPT /* dummy version */ +#endif + +#define RAND_HEAD_LEN 12 /* length of encryption random header */ + +#define zencode +#define zdecode diff -u --recursive --new-file linux-1.3.10/include/linux/rd_gz_gzip.h linux/include/linux/rd_gz_gzip.h --- linux-1.3.10/include/linux/rd_gz_gzip.h Wed Dec 31 17:00:00 1969 +++ linux/include/linux/rd_gz_gzip.h Sun Jul 16 14:18:11 1995 @@ -0,0 +1,278 @@ +/* gzip.h -- common declarations for all gzip modules + * Copyright (C) 1992-1993 Jean-loup Gailly. + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License, see the file COPYING. + */ + +#if defined(__STDC__) || defined(PROTO) +# define OF(args) args +#else +# define OF(args) () +#endif + +#ifdef __STDC__ + typedef void *voidp; +#else + typedef char *voidp; +#endif + +#ifndef NULL +#define NULL 0 +#endif +#define memzero(s, n) memset((s), 0, (n)) +#define malloc(size) kmalloc(size, GFP_KERNEL) +#define free(ptr) kfree_s((ptr), 0) + +#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +#endif + +#ifndef RETSIGTYPE +# define RETSIGTYPE void +#endif + +#define local static + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +/* Return codes from gzip */ +#define OK 0 +#define ERROR 1 +#define WARNING 2 + +/* Compression methods (see algorithm.doc) */ +#define STORED 0 +#define COMPRESSED 1 +#define PACKED 2 +/* methods 3 to 7 reserved */ +#define DEFLATED 8 +extern int method; /* compression method */ + +/* To save memory for 16 bit systems, some arrays are overlayed between + * the various modules: + * deflate: prev+head window d_buf l_buf outbuf + * unlzw: tab_prefix tab_suffix stack inbuf outbuf + * inflate: window inbuf + * unpack: window inbuf + * For compression, input is done in window[]. For decompression, output + * is done in window except for unlzw. + */ + +#ifndef INBUFSIZ +# define INBUFSIZ 0x800 /* input buffer size */ +#endif +#define INBUF_EXTRA 64 /* required by unlzw() */ + +#ifndef OUTBUFSIZ +# define OUTBUFSIZ 0x800000 /* output buffer size */ +#endif +#define OUTBUF_EXTRA 2048 /* required by unlzw() */ + +#define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ + +#ifdef DYN_ALLOC +# define EXTERN(type, array) extern type * near array +# define DECLARE(type, array, size) type * near array +# define ALLOC(type, array, size) { \ + array = (type*)fcalloc((unsigned)(((size)+1L)/2), 2*sizeof(type)); \ + if (array == NULL) error("insufficient memory"); \ + } +# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;} +#else +# define EXTERN(type, array) extern type array[] +# define DECLARE(type, array, size) type array[size] +# define ALLOC(type, array, size) +# define FREE(array) +#endif + +EXTERN(uch, inbuf); +extern unsigned char * outbuf; +EXTERN(ush, d_buf); /* buffer for distances, see trees.c */ +EXTERN(uch, window); /* Sliding window and suffix table (unlzw) */ +#define tab_suffix window +#ifndef MAXSEG_64K +# define tab_prefix prev /* hash link (see deflate.c) */ +# define head (prev+WSIZE) /* hash head (see deflate.c) */ + EXTERN(ush, tab_prefix); /* prefix code (see unlzw.c) */ +#else +# define tab_prefix0 prev +# define head tab_prefix1 + EXTERN(ush, tab_prefix0); /* prefix for even codes */ + EXTERN(ush, tab_prefix1); /* prefix for odd codes */ +#endif + +extern unsigned insize; /* valid bytes in inbuf */ +extern unsigned inptr; /* index of next byte to be processed in inbuf */ +extern unsigned outcnt; /* bytes in output buffer */ + +extern long bytes_in; /* number of input bytes */ +extern long bytes_out; /* number of output bytes */ +extern long overhead; /* number of bytes in gzip header */ + +#define isize bytes_in +/* for compatibility with old zip sources (to be cleaned) */ + +extern int ifd; /* input file descriptor */ +extern int ofd; /* output file descriptor */ +extern char ifname[]; /* input filename or "stdin" */ +extern char ofname[]; /* output filename or "stdout" */ + +extern ulg time_stamp; /* original time stamp (modification time) */ +extern long ifile_size; /* input file size, -1 for devices (debug only) */ + +extern int exit_code; /* program exit code */ + +typedef int file_t; /* Do not use stdio */ +#define NO_FILE (-1) /* in memory compression */ + + +#define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ +#define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ +#define PKZIP_MAGIC "PK\003\004" /* Magic header for pkzip files */ +#define PACK_MAGIC "\037\036" /* Magic header for packed files */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +/* internal file attribute */ +#define UNKNOWN (-1) +#define BINARY 0 +#define ASCII 1 + +#ifndef WSIZE +# define WSIZE 0x8000 /* window size--must be a power of two, and */ +#endif /* at least 32K for zip's deflate method */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST (WSIZE-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +extern int decrypt; /* flag to turn on decryption */ +extern int save_orig_name; /* set if original name must be saved */ +extern int verbose; /* be verbose (-v) */ +extern int level; /* compression level */ +extern int test; /* check .z file integrity */ +extern int to_stdout; /* output to stdout (-c) */ + +extern int get_byte(void); + +/* put_byte is used for the compressed output, put_char for the + * uncompressed output. However unlzw() uses window for its + * suffix table instead of its output buffer, so it does not use put_char. + * (to be cleaned up). + */ +#define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\ + flush_outbuf();} +#define put_char(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\ + flush_window();} + +/* Output a 16 bit value, lsb first */ +#define put_short(w) \ +{ if (outcnt < OUTBUFSIZ-2) { \ + outbuf[outcnt++] = (uch) ((w) & 0xff); \ + outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \ + } else { \ + put_byte((uch)((w) & 0xff)); \ + put_byte((uch)((ush)(w) >> 8)); \ + } \ +} + +/* Output a 32 bit value to the bit stream, lsb first */ +#define put_long(n) { \ + put_short((n) & 0xffff); \ + put_short(((ulg)(n)) >> 16); \ +} + +#define seekable() 0 /* force sequential output */ +#define translate_eol 0 /* no option -a yet */ + +#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) /* force to lower case */ + +/* Macros for getting two-byte and four-byte header values */ +#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) +#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + /* in zip.c: */ +extern void zip OF((int in, int out)); +extern int file_read OF((char *buf, unsigned size)); + + /* in unzip.c */ +extern void unzip OF((int in, int out)); +extern int check_zipfile OF((int in)); + + /* in unpack.c */ +extern void unpack OF((int in, int out)); + + /* in gzip.c */ +RETSIGTYPE abort_gzip OF((void)); + + /* in deflate.c */ +void lm_init OF((int pack_level, ush *flags)); +ulg deflate OF((void)); + + /* in trees.c */ +void ct_init OF((ush *attr, int *method)); +int ct_tally OF((int dist, int lc)); +ulg flush_block OF((char *buf, ulg stored_len, int eof)); + + /* in bits.c */ +void bi_init OF((file_t zipfile)); +void send_bits OF((int value, int length)); +unsigned bi_reverse OF((unsigned value, int length)); +void bi_windup OF((void)); +void copy_block OF((char *buf, unsigned len, int header)); +extern int (*read_buf) OF((char *buf, unsigned size)); + + /* in util.c: */ +extern ulg updcrc OF((uch *s, unsigned n)); +extern void clear_bufs OF((void)); +extern int fill_inbuf OF((void)); +extern void flush_outbuf OF((void)); +extern void flush_window OF((void)); +extern char *strlwr OF((char *s)); +extern char *basename OF((char *fname)); +extern char *add_envopt OF((int *argcp, char ***argvp, char *env)); +extern void error OF((char *m)); +extern void warn OF((char *a, char *b)); +extern void read_error OF((void)); +extern void write_error OF((void)); +extern void display_ratio OF((long num, long den)); +extern voidp xmalloc OF((unsigned int size)); + + /* in inflate.c */ +extern int inflate OF((void)); diff -u --recursive --new-file linux-1.3.10/include/linux/rd_gz_lzw.h linux/include/linux/rd_gz_lzw.h --- linux-1.3.10/include/linux/rd_gz_lzw.h Wed Dec 31 17:00:00 1969 +++ linux/include/linux/rd_gz_lzw.h Sun Jul 16 14:18:11 1995 @@ -0,0 +1,42 @@ +/* lzw.h -- define the lzw functions. + * Copyright (C) 1992-1993 Jean-loup Gailly. + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License, see the file COPYING. + */ + +#if !defined(OF) && defined(lint) +# include "gzip.h" +#endif + +#ifndef BITS +# define BITS 16 +#endif +#define INIT_BITS 9 /* Initial number of bits per code */ + +#define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ + +#define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ +/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free. + * It's a pity that old uncompress does not check bit 0x20. That makes + * extension of the format actually undesirable because old compress + * would just crash on the new format instead of giving a meaningful + * error message. It does check the number of bits, but it's more + * helpful to say "unsupported format, get a new version" than + * "can only handle 16 bits". + */ + +#define BLOCK_MODE 0x80 +/* Block compression: if table is full and compression rate is dropping, + * clear the dictionary. + */ + +#define LZW_RESERVED 0x60 /* reserved bits */ + +#define CLEAR 256 /* flush the dictionary */ +#define FIRST (CLEAR+1) /* first free entry */ + +extern int maxbits; /* max bits per code for LZW */ +extern int block_mode; /* block compress mode -C compatible with 2.0 */ + +extern void lzw OF((int in, int out)); +extern void unlzw OF((int in, int out)); diff -u --recursive --new-file linux-1.3.10/include/linux/version.h linux/include/linux/version.h --- linux-1.3.10/include/linux/version.h Sun Jul 16 13:48:57 1995 +++ linux/include/linux/version.h Sun Jul 16 14:23:05 1995 @@ -1,6 +1,6 @@ #define UTS_RELEASE "1.3.10" -#define UTS_VERSION "#17 Thu Jul 13 23:29:22 MST 1995" -#define LINUX_COMPILE_TIME "23:29:22" +#define UTS_VERSION "#23 Sun Jul 16 14:23:04 MST 1995" +#define LINUX_COMPILE_TIME "14:23:04" #define LINUX_COMPILE_BY "root" #define LINUX_COMPILE_HOST "flyer" #define LINUX_COMPILE_DOMAIN "page.com"