Import 1.1.21.1.2
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:27 +0000 (23 15:09 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:27 +0000 (23 15:09 -0500)
70 files changed:
CREDITS
Makefile
README
drivers/block/hd.c
drivers/block/ramdisk.c
drivers/block/xd.c
drivers/char/keyboard.c
drivers/net/3c503.c
drivers/net/3c507.c
drivers/net/depca.c
drivers/net/depca.h
drivers/net/eexpress.c
drivers/net/net_init.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_ioctl.h
drivers/scsi/sd.c
drivers/scsi/sd_ioctl.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/sound/os.h
fs/block_dev.c
fs/buffer.c
fs/ext/file.c
fs/ext/freelists.c
fs/ext/inode.c
fs/ext/namei.c
fs/ext/truncate.c
fs/ext2/balloc.c
fs/ext2/file.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/ext2/super.c
fs/ext2/truncate.c
fs/hpfs/hpfs_fs.c
fs/isofs/dir.c
fs/isofs/file.c
fs/isofs/inode.c
fs/isofs/rock.c
fs/minix/bitmap.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/namei.c
fs/minix/truncate.c
fs/msdos/fat.c
fs/msdos/file.c
fs/msdos/inode.c
fs/msdos/misc.c
fs/msdos/namei.c
fs/sysv/balloc.c
fs/sysv/file.c
fs/sysv/ialloc.c
fs/sysv/inode.c
fs/sysv/namei.c
fs/sysv/truncate.c
fs/xiafs/bitmap.c
fs/xiafs/file.c
fs/xiafs/inode.c
fs/xiafs/namei.c
fs/xiafs/truncate.c
include/linux/fs.h
kernel/ksyms.c
mm/memory.c
net/inet/icmp.c
net/inet/ip.c
net/inet/skbuff.c

index 541d550..4368680 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -351,6+351,13 @@ S: 249 Nichols Avenue
 S: Syracuse, New York 13206
 S: USA
 
+N: Dirk Melchers
+E: dirk@merlin.nbg.sub.org
+D: 8 bit XT hard disk driver for OMTI5520
+S: Branderweg 4
+S: D-91058 Erlangen
+S: Germany
+
 N: Craig Metz
 E: cmetz@tjhsst.edu
 D: Some of PAS 16 mixer & PCM support
index e7ff908..c06f8b7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6+1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 1
+SUBLEVEL = 2
 
 all:   Version zImage
 
@@ -9,7+9,7 @@ all:    Version zImage
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
          else if [ -x /bin/bash ]; then echo /bin/bash; \
          else echo sh; fi ; fi)
-ROOT   := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
+TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
 
 #
 # Make "config" the default target if there is no configuration file or
@@ -77,7+77,7 @@ AS    =as
 LD     =ld
 LDFLAGS        =#-qmagic
 HOSTCC =gcc
-CC     =gcc -D__KERNEL__ -I$(ROOT)/include
+CC     =gcc -D__KERNEL__ -I$(TOPDIR)/include
 MAKE   =make
 CPP    =$(CC) -E
 AR     =ar
diff --git a/READMEb/README
index 5bea132..f6be4be 100644 (file)
--- a/README
+++ b/README
@@ -81,9+81,6 @@ CONFIGURING the kernel:
          should probably answer 'n' to the questions for a "production"
          kernel. 
 
- - edit drivers/net/CONFIG to configure the networking parts of the
-   kernel.  The comments should hopefully clarify it all. 
-
  - Check the top Makefile for further site-dependent configuration
    (default SVGA mode etc). 
 
index c26348f..564dc99 100644 (file)
@@ -542,6+542,12 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        put_fs_long(hd[MINOR(inode->i_rdev)].start_sect,
                                (long *) &loc->start);
                        return 0;
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                case BLKGETSIZE:   /* Return device size */
                        if (!arg)  return -EINVAL;
                        err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
index 4904409..0a13e7a 100644 (file)
@@ -126,7+126,7 @@ void rd_load(void)
         */
        for (tries = 0; tries < 1000; tries += 512) {
                block = tries;
-               bh = breada(ROOT_DEV,block+1,block,block+2,-1);
+               bh = breada(ROOT_DEV,block+1,BLOCK_SIZE, 0,  PAGE_SIZE);
                if (!bh) {
                        printk("RAMDISK: I/O error while looking for super block!\n");
                        return;
@@ -154,7+154,7 @@ void rd_load(void)
                cp = rd_start;
                while (nblocks) {
                        if (nblocks > 2) 
-                               bh = breada(ROOT_DEV, block, block+1, block+2, -1);
+                               bh = breada(ROOT_DEV, block, BLOCK_SIZE, 0,  PAGE_SIZE);
                        else
                                bh = bread(ROOT_DEV, block, BLOCK_SIZE);
                        if (!bh) {
index bc5258c..973a902 100644 (file)
@@ -252,6+252,12 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
                                        return (0);
                                }
                                break;
+                       case BLKRASET:
+                         if(!suser())  return -EACCES;
+                         if(!inode->i_rdev) return -EINVAL;
+                         if(arg > 0xff) return -EINVAL;
+                         read_ahead[MAJOR(inode->i_rdev)] = arg;
+                         return 0;
                        case BLKGETSIZE:
                                if (arg) {
                                        if ((err = verify_area(VERIFY_WRITE,(long *) arg,sizeof(long))))
index cec5449..5742576 100644 (file)
@@ -85,7+85,7 @@ static int want_console = -1;
 static int last_console = 0;           /* last used VC */
 static int dead_key_next = 0;
 static int shift_state = 0;
-static int npadch = -1;                        /* -1 or number assembled on pad */
+static int npadch = -1;                        /* -1 or number assembled on pad */
 static unsigned char diacr = 0;
 static char rep = 0;                   /* flag telling character repeat */
 struct kbd_struct kbd_table[NR_CONSOLES];
@@ -100,7+100,7 @@ typedef void (*k_hand)(unsigned char value, char up_flag);
 typedef void (k_handfn)(unsigned char value, char up_flag);
 
 static k_handfn
-        do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+       do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
        do_meta, do_ascii, do_lock, do_lowercase;
 
 static k_hand key_handler[] = {
@@ -196,7+196,7 @@ static void keyboard_interrupt(int int_pt_regs)
 {
        unsigned char scancode;
        static unsigned int prev_scancode = 0;   /* remember E0, E1 */
-       char up_flag;                            /* 0 or 0200 */
+       char up_flag;                            /* 0 or 0200 */
        char raw_mode;
 
        pt_regs = (struct pt_regs *) int_pt_regs;
@@ -214,15+214,15 @@ static void keyboard_interrupt(int int_pt_regs)
                goto end_kbd_intr;
        } else if (scancode == 0) {
 #ifdef KBD_REPORT_ERR
-               printk("keyboard buffer overflow\n");
+               printk("keyboard buffer overflow\n");
 #endif
                goto end_kbd_intr;
        } else if (scancode == 0xff) {
 #ifdef KBD_REPORT_ERR
-               printk("keyboard error\n");
+               printk("keyboard error\n");
 #endif
-               prev_scancode = 0;
-               goto end_kbd_intr;
+               prev_scancode = 0;
+               goto end_kbd_intr;
        }
        tty = TTY_TABLE(0);
        kbd = kbd_table + fg_console;
@@ -242,7+242,7 @@ static void keyboard_interrupt(int int_pt_regs)
         */
        up_flag = (scancode & 0200);
        scancode &= 0x7f;
-  
+
        if (prev_scancode) {
          /*
           * usually it will be 0xe0, but a Pause key generates
@@ -294,7+294,7 @@ static void keyboard_interrupt(int int_pt_regs)
 #endif
          goto end_kbd_intr;
        }
-  
+
        /*
         * At this point the variable `scancode' contains the keysym.
         * We keep track of the up/down status of the key, and
@@ -308,15+308,15 @@ static void keyboard_interrupt(int int_pt_regs)
                rep = 0;
        } else
                rep = set_bit(scancode, key_down);
-  
+
        if (raw_mode)
-               goto end_kbd_intr;
+               goto end_kbd_intr;
 
        if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) {
                put_queue(scancode + up_flag);
                goto end_kbd_intr;
        }
-  
+
        /*
         * Small change in philosophy: earlier we defined repetition by
         *       rep = scancode == prev_keysym;
@@ -330,7+330,7 @@ static void keyboard_interrupt(int int_pt_regs)
         *  characters get echoed locally. This makes key repeat usable
         *  with slow applications and under heavy loads.
         */
-       if (!rep || 
+       if (!rep ||
            (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
             (L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
        {
@@ -499,7+499,7 @@ static void boot_it(void)
 
 static void compose(void)
 {
-        dead_key_next = 1;
+       dead_key_next = 1;
 }
 
 static void do_spec(unsigned char value, char up_flag)
@@ -523,22+523,22 @@ static void do_spec(unsigned char value, char up_flag)
 
 static void do_lowercase(unsigned char value, char up_flag)
 {
-        printk("keyboard.c: do_lowercase was called - impossible\n");
+       printk("keyboard.c: do_lowercase was called - impossible\n");
 }
-  
+
 static void do_self(unsigned char value, char up_flag)
 {
        if (up_flag)
                return;         /* no action, if this is a key release */
 
-        if (diacr)
-                value = handle_diacr(value);
+       if (diacr)
+               value = handle_diacr(value);
 
-        if (dead_key_next) {
-                dead_key_next = 0;
-                diacr = value;
-                return;
-        }
+       if (dead_key_next) {
+               dead_key_next = 0;
+               diacr = value;
+               return;
+       }
 
        put_queue(value);
 }
@@ -549,7+549,7 @@ static void do_self(unsigned char value, char up_flag)
 #define A_TILDE  '~'
 #define A_DIAER  '"'
 static unsigned char ret_diacr[] =
-        {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
+       {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
 
 /* If a dead key pressed twice, output a character corresponding to it,        */
 /* otherwise just remember the dead key.                               */
@@ -559,12+559,12 @@ static void do_dead(unsigned char value, char up_flag)
        if (up_flag)
                return;
 
-        value = ret_diacr[value];
-        if (diacr == value) {   /* pressed twice */
-                diacr = 0;
-                put_queue(value);
-                return;
-        }
+       value = ret_diacr[value];
+       if (diacr == value) {   /* pressed twice */
+               diacr = 0;
+               put_queue(value);
+               return;
+       }
        diacr = value;
 }
 
@@ -574,19+574,20 @@ static void do_dead(unsigned char value, char up_flag)
 
 unsigned char handle_diacr(unsigned char ch)
 {
-        int d = diacr;
-        int i;
+       int d = diacr;
+       int i;
 
-        diacr = 0;
-        if (ch == ' ')
-                return d;
+       diacr = 0;
+       if (ch == ' ')
+               return d;
 
-        for (i = 0; i < accent_table_size; i++)
-          if(accent_table[i].diacr == d && accent_table[i].base == ch)
-            return accent_table[i].result;
+       for (i = 0; i < accent_table_size; i++) {
+               if (accent_table[i].diacr == d && accent_table[i].base == ch)
+                       return accent_table[i].result;
+       }
 
-        put_queue(d);
-        return ch;
+       put_queue(d);
+       return ch;
 }
 
 static void do_cons(unsigned char value, char up_flag)
@@ -601,9+602,9 @@ static void do_fn(unsigned char value, char up_flag)
        if (up_flag)
                return;
        if (value < SIZE(func_table))
-               puts_queue(func_table[value]);
+               puts_queue(func_table[value]);
        else
-               printk("do_fn called with value=%d\n", value);
+               printk("do_fn called with value=%d\n", value);
 }
 
 static void do_pad(unsigned char value, char up_flag)
@@ -686,7+687,7 @@ static void do_shift(unsigned char value, char up_flag)
        }
 
        if (up_flag) {
-               /* handle the case that two shift or control
+               /* handle the case that two shift or control
                   keys are depressed simultaneously */
                if (k_down[value])
                        k_down[value]--;
@@ -709,9+710,9 @@ static void do_shift(unsigned char value, char up_flag)
    recompute k_down[] and shift_state from key_down[] */
 void compute_shiftstate(void)
 {
-        int i, j, k, sym, val;
+       int i, j, k, sym, val;
 
-        shift_state = 0;
+       shift_state = 0;
        for(i=0; i < SIZE(k_down); i++)
          k_down[i] = 0;
 
@@ -725,7+726,7 @@ void compute_shiftstate(void)
                  val = KVAL(sym);
                  k_down[val]++;
                  shift_state |= (1<<val);
-               }
+               }
              }
          }
 }
@@ -748,9+749,9 @@ static void do_ascii(unsigned char value, char up_flag)
                return;
 
        if (npadch == -1)
-               npadch = value;
+               npadch = value;
        else
-               npadch = (npadch * 10 + value) % 1000;
+               npadch = (npadch * 10 + value) % 1000;
 }
 
 static void do_lock(unsigned char value, char up_flag)
index f46f3b1..6e5ef8d 100644 (file)
@@ -22,6+22,7 @@ static char *version =
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 4c6221e..cdf16cd 100644 (file)
@@ -44,12+44,12 @@ static char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <errno.h>
-#include <memory.h>
+#include <linux/errno.h>
 
 #include "dev.h"
 #include "eth.h"
index 3178159..2c996a8 100644 (file)
-/*  depca.c: A DIGITAL DEPCA ethernet driver for linux.
+/*  depca.c: A DIGITAL DEPCA  & EtherWORKS ethernet driver for linux.
 
     Written 1994 by David C. Davies.
 
-    Copyright 1994 David C. Davies and United States Government as
-    represented by the Director, National Security Agency.  This software
-    may be used and distributed according to the terms of the GNU Public
-    License, incorporated herein by reference.
+
+                      Copyright 1994 David C. Davies
+                                  and 
+                        United States Government
+        (as represented by the Director, National Security Agency).  
+
+
+    This software may be used and distributed according to the terms of
+    the GNU Public License, incorporated herein by reference.
 
     This driver is written for the Digital Equipment Corporation series
-    of DEPCA ethernet cards:
+    of DEPCA and EtherWORKS ethernet cards:
 
-       DE100 DEPCA
-       DE200 DEPCA Turbo
-       DE202 DEPCA Turbo (TP BNC)
-       DE210 DEPCA
+        DEPCA       (the original)
+       DE100
+       DE200 Turbo
+       DE201 Turbo
+       DE202 Turbo (TP BNC)
+       DE210
 
-    The driver has been tested on DE100 and DE20x cards in a relatively busy 
-    network.
+    The  driver has been tested on DE100, DE200 and DE202 cards  in  a
+    relatively busy network.
 
-    The author may be reached as davies@wanton.enet.dec.com or
+    This driver  will  not work  for the DE203,  DE204  and DE205 series  of
+    cards, since they have a new custom ASIC in place of the AMD LANCE chip.
+
+    The author may be reached as davies@wanton.lkg.dec.com or
     Digital Equipment Corporation, 146 Main Street, Maynard MA 01754.
 
     =========================================================================
     the   filter bit   positions  correctly.  Hash   filtering  is  not  yet
     implemented in the current driver set.
 
-    The  DE200 series boards have   on-board 64kB RAM  for  use as a  shared
-    memory network buffer. Only  the DE100 cards  make  use of a  2kB buffer
-    mode  which has not  been implemented in  this driver (only the 32kB and
-    64kB modes are supported).
+    The original DEPCA  card requires that  the ethernet ROM address counter
+    be enabled to count and has an 8 bit NICSR.  The ROM counter enabling is
+    only done when  a 0x08 is read as  the first address octet  (to minimise
+    the chances of  writing over some other hardware's  I/O  register).  The
+    size of the NICSR is tested by a word read: if  both bytes are the same,
+    the register  is 8 bits wide.   Also,  there is a   maximum of only 48kB
+    network  RAM for   this card.  My   thanks  to Torbjorn Lindh   for help
+    debugging all this  (and holding  my  feet to the   fire until I got  it
+    right).
+
+    The DE200  series  boards have  on-board 64kB  RAM for  use  as a shared
+    memory network  buffer. Only the DE100  cards make use  of a  2kB buffer
+    mode which has not  been implemented in  this driver (only the 32kB  and
+    64kB modes are supported [16kB/48kB for the original DEPCA]).
 
     At the  most only 2 DEPCA  cards can be supported  because there is only
     provision for two I/O base addresses on the cards (0x300 and 0x200). The
     this unambiguously at the moment, since there is nothing on the cards to
     tie I/O and memory information together.
 
-    I   am unable to test    2 DEPCAs together for   now,   so this code  is
+    I am unable  to  test  2 cards   together for now,    so this  code   is
     unchecked. All reports, good or bad, are welcome.
 
     ************************************************************************
 
-    The board IRQ  setting must be  at  an unused  IRQ  which is auto-probed
-    using   Donald Becker's   autoprobe   routines. DE100   board IRQs   are
-    {2,3,4,5,7}, whereas  the DE200 is at  {5,9,10,11,15}. Note that IRQ2 is
+    The board IRQ   setting must be  at an  unused IRQ which  is auto-probed
+    using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
+    {2,3,4,5,7}, whereas the  DE200 is at {5,9,10,11,15}.  Note that IRQ2 is
     really IRQ9 in machines with 16 IRQ lines.
 
     No 16MB memory  limitation should exist with this  driver as DMA is  not
     used and the common memory area is in low memory on the network card (my
     current system has 20MB and I've not had problems yet).
 
-    The DE203,  DE204  and DE205 cards  may  also work  with this driver  (I
-    haven't tested  them so I don't  know). If you have  one of these cards,
-    place the name in the DEPCA_SIGNATURE string  around line 160, recompile
-    the kernel and reboot. Check if the card  is recognised and works - mail
-    me if so, so that I can add it into the list of supported cards!
-
     TO DO:
     ------
 
 
     Version   Date        Description
   
-      0.1   25-jan-94     Initial writing
-      0.2   27-jan-94     Added LANCE TX buffer chaining
-      0.3    1-feb-94     Added multiple DEPCA support
-      0.31   4-feb-94     Added DE202 recognition
+      0.1   25-jan-94     Initial writing.
+      0.2   27-jan-94     Added LANCE TX buffer chaining.
+      0.3    1-feb-94     Added multiple DEPCA support.
+      0.31   4-feb-94     Added DE202 recognition.
       0.32  19-feb-94     Tidy up. Improve multi-DEPCA support.
+      0.33  25-feb-94     Fix DEPCA ethernet ROM counter enable.
+                          Add jabber packet fix from murf@perftech.com
+                         and becker@super.org
+      0.34   7-mar-94     Fix DEPCA max network memory RAM & NICSR access.
+      0.35   8-mar-94     Added DE201 recognition.
 
     =========================================================================
 */
 
-static char *version = "depca.c:v0.32 2/19/94 davies@wanton.enet.dec.com\n";
+static char *version = "depca.c:v0.35 3/8/94 davies@wanton.lkg.dec.com\n";
 
 #include <stdarg.h>
 #include <linux/config.h>
@@ -129,7+148,7 @@ static char *version = "depca.c:v0.32 2/19/94 davies@wanton.enet.dec.com\n";
 #include <asm/dma.h>
 
 #include "dev.h"
-#include "iow.h"
+#include "iow.h"                    /* left in for pl13/14 compatibility... */
 #include "eth.h"
 #include "skbuff.h"
 #include "arp.h"
@@ -155,7+174,7 @@ int depca_debug = 1;
 #endif
 
 #ifndef DEPCA_SIGNATURE
-#define DEPCA_SIGNATURE {"DEPCA","DE100","DE200","DE202","DE210",""}
+#define DEPCA_SIGNATURE {"DEPCA","DE100","DE200","DE201","DE202","DE210",""}
 #define DEPCA_NAME_LENGTH 8
 #endif
 
@@ -241,7+260,7 @@ struct depca_private {
     int dirty_rx, dirty_tx;    /* The ring entries to be free()ed. */
     int dma;
     struct enet_statistics stats;
-    char old_depca;
+    char depca_na;              /* NICSR access width: 0=>byte, 1=>word */
     short ringSize;             /* ring size based on available memory */
     short rmask;                /* modulus mask based on ring size */
     long rlen;                  /* log2(ringSize) for the descriptors */
@@ -275,6+294,7 @@ static int DevicePresent(short ioaddr);
 static void SetMulticastFilter(int num_addrs, char *addrs, char *multicast_table);
 #endif
 
+static int depca_na;
 static int num_depcas = 0, num_eth = 0;;
 
 /*
@@ -284,6+304,21 @@ static int num_depcas = 0, num_eth = 0;;
     outw(CSR0, DEPCA_ADDR);\
     outw(STOP, DEPCA_DATA)
 
+#define GET_NICSR(a,b) \
+    if (depca_na) { \
+      (a) = inw((b)); \
+    } else { \
+      (a) = inb((b)); \
+    }
+
+#define PUT_NICSR(a,b) \
+    if (depca_na) { \
+      outw((a), (b)); \
+    } else { \
+      outb((a), (b)); \
+    }
+
+
 \f
 
 int depca_probe(struct device *dev)
@@ -294,7+329,10 @@ int depca_probe(struct device *dev)
     struct device *eth0 = (struct device *) NULL;
 
     if (base_addr > 0x1ff) {         /* Check a single specified location. */
-               status = depca_probe1(dev, base_addr);
+      status = -ENODEV;
+      if (DevicePresent(base_addr) == 0) { /* Is DEPCA really here? */
+       status = depca_probe1(dev, base_addr);
+      }
     } else if (base_addr > 0) {              /* Don't probe at all. */
                status = -ENXIO;
     } else {                          /* First probe for the DEPCA test */
@@ -308,7+346,7 @@ int depca_probe(struct device *dev)
        if (check_region(ioaddr, DEPCA_TOTAL_SIZE))
            continue;
 #endif
-       if (DevicePresent(DEPCA_PROM) == 0) {
+       if (DevicePresent(ioaddr) == 0) {
          if (num_depcas > 0) {        /* only gets here in autoprobe */
 
            /*
@@ -370,17+408,18 @@ depca_probe1(struct device *dev, short ioaddr)
     int i,j, status=0;
     unsigned long mem_start, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
     char *name=(char *)NULL;
-    int nicsr, offset;
+    unsigned int nicsr, offset, netRAM;
 
 
     /*
-    ** Stop the DEPCA. Enable the DBR ROM. Disable interrupts and remote boot
+    ** Stop the DEPCA. Enable the DBR ROM and the ethernet ROM address counter
+    ** (for the really old DEPCAs). Disable interrupts and remote boot.
     */
     STOP_DEPCA;
 
-    nicsr = inw(DEPCA_NICSR);
-    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
-    outw(nicsr, DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
+    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | AAC | IM);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     if (inw(DEPCA_DATA) == STOP) {
 
@@ -438,18+477,27 @@ depca_probe1(struct device *dev, short ioaddr)
        snarf_region(ioaddr, DEPCA_TOTAL_SIZE);
 #endif
 
+       /*
+       ** Set up the maximum amount of network RAM(kB)
+       */
+       if (strstr(name,"DEPCA")==(char *)NULL) {
+         netRAM=64;
+       } else {
+         netRAM=48;
+       }
+
        /* 
         ** Determine the base address for the DEPCA RAM from the NI-CSR
         ** and make up a DEPCA-specific-data structure. 
         */
 
        if (nicsr & BUF) {
-         offset = 0x8000;              /* 32kbyte RAM */
+         offset = 0x8000;              /* 32kbyte RAM offset*/
          nicsr &= ~BS;                 /* DEPCA RAM in top 32k */
-         printk(",\n      with 32kB RAM");
+         printk(",\n      with %dkB RAM", netRAM-(offset >> 10));
        } else {
-         offset = 0x0000;              /* 64kbyte RAM */
-         printk(",\n      with 64kB RAM");
+         offset = 0x0000;              /* 64k/48k bytes RAM */
+         printk(",\n      with %dkB RAM", netRAM);
        }
 
        mem_start += offset;
@@ -459,17+507,19 @@ depca_probe1(struct device *dev, short ioaddr)
         ** Enable the shadow RAM.
        */
        nicsr |= SHE;
-       outw(nicsr, DEPCA_NICSR);
+       PUT_NICSR(nicsr, DEPCA_NICSR);
  
        /*
        ** Calculate the ring size based on the available RAM
        ** found above. Allocate an equal number of buffers, each
-       ** of size PKT_BUF_SZ (1544 bytes) to the Tx and Rx. Make sure
+       ** of size PKT_BUF_SZ (1544 bytes) to the Tx and Rx, allowing one
+       ** descriptor entry (8 bytes) for each buffer. Make sure
        ** that this ring size is <= RING_SIZE. The ring size must be
        ** a power of 2.
        */
 
-       j = ((0x10000 - offset) / PKT_BUF_SZ) >> 1;
+       j = (((netRAM << 10) - offset - sizeof(struct depca_private)) / 
+                                                      (PKT_BUF_SZ + 8)) >> 1;
        for (i=0;j>1;i++) {
          j >>= 1;
        }
@@ -549,10+599,15 @@ depca_probe1(struct device *dev, short ioaddr)
        LoadCSRs(dev);
 
        /*
+       ** Store the NICSR width for this DEPCA
+       */
+       lp->depca_na = depca_na;
+
+       /*
        ** Enable DEPCA board interrupts for autoprobing
        */
        nicsr = ((nicsr & ~IM)|IEN);
-       outw(nicsr, DEPCA_NICSR);
+       PUT_NICSR(nicsr, DEPCA_NICSR);
 
        /* The DMA channel may be passed in on this parameter. */
        dev->dma = 0;
@@ -646,8+701,9 @@ depca_open(struct device *dev)
     /*
     ** Stop the DEPCA & get the board status information.  
     */
+    depca_na=lp->depca_na;
     STOP_DEPCA;
-    nicsr = inw(DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
 
     /* 
     ** Re-initialize the DEPCA... 
@@ -698,7+754,7 @@ depca_open(struct device *dev)
     ** Enable DEPCA board interrupts
     */
     nicsr = ((nicsr & ~IM & ~LED)|SHE|IEN);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
     outw(CSR0,DEPCA_ADDR);
 
     dev->tbusy = 0;                         
@@ -709,7+765,8 @@ depca_open(struct device *dev)
 
     if (depca_debug > 1){
       printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));
-      printk("nicsr: 0x%4.4x\n",inw(DEPCA_NICSR));
+      GET_NICSR(nicsr, DEPCA_NICSR);
+      printk("nicsr: 0x%4.4x\n",nicsr);
     }
 
     return 0;                            /* Always succeed */
@@ -760,7+817,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev)
     /* Transmitter timeout, serious problems. */
     if (dev->tbusy) {
       int tickssofar = jiffies - dev->trans_start;
-      if (tickssofar < 5) {
+      if (tickssofar < 10) {
        status = -1;
       } else {
        STOP_DEPCA;
@@ -921,6+978,7 @@ depca_interrupt(int reg_ptr)
     } else {
       lp = (struct depca_private *)dev->priv;
       ioaddr = dev->base_addr;
+      depca_na = lp->depca_na;
     }
 
     if (dev->interrupt)
@@ -929,9+987,9 @@ depca_interrupt(int reg_ptr)
     dev->interrupt = MASK_INTERRUPTS;
 
     /* mask the DEPCA board interrupts and turn on the LED */
-    nicsr = inw(DEPCA_NICSR);
+    GET_NICSR(nicsr, DEPCA_NICSR);
     nicsr |= (IM|LED);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     outw(CSR0, DEPCA_ADDR);
     csr0 = inw(DEPCA_DATA);
@@ -961,7+1019,7 @@ depca_interrupt(int reg_ptr)
 
     /* Unmask the DEPCA board interrupts and turn off the LED */
     nicsr = (nicsr & ~IM & ~LED);
-    outw(nicsr, DEPCA_NICSR);
+    PUT_NICSR(nicsr, DEPCA_NICSR);
 
     dev->interrupt = UNMASK_INTERRUPTS;
     return;
@@ -976,9+1034,32 @@ depca_rx(struct device *dev)
     /* If we own the next entry, it's a new packet. Send it up. */
     for (; lp->rx_ring[entry].base >= 0; entry = (++lp->cur_rx) & lp->rmask) {
        int status = lp->rx_ring[entry].base >> 16 ;
+       int chained;
 
-       if (status & R_ERR) {          /* There was an error. */
-           lp->stats.rx_errors++;     /* Update the error stats. */
+       /*
+       ** There is a tricky error noted by John Murphy, <murf@perftech.com>
+       ** to Russ Nelson: even with full-sized buffers, it's possible for a
+       ** jabber packet to use two buffers, with only the last one correctly
+       ** noting the error.
+       */
+
+       /* Check for a chaining buffer */
+       chained = 0;
+       if (status == R_STP) { 
+         chained = 1;
+
+         /* 
+         ** Wait for next buffer to complete to check for errors. This
+         ** is slow but infrequent and allows for correct hardware buffer
+         ** chaining (whilst defeating the chaining's purpose).
+         */
+         while ((status=(lp->rx_ring[(entry+1)&lp->rmask].base >> 16)) < 0);
+
+         /* NB: 'status' now comes from the buffer following 'entry'. */
+       }
+         
+       if (status & R_ERR) {                  /* There was an error. */
+           lp->stats.rx_errors++;             /* Update the error stats. */
            if (status & R_FRAM) lp->stats.rx_frame_errors++;
            if (status & R_OFLO) lp->stats.rx_over_errors++;
            if (status & R_CRC)  lp->stats.rx_crc_errors++;
@@ -1020,6+1101,10 @@ depca_rx(struct device *dev)
 
        /* turn over ownership of the current entry back to the LANCE */
        lp->rx_ring[entry].base |= R_OWN;
+       if (chained && (status & R_ERR)) {          /* next entry also bad */
+         entry = (++lp->cur_rx) & lp->rmask;
+         lp->rx_ring[entry].base |= R_OWN;
+       }
     }
 
     /* 
@@ -1277,7+1362,15 @@ static char *DepcaSignature(unsigned long mem_addr)
 
 /*
 ** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DEPCA products.
+** is common across all DEPCA products. Note that the original DEPCA needs
+** its ROM address counter to be initialized and enabled. Only enable
+** if the first address octet is a 0x08 - this minimises the chances of
+** messing around with some other hardware, but it assumes that this DEPCA
+** card initialized itself correctly. It also assumes that all past and
+** future DEPCA/EtherWORKS cards will have ethernet addresses beginning with
+** a 0x08. The choice of byte or word addressing is made here based on whether
+** word read of the NICSR returns two identical lower and upper bytes: if so
+** the register is 8 bits wide.
 */
 
 static int DevicePresent(short ioaddr)
@@ -1285,9+1378,40 @@ static int DevicePresent(short ioaddr)
   static short fp=1,sigLength=0;
   static char devSig[] = PROBE_SEQUENCE;
   char data;
-  int i, j, status = 0;
+  unsigned char LSB,MSB;
+  int i, j, nicsr, status = 0;
   static char asc2hex(char value);
 
+/*
+** Initialize the counter on a DEPCA card. Two reads to ensure DEPCA ethernet
+** address counter is a) cleared and b) the correct data read.
+*/
+  data = inb(DEPCA_PROM);                /* clear counter */
+  data = inb(DEPCA_PROM);                /* read data */
+
+/*
+** Determine whether a byte or word access should be made on the NICSR.
+** Since the I/O 'functions' are actually in-line code, the choice not to use
+** pointers to functions vs. just set a conditional, is made for us. This code
+** assumes that the NICSR has an asymmetric bit pattern already in it.
+*/
+  nicsr = inw(DEPCA_NICSR);
+  LSB = nicsr & 0xff;
+  MSB = (((unsigned) nicsr) >> 8) & 0xff;
+  if (MSB == LSB) {
+    depca_na = 0;        /* byte accesses */
+  } else {
+    depca_na = 1;        /* word accesses */
+  }
+
+/*
+** Enable counter
+*/
+  if (data == 0x08) {
+    nicsr |= AAC;
+    PUT_NICSR(nicsr, DEPCA_NICSR);
+  }
+  
 /* 
 ** Convert the ascii signature to a hex equivalent & pack in place 
 */
@@ -1318,7+1442,7 @@ static int DevicePresent(short ioaddr)
 */
   if (!status) {
     for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {
-      data = inb(ioaddr);
+      data = inb(DEPCA_PROM);
       if (devSig[j] == data) {    /* track signature */
        j++;
       } else {                    /* lost signature; begin search again */
index 4f5d719..5312118 100644 (file)
 #define BS             0x0040  /* Bank Select */
 #define BUF            0x0020  /* BUFfer size (1->32k, 0->64k) */
 #define RBE            0x0010  /* Remote Boot Enable (1->net boot) */
-#define AAC            0x0008  /* for DEPCA family compatability */
+#define AAC            0x0008  /* Address ROM Address Counter (1->enable) */
 #define IM             0x0004  /* Interrupt Mask (1->mask) */
 #define IEN            0x0002  /* Interrupt tristate ENable (1->enable) */
 #define LED            0x0001  /* LED control */
index 5372fa1..c47bfd7 100644 (file)
@@ -42,12+42,12 @@ static char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <errno.h>
-#include <memory.h>
+#include <linux/errno.h>
 
 #include "dev.h"
 #include "eth.h"
index 4c15147..490abae 100644 (file)
 #include <linux/fs.h>
 #include <linux/malloc.h>
 #include <linux/if_ether.h>
-#include <memory.h>
+#include <linux/string.h>
 #include "dev.h"
 #include "eth.h"
 
index abef8aa..e2f0f90 100644 (file)
@@ -127,6+127,7 @@ static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
 static struct blist blacklist[] = 
 {
    {"CHINON","CD-ROM CDS-431","H42"},  /* Locks up if polled for lun != 0 */
+   {"CHINON","CD-ROM CDS-535","Q14"}, /* Lockup if polled for lun != 0 */
    {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
    {"IMS", "CDD521/10","2.06"},   /* Locks-up when LUN>0 polled. */
    {"MAXTOR","XT-3280","PR02"},   /* Locks-up when LUN>0 polled. */
@@ -533,7+534,7 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
 {
   Scsi_Cmnd * SCpnt = NULL;
   int tablesize;
-  struct buffer_head * bh;
+  struct buffer_head * bh, *bhp;
 
   if ((index < 0) ||  (index > NR_SCSI_DEVICES))
     panic ("Index number in allocate_device() is out of range.\n");
@@ -557,16+558,17 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
   if (req) {
     memcpy(&SCpnt->request, req, sizeof(struct request));
     tablesize = scsi_devices[index].host->sg_tablesize;
-    bh = req->bh;
+    bhp = bh = req->bh;
     if(!tablesize) bh = NULL;
     /* Take a quick look through the table to see how big it is.  We already
        have our copy of req, so we can mess with that if we want to.  */
     while(req->nr_sectors && bh){
-           tablesize--;
+           bhp = bhp->b_reqnext;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
            req->nr_sectors -= bh->b_size >> 9;
            req->sector += bh->b_size >> 9;
            if(!tablesize) break;
-           bh = bh->b_reqnext;
+           bh = bhp;
     };
     if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
       SCpnt->request.bhtail = bh;
@@ -579,9+581,10 @@ Scsi_Cmnd * request_queueable (struct request * req, int index)
       req->current_nr_sectors = bh->b_size >> 9;
       req->buffer = bh->b_data;
       SCpnt->request.waiting = NULL; /* Wait until whole thing done */
-    } else
+    } else {
       req->dev = -1;
-      
+      wake_up(&wait_for_request);
+    };      
   } else {
     SCpnt->request.dev = 0xffff; /* Busy, but no request */
     SCpnt->request.waiting = NULL;  /* And no one is waiting for the device either */
@@ -608,7+611,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
   int dev = -1;
   struct request * req = NULL;
   int tablesize;
-  struct buffer_head * bh;
+  struct buffer_head * bh, *bhp;
   struct Scsi_Host * host;
   Scsi_Cmnd * SCpnt = NULL;
   Scsi_Cmnd * SCwait = NULL;
@@ -654,16+657,17 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
        if (req) {
          memcpy(&SCpnt->request, req, sizeof(struct request));
          tablesize = scsi_devices[index].host->sg_tablesize;
-         bh = req->bh;
+         bhp = bh = req->bh;
          if(!tablesize) bh = NULL;
          /* Take a quick look through the table to see how big it is.  We already
             have our copy of req, so we can mess with that if we want to.  */
          while(req->nr_sectors && bh){
-           tablesize--;
+           bhp = bhp->b_reqnext;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
            req->nr_sectors -= bh->b_size >> 9;
            req->sector += bh->b_size >> 9;
            if(!tablesize) break;
-           bh = bh->b_reqnext;
+           bh = bhp;
          };
          if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
            SCpnt->request.bhtail = bh;
@@ -680,6+684,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
            {
              req->dev = -1;
              *reqp = req->next;
+             wake_up(&wait_for_request);
            };
        } else {
          SCpnt->request.dev = 0xffff; /* Busy */
@@ -1503,8+1508,8 @@ void *scsi_malloc(unsigned int len)
 {
   unsigned int nbits, mask;
   int i, j;
-  if((len & 0x1ff) || len > 4096)
-    panic("Inappropriate buffer size requested");
+  if((len & 0x1ff) || len > 8192)
+    return NULL;
   
   cli();
   nbits = len >> 9;
@@ -1593,6+1598,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
 
        for (i=0; i< NR_SCSI_DEVICES; i++) {
          int j;
+         scsi_devices[i].scsi_request_fn = NULL;
          switch (scsi_devices[i].type)
            {
            case TYPE_TAPE :
index 381b86b..3e7ae55 100644 (file)
@@ -262,6+262,7 @@ typedef struct scsi_device {
        int access_count;       /* Count of open channels/mounts */
        struct wait_queue * device_wait;  /* Used to wait if device is busy */
        struct Scsi_Host * host;
+       void (*scsi_request_fn)(void); /* Used to jumpstart things after an ioctl */
        char type;
        char scsi_level;
        unsigned writeable:1;
@@ -307,10+308,12 @@ struct scatterlist {
      char *  address; /* Location data is to be transferred to */
      char * alt_address; /* Location of actual if address is a 
                            dma indirect buffer.  NULL otherwise */
-     unsigned short length;
+     unsigned int length;
      };
 
 #define ISA_DMA_THRESHOLD (0x00ffffff)
+#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
+
 
 void *   scsi_malloc(unsigned int);
 int      scsi_free(void *, unsigned int);
@@ -389,7+392,6 @@ typedef struct scsi_cmnd {
        /* Low-level done function - can be used by low-level driver to point
         to completion function.  Not used by mid/upper level code. */
        void (*scsi_done)(struct scsi_cmnd *);  
-
        void (*done)(struct scsi_cmnd *);  /* Mid-level done function */
 
 /* The following fields can be written to by the host specific code. 
@@ -426,7+428,6 @@ extern void scsi_do_cmd (Scsi_Cmnd *, const void *cmnd ,
 extern Scsi_Cmnd * allocate_device(struct request **, int, int);
 
 extern Scsi_Cmnd * request_queueable(struct request *, int);
-
 extern int scsi_reset (Scsi_Cmnd *);
 
 extern int max_scsi_hosts;
index 4fe973e..afc617f 100644 (file)
 
 #include <asm/system.h>
 #include <asm/io.h>
-
 #include "../block/blk.h"
 #include "scsi.h"
 #include "hosts.h"
 
+/* A few options that we want selected */
+
+/* Do not attempt to use a timer to simulate a real disk with latency */
+/* Only use this in the actual kernel, not in the simulator. */
+#define IMMEDIATE
+
+/* Skip some consistency checking.  Good for benchmarking */
+#define SPEEDY
+
 /* Number of real scsi disks that will be detected ahead of time */
 static int NR_REAL=-1;
 
-#define MAJOR_NR SCSI_DISK_MAJOR
+#define NR_BLK_DEV     12
+#ifndef MAJOR_NR
+#define MAJOR_NR 8
+#endif
 #define START_PARTITION 4
 #define SCSI_DEBUG_TIMER 20
 /* Number of jiffies to wait before completing a command */
@@ -43,6+54,11 @@ static int npart = 0;
 #define DEB(x)
 #endif
 
+#ifdef SPEEDY
+#define VERIFY1_DEBUG(RW) 1
+#define VERIFY_DEBUG(RW) 1
+#else
+
 #define VERIFY1_DEBUG(RW)                                              \
       if (bufflen != 1024) {printk("%d", bufflen); panic("(1)Bad bufflen");};                  \
       start = 0;                                                       \
@@ -79,6+95,7 @@ static int npart = 0;
          panic ("Wrong bh block#");};  \
        if (SCpnt->request.bh->b_dev != SCpnt->request.dev) panic ("Bad bh target");\
       };
+#endif
 
 static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
 static int scsi_debug_host = 0;
@@ -154,7+171,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     
     buff = (unsigned char *) SCpnt->request_buffer;
 
-    if(target>=2 || SCpnt->lun != 0) {
+    if(target>=1 || SCpnt->lun != 0) {
       SCpnt->result =  DID_NO_CONNECT << 16;
       done(SCpnt);
       return 0;
@@ -187,6+204,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       buff[0] = TYPE_DISK;
       buff[1] = 0x80;  /* Removable disk */
       buff[2] = 1;
+      buff[4] = 33 - 5;
       memcpy(&buff[8],"Foo Inc",7);
       memcpy(&buff[16],"XYZZY",5);
       memcpy(&buff[32],"1",1);
@@ -219,7+237,21 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       else 
        block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
       VERIFY_DEBUG(READ);
+#if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE)
+      {
+       int delay = SCSI_SETUP_LATENCY;
+       double usec;
+
+       usec = 0.0;
+       usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE;
+       delay += usec;
+       if(delay) usleep(delay);
+      };
+#endif
+
+#ifdef DEBUG
       printk("(r%d)",SCpnt->request.nr_sectors);
+#endif
       nbytes = bufflen;
       if(SCpnt->use_sg){
        sgcount = 0;
@@ -231,7+263,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       scsi_debug_errsts = 0;
       do{
        VERIFY1_DEBUG(READ);
+/* For the speedy test, we do not even want to fill the buffer with anything */
+#ifndef SPEEDY
        memset(buff, 0, bufflen);
+#endif
 /* If this is block 0, then we want to read the partition table for this
    device.  Let's make one up */
        if(block == 0 && target == 0) {
@@ -252,6+287,8 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        if (SCpnt->use_sg) printk("Block %x (%d %d)\n",block, SCpnt->request.nr_sectors,
               SCpnt->request.current_nr_sectors);
 #endif
+
+#if 0
        /* Simulate a disk change */
        if(block == 0xfff0) {
          sense_buffer[0] = 0x70;
@@ -270,14+307,19 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
          scsi_debug_errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
          break;
        } /* End phony disk change code */
-       memset(buff, 0, bufflen);
+#endif
+
+#ifndef SPEEDY
        memcpy(buff, &target, sizeof(target));
        memcpy(buff+sizeof(target), cmd, 24);
        memcpy(buff+60, &block, sizeof(block));
        memcpy(buff+64, SCpnt, sizeof(Scsi_Cmnd));
+#endif
        nbytes -= bufflen;
        if(SCpnt->use_sg){
+#ifndef SPEEDY
          memcpy(buff+128, bh, sizeof(struct buffer_head));
+#endif
          block += bufflen >> 9;
          bh = bh->b_reqnext;
          sgcount++;
@@ -288,6+330,11 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
          };
        }
       } while(nbytes);
+
+      SCpnt->result = 0;
+      (done)(SCpnt);
+      return;
+
       if (SCpnt->use_sg && !scsi_debug_errsts)
        if(bh) scsi_dump(SCpnt, 0);
       break;
@@ -301,7+348,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       else 
        block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
       VERIFY_DEBUG(WRITE);
-      printk("(w%d)",SCpnt->request.nr_sectors);
+/*      printk("(w%d)",SCpnt->request.nr_sectors); */
       if (SCpnt->use_sg){
        if ((bufflen >> 9) != SCpnt->request.nr_sectors)
          panic ("Trying to write wrong number of blocks\n");
@@ -344,6+391,10 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     else
       printk("scsi_debug_queuecommand: done cant be NULL\n");
 
+#ifdef IMMEDIATE
+    SCpnt->result = scsi_debug_errsts;
+    scsi_debug_intr_handle();  /* No timer - do this one right away */
+#else
     timeout[i] = jiffies+DISK_SPEED;
 
 /* If no timers active, then set this one */
@@ -358,6+409,7 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 #if 0
     printk("Sending command (%d %x %d %d)...", i, done, timeout[i],jiffies);
 #endif
+#endif
 
     return 0;
 }
@@ -390,18+442,25 @@ static void scsi_debug_intr_handle(void)
     void (*my_done)(Scsi_Cmnd *); 
    int to;
 
+#ifndef IMMEDIATE
     timer_table[SCSI_DEBUG_TIMER].expires = 0;
     timer_active &= ~(1 << SCSI_DEBUG_TIMER);
+#endif
 
   repeat:
     cli();
     for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
       if (SCint[i] == 0) continue;
+#ifndef IMMEDIATE
       if (timeout[i] == 0) continue;
       if (timeout[i] <= jiffies) break;
+#else
+      break;
+#endif
     };
 
     if(i == SCSI_DEBUG_MAILBOXES){
+#ifndef IMMEDIATE
       pending = INT_MAX;
       for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
        if (SCint[i] == 0) continue;
@@ -418,6+477,7 @@ static void scsi_debug_intr_handle(void)
        timer_active |= 1 << SCSI_DEBUG_TIMER;
       };
       sti();
+#endif
       return;
     };
 
@@ -454,8+514,10 @@ static void scsi_debug_intr_handle(void)
 int scsi_debug_detect(int hostnum)
 {
     scsi_debug_host = hostnum;
+#ifndef IMMEDIATE
     timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
     timer_table[SCSI_DEBUG_TIMER].expires = 0;
+#endif
     return 1;
 }
 
@@ -479,7+541,7 @@ int scsi_debug_abort(Scsi_Cmnd * SCpnt,int i)
     return 0;
 }
 
-int scsi_debug_biosparam(int size, int* info){
+int scsi_debug_biosparam(int size, int dev, int* info){
   info[0] = 32;
   info[1] = 64;
   info[2] = (size + 2047) >> 11;
@@ -506,7+568,7 @@ int scsi_debug_reset(Scsi_Cmnd * SCpnt)
     return 0;
 }
 
-char *scsi_debug_info(void)
+const char *scsi_debug_info(void)
 {
     static char buffer[] = " ";                        /* looks nicer without anything here */
     return buffer;
index 725b37e..97ff8c9 100644 (file)
@@ -6,8+6,8 @@ int scsi_debug_detect(int);
 int scsi_debug_command(Scsi_Cmnd *);
 int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int scsi_debug_abort(Scsi_Cmnd *, int);
-int scsi_debug_biosparam(int, int*);
-char *scsi_debug_info(void);
+int scsi_debug_biosparam(int, int, int[]);
+const char *scsi_debug_info(void);
 int scsi_debug_reset(Scsi_Cmnd *);
 
 #ifndef NULL
index 51406de..1b4b496 100644 (file)
@@ -134,7+134,7 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
          };
 
        result = SCpnt->result;
-       SCpnt->request.dev = -1;  /* Mark as not busy */
+       SCpnt->request.dev = -1;
        wake_up(&scsi_devices[SCpnt->index].device_wait);
        return result;
 }
@@ -203,6+203,10 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
        result = SCpnt->result;
        SCpnt->request.dev = -1;  /* Mark as not busy */
        if (buf) scsi_free(buf, needed);
+
+       if(scsi_devices[SCpnt->index].scsi_request_fn)
+         (*scsi_devices[SCpnt->index].scsi_request_fn)();
+
        wake_up(&scsi_devices[SCpnt->index].device_wait);
        return result;
 #else
@@ -223,8+227,6 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
 #endif
 }
 
-       
-
 /*
        the scsi_ioctl() function differs from most ioctls in that it does
        not take a major/minor number as the dev filed.  Rather, it takes
@@ -302,4+304,3 @@ int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) {
   set_fs(oldfs);
   return tmp;
 }
-
index dac9548..9046f60 100644 (file)
@@ -4,6+4,7 @@
 #define SCSI_IOCTL_PROBE_HOST 0
 #define SCSI_IOCTL_SEND_COMMAND 1
 #define SCSI_IOCTL_TEST_UNIT_READY 2
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
 /* The door lock/unlock constants are compatible with Sun constants for
    the cdrom */
 #define SCSI_IOCTL_DOORLOCK 0x5380             /* lock the eject mechanism */
index 31ba51d..68086bf 100644 (file)
@@ -34,10+34,14 @@ static const char RCSid[] = "$Header:";
 #define MAX_RETRIES 5
 
 /*
- *     Time out in seconds
+ *     Time out in seconds for disks and Magneto-opticals (which are slower).
  */
 
 #define SD_TIMEOUT 300
+#define SD_MOD_TIMEOUT 750
+
+#define CLUSTERABLE_DEVICE(SC) (SC->host->sg_tablesize < 64 && \
+                           scsi_devices[SC->index].type != TYPE_MOD)
 
 struct hd_struct * sd;
 
@@ -369,9+373,7 @@ static void do_sd_request (void)
     };
     
     if (!SCpnt) return; /* Could not find anything to do */
-    
-    wake_up(&wait_for_request);
-    
+        
     /* Queue command */
     requeue_sd_request(SCpnt);
   };  /* While */
@@ -381,7+383,10 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
 {
        int dev, block, this_count;
        unsigned char cmd[10];
-       char * buff;
+       int bounce_size, contiguous;
+       int max_sg;
+       struct buffer_head * bh, *bhp;
+       char * buff, *bounce_buffer;
 
 repeat:
 
@@ -440,8+445,35 @@ repeat:
 
        SCpnt->this_count = 0;
 
-       if (!SCpnt->request.bh || 
-           (SCpnt->request.nr_sectors == SCpnt->request.current_nr_sectors)) {
+       /* If the host adapter can deal with very large scatter-gather
+          requests, it is a waste of time to cluster */
+       contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1);
+       bounce_buffer = NULL;
+       bounce_size = (SCpnt->request.nr_sectors << 9);
+
+       /* First see if we need a bounce buffer for this request.  If we do, make sure
+          that we can allocate a buffer.  Do not waste space by allocating a bounce
+          buffer if we are straddling the 16Mb line */
+
+       
+       if (contiguous && SCpnt->request.bh &&
+           ((int) SCpnt->request.bh->b_data) + (SCpnt->request.nr_sectors << 9) - 1 > 
+           ISA_DMA_THRESHOLD && SCpnt->host->unchecked_isa_dma) {
+         if(((int) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
+           bounce_buffer = scsi_malloc(bounce_size);
+         if(!bounce_buffer) contiguous = 0;
+       };
+
+       if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext)
+         for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, 
+             bhp = bhp->b_reqnext) {
+           if(!CONTIGUOUS_BUFFERS(bh,bhp)) { 
+             if(bounce_buffer) scsi_free(bounce_buffer, bounce_size);
+             contiguous = 0;
+             break;
+           } 
+         };
+       if (!SCpnt->request.bh || contiguous) {
 
          /* case of page request (i.e. raw device), or unlinked buffer */
          this_count = SCpnt->request.nr_sectors;
@@ -450,7+482,7 @@ repeat:
 
        } else if (SCpnt->host->sg_tablesize == 0 ||
                   (need_isa_buffer && 
-                   dma_free_sectors < 10)) {
+                   dma_free_sectors <= 10)) {
 
          /* Case of host adapter that cannot scatter-gather.  We also
           come here if we are running low on DMA buffer memory.  We set
@@ -461,7+493,7 @@ repeat:
 
          if (SCpnt->host->sg_tablesize != 0 &&
              need_isa_buffer && 
-             dma_free_sectors < 10)
+             dma_free_sectors <= 10)
            printk("Warning: SCSI DMA buffer space running low.  Using non scatter-gather I/O.\n");
 
          this_count = SCpnt->request.current_nr_sectors;
@@ -471,25+503,41 @@ repeat:
        } else {
 
          /* Scatter-gather capable host adapter */
-         struct buffer_head * bh;
          struct scatterlist * sgpnt;
          int count, this_count_max;
+         int counted;
+
          bh = SCpnt->request.bh;
          this_count = 0;
          this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff);
          count = 0;
-         while(bh && count < SCpnt->host->sg_tablesize) {
+         bhp = NULL;
+         while(bh) {
            if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
+           if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) ||
+              !CLUSTERABLE_DEVICE(SCpnt) ||
+              (SCpnt->host->unchecked_isa_dma &&
+              ((unsigned int) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
+             if (count < SCpnt->host->sg_tablesize) count++;
+             else break;
+           };
            this_count += (bh->b_size >> 9);
-           count++;
+           bhp = bh;
            bh = bh->b_reqnext;
          };
+#if 0
+         if(SCpnt->host->unchecked_isa_dma &&
+            ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
+#endif
          SCpnt->use_sg = count;  /* Number of chains */
          count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
          while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
            count = count << 1;
          SCpnt->sglist_len = count;
+         max_sg = count / sizeof(struct scatterlist);
+         if(SCpnt->host->sg_tablesize < max_sg) max_sg = SCpnt->host->sg_tablesize;
          sgpnt = (struct scatterlist * ) scsi_malloc(count);
+         memset(sgpnt, 0, count);  /* Zero so it is easy to fill */
          if (!sgpnt) {
            printk("Warning - running *really* short on DMA buffers\n");
            SCpnt->use_sg = 0;  /* No memory left - bail out */
@@ -497,20+545,25 @@ repeat:
            buff = SCpnt->request.buffer;
          } else {
            buff = (char *) sgpnt;
-           count = 0;
-           bh = SCpnt->request.bh;
-           for(count = 0, bh = SCpnt->request.bh; count < SCpnt->use_sg; 
-               count++, bh = bh->b_reqnext) {
-             sgpnt[count].address = bh->b_data;
-             sgpnt[count].alt_address = NULL;
-             sgpnt[count].length = bh->b_size;
-             if (((int) sgpnt[count].address) + sgpnt[count].length > 
-                 ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
+           counted = 0;
+           for(count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext;
+               count < SCpnt->use_sg && bh; 
+               count++, bh = bhp) {
+
+             bhp = bh->b_reqnext;
+
+             if(!sgpnt[count].address) sgpnt[count].address = bh->b_data;
+             sgpnt[count].length += bh->b_size;
+             counted += bh->b_size >> 9;
+
+             if (((int) sgpnt[count].address) + sgpnt[count].length - 1 > 
+                 ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
+                 !sgpnt[count].alt_address) {
                sgpnt[count].alt_address = sgpnt[count].address;
                /* We try and avoid exhausting the DMA pool, since it is easier
                   to control usage here.  In other places we might have a more
                   pressing need, and we would be screwed if we ran out */
-               if(dma_free_sectors < (bh->b_size >> 9) + 5) {
+               if(dma_free_sectors < (sgpnt[count].length >> 9) + 10) {
                  sgpnt[count].address = NULL;
                } else {
                  sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
@@ -520,6+573,7 @@ repeat:
    ensure that all scsi operations are able to do at least a non-scatter/gather
    operation */
                if(sgpnt[count].address == NULL){ /* Out of dma memory */
+#if 0
                  printk("Warning: Running low on SCSI DMA buffers");
                  /* Try switching back to a non scatter-gather operation. */
                  while(--count >= 0){
@@ -529,30+583,93 @@ repeat:
                  this_count = SCpnt->request.current_nr_sectors;
                  buff = SCpnt->request.buffer;
                  SCpnt->use_sg = 0;
-                 scsi_free(buff, SCpnt->sglist_len);
+                 scsi_free(sgpnt, SCpnt->sglist_len);
+#endif
+                 SCpnt->use_sg = count;
+                 this_count = counted -= bh->b_size >> 9;
                  break;
                };
 
-               if (SCpnt->request.cmd == WRITE)
-                 memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
-                        sgpnt[count].length);
              };
+
+             /* Only cluster buffers if we know that we can supply DMA buffers
+                large enough to satisfy the request.  Do not cluster a new
+                request if this would mean that we suddenly need to start
+                using DMA bounce buffers */
+             if(bhp && CONTIGUOUS_BUFFERS(bh,bhp) && CLUSTERABLE_DEVICE(SCpnt)) {
+               char * tmp;
+
+               if (((int) sgpnt[count].address) + sgpnt[count].length +
+                   bhp->b_size - 1 > ISA_DMA_THRESHOLD && 
+                   (SCpnt->host->unchecked_isa_dma) &&
+                   !sgpnt[count].alt_address) continue;
+
+               if(!sgpnt[count].alt_address) {count--; continue; }
+               if(dma_free_sectors > 10)
+                 tmp = scsi_malloc(sgpnt[count].length + bhp->b_size);
+               else {
+                 tmp = NULL;
+                 max_sg = SCpnt->use_sg;
+               };
+               if(tmp){
+                 scsi_free(sgpnt[count].address, sgpnt[count].length);
+                 sgpnt[count].address = tmp;
+                 count--;
+                 continue;
+               };
+
+               /* If we are allowed another sg chain, then increment counter so we
+                  can insert it.  Otherwise we will end up truncating */
+
+               if (SCpnt->use_sg < max_sg) SCpnt->use_sg++;
+             };  /* contiguous buffers */
            }; /* for loop */
+
+           this_count = counted; /* This is actually how many we are going to transfer */
+
+           if(count < SCpnt->use_sg || SCpnt->use_sg > SCpnt->host->sg_tablesize){
+             bh = SCpnt->request.bh;
+             printk("Use sg, count %d %x %d\n", SCpnt->use_sg, count, dma_free_sectors);
+             printk("maxsg = %x, counted = %d this_count = %d\n", max_sg, counted, this_count);
+             while(bh){
+               printk("[%8.8x %x] ", bh->b_data, bh->b_size);
+               bh = bh->b_reqnext;
+             };
+             if(SCpnt->use_sg < 16)
+               for(count=0; count<SCpnt->use_sg; count++)
+                 printk("{%d:%8.8x %8.8x %d}  ", count,
+                        sgpnt[count].address,
+                        sgpnt[count].alt_address,
+                        sgpnt[count].length);
+             panic("Ooops");
+           };
+
+           if (SCpnt->request.cmd == WRITE)
+             for(count=0; count<SCpnt->use_sg; count++)
+               if(sgpnt[count].alt_address)
+                 memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
+                        sgpnt[count].length);
          };  /* Able to malloc sgpnt */
        };  /* Host adapter capable of scatter-gather */
 
 /* Now handle the possibility of DMA to addresses > 16Mb */
 
        if(SCpnt->use_sg == 0){
-         if (((int) buff) + (this_count << 9) > ISA_DMA_THRESHOLD && 
+         if (((int) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && 
            (SCpnt->host->unchecked_isa_dma)) {
-           buff = (char *) scsi_malloc(this_count << 9);
-           if(buff == NULL) panic("Ran out of DMA buffers.");
+           if(bounce_buffer)
+             buff = bounce_buffer;
+           else
+             buff = (char *) scsi_malloc(this_count << 9);
+           if(buff == NULL) {  /* Try backing off a bit if we are low on mem*/
+             this_count = SCpnt->request.current_nr_sectors;
+             buff = (char *) scsi_malloc(this_count << 9);
+             if(!buff) panic("Ran out of DMA buffers.");
+           };
            if (SCpnt->request.cmd == WRITE)
              memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9);
          };
        };
-
 #ifdef DEBUG
        printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(SCpnt->request.dev),
                (SCpnt->request.cmd == WRITE) ? "writing" : "reading",
@@ -607,10+724,12 @@ repeat:
 
         SCpnt->transfersize = rscsi_disks[dev].sector_size;
         SCpnt->underflow = this_count << 9; 
-
        scsi_do_cmd (SCpnt, (void *) cmd, buff, 
                     this_count * rscsi_disks[dev].sector_size,
-                    rw_intr, SD_TIMEOUT, MAX_RETRIES);
+                    rw_intr, 
+                    (scsi_devices[SCpnt->index].type == TYPE_DISK ? 
+                                    SD_TIMEOUT : SD_MOD_TIMEOUT),
+                    MAX_RETRIES);
 }
 
 int check_scsidisk_media_change(int full_dev, int flag){
@@ -857,6+976,7 @@ static int sd_init_onedisk(int i)
        their size, and reads partition table entries for them.
 */
 
+
 unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
 {
        int i;
@@ -893,7+1013,7 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
           the read-ahead to 16 blocks (32 sectors).  If not, we use
           a two block (4 sector) read ahead. */
        if(rscsi_disks[0].device->host->sg_tablesize)
-         read_ahead[MAJOR_NR] = 32;
+         read_ahead[MAJOR_NR] = 120;
        /* 64 sector read-ahead */
        else
          read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
@@ -910,6+1030,7 @@ unsigned long sd_init1(unsigned long mem_start, unsigned long mem_end){
 };
 
 void sd_attach(Scsi_Device * SDp){
+  SDp->scsi_request_fn = do_sd_request;
   rscsi_disks[NR_SD++].device = SDp;
   if(NR_SD > MAX_SD) panic ("scsi_devices corrupt (sd)");
 };
@@ -968,3+1089,4 @@ int revalidate_scsidisk(int dev, int maxusage){
          DEVICE_BUSY = 0;
          return 0;
 }
+
index f51ec66..385221d 100644 (file)
@@ -53,6+53,12 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
                        put_fs_long(sd[MINOR(inode->i_rdev)].nr_sects,
                                (long *) arg);
                        return 0;
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                case BLKFLSBUF:
                        if(!suser())  return -EACCES;
                        if(!inode->i_rdev) return -EINVAL;
index bdaf3a6..d1fc8a3 100644 (file)
@@ -624,6+624,7 @@ unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
 };
 
 void sr_attach(Scsi_Device * SDp){
+  SDp->scsi_request_fn = do_sr_request;
   scsi_CDs[NR_SR++].device = SDp;
   if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
 };
index c43122e..5b3c8df 100644 (file)
@@ -385,6+385,12 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
                case CDROMREADMODE1:
                        return -EINVAL;
 
+               case BLKRASET:
+                       if(!suser())  return -EACCES;
+                       if(!inode->i_rdev) return -EINVAL;
+                       if(arg > 0xff) return -EINVAL;
+                       read_ahead[MAJOR(inode->i_rdev)] = arg;
+                       return 0;
                RO_IOCTLS(dev,arg);
                default:
                        return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
index fbad9ea..76a3b05 100644 (file)
 #include <linux/timer.h>
 #include <linux/tty.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/system.h>
index 22ffc21..cf4ab3b 100644 (file)
@@ -54,7+54,8 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
                if (chars == blocksize)
                        bh = getblk(dev, block, blocksize);
                else
-                       bh = breada(dev,block,block+1,block+2,-1);
+                       bh = breada(dev, block, blocksize, offset, 
+                                   size << blocksize_bits);
                block++;
                if (!bh)
                        return written?written:-EIO;
@@ -67,7+68,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
                p += chars;
                buf += chars;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        return written;
index 923343f..49f1e4a 100644 (file)
@@ -46,6+46,10 @@ extern int check_cdu31a_media_change(int, int);
 extern int check_mcd_media_change(int, int);
 #endif
 
+static char buffersize_index[9] = {-1,  0,  1, -1,  2, -1, -1, -1, 3};
+
+#define BUFSIZE_INDEX(X) (buffersize_index[(X)>>9])
+
 static int grow_buffers(int pri, int size);
 
 static struct buffer_head * hash_table[NR_HASH];
@@ -556,42+560,62 @@ struct buffer_head * bread(dev_t dev, int block, int size)
 
 /*
  * Ok, breada can be used as bread, but additionally to mark other
- * blocks for reading as well. End the argument list with a negative
- * number.
+ * blocks for reading as well.
  */
-struct buffer_head * breada(dev_t dev,int first, ...)
-{
-       va_list args;
-       unsigned int blocksize;
-       struct buffer_head * bh, *tmp;
 
-       va_start(args,first);
+#define NBUF 16
 
-       blocksize = BLOCK_SIZE;
-       if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
-               blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
+struct buffer_head * breada(dev_t dev, int block, int bufsize,
+       unsigned int pos, unsigned int filesize)
+{
+       struct buffer_head * bhlist[NBUF];
+       unsigned int blocks;
+       struct buffer_head * bh;
+       int index;
+       int i, j;
 
-       if (!(bh = getblk(dev, first, blocksize))) {
-               printk("VFS: breada: READ error on device %d/%d\n",
-                                               MAJOR(dev), MINOR(dev));
+       if (pos >= filesize)
                return NULL;
-       }
-       if (!bh->b_uptodate)
-               ll_rw_block(READ, 1, &bh);
-       while ((first=va_arg(args,int))>=0) {
-               tmp = getblk(dev, first, blocksize);
-               if (tmp) {
-                       if (!tmp->b_uptodate)
-                               ll_rw_block(READA, 1, &tmp);
-                       tmp->b_count--;
+
+       if (block < 0 || !(bh = getblk(dev,block,bufsize)))
+               return NULL;
+
+       index = BUFSIZE_INDEX(bh->b_size);
+
+       if (bh->b_uptodate)
+               return bh;
+
+       blocks = ((filesize & (bufsize - 1)) - (pos & (bufsize - 1))) >> (9+index);
+
+       if (blocks > (read_ahead[MAJOR(dev)] >> index))
+               blocks = read_ahead[MAJOR(dev)] >> index;
+       if (blocks > NBUF)
+               blocks = NBUF;
+       
+       bhlist[0] = bh;
+       j = 1;
+       for(i=1; i<blocks; i++) {
+               bh = getblk(dev,block+i,bufsize);
+               if (bh->b_uptodate) {
+                       brelse(bh);
+                       break;
                }
+               bhlist[j++] = bh;
        }
-       va_end(args);
+
+       /* Request the read for these buffers, and then release them */
+       ll_rw_block(READ, j, bhlist);
+
+       for(i=1; i<j; i++)
+               brelse(bhlist[i]);
+
+       /* Wait for this buffer, and then continue on */
+       bh = bhlist[0];
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
        brelse(bh);
-       return (NULL);
+       return NULL;
 }
 
 /*
@@ -616,7+640,7 @@ static void get_more_buffer_heads(void)
        if (unused_list)
                return;
 
-       if(! (bh = (struct buffer_head*) get_free_page(GFP_BUFFER)))
+       if (!(bh = (struct buffer_head*) get_free_page(GFP_BUFFER)))
                return;
 
        for (nr_buffer_heads+=i=PAGE_SIZE/sizeof*bh ; i>0; i--) {
@@ -870,7+894,7 @@ static int grow_buffers(int pri, int size)
                printk("VFS: grow_buffers: size = %d\n",size);
                return 0;
        }
-       if(!(page = __get_free_page(pri)))
+       if (!(page = __get_free_page(pri)))
                return 0;
        bh = create_buffers(page, size);
        if (!bh) {
index d8caabd..16fe1ff 100644 (file)
@@ -104,7+104,8 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
        blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+               if(blocks < read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9))
+                 blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -247,7+248,7 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index 6462da1..e46bb9e 100644 (file)
@@ -83,7+83,7 @@ printk("ext_free_block: block full, skipping to %d\n", block);
        }
        sb->u.ext_sb.s_freeblockscount ++;
        sb->s_dirt = 1;
-       sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
+       dirtify_buffer(sb->u.ext_sb.s_firstfreeblock, 1);
        unlock_super (sb);
        return;
 }
@@ -104,7+104,7 @@ int ext_new_block(struct super_block * sb)
        efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
        if (efb->count) {
                j = efb->free[--efb->count];
-               sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
+               dirtify_buffer(sb->u.ext_sb.s_firstfreeblock, 1);
        } else {
 #ifdef EXTFS_DEBUG
 printk("ext_new_block: block empty, skipping to %d\n", efb->next);
@@ -135,7+135,7 @@ printk("ext_new_block: block empty, skipping to %d\n", efb->next);
        }
        clear_block(bh->b_data);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
 #ifdef EXTFS_DEBUG
 printk("ext_new_block: allocating block %d\n", j);
@@ -239,7+239,7 @@ printk("ext_free_inode: inode full, skipping to %d\n", ino);
        }
        sb->u.ext_sb.s_freeinodescount ++;
        sb->s_dirt = 1;
-       sb->u.ext_sb.s_firstfreeinodeblock->b_dirt = 1;
+       dirtify_buffer(sb->u.ext_sb.s_firstfreeinodeblock, 1);
        unlock_super (sb);
 }
 
@@ -263,7+263,7 @@ struct inode * ext_new_inode(const struct inode * dir)
                (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK;
        if (efi->count) {
                j = efi->free[--efi->count];
-               sb->u.ext_sb.s_firstfreeinodeblock->b_dirt = 1;
+               dirtify_buffer(sb->u.ext_sb.s_firstfreeinodeblock, 1);
        } else {
 #ifdef EXTFS_DEBUG
 printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
index 910ab58..eff68fc 100644 (file)
@@ -139,7+139,7 @@ void ext_write_super (struct super_block *sb)
        es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount;
        es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber;
        es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
        sb->s_dirt = 0;
 }
@@ -296,7+296,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return result;
 }
@@ -407,7+407,7 @@ static struct buffer_head * ext_update_inode(struct inode * inode)
                raw_inode->i_zone[0] = inode->i_rdev;
        else for (block = 0; block < 12; block++)
                raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        inode->i_dirt=0;
        return bh;
 }
index a8bc1cb..5a1ac36 100644 (file)
@@ -249,7+249,7 @@ printk ("ext_add_entry: skipping to next block\n");
 #if 0
                                        dir->i_ctime = CURRENT_TIME;
 #endif
-                                       bh->b_dirt = 1;
+                                       dirtify_buffer(bh, 1);
                                }
                                brelse (bh);
                                bh = NULL;
@@ -296,7+296,7 @@ printk ("ext_add_entry : creating next block\n");
                        de->name_len = namelen;
                        for (i=0; i < namelen ; i++)
                                de->name[i] = name[i];
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        return bh;
                }
@@ -334,7+334,7 @@ int ext_create(struct inode * dir,const char * name, int len, int mode,
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -393,7+393,7 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -445,7+445,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->name_len=2;
        strcpy(de->name,"..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -459,7+459,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -567,7+567,7 @@ int ext_rmdir(struct inode * dir, const char * name, int len)
        de->inode = 0;
        de->name_len = 0;
        ext_merge_entries (de, pde, nde);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -610,7+610,7 @@ int ext_unlink(struct inode * dir, const char * name, int len)
        de->inode = 0;
        de->name_len = 0;
        ext_merge_entries (de, pde, nde);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink--;
        inode->i_dirt = 1;
        inode->i_ctime = CURRENT_TIME;
@@ -650,7+650,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
        while (i < 1023 && (c = *(symname++)))
                name_block->b_data[i++] = c;
        name_block->b_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -672,7+672,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
                return -ENOSPC;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -708,7+708,7 @@ int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int
                return -ENOSPC;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -851,11+851,11 @@ start_up:
                new_inode->i_nlink--;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
                old_dir->i_dirt = 1;
index d14dc6c..21f85be 100644 (file)
@@ -102,7+102,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                brelse(bh);
                ext_free_block(inode->i_sb,tmp);
        }
@@ -154,7+154,7 @@ repeat:
                if (!tmp)
                        continue;
                retry |= trunc_indirect(inode,offset+(i<<8),dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned long *) dind_bh->b_data;
        for (i = 0; i < 256; i++)
@@ -201,7+201,7 @@ repeat:
                        goto repeat;
                tind = i+(unsigned long *) tind_bh->b_data;
                retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
-               tind_bh->b_dirt = 1;
+               dirtify_buffer(tind_bh, 1);
        }
        tind = (unsigned long *) tind_bh->b_data;
        for (i = 0; i < 256; i++)
index a8d8689..82e4019 100644 (file)
@@ -310,10+310,10 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block,
                }
        }
        
-       bh2->b_dirt = 1;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
 
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -524,7+524,7 @@ got_block:
 
        j = tmp;
 
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -544,16+544,16 @@ got_block:
        }
        clear_block (bh->b_data, sb->s_blocksize);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
 
        ext2_debug ("allocating block %d. "
                    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
 
        gdp->bg_free_blocks_count--;
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        es->s_free_blocks_count--;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 1;
        unlock_super (sb);
        return j;
index 7251a40..806165f 100644 (file)
@@ -112,8+112,8 @@ static int ext2_file_read (struct inode * inode, struct file * filp,
        blocks = (left + offset + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb);
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] >>
-                       (EXT2_BLOCK_SIZE_BITS(sb) - 9);
+               if (blocks < read_ahead[MAJOR(inode->i_dev)] >> (EXT2_BLOCK_SIZE_BITS(sb) - 9))
+                   blocks = read_ahead[MAJOR(inode->i_dev)] >> (EXT2_BLOCK_SIZE_BITS(sb) - 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -277,7+277,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp,
                memcpy_fromfs (p, buf, c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse (bh);
        }
        up(&inode->i_sem);
index de2144a..d3ba1df 100644 (file)
@@ -202,7+202,7 @@ static void set_inode_dtime (struct inode * inode,
                        EXT2_INODES_PER_BLOCK(inode->i_sb));
        raw_inode->i_links_count = 0;
        raw_inode->i_dtime = CURRENT_TIME;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(inode)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -266,12+266,12 @@ void ext2_free_inode (struct inode * inode)
                gdp->bg_free_inodes_count++;
                if (S_ISDIR(inode->i_mode))
                        gdp->bg_used_dirs_count--;
-               bh2->b_dirt = 1;
+               dirtify_buffer(bh2, 1);
                es->s_free_inodes_count++;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                set_inode_dtime (inode, gdp);
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (sb->s_flags & MS_SYNC) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -313,7+313,7 @@ static void inc_inode_version (struct inode * inode,
                        EXT2_INODES_PER_BLOCK(inode->i_sb));
        raw_inode->i_version++;
        inode->u.ext2_i.i_version = raw_inode->i_version;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse (bh);
 }
 
@@ -438,7+438,7 @@ repeat:
                                      "bit already set for inode %d", j);
                        goto repeat;
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                if (sb->s_flags & MS_SYNC) {
                        ll_rw_block (WRITE, 1, &bh);
                        wait_on_buffer (bh);
@@ -466,9+466,9 @@ repeat:
        gdp->bg_free_inodes_count--;
        if (S_ISDIR(mode))
                gdp->bg_used_dirs_count++;
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        es->s_free_inodes_count--;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 1;
        inode->i_mode = mode;
        inode->i_sb = sb;
index 050b0f2..4098465 100644 (file)
@@ -109,7+109,7 @@ static int ext2_alloc_block (struct inode * inode, unsigned long goal)
                }
                clear_block (bh->b_data, inode->i_sb->s_blocksize);
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                brelse (bh);
        } else {
                ext2_discard_prealloc (inode);
@@ -314,7+314,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(inode)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -549,7+549,7 @@ static struct buffer_head * ext2_update_inode (struct inode * inode)
                raw_inode->i_block[0] = inode->i_rdev;
        else for (block = 0; block < EXT2_N_BLOCKS; block++)
                raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_dirt = 0;
        return bh;
 }
index 960fae9..6a92d13 100644 (file)
@@ -275,9+275,6 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
                                de->rec_len = sb->s_blocksize;
                                dir->i_size = offset + sb->s_blocksize;
                                dir->i_dirt = 1;
-#if 0 /* XXX don't update any times until successful completion of syscall */
-                               dir->i_ctime = CURRENT_TIME;
-#endif
                        } else {
 
                                ext2_debug ("skipping to next block\n");
@@ -323,7+320,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
                         */
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        dir->i_dirt = 1;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        *err = 0;
                        return bh;
@@ -397,7+394,7 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -449,14+446,6 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
                init_fifo(inode);
        if (S_ISBLK(mode) || S_ISCHR(mode))
                inode->i_rdev = rdev;
-#if 0
-       /*
-        * XXX we may as well use the times set by ext2_new_inode().  The
-        * following usually does nothing, but sometimes it invalidates
-        * inode->i_ctime.
-        */
-       inode->i_mtime = inode->i_atime = CURRENT_TIME;
-#endif
        inode->i_dirt = 1;
        bh = ext2_add_entry (dir, name, len, &de, &err);
        if (!bh) {
@@ -471,7+460,7 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -508,9+497,6 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        }
        inode->i_op = &ext2_dir_inode_operations;
        inode->i_size = inode->i_sb->s_blocksize;
-#if 0 /* XXX as above */
-       inode->i_mtime = inode->i_atime = CURRENT_TIME;
-#endif
        dir_block = ext2_bread (inode, 0, 1, &err);
        if (!dir_block) {
                iput (dir);
@@ -531,7+517,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        de->name_len = 2;
        strcpy (de->name, "..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse (dir_block);
        inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -550,7+536,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -674,7+660,7 @@ repeat:
        up(&inode->i_sem);
        if (retval)
                goto end_rmdir;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -742,7+728,7 @@ repeat:
        retval = ext2_delete_entry (de, bh);
        if (retval)
                goto end_unlink;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -807,7+793,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
                link[i++] = c;
        link[i] = 0;
        if (name_block) {
-               name_block->b_dirt = 1;
+               dirtify_buffer(name_block, 1);
                brelse (name_block);
        }
        inode->i_size = i;
@@ -834,7+820,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -880,7+866,7 @@ int ext2_link (struct inode * oldinode, struct inode * dir,
        ext2_dcache_add (dir->i_dev, dir->i_ino, de->name, de->name_len,
                         de->inode);
 #endif
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if (IS_SYNC(dir)) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
@@ -1056,19+1042,19 @@ start_up:
        }
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
        old_dir->i_dirt = 1;
-       old_bh->b_dirt = 1;
+       dirtify_buffer(old_bh,  1);
        if (IS_SYNC(old_dir)) {
                ll_rw_block (WRITE, 1, &old_bh);
                wait_on_buffer (old_bh);
        }
-       new_bh->b_dirt = 1;
+       dirtify_buffer(new_bh, 1);
        if (IS_SYNC(new_dir)) {
                ll_rw_block (WRITE, 1, &new_bh);
                wait_on_buffer (new_bh);
        }
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index 1ceaf34..4cfa9ff 100644 (file)
@@ -36,7+36,7 @@ void ext2_error (struct super_block * sb, const char * function,
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
                sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
        }
        va_start (args, fmt);
@@ -66,7+66,7 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
                sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
        }
        va_start (args, fmt);
@@ -96,7+96,7 @@ void ext2_put_super (struct super_block * sb)
        lock_super (sb);
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        }
 #ifndef DONT_USE_DCACHE
        ext2_dcache_invalidate (sb->s_dev);
@@ -159,10+159,10 @@ static int convert_pre_02b_fs (struct super_block * sb,
                gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count;
                gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count;
        }
-       bh2->b_dirt = 1;
+       dirtify_buffer(bh2, 1);
        brelse (bh2);
        es->s_magic = EXT2_SUPER_MAGIC;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        sb->s_magic = EXT2_SUPER_MAGIC;
        return 1;
 }
@@ -287,7+287,7 @@ static void ext2_setup_super (struct super_block * sb,
                        es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
                es->s_mnt_count++;
                es->s_mtime = CURRENT_TIME;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
                if (test_opt (sb, DEBUG))
                        printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
@@ -570,7+570,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
 #ifdef EXT2FS_PRE_02B_COMPAT
        if (fs_converted) {
                for (i = 0; i < bh_count; i++)
-                       sb->u.ext2_sb.s_group_desc[i]->b_dirt = 1;
+                       dirtify_buffer(sb->u.ext2_sb.s_group_desc[i], 1);
                sb->s_dirt = 1;
        }
 #endif
@@ -582,7+582,7 @@ static void ext2_commit_super (struct super_block * sb,
                               struct ext2_super_block * es)
 {
        es->s_wtime = CURRENT_TIME;
-       sb->u.ext2_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
        sb->s_dirt = 0;
 }
 
@@ -639,7+639,7 @@ int ext2_remount (struct super_block * sb, int * flags, char * data)
                 */
                es->s_state = sb->u.ext2_sb.s_mount_state;
                es->s_mtime = CURRENT_TIME;
-               sb->u.ext2_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.ext2_sb.s_sbh, 1);
                sb->s_dirt = 1;
                ext2_commit_super (sb, es);
        }
index 95db1ed..589e365 100644 (file)
@@ -90,7+90,7 @@ repeat:
                if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
                        clear_block (bh->b_data, inode->i_sb->s_blocksize,
                                     RANDOM_INT);
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                }
                brelse (bh);
                if (free_count == 0) {
@@ -162,11+162,11 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                if (inode->u.ext2_i.i_flags & EXT2_SECRM_FL) {
                        clear_block (bh->b_data, inode->i_sb->s_blocksize,
                                     RANDOM_INT);
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                }
                brelse (bh);
                if (free_count == 0) {
@@ -243,7+243,7 @@ repeat:
                        continue;
                retry |= trunc_indirect (inode, offset + (i * addr_per_block),
                                          dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned long *) dind_bh->b_data;
        for (i = 0; i < addr_per_block; i++)
@@ -302,7+302,7 @@ repeat:
                retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS +
                        addr_per_block + (i + 1) * addr_per_block * addr_per_block,
                        tind);
-               tind_bh->b_dirt = 1;
+               dirtify_buffer(tind_bh, 1);
        }
        tind = (unsigned long *) tind_bh->b_data;
        for (i = 0; i < addr_per_block; i++)
index f2abf2c..aee32f7 100644 (file)
 #include <linux/hpfs_fs.h>
 #include <linux/errno.h>
 #include <linux/malloc.h>
+#include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/locks.h>
 #include <linux/stat.h>
@@ -1676,8+1677,7 @@ static void *map_4sectors(dev_t dev, unsigned secno,
        if (!data)
                goto bail;
 
-       qbh->bh[0] = bh = breada(dev,
-                                secno, secno + 1, secno + 2, secno + 3, -1);
+       qbh->bh[0] = bh = breada(dev, secno, 512, 0, UINT_MAX);
        if (!bh)
                goto bail0;
        memcpy(data, bh->b_data, 512);
index 1aebbb1..7d8260f 100644 (file)
@@ -1,7+1,7 @@
 /*
  *  linux/fs/isofs/dir.c
  *
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/locks.h>
 
 static int isofs_readdir(struct inode *, struct file *, struct dirent *, int);
 
@@ -81,9+83,12 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
        
        offset = filp->f_pos & (bufsize - 1);
        block = isofs_bmap(inode,filp->f_pos>>bufbits);
-       if (!block || !(bh = bread(inode->i_dev,block,bufsize)))
-               return 0;
-       
+
+       if(!block) return 0;
+
+       if(!(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size)))
+         return 0;
+
        while (filp->f_pos < inode->i_size) {
 #ifdef DEBUG
                printk("Block, offset: %x %x %x\n",
@@ -103,7+108,8 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
                                       + ISOFS_BLOCK_SIZE);
                        block = isofs_bmap(inode,(filp->f_pos)>>bufbits);
                        if (!block
-                           || !(bh = bread(inode->i_dev,block,bufsize)))
+                           || !(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, 
+                                            inode->i_size)))
                                return 0;
                        continue;
                }
@@ -126,7+132,8 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
                        offset = filp->f_pos & (bufsize - 1);
                        block = isofs_bmap(inode,(filp->f_pos)>> bufbits);
                        if (!block
-                           || !(bh = bread(inode->i_dev,block,bufsize))) {
+                           || !(bh = breada(inode->i_dev, block, bufsize,
+                                            filp->f_pos, inode->i_size))) {
                                kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
                                return 0;
                        };
index 35d501a..03cf412 100644 (file)
@@ -1,7+1,7 @@
 /*
  *  linux/fs/isofs/file.c
  *
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *
@@ -146,6+146,8 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
        bhb = bhe = buflist;
 
        ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+       if(ra_blocks > blocks) blocks = ra_blocks;
+
        max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
        nextblock = -1;
 
@@ -169,7+171,6 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
                        if (*bhb && !(*bhb)->b_uptodate) {
                                uptodate = 0;
                                bhreq[bhrequest++] = *bhb;
-                               nextblock = (*bhb)->b_blocknr + 1;
                              };
 
                        if (++bhb == &buflist[NBUF])
@@ -177,37+178,12 @@ static int isofs_file_read(struct inode * inode, struct file * filp, char * buf,
 
                        /* If the block we have on hand is uptodate, go ahead
                           and complete processing. */
-                       if(bhrequest == 0 && uptodate) break;
+                       if(uptodate) break;
 
                        if (bhb == bhe)
                                break;
                      }
 
-               if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) { 
-                 /* If we are going to read something anyways, add in the
-                    read-ahead blocks */
-                 while(ra_blocks){
-                   if (block >= max_block) break;
-                   if(bhrequest == NBUF) break;  /* Block full */
-                   --ra_blocks;
-                   *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
-
-                   if (*bhb && !(*bhb)->b_uptodate) {
-                     if((*bhb)->b_blocknr != nextblock) {
-                       brelse(*bhb);
-                       break;
-                     };
-                     nextblock = (*bhb)->b_blocknr + 1;
-                     bhreq[bhrequest++] = *bhb;
-                   };
-                   
-                   if (++bhb == &buflist[NBUF])
-                     bhb = buflist;
-                   
-                   if (bhb == bhe)
-                     break;
-                 };
-               };
                /* Now request them all */
                if (bhrequest)
                  ll_rw_block(READ, bhrequest, bhreq);
index 0ba69b3..2b32589 100644 (file)
@@ -1,7+1,7 @@
 /*
  *  linux/fs/isofs/inode.c
  * 
- *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
+ *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
@@ -354,7+354,7 @@ void isofs_read_inode(struct inode * inode)
        if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
                cpnt = kmalloc(1 << ISOFS_BLOCK_BITS, GFP_KERNEL);
                if (cpnt == NULL) {
-                       printk(KERN_INFO "NoMem ISO inode %d\n",inode->i_ino);
+                       printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
                        brelse(bh);
                        goto fail;
                }
@@ -600,7+600,8 @@ int isofs_lookup_grandparent(struct inode * parent, int extent)
                        brelse(bh);
                        offset = 0;
                        block++;
-                       if(block & 1) return -1;
+                       if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
+                         return -1;
                        if (!block
                            || !(bh = bread(parent->i_dev,block, bufsize)))
                                return -1;
index f62faf1..dea267f 100644 (file)
@@ -1,7+1,7 @@
 /*
  *  linux/fs/isofs/rock.c
  *
- *  (C) 1992  Eric Youngdale
+ *  (C) 1992, 1993  Eric Youngdale
  *
  *  Rock Ridge Extensions to iso9660
  */
index 8f4d1c8..4d8cf17 100644 (file)
@@ -93,7+93,7 @@ void minix_free_block(struct super_block * sb, int block)
        }
        if (!clear_bit(bit,bh->b_data))
                printk("free_block (%04x:%d): bit already cleared\n",sb->s_dev,block);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        return;
 }
 
@@ -118,7+118,7 @@ repeat:
                printk("new_block: bit already set");
                goto repeat;
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
        if (j < sb->u.minix_sb.s_firstdatazone ||
            j >= sb->u.minix_sb.s_nzones)
@@ -129,7+129,7 @@ repeat:
        }
        clear_block(bh->b_data);
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return j;
 }
@@ -175,7+175,7 @@ void minix_free_inode(struct inode * inode)
        clear_inode(inode);
        if (!clear_bit(ino & 8191, bh->b_data))
                printk("free_inode: bit %lu already cleared.\n",ino);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
 }
 
 struct inode * minix_new_inode(const struct inode * dir)
@@ -204,7+204,7 @@ struct inode * minix_new_inode(const struct inode * dir)
                iput(inode);
                return NULL;
        }
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        j += i*8192;
        if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
                iput(inode);
index 8329a48..73088e0 100644 (file)
@@ -98,7+98,8 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
        blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
        bhb = bhe = buflist;
        if (filp->f_reada) {
-               blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+               if(blocks < read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9))
+                 blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
                if (block + blocks > size)
                        blocks = size - block;
        }
@@ -239,7+240,7 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index bc4b16c..b4226db 100644 (file)
@@ -28,7+28,7 @@ void minix_put_inode(struct inode *inode)
 static void minix_commit_super (struct super_block * sb,
                               struct minix_super_block * ms)
 {
-       sb->u.minix_sb.s_sbh->b_dirt = 1;
+       dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
        sb->s_dirt = 0;
 }
 
@@ -54,7+54,7 @@ void minix_put_super(struct super_block *sb)
        lock_super(sb);
        if (!(sb->s_flags & MS_RDONLY)) {
                sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
        }
        sb->s_dev = 0;
        for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
@@ -90,7+90,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
                        return 0;
                /* Mounting a rw partition read-only. */
                ms->s_state = sb->u.minix_sb.s_mount_state;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
                sb->s_dirt = 1;
                minix_commit_super (sb, ms);
        }
@@ -98,7+98,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
                /* Mount a partition which is read-only, read-write. */
                sb->u.minix_sb.s_mount_state = ms->s_state;
                ms->s_state &= ~MINIX_VALID_FS;
-               sb->u.minix_sb.s_sbh->b_dirt = 1;
+               dirtify_buffer(sb->u.minix_sb.s_sbh, 1);
                sb->s_dirt = 1;
 
                if (!(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
@@ -197,7+197,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
        }
        if (!(s->s_flags & MS_RDONLY)) {
                ms->s_state &= ~MINIX_VALID_FS;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                s->s_dirt = 1;
        }
        if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
@@ -349,7+349,7 @@ repeat:
                goto repeat;
        }
        *p = tmp;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        return result;
 }
@@ -477,7+477,7 @@ static struct buffer_head * minix_update_inode(struct inode * inode)
        else for (block = 0; block < 9; block++)
                raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
        inode->i_dirt=0;
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        return bh;
 }
 
index f4814ee..68d7ced 100644 (file)
@@ -195,7+195,7 @@ static int minix_add_entry(struct inode * dir,
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        for (i = 0; i < info->s_namelen ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        break;
                }
@@ -238,7+238,7 @@ int minix_create(struct inode * dir,const char * name, int len, int mode,
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -295,7+295,7 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -347,7+347,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->inode = dir->i_ino;
        strcpy(de->name,"..");
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -361,7+361,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -469,7+469,7 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
        if (inode->i_nlink != 2)
                printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -522,7+522,7 @@ repeat:
                inode->i_nlink=1;
        }
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_dirt = 1;
        inode->i_nlink--;
@@ -562,7+562,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
        while (i < 1023 && (c=*(symname++)))
                name_block->b_data[i++] = c;
        name_block->b_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -584,7+584,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
                return i;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -621,7+621,7 @@ int minix_link(struct inode * oldinode, struct inode * dir, const char * name, i
                return error;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -774,11+774,11 @@ start_up:
                new_inode->i_ctime = CURRENT_TIME;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index bef81a3..bd54453 100644 (file)
@@ -96,7+96,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               ind_bh->b_dirt = 1;
+               dirtify_buffer(ind_bh, 1);
                brelse(bh);
                minix_free_block(inode->i_sb,tmp);
        }
@@ -144,7+144,7 @@ repeat:
                        goto repeat;
                dind = i+(unsigned short *) dind_bh->b_data;
                retry |= trunc_indirect(inode,7+512+(i<<9),dind);
-               dind_bh->b_dirt = 1;
+               dirtify_buffer(dind_bh, 1);
        }
        dind = (unsigned short *) dind_bh->b_data;
        for (i = 0; i < 512; i++)
index b4ec8d7..8576a81 100644 (file)
@@ -72,15+72,15 @@ int fat_access(struct super_block *sb,int nr,int new_value)
                                *p_first = new_value & 0xff;
                                *p_last = (*p_last & 0xf0) | (new_value >> 8);
                        }
-                       bh2->b_dirt = 1;
+                       dirtify_buffer(bh2, 1);
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) {
                        if (!(c_bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->
                            fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)->
                            fat_length*copy,&c_data))) break;
                        memcpy(c_data,data,SECTOR_SIZE);
-                       c_bh->b_dirt = 1;
+                       dirtify_buffer(c_bh, 1);
                        if (data != data2 || bh != bh2) {
                                if (!(c_bh2 = msdos_sread(sb->s_dev,
                                    MSDOS_SB(sb)->fat_start+(first >>
index fc5463d..ba1d623 100644 (file)
@@ -200,7+200,7 @@ static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
                        inode->i_size = filp->f_pos;
                        inode->i_dirt = 1;
                }
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        if (start == buf)
index cf33362..7d028fd 100644 (file)
@@ -415,7+415,7 @@ void msdos_write_inode(struct inode *inode)
        date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
        raw_entry->time = CT_LE_W(raw_entry->time);
        raw_entry->date = CT_LE_W(raw_entry->date);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
 }
 
index 49b7215..7b23886 100644 (file)
@@ -185,7+185,7 @@ printk("zeroing sector %d\n",sector);
                        else memset(data,0,SECTOR_SIZE);
                }
                if (bh) {
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        brelse(bh);
                }
        }
index cf64067..2ed3ee9 100644 (file)
@@ -181,7+181,7 @@ static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
        de->start = 0;
        date_unix2dos(dir->i_mtime,&de->time,&de->date);
        de->size = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        if ((*result = iget(dir->i_sb,ino)) != NULL)
                msdos_read_inode(*result);
        brelse(bh);
@@ -350,7+350,7 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
        dir->i_nlink--;
        inode->i_dirt = dir->i_dirt = 1;
        de->name[0] = DELETED_FLAG;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        res = 0;
 rmdir_done:
        brelse(bh);
@@ -384,7+384,7 @@ int msdos_unlink(struct inode *dir,const char *name,int len)
        MSDOS_I(inode)->i_busy = 1;
        inode->i_dirt = dir->i_dirt = 1;
        de->name[0] = DELETED_FLAG;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
 unlink_done:
        brelse(bh);
        iput(inode);
@@ -429,12+429,12 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,
                MSDOS_I(new_inode)->i_busy = 1;
                new_inode->i_dirt = 1;
                new_de->name[0] = DELETED_FLAG;
-               new_bh->b_dirt = 1;
+               dirtify_buffer(new_bh, 1);
                iput(new_inode);
                brelse(new_bh);
        }
        memcpy(old_de->name,new_name,MSDOS_NAME);
-       old_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
        if (MSDOS_SB(old_dir->i_sb)->conversion == 'a') /* update binary info */
                if ((old_inode = iget(old_dir->i_sb,old_ino)) != NULL) {
                        msdos_read_inode(old_inode);
@@ -503,7+503,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
                MSDOS_I(new_inode)->i_busy = 1;
                new_inode->i_dirt = 1;
                new_de->name[0] = DELETED_FLAG;
-               new_bh->b_dirt = 1;
+               dirtify_buffer(new_bh, 1);
        }
        memcpy(free_de,old_de,sizeof(struct msdos_dir_entry));
        memcpy(free_de->name,new_name,MSDOS_NAME);
@@ -526,8+526,8 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
        cache_inval_inode(old_inode);
        old_inode->i_dirt = 1;
        old_de->name[0] = DELETED_FLAG;
-       old_bh->b_dirt = 1;
-       free_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(free_bh, 1);
        if (!exists) iput(free_inode);
        else {
                MSDOS_I(new_inode)->i_depend = free_inode;
@@ -547,7+547,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
                dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
                    MSDOS_I(new_dir)->i_start;
                dotdot_inode->i_dirt = 1;
-               dotdot_bh->b_dirt = 1;
+               dirtify_buffer(dotdot_bh, 1);
                old_dir->i_nlink--;
                new_dir->i_nlink++;
                /* no need to mark them dirty */
index 6990b41..6707267 100644 (file)
@@ -96,7+96,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                }
                *flc_count = *sb->sv_sb_flc_count; /* = sb->sv_flc_size */
                memcpy(flc_blocks, sb->sv_sb_flc_blocks, *flc_count * sizeof(sysv_zone_t));
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                bh->b_uptodate = 1;
                brelse(bh);
                *sb->sv_sb_flc_count = 0;
@@ -117,7+117,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                bh_data = bh->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits);
                memzero(bh_data, sb->sv_block_size);
                /* this implies ((struct ..._freelist_chunk *) bh_data)->flc_count = 0; */
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                bh->b_uptodate = 1;
                brelse(bh);
                /* still *sb->sv_sb_flc_count = 0 */
@@ -138,7+138,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                  to_coh_ulong(from_coh_ulong(*sb->sv_sb_total_free_blocks) + 1);
        else
                *sb->sv_sb_total_free_blocks = *sb->sv_sb_total_free_blocks + 1;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        unlock_super(sb);
 }
@@ -229,7+229,7 @@ int sysv_new_block(struct super_block * sb)
                        return 0;
                }
        memzero(bh_data,sb->sv_block_size);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        bh->b_uptodate = 1;
        brelse(bh);
        if (sb->sv_convert)
@@ -237,7+237,7 @@ int sysv_new_block(struct super_block * sb)
                  to_coh_ulong(from_coh_ulong(*sb->sv_sb_total_free_blocks) - 1);
        else
                *sb->sv_sb_total_free_blocks = *sb->sv_sb_total_free_blocks - 1;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        unlock_super(sb);
        return block;
@@ -331,7+331,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
                printk("sysv_count_free_blocks: free block count was %d, correcting to %d\n",old_count,count);
                if (!(sb->s_flags & MS_RDONLY)) {
                        *sb->sv_sb_total_free_blocks = (sb->sv_convert ? to_coh_ulong(count) : count);
-                       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+                       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
                        sb->s_dirt = 1; /* and needs time stamp */
                }
        }
index 4c012fc..df61c0d 100644 (file)
@@ -301,7+301,7 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
                memcpy_fromfs(p,buf,c);
                buf += c;
                bh->b_uptodate = 1;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 0);
                brelse(bh);
        }
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index cfa5694..4aa7903 100644 (file)
@@ -74,10+74,10 @@ void sysv_free_inode(struct inode * inode)
        if (*sb->sv_sb_fic_count < sb->sv_fic_size)
                sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)++] = ino;
        (*sb->sv_sb_total_free_inodes)++;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        memset(raw_inode, 0, sizeof(struct sysv_inode));
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        unlock_super(sb);
        brelse(bh);
        clear_inode(inode);
@@ -130,7+130,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        }
        /* Now *sb->sv_sb_fic_count > 0. */
        ino = sb->sv_sb_fic_inodes[--(*sb->sv_sb_fic_count)];
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
        sb->s_dirt = 1; /* and needs time stamp */
        inode->i_count = 1;
        inode->i_nlink = 1;
@@ -152,7+152,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
        inode->i_dirt = 1;              /* cleared by sysv_write_inode() */
        /* That's it. */
        (*sb->sv_sb_total_free_inodes)--;
-       sb->sv_bh->b_dirt = 1; /* super-block has been modified again */
+       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified again */
        sb->s_dirt = 1; /* and needs time stamp again */
        unlock_super(sb);
        return inode;
@@ -191,7+191,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
                printk("sysv_count_free_inodes: free inode count was %d, correcting to %d\n",(short)(*sb->sv_sb_total_free_inodes),count);
                if (!(sb->s_flags & MS_RDONLY)) {
                        *sb->sv_sb_total_free_inodes = count;
-                       sb->sv_bh->b_dirt = 1; /* super-block has been modified */
+                       dirtify_buffer(sb->sv_bh, 1); /* super-block has been modified */
                        sb->s_dirt = 1; /* and needs time stamp */
                }
        }
index d9eb848..4c1d94b 100644 (file)
@@ -557,7+557,7 @@ repeat:
                goto repeat;
        }
        *p = (sb->sv_convert ? to_coh_ulong(block) : block);
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        *start = result->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits);
        return result;
@@ -773,7+773,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
                for (block = 0; block < 10+1+1+1; block++)
                        write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
        inode->i_dirt=0;
-       bh->b_dirt=1;
+       dirtify_buffer(bh, 1);
        return bh;
 }
 
index e0e17cd..a08d294 100644 (file)
@@ -193,7+193,7 @@ static int sysv_add_entry(struct inode * dir,
                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
                        for (i = 0; i < SYSV_NAMELEN ; i++)
                                de->name[i] = (i < namelen) ? name[i] : 0;
-                       bh->b_dirt = 1;
+                       dirtify_buffer(bh, 1);
                        *res_dir = de;
                        break;
                }
@@ -238,7+238,7 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        *result = inode;
@@ -298,7+298,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -349,7+349,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
        de->inode = dir->i_ino;
        strcpy(de->name,".."); /* rest of de->name is zero, see sysv_new_block */
        inode->i_nlink = 2;
-       dir_block->b_dirt = 1;
+       dirtify_buffer(dir_block, 1);
        brelse(dir_block);
        inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        if (dir->i_mode & S_ISGID)
@@ -363,7+363,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
                return error;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_nlink++;
        dir->i_dirt = 1;
        iput(dir);
@@ -473,7+473,7 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
        if (inode->i_nlink != 2)
                printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        inode->i_nlink=0;
        inode->i_dirt=1;
        dir->i_nlink--;
@@ -526,7+526,7 @@ repeat:
                inode->i_nlink=1;
        }
        de->inode = 0;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
        dir->i_dirt = 1;
        inode->i_nlink--;
@@ -570,7+570,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
        while (i < sb->sv_block_size_1 && (c = *(symname++)))
                name_block_data[i++] = c;
        name_block_data[i] = 0;
-       name_block->b_dirt = 1;
+       dirtify_buffer(name_block, 1);
        brelse(name_block);
        inode->i_size = i;
        inode->i_dirt = 1;
@@ -592,7+592,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
                return i;
        }
        de->inode = inode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        iput(inode);
@@ -629,7+629,7 @@ int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, in
                return error;
        }
        de->inode = oldinode->i_ino;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 1);
        brelse(bh);
        iput(dir);
        oldinode->i_nlink++;
@@ -782,11+782,11 @@ start_up:
                new_inode->i_ctime = CURRENT_TIME;
                new_inode->i_dirt = 1;
        }
-       old_bh->b_dirt = 1;
-       new_bh->b_dirt = 1;
+       dirtify_buffer(old_bh, 1);
+       dirtify_buffer(new_bh, 1);
        if (dir_bh) {
                PARENT_INO(dir_bh_data) = new_dir->i_ino;
-               dir_bh->b_dirt = 1;
+               dirtify_buffer(dir_bh, 1);
                old_dir->i_nlink--;
                old_dir->i_dirt = 1;
                if (new_inode) {
index e9b6ccf..e8b5dde 100644 (file)
@@ -84,7+84,7 @@ static int coh_trunc_indirect (struct inode * inode, unsigned long blocks, unsig
                if (!indblock)
                        continue;
                *ind = 0;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                sysv_free_block(sb,indblock);
        }
        for (i = 0; i < sb->sv_ind_per_block; i++)
@@ -338,7+338,7 @@ repeat:
                        continue;
                }
                *ind = 0;
-               indbh->b_dirt = 1;
+               dirtify_buffer(indbh, 1);
                brelse(bh);
                sysv_free_block(sb,block);
        }
index 3dd74fa..c191d64 100644 (file)
@@ -65,7+65,7 @@ zone_found:
         start_bit=j + (i << 5) + 1;
        goto repeat;
     }
-    bh->b_dirt=1;
+    dirtify_buffer(bh, 1);
     return j + (i << 5);
 }
 
@@ -245,7+245,7 @@ void xiafs_free_zone(struct super_block * sb, int d_addr)
         printk("XIA-FS: dev %04x"
               " block bit %u (0x%x) already cleared (%s %d)\n",
               sb->s_dev, bit, bit, WHERE_ERR);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
 }
 
@@ -277,7+277,7 @@ int xiafs_new_zone(struct super_block * sb, u_long prev_addr)
     }
     clear_buf(bh);
     bh->b_uptodate = 1;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     return tmp;
 }
@@ -305,7+305,7 @@ void xiafs_free_inode(struct inode * inode)
         printk("XIA-FS: dev %04x"
               "inode bit %ld (0x%lx) already cleared (%s %d)\n",
               inode->i_dev, ino, ino, WHERE_ERR);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
 }
 
index 3c5bd5a..92075b5 100644 (file)
@@ -97,7+97,8 @@ xiafs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
     zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb);
     bhb = bhe = buflist;
     if (filp->f_reada) {
-        zones += read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
+        if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)))
+         zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
        if (zone_nr + zones > f_zones)
            zones = f_zones - zone_nr;
     }
@@ -240,7+241,7 @@ xiafs_file_write(struct inode * inode, struct file * filp, char * buf, int count
        memcpy_fromfs(cp,buf,c);
        buf += c;
        bh->b_uptodate = 1;
-       bh->b_dirt = 1;
+       dirtify_buffer(bh, 0);
        brelse(bh);
     }
     inode->i_mtime = inode->i_ctime = CURRENT_TIME;
index 84e2109..8af15c3 100644 (file)
@@ -306,7+306,7 @@ repeat:
     }
     *lp = tmp;
     inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     return result;
 }
@@ -466,7+466,7 @@ static struct buffer_head *  xiafs_update_inode(struct inode * inode)
                                     | (inode->u.xiafs_i.i_dind_zone  & 0xffffff);
     }
     inode->i_dirt=0;
-    bh->b_dirt=1;
+    dirtify_buffer(bh, 1);
     return bh;
 }
 
index 52c9a68..13d49d6 100644 (file)
@@ -221,7+221,7 @@ static struct buffer_head * xiafs_add_entry(struct inode * dir,
                memcpy(de->d_name, name, namelen);
                de->d_name[namelen]=0;
                de->d_name_len=namelen;
-               bh->b_dirt = 1;
+               dirtify_buffer(bh, 1);
                *res_dir = de;
                if (res_pre)
                    *res_pre = de_pre;
@@ -268,7+268,7 @@ int xiafs_create(struct inode * dir, const char * name, int len, int mode,
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     *result = inode;
@@ -325,7+325,7 @@ int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     iput(inode);
@@ -375,7+375,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
     de->d_name_len=2;
     de->d_rec_len=XIAFS_ZSIZE(dir->i_sb)-12;
     inode->i_nlink = 2;
-    dir_block->b_dirt = 1;
+    dirtify_buffer(dir_block, 1);
     brelse(dir_block);
     inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->umask);
     if (dir->i_mode & S_ISGID)
@@ -389,7+389,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     dir->i_nlink++;
     dir->i_dirt = 1;
     iput(dir);
@@ -518,7+518,7 @@ int xiafs_rmdir(struct inode * dir, const char * name, int len)
     if (inode->i_nlink != 2)
         printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR);
     xiafs_rm_entry(de, de_pre);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     inode->i_nlink=0;
     inode->i_dirt=1;
     dir->i_nlink--;
@@ -566,7+566,7 @@ repeat:
        inode->i_nlink=1;
     }
     xiafs_rm_entry(de, de_pre);
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
     dir->i_dirt = 1;
     inode->i_nlink--;
@@ -611,7+611,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
     for (i = 0; i < BLOCK_SIZE-1 && (c=*symname++); i++)
         name_block->b_data[i] = c;
     name_block->b_data[i] = 0;
-    name_block->b_dirt = 1;
+    dirtify_buffer(name_block, 1);
     brelse(name_block);
     inode->i_size = i;
     inode->i_dirt = 1;
@@ -624,7+624,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
        return -ENOSPC;
     }
     de->d_ino = inode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     iput(inode);
@@ -661,7+661,7 @@ int xiafs_link(struct inode * oldinode, struct inode * dir,
        return -ENOSPC;
     }
     de->d_ino = oldinode->i_ino;
-    bh->b_dirt = 1;
+    dirtify_buffer(bh, 1);
     brelse(bh);
     iput(dir);
     oldinode->i_nlink++;
@@ -798,11+798,11 @@ try_again:
         new_inode->i_nlink--;
        new_inode->i_dirt = 1;
     }
-    old_bh->b_dirt = 1;
-    new_bh->b_dirt = 1;
+    dirtify_buffer(old_bh, 1);
+    dirtify_buffer(new_bh, 1);
     if (dir_bh) {
         PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-       dir_bh->b_dirt = 1;
+       dirtify_buffer(dir_bh, 1);
        old_dir->i_nlink--;
        new_dir->i_nlink++;
        old_dir->i_dirt = 1;
index 336dcb0..6cae250 100644 (file)
@@ -104,7+104,7 @@ repeat:
            retry = 1;
        else {
            *indp = 0;
-           ind_bh->b_dirt = 1;
+           dirtify_buffer(ind_bh, 1);
            inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);
            xiafs_free_zone(inode->i_sb, tmp);
        }
@@ -157,7+157,7 @@ repeat:
        retry |= trunc_indirect(inode, 
                                8+((1+i)<<XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)), 
                                dindp);
-       dind_bh->b_dirt = 1;
+       dirtify_buffer(dind_bh, 1);
     }
     dindp = (u_long *) dind_bh->b_data;
     for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*dindp++); i++);
index 173d333..16ebab9 100644 (file)
@@ -103,6+103,7 @@ extern unsigned long file_table_init(unsigned long start, unsigned long end);
 #define BLKRRPART 4703 /* re-read partition table */
 #define BLKGETSIZE 4704 /* return device size */
 #define BLKFLSBUF 4705 /* flush buffer cache */
+#define BLKRASET 4706 /* Set read ahead for block device */
 
 /* These are a few other constants  only used by scsi  devices */
 
@@ -210,7+211,7 @@ struct file {
        off_t f_pos;
        unsigned short f_flags;
        unsigned short f_count;
-       unsigned short f_reada;
+       off_t f_reada;
        struct file *f_next, *f_prev;
        struct inode * f_inode;
        struct file_operations * f_op;
@@ -359,6+360,12 @@ extern int nr_buffers;
 extern int buffermem;
 extern int nr_buffer_heads;
 
+/* Once the full cluster diffs are in place, this will be filled out a bit. */
+extern inline void dirtify_buffer(struct buffer_head * bh, int flag)
+{
+  bh->b_dirt = 1;
+}
+
 extern void check_disk_change(dev_t dev);
 extern void invalidate_inodes(dev_t dev);
 extern void invalidate_buffers(dev_t dev);
@@ -392,7+399,8 @@ extern void brelse(struct buffer_head * buf);
 extern void set_blocksize(dev_t dev, int size);
 extern struct buffer_head * bread(dev_t dev, int block, int size);
 extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int prot);
-extern struct buffer_head * breada(dev_t dev,int block,...);
+extern struct buffer_head * breada(dev_t dev,int block, int size, 
+                                  unsigned int pos, unsigned int filesize);
 extern void put_super(dev_t dev);
 extern dev_t ROOT_DEV;
 
index ad39118..e83874b 100644 (file)
 
 #define X(name)        { (void *) &name, "_" #name }
 
+#ifdef CONFIG_FTAPE
+extern char * ftape_big_buffer;
+extern void (*do_floppy)(void);
+#endif
+
 struct {
        void *addr;
        const char *name;
index 30ecb87..d3914af 100644 (file)
@@ -902,7+902,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                        } else 
                                user_esp = regs->esp;
                }
-               if (error_code & 1)
+               if (error_code & PAGE_PRESENT)
                        do_wp_page(error_code, address, current, user_esp);
                else
                        do_no_page(error_code, address, current, user_esp);
@@ -1084,10+1084,17 @@ void mem_init(unsigned long start_low_mem,
        /* mark usable pages in the mem_map[] */
        start_low_mem = PAGE_ALIGN(start_low_mem);
        start_mem = PAGE_ALIGN(start_mem);
-       while (start_low_mem < 0xA0000) {
+
+       /*
+        * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
+        * They seem to have done something stupid with the floppy
+        * controller as well..
+        */
+       while (start_low_mem < 0x9f000) {
                mem_map[MAP_NR(start_low_mem)] = 0;
                start_low_mem += PAGE_SIZE;
        }
+
        while (start_mem < high_memory) {
                mem_map[MAP_NR(start_mem)] = 0;
                start_mem += PAGE_SIZE;
@@ -1133,21+1140,18 @@ void si_meminfo(struct sysinfo *val)
 
        i = high_memory >> PAGE_SHIFT;
        val->totalram = 0;
-       val->freeram = 0;
        val->sharedram = 0;
+       val->freeram = nr_free_pages << PAGE_SHIFT;
        val->bufferram = buffermem;
        while (i-- > 0)  {
                if (mem_map[i] & MAP_PAGE_RESERVED)
                        continue;
                val->totalram++;
-               if (!mem_map[i]) {
-                       val->freeram++;
+               if (!mem_map[i])
                        continue;
-               }
                val->sharedram += mem_map[i]-1;
        }
        val->totalram <<= PAGE_SHIFT;
-       val->freeram <<= PAGE_SHIFT;
        val->sharedram <<= PAGE_SHIFT;
        return;
 }
index e1874f2..419681a 100644 (file)
 #include <linux/fcntl.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include "inet.h"
 #include "dev.h"
 #include "ip.h"
index a3f17e7..d1840ce 100644 (file)
  *             Linus Torvalds/ :       Memory leakage on fragmentation 
  *             Alan Cox        :       handling.
  *             Gerhard Koerting:       Forwarding uses IP priority hints
+ *             Teemu Rantanen  :       Fragment problems.
  *
  * To Fix:
  *             IP option processing is mostly not needed. ip_forward needs to know about routing rules
@@ -774,6+775,7 @@ static struct sk_buff *ip_glue(struct ipq *qp)
        skb->len = (len - qp->maclen);
        skb->h.raw = skb->data;
        skb->free = 1;
+       skb->dev = qp->dev;
  
        /* Copy the original MAC and IP headers into the new buffer. */
        ptr = (unsigned char *) skb->h.raw;
index 20af8c0..6be78d7 100644 (file)
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
+#include <linux/string.h>
 #include "inet.h"
 #include "dev.h"
 #include "ip.h"
close