On Thu, Jan 27, 2000 at 05:08:25PM +0100, Thomas Kotzian wrote:
> There was a little bit of discussion about the stability of the adaptec
> 2940U2W under heavy load. (like under raid).

I have an SMP box with nine IBM 36.5GB drives across two 2940U2W in RAID-5.
It had a lot of trouble for a while with buggy SCSI drivers and some ext2fs 
issues that would knock out the disk array and require reconstruction etc...
This is all in the past and the box is very stable and fast

Use recent aic7xxx drivers. The bug was fixed only a short time ago. I am using
version 5.1.21 of the aic7xxx driver in a 2.2.13 kernel with an ext2fs patch and
things are good. Previous versions of the driver could produce corrupt data
under heavy input load, e.g., computing the MD5 signatures of all the files
the array prior to moving them somewhere else :(  The files were on the disks okay
but you just couldn't read them off quickly!  That's fixed with the 5.1.21 driver.

One problem that seems to hit a lot of people is the infamous "tried to access
beyond end of device" scenario where all your disks get knocked out one after
the other when the RAID code assumes the invalid block # is a failed disk. Scared
me witless the first time.  The following patch from Andrea Arcangeli seems to fix
it all (this patch is apparently in 2.2.14 but I haven't been following things).



diff -urN 2.2.13/fs/ext2/balloc.c ext2/fs/ext2/balloc.c
--- 2.2.13/fs/ext2/balloc.c     Sun Oct 31 23:31:31 1999
+++ ext2/fs/ext2/balloc.c       Sat Nov  6 02:32:48 1999
@@ -603,6 +603,8 @@
                unlock_super (sb);
                return 0;
        }
+       if (!buffer_uptodate(bh))
+               wait_on_buffer(bh);
        memset(bh->b_data, 0, sb->s_blocksize);
        mark_buffer_uptodate(bh, 1);
        mark_buffer_dirty(bh, 1);
diff -urN 2.2.13/fs/ext2/fsync.c ext2/fs/ext2/fsync.c
--- 2.2.13/fs/ext2/fsync.c      Sun Oct 31 23:31:31 1999
+++ ext2/fs/ext2/fsync.c        Sat Nov  6 04:25:40 1999
@@ -45,10 +45,21 @@
        if (!bh)
                return 0;
        if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
-               brelse (bh);
-               return -1;
+               /* There can be a parallell read(2) that started read-I/O
+                  on the buffer so we can't assume that there's been
+                  an I/O error without first waiting I/O completation. */
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh))
+               {
+                       brelse (bh);
+                       return -1;
+               }
        }
        if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
+               if (wait)
+                       /* when we return from fsync all the blocks
+                          must be _just_ stored on disk */
+                       wait_on_buffer(bh);
                brelse (bh);
                return 0;
        }
@@ -68,10 +79,21 @@
        if (!bh)
                return 0;
        if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
-               brelse (bh);
-               return -1;
+               /* There can be a parallell read(2) that started read-I/O
+                  on the buffer so we can't assume that there's been
+                  an I/O error without first waiting I/O completation. */
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh))
+               {
+                       brelse (bh);
+                       return -1;
+               }
        }
        if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
+               if (wait)
+                       /* when we return from fsync all the blocks
+                          must be _just_ stored on disk */
+                       wait_on_buffer(bh);
                brelse (bh);
                return 0;
        }
diff -urN 2.2.13/fs/ext2/inode.c ext2/fs/ext2/inode.c
--- 2.2.13/fs/ext2/inode.c      Sun Oct 31 23:31:31 1999
+++ ext2/fs/ext2/inode.c        Sat Nov  6 21:48:10 1999
@@ -121,6 +121,8 @@
                                    "cannot get block %lu", result);
                        return 0;
                }
+               if (!buffer_uptodate(bh))
+                       wait_on_buffer(bh);
                memset(bh->b_data, 0, inode->i_sb->s_blocksize);
                mark_buffer_uptodate(bh, 1);
                mark_buffer_dirty(bh, 1);

-- 
Andy Newman

Reply via email to