]> git.neil.brown.name Git - history.git/commitdiff
Here is the patch to 0.96a that corrects the harddisk error bug, dup2() 0.96a-patch1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:00 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:00 +0000 (15:09 -0500)
and X11 text-mode restoration.  Thanks to Rick Sladkey for finding the
dup2() bug.

fs/fcntl.c
include/linux/tty.h
kernel/blk_drv/blk.h
kernel/blk_drv/hd.c
kernel/chr_drv/console.c
kernel/chr_drv/vt.c

index 952bf8cb488bde00e5d3b6f56d6a1f8e7110337f..bf2861d65bb84f9edff7c3078bfac0e3e4b77a8b 100644 (file)
@@ -37,6 +37,8 @@ static int dupfd(unsigned int fd, unsigned int arg)
 
 int sys_dup2(unsigned int oldfd, unsigned int newfd)
 {
+       if (oldfd >= NR_OPEN || !current->filp[oldfd])
+               return -EBADF;
        if (newfd == oldfd)
                return newfd;
        sys_close(newfd);
index 57c3b58c1c5eabc4aa94bc5fd7abca76599e2c8d..82dd517e845e667ab3acf24c008162aecd08ae5e 100644 (file)
@@ -195,6 +195,8 @@ extern void serial_open(unsigned int line);
 void copy_to_cooked(struct tty_struct * tty);
 
 void update_screen(int new_console);
+void blank_screen(void);
+void unblank_screen(void);
 
 int kill_pg(int pgrp, int sig, int priv);
    
index 40a59255f877ce7c9b90a6a6d3157e28c81f8f9d..1bc455cb261fa7a3ab5b42aa9a8bbd029a94b29e 100644 (file)
@@ -149,26 +149,6 @@ extern inline void unlock_buffer(struct buffer_head * bh)
        wake_up(&bh->b_wait);
 }
 
-extern inline void next_buffer(int uptodate)
-{
-       struct buffer_head *tmp;
-
-       CURRENT->bh->b_uptodate = uptodate;
-       unlock_buffer(CURRENT->bh);
-       if (!uptodate) {
-               printk(DEVICE_NAME " I/O error\n\r");
-               printk("dev %04x, block %d\n\r",CURRENT->dev,
-                       CURRENT->bh->b_blocknr);
-       }
-       tmp = CURRENT->bh;
-       CURRENT->bh = CURRENT->bh->b_reqnext;
-       tmp->b_reqnext = NULL;
-       if (!CURRENT->bh)
-               panic("next_buffer: request buffer list destroyed\r\n");
-       CURRENT->buffer = CURRENT->bh->b_data;
-       CURRENT->errors = 0;
-}
-
 extern inline void end_request(int uptodate)
 {
        struct request * tmp;
@@ -190,6 +170,28 @@ extern inline void end_request(int uptodate)
        wake_up(&wait_for_request);
 }
 
+extern inline void next_buffer(int uptodate)
+{
+       struct buffer_head *tmp;
+
+       tmp = CURRENT->bh;
+       CURRENT->bh = tmp->b_reqnext;
+       tmp->b_reqnext = NULL;
+       tmp->b_uptodate = uptodate;
+       unlock_buffer(tmp);
+       if (!uptodate) {
+               printk(DEVICE_NAME " I/O error\n\r");
+               printk("dev %04x, block %d\n\r",tmp->b_dev, tmp->b_blocknr);
+       }
+       if (!CURRENT->bh) {
+               printk("next_buffer: request buffer list destroyed\r\n");
+               end_request(0);
+               return;
+       }
+       CURRENT->buffer = CURRENT->bh->b_data;
+       CURRENT->errors = 0;
+}
+
 #ifdef DEVICE_INTR
 #define CLEAR_INTR SET_INTR(NULL)
 #else
index 43ce9b722ea5d2dfa904b42a9033ddcf0c108d88..6244567dc7a45798eae788cbaa20a50a6918d4f1 100644 (file)
@@ -424,7 +424,12 @@ static void bad_rw_intr(void)
                return;
        if (++CURRENT->errors >= MAX_ERRORS)
                if (CURRENT->bh && CURRENT->nr_sectors > 2) {
-                       CURRENT->nr_sectors &= ~1;
+                       CURRENT->nr_sectors--;
+                       CURRENT->sector++;
+                       if (CURRENT->nr_sectors & 1) {
+                               CURRENT->nr_sectors--;
+                               CURRENT->sector++;
+                       }
                        next_buffer(0);
                } else
                        end_request(0);
@@ -530,7 +535,12 @@ static void hd_times_out(void)
        cli();
        if (++CURRENT->errors >= MAX_ERRORS)
                if (CURRENT->bh && CURRENT->nr_sectors > 2) {
-                       CURRENT->nr_sectors &= ~1;
+                       CURRENT->nr_sectors--;
+                       CURRENT->sector++;
+                       if (CURRENT->nr_sectors & 1) {
+                               CURRENT->nr_sectors--;
+                               CURRENT->sector++;
+                       }
                        next_buffer(0);
                } else
                        end_request(0);
index 824f1ad6410929ca8ec6172fd1248a4944affbe0..8709a22100be7aa374a3f8ecd808d2f9c84553fa 100644 (file)
@@ -56,9 +56,6 @@
        INIT_C_CC \
 }
 
-static void blank_screen(void);
-static void unblank_screen(void);
-
 /*
  * These are set up by the setup-routine at boot-time:
  */
@@ -223,7 +220,7 @@ static inline void set_origin(int currcons)
 {
        if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
                return;
-       if (currcons != fg_console)
+       if (currcons != fg_console || vt_cons[currcons].vt_mode == KD_GRAPHICS)
                return;
        cli();
        outb_p(12, video_port_reg);
@@ -584,10 +581,6 @@ void con_write(struct tty_struct * tty)
                printk("con_write: illegal tty\n\r");
                return;
        }
-       if (vt_cons[currcons].vt_mode == KD_GRAPHICS) {
-               flush(tty->write_q);
-               return;                 /* no output in graphics mode */
-       }
        while (!tty->stopped && (c = GETCH(tty->write_q)) >= 0) {
                if (c == 24 || c == 26)
                        state = ESnormal;
@@ -834,8 +827,10 @@ void con_write(struct tty_struct * tty)
                                state = ESnormal;
                }
        }
-       set_cursor(currcons);
        timer_active &= ~(1<<BLANK_TIMER);
+       if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
+               return;
+       set_cursor(currcons);
        if (currcons == fg_console)
                if (console_blanked) {
                        timer_table[BLANK_TIMER].expires = 0;
@@ -1129,8 +1124,6 @@ void console_print(const char * b)
 
        if (currcons<0 || currcons>=NR_CONSOLES)
                currcons = 0;
-       if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
-               return; /* no output in graphics mode */
        while (c = *(b++)) {
                if (c == 10) {
                        cr(currcons);
index 8bac0fe4bbbc78167822f51b17701fcd06e224ea..051460172c457fa798f725341f71dcc36989695a 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/tty.h>
+#include <linux/timer.h>
 #include <linux/kernel.h>
 
 #include "vt_kern.h"
@@ -121,7 +122,17 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg)
                default:
                        return -EINVAL;
                }
-               vt_cons[console].vt_mode = arg;
+               if (vt_cons[console].vt_mode == (unsigned char) arg)
+                       return 0;
+               vt_cons[console].vt_mode = (unsigned char) arg;
+               if (console != fg_console)
+                       return 0;
+               if (arg == KD_TEXT)
+                       unblank_screen();
+               else {
+                       timer_active &= 1<<BLANK_TIMER;
+                       blank_screen();
+               }
                return 0;
        case KDGETMODE:
                verify_area((void *) arg, sizeof(unsigned long));