Commit 5b58d8fe authored by Linus Torvalds's avatar Linus Torvalds

Here is the patch to 0.96a that corrects the harddisk error bug, dup2()

and X11 text-mode restoration.  Thanks to Rick Sladkey for finding the
dup2() bug.
parent c27acf0e
...@@ -37,6 +37,8 @@ static int dupfd(unsigned int fd, unsigned int arg) ...@@ -37,6 +37,8 @@ static int dupfd(unsigned int fd, unsigned int arg)
int sys_dup2(unsigned int oldfd, unsigned int newfd) int sys_dup2(unsigned int oldfd, unsigned int newfd)
{ {
if (oldfd >= NR_OPEN || !current->filp[oldfd])
return -EBADF;
if (newfd == oldfd) if (newfd == oldfd)
return newfd; return newfd;
sys_close(newfd); sys_close(newfd);
......
...@@ -195,6 +195,8 @@ extern void serial_open(unsigned int line); ...@@ -195,6 +195,8 @@ extern void serial_open(unsigned int line);
void copy_to_cooked(struct tty_struct * tty); void copy_to_cooked(struct tty_struct * tty);
void update_screen(int new_console); void update_screen(int new_console);
void blank_screen(void);
void unblank_screen(void);
int kill_pg(int pgrp, int sig, int priv); int kill_pg(int pgrp, int sig, int priv);
......
...@@ -149,26 +149,6 @@ extern inline void unlock_buffer(struct buffer_head * bh) ...@@ -149,26 +149,6 @@ extern inline void unlock_buffer(struct buffer_head * bh)
wake_up(&bh->b_wait); 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) extern inline void end_request(int uptodate)
{ {
struct request * tmp; struct request * tmp;
...@@ -190,6 +170,28 @@ extern inline void end_request(int uptodate) ...@@ -190,6 +170,28 @@ extern inline void end_request(int uptodate)
wake_up(&wait_for_request); 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 #ifdef DEVICE_INTR
#define CLEAR_INTR SET_INTR(NULL) #define CLEAR_INTR SET_INTR(NULL)
#else #else
......
...@@ -424,7 +424,12 @@ static void bad_rw_intr(void) ...@@ -424,7 +424,12 @@ static void bad_rw_intr(void)
return; return;
if (++CURRENT->errors >= MAX_ERRORS) if (++CURRENT->errors >= MAX_ERRORS)
if (CURRENT->bh && CURRENT->nr_sectors > 2) { 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); next_buffer(0);
} else } else
end_request(0); end_request(0);
...@@ -530,7 +535,12 @@ static void hd_times_out(void) ...@@ -530,7 +535,12 @@ static void hd_times_out(void)
cli(); cli();
if (++CURRENT->errors >= MAX_ERRORS) if (++CURRENT->errors >= MAX_ERRORS)
if (CURRENT->bh && CURRENT->nr_sectors > 2) { 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); next_buffer(0);
} else } else
end_request(0); end_request(0);
......
...@@ -56,9 +56,6 @@ ...@@ -56,9 +56,6 @@
INIT_C_CC \ INIT_C_CC \
} }
static void blank_screen(void);
static void unblank_screen(void);
/* /*
* These are set up by the setup-routine at boot-time: * These are set up by the setup-routine at boot-time:
*/ */
...@@ -223,7 +220,7 @@ static inline void set_origin(int currcons) ...@@ -223,7 +220,7 @@ static inline void set_origin(int currcons)
{ {
if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
return; return;
if (currcons != fg_console) if (currcons != fg_console || vt_cons[currcons].vt_mode == KD_GRAPHICS)
return; return;
cli(); cli();
outb_p(12, video_port_reg); outb_p(12, video_port_reg);
...@@ -584,10 +581,6 @@ void con_write(struct tty_struct * tty) ...@@ -584,10 +581,6 @@ void con_write(struct tty_struct * tty)
printk("con_write: illegal tty\n\r"); printk("con_write: illegal tty\n\r");
return; 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) { while (!tty->stopped && (c = GETCH(tty->write_q)) >= 0) {
if (c == 24 || c == 26) if (c == 24 || c == 26)
state = ESnormal; state = ESnormal;
...@@ -834,8 +827,10 @@ void con_write(struct tty_struct * tty) ...@@ -834,8 +827,10 @@ void con_write(struct tty_struct * tty)
state = ESnormal; state = ESnormal;
} }
} }
set_cursor(currcons);
timer_active &= ~(1<<BLANK_TIMER); timer_active &= ~(1<<BLANK_TIMER);
if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
return;
set_cursor(currcons);
if (currcons == fg_console) if (currcons == fg_console)
if (console_blanked) { if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0; timer_table[BLANK_TIMER].expires = 0;
...@@ -1129,8 +1124,6 @@ void console_print(const char * b) ...@@ -1129,8 +1124,6 @@ void console_print(const char * b)
if (currcons<0 || currcons>=NR_CONSOLES) if (currcons<0 || currcons>=NR_CONSOLES)
currcons = 0; currcons = 0;
if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
return; /* no output in graphics mode */
while (c = *(b++)) { while (c = *(b++)) {
if (c == 10) { if (c == 10) {
cr(currcons); cr(currcons);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/timer.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include "vt_kern.h" #include "vt_kern.h"
...@@ -121,7 +122,17 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg) ...@@ -121,7 +122,17 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg)
default: default:
return -EINVAL; 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; return 0;
case KDGETMODE: case KDGETMODE:
verify_area((void *) arg, sizeof(unsigned long)); verify_area((void *) arg, sizeof(unsigned long));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment