Commit 20fca9a1 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.123pre1

parent f85f3898
......@@ -51,7 +51,7 @@ Then WaveTable goes. For some reason Plug-n-Play detects only one I/O port,
but the wavetable needs THREE! My working string is:
"(CONFIGURE CTL044/1132685 (LD 2 (IO 0 (BASE 0x0620)) (IO 1 (BASE 0x0A20))
(IO 3 (BASE 0x0E20)) (ACT Y) ))"
(IO 2 (BASE 0x0E20)) (ACT Y) ))"
Resources 0x0620, 0x0A20 and 0x0E20 should work. Other on-board devices:
Gameport and StereoEnhance are not required to be inited.
......
......@@ -540,10 +540,10 @@ void release_thread(struct task_struct *dead_task)
static inline void unlazy_fpu(struct task_struct *tsk)
{
if (tsk->flags & PF_USEDFPU) {
tsk->flags &= ~PF_USEDFPU;
__asm__("fnsave %0":"=m" (tsk->tss.i387));
stts();
asm volatile("fwait");
tsk->flags &= ~PF_USEDFPU;
stts();
}
}
......@@ -737,8 +737,11 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
asm volatile("lldt %0": :"g" (*(unsigned short *)&next->tss.ldt));
/* Re-load page tables */
if (next->tss.cr3 != prev->tss.cr3)
asm volatile("movl %0,%%cr3": :"r" (next->tss.cr3));
{
unsigned long new_cr3 = next->tss.cr3;
if (new_cr3 != prev->tss.cr3)
asm volatile("movl %0,%%cr3": :"r" (new_cr3));
}
/*
* Restore %fs and %gs.
......
This diff is collapsed.
......@@ -26,8 +26,6 @@
#define utf (vc_cons[currcons].d->vc_utf)
#define utf_count (vc_cons[currcons].d->vc_utf_count)
#define utf_char (vc_cons[currcons].d->vc_utf_char)
#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
......@@ -64,6 +62,7 @@
#define cursor_type (vc_cons[currcons].d->vc_cursor_type)
#define display_fg (vc_cons[currcons].d->vc_display_fg)
#define complement_mask (vc_cons[currcons].d->vc_complement_mask)
#define s_complement_mask (vc_cons[currcons].d->vc_s_complement_mask)
#define hi_font_mask (vc_cons[currcons].d->vc_hi_font_mask)
#define vcmode (vt_cons[currcons]->vc_mode)
......
......@@ -575,6 +575,24 @@ con_set_default_unimap(int con)
return err;
}
int
con_copy_unimap(int dstcon, int srccon)
{
struct vc_data *sconp = vc_cons[srccon].d;
struct vc_data *dconp = vc_cons[dstcon].d;
struct uni_pagedir *q;
if (!vc_cons_allocated(srccon) || !*sconp->vc_uni_pagedir_loc)
return -EINVAL;
if (*dconp->vc_uni_pagedir_loc == *sconp->vc_uni_pagedir_loc)
return 0;
con_free_unimap(dstcon);
q = (struct uni_pagedir *)*sconp->vc_uni_pagedir_loc;
q->refcount++;
*dconp->vc_uni_pagedir_loc = (long)q;
return 0;
}
int
con_get_unimap(int con, ushort ct, ushort *uct, struct unipair *list)
{
......
......@@ -123,7 +123,7 @@ int set_selection(const unsigned long arg, struct tty_struct *tty, int user)
int i, ps, pe;
unsigned int currcons = fg_console;
do_unblank_screen();
unblank_screen();
poke_blanked_console();
{ unsigned short *args, xs, ys, xe, ye;
......
/* -*- linux-c -*-
*
* $Id: sysrq.c,v 1.7 1997/11/06 15:57:09 mj Exp $
* $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
*
* Linux Magic System Request Key Hacks
*
......@@ -70,12 +70,14 @@ void handle_sysrq(int key, struct pt_regs *pt_regs,
printk("Keyboard mode set to XLATE\n");
}
break;
#ifdef CONFIG_VT
case 'k': /* K -- SAK */
printk("SAK\n");
if (tty)
do_SAK(tty);
reset_vc(fg_console);
break;
#endif
case 'b': /* B -- boot immediately */
printk("Resetting\n");
machine_restart(NULL);
......@@ -131,8 +133,10 @@ void handle_sysrq(int key, struct pt_regs *pt_regs,
default: /* Unknown: help */
if (kbd)
printk("unRaw ");
#ifdef CONFIG_VT
if (tty)
printk("saK ");
#endif
printk("Boot "
#ifdef CONFIG_APM
"Off "
......
......@@ -126,11 +126,11 @@ static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
static int tty_release(struct inode *, struct file *);
static int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on);
#ifdef CONFIG_8xx
extern long console_8xx_init(void);
extern long console_8xx_init(long, long);
extern int rs_8xx_init(void);
#endif /* CONFIG_8xx */
......@@ -640,7 +640,13 @@ static inline ssize_t do_tty_write(
size_t count)
{
ssize_t ret = 0, written = 0;
struct inode *inode = file->f_dentry->d_inode;
up(&inode->i_sem);
if (down_interruptible(&inode->i_atomic_write)) {
down(&inode->i_sem);
return -ERESTARTSYS;
}
for (;;) {
unsigned long size = PAGE_SIZE*2;
if (size > count)
......@@ -663,6 +669,8 @@ static inline ssize_t do_tty_write(
file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
ret = written;
}
up(&inode->i_atomic_write);
down(&inode->i_sem);
return ret;
}
......@@ -1604,8 +1612,8 @@ static int send_break(struct tty_struct *tty, int duration)
/*
* Split this up, as gcc can choke on it otherwise..
*/
static int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
struct tty_struct *tty, *real_tty;
int retval;
......@@ -2004,7 +2012,11 @@ long __init console_init(long kmem_start, long kmem_end)
kmem_start = con_init(kmem_start);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_8xx
kmem_start = console_8xx_init(kmem_start, kmem_end);
#else
kmem_start = serial_console_init(kmem_start, kmem_end);
#endif /* CONFIG_8xx */
#endif
return kmem_start;
}
......
......@@ -73,45 +73,6 @@ unsigned int video_scan_lines;
#define GPLAST 0x3df
#define GPNUM (GPLAST - GPFIRST + 1)
/*
* This function is called when the size of the physical screen has been
* changed. If either the row or col argument is nonzero, set the appropriate
* entry in each winsize structure for all the virtual consoles, then
* send SIGWINCH to all processes with a virtual console as controlling
* tty.
*/
static int
kd_size_changed(int row, int col)
{
struct task_struct *p;
int i;
if ( !row && !col ) return 0;
for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
{
if ( console_driver.table[i] )
{
if ( row ) console_driver.table[i]->winsize.ws_row = row;
if ( col ) console_driver.table[i]->winsize.ws_col = col;
}
}
read_lock(&tasklist_lock);
for_each_task(p)
{
if ( p->tty && MAJOR(p->tty->device) == TTY_MAJOR &&
MINOR(p->tty->device) <= MAX_NR_CONSOLES && MINOR(p->tty->device) )
{
send_sig(SIGWINCH, p, 1);
}
}
read_unlock(&tasklist_lock);
return 0;
}
/*
* Generates sound of some frequency for some number of clock ticks
*
......@@ -553,7 +514,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* explicitly blank/unblank the screen if switching modes
*/
if (arg == KD_TEXT)
do_unblank_screen();
unblank_screen();
else
do_blank_screen(1);
return 0;
......@@ -781,7 +742,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (arg == 0 || arg > MAX_NR_CONSOLES)
return -ENXIO;
arg--;
i = vc_allocate(arg, 0);
i = vc_allocate(arg);
if (i)
return i;
set_console(arg);
......@@ -833,7 +794,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
int newvt = vt_cons[console]->vt_newvt;
vt_cons[console]->vt_newvt = -1;
i = vc_allocate(newvt, 0);
i = vc_allocate(newvt);
if (i)
return i;
/*
......@@ -893,8 +854,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i;
__get_user(ll, &vtsizes->v_rows);
__get_user(cc, &vtsizes->v_cols);
i = vc_resize_all(ll, cc);
return i ? i : kd_size_changed(ll, cc);
return vc_resize_all(ll, cc);
}
case VT_RESIZEX:
......@@ -942,12 +902,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if ( clin )
video_font_height = clin;
i = vc_resize_all(ll, cc);
if (i)
return i;
kd_size_changed(ll, cc);
return 0;
return vc_resize_all(ll, cc);
}
case PIO_FONT: {
......@@ -1201,7 +1156,7 @@ void complete_change_console(unsigned int new_console)
* unblank the screen later.
*/
old_vc_mode = vt_cons[fg_console]->vc_mode;
update_screen(new_console);
switch_screen(new_console);
/*
* If this new console is under process control, send it a signal
......@@ -1239,15 +1194,11 @@ void complete_change_console(unsigned int new_console)
if (old_vc_mode != vt_cons[new_console]->vc_mode)
{
if (vt_cons[new_console]->vc_mode == KD_TEXT)
do_unblank_screen();
unblank_screen();
else
do_blank_screen(1);
}
/* Set the colour palette for this VT */
if (vt_cons[new_console]->vc_mode == KD_TEXT)
set_palette() ;
/*
* Wake anyone waiting for their VT to activate
*/
......
......@@ -64,8 +64,6 @@
*/
#undef TRIDENT_GLITCH
#undef VGA_CAN_DO_64KB
#define dac_reg 0x3c8
#define dac_val 0x3c9
#define attrib_port 0x3c0
......@@ -115,6 +113,7 @@ static int vga_palette_blanked;
static int vga_is_gfx;
static int vga_512_chars;
static int vga_video_font_height;
static unsigned int vga_rolled_over = 0;
void no_scroll(char *str, int *ints)
......@@ -190,7 +189,7 @@ __initfunc(static const char *vgacon_startup(void))
display_desc = "*MDA";
request_region(0x3b0,12,"mda");
request_region(0x3bf, 1,"mda");
vga_video_font_height = 16;
vga_video_font_height = 14;
}
}
else /* If not, it is color. */
......@@ -453,9 +452,8 @@ static int vgacon_switch(struct vc_data *c)
*/
vga_video_num_columns = c->vc_cols;
vga_video_num_lines = c->vc_rows;
if (vga_is_gfx)
return 1;
scr_memcpyw_to((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
if (!vga_is_gfx)
scr_memcpyw_to((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
return 0; /* Redrawing not needed */
}
......@@ -474,8 +472,7 @@ static void vga_set_palette(struct vc_data *c, unsigned char *table)
static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
{
#ifdef CAN_LOAD_PALETTE
if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked)
if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(c))
return -EINVAL;
vga_set_palette(c, table);
return 0;
......@@ -637,10 +634,11 @@ static int vgacon_blank(struct vc_data *c, int blank)
vga_palette_blanked = 1;
return 0;
}
scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
vgacon_set_origin(c);
scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
return 1;
case -1: /* Entering graphic mode */
scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
vga_is_gfx = 1;
return 1;
default: /* VESA blanking */
......@@ -899,14 +897,24 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
if (!lines) /* Turn scrollback off */
c->vc_visible_origin = c->vc_origin;
else {
int p = c->vc_visible_origin - vga_vram_base;
int margin = c->vc_rows/4 * c->vc_size_row;
p += lines * c->vc_size_row;
if (lines < 0 && p < margin)
int vram_size = vga_vram_end - vga_vram_base;
int margin = c->vc_size_row * 4;
int ul, we, p, st;
if (vga_rolled_over > (c->vc_scr_end - vga_vram_base) + margin) {
ul = c->vc_scr_end - vga_vram_base;
we = vga_rolled_over + c->vc_size_row;
} else {
ul = 0;
we = vram_size;
}
p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row;
st = (c->vc_origin - vga_vram_base - ul + we) % we;
if (p < margin)
p = 0;
c->vc_visible_origin = p + vga_vram_base;
if (lines > 0 && c->vc_visible_origin > c->vc_origin - margin)
c->vc_visible_origin = c->vc_origin;
if (p > st - margin)
p = st;
c->vc_visible_origin = vga_vram_base + (p + ul) % we;
}
vga_set_mem_top(c);
return 1;
......@@ -919,6 +927,7 @@ static int vgacon_set_origin(struct vc_data *c)
return 0;
c->vc_origin = c->vc_visible_origin = vga_vram_base;
vga_set_mem_top(c);
vga_rolled_over = 0;
return 1;
}
......@@ -935,9 +944,8 @@ static void vgacon_save_screen(struct vc_data *c)
c->vc_x = ORIG_X;
c->vc_y = ORIG_Y;
}
if (vga_is_gfx)
return;
scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
if (!vga_is_gfx)
scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
}
static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
......@@ -962,6 +970,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
(u16 *)(oldo + delta),
c->vc_screenbuf_size - delta);
c->vc_origin = vga_vram_base;
vga_rolled_over = oldo - vga_vram_base;
} else
c->vc_origin += delta;
scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);
......@@ -971,6 +980,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
(u16 *)oldo,
c->vc_screenbuf_size - delta);
c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
vga_rolled_over = 0;
} else
c->vc_origin -= delta;
c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
......
......@@ -20,7 +20,7 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
static int affs_readlink(struct dentry *, char *, int);
static struct dentry *affs_follow_link(struct dentry *dentry, struct dentry *base);
static struct dentry *affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int);
struct inode_operations affs_symlink_inode_operations = {
NULL, /* no file-operations */
......@@ -98,7 +98,7 @@ affs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static struct dentry *
affs_follow_link(struct dentry *dentry, struct dentry *base)
affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct buffer_head *bh;
......@@ -150,7 +150,7 @@ affs_follow_link(struct dentry *dentry, struct dentry *base)
}
buffer[i] = '\0';
affs_brelse(bh);
base = lookup_dentry(buffer,base,1);
base = lookup_dentry(buffer,base,follow);
kfree(buffer);
return base;
}
......
......@@ -27,12 +27,13 @@ static int autofs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static struct dentry * autofs_follow_link(struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct autofs_symlink *sl;
sl = (struct autofs_symlink *)dentry->d_inode->u.generic_ip;
return lookup_dentry(sl->data, base, 1);
return lookup_dentry(sl->data, base, follow);
}
struct inode_operations autofs_symlink_inode_operations = {
......
......@@ -26,7 +26,7 @@
#include <linux/coda_proc.h>
static int coda_readlink(struct dentry *de, char *buffer, int length);
static struct dentry *coda_follow_link(struct dentry *, struct dentry *);
static struct dentry *coda_follow_link(struct dentry *, struct dentry *, unsigned int);
struct inode_operations coda_symlink_inode_operations = {
NULL, /* no file-operations */
......@@ -86,7 +86,8 @@ static int coda_readlink(struct dentry *de, char *buffer, int length)
}
static struct dentry *coda_follow_link(struct dentry *de,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = de->d_inode;
int error;
......@@ -116,7 +117,7 @@ static struct dentry *coda_follow_link(struct dentry *de,
memcpy(path, mem, len);
path[len] = 0;
base = lookup_dentry(path, base, 1);
base = lookup_dentry(path, base, follow);
kfree(path);
return base;
}
......@@ -25,7 +25,7 @@
#include <linux/stat.h>
static int ext2_readlink (struct dentry *, char *, int);
static struct dentry *ext2_follow_link(struct dentry *, struct dentry *);
static struct dentry *ext2_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
......@@ -52,7 +52,8 @@ struct inode_operations ext2_symlink_inode_operations = {
};
static struct dentry * ext2_follow_link(struct dentry * dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct buffer_head * bh = NULL;
......@@ -68,7 +69,7 @@ static struct dentry * ext2_follow_link(struct dentry * dentry,
link = bh->b_data;
}
UPDATE_ATIME(inode);
base = lookup_dentry(link, base, 1);
base = lookup_dentry(link, base, follow);
if (bh)
brelse(bh);
return base;
......
......@@ -131,6 +131,7 @@ static inline void init_once(struct inode * inode)
INIT_LIST_HEAD(&inode->i_hash);
INIT_LIST_HEAD(&inode->i_dentry);
sema_init(&inode->i_sem, 1);
sema_init(&inode->i_atomic_write, 1);
}
static inline void write_inode(struct inode *inode)
......@@ -714,8 +715,11 @@ if (inode->i_count)
printk(KERN_ERR "iput: device %s inode %ld count changed, count=%d\n",
kdevname(inode->i_dev), inode->i_ino, inode->i_count);
if (atomic_read(&inode->i_sem.count) != 1)
printk(KERN_ERR "iput: Aieee, semaphore in use device %s, count=%d\n",
kdevname(inode->i_dev), atomic_read(&inode->i_sem.count));
printk(KERN_ERR "iput: Aieee, semaphore in use inode %s/%ld, count=%d\n",
kdevname(inode->i_dev), inode->i_ino, atomic_read(&inode->i_sem.count));
if (atomic_read(&inode->i_atomic_write.count) != 1)
printk(KERN_ERR "iput: Aieee, atomic write semaphore in use inode %s/%ld, count=%d\n",
kdevname(inode->i_dev), inode->i_ino, atomic_read(&inode->i_sem.count));
#endif
}
if (inode->i_count > (1<<31)) {
......
......@@ -19,7 +19,7 @@
#include <asm/uaccess.h>
static int isofs_readlink(struct dentry *, char *, int);
static struct dentry * isofs_follow_link(struct dentry *, struct dentry *);
static struct dentry * isofs_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
......@@ -66,7 +66,8 @@ static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen)
}
static struct dentry * isofs_follow_link(struct dentry * dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
char * pnt;
......@@ -76,7 +77,7 @@ static struct dentry * isofs_follow_link(struct dentry * dentry,
return ERR_PTR(-ELOOP);
}
base = lookup_dentry(pnt, base, 1);
base = lookup_dentry(pnt, base, follow);
kfree(pnt);
return base;
......
......@@ -15,7 +15,7 @@
#include <asm/uaccess.h>
static int minix_readlink(struct dentry *, char *, int);
static struct dentry *minix_follow_link(struct dentry *, struct dentry *);
static struct dentry *minix_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
......@@ -41,7 +41,8 @@ struct inode_operations minix_symlink_inode_operations = {
};
static struct dentry * minix_follow_link(struct dentry * dentry,
struct dentry * base)
struct dentry * base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct buffer_head * bh;
......@@ -52,7 +53,7 @@ static struct dentry * minix_follow_link(struct dentry * dentry,
return ERR_PTR(-EIO);
}
UPDATE_ATIME(inode);
base = lookup_dentry(bh->b_data, base, 1);
base = lookup_dentry(bh->b_data, base, follow);
brelse(bh);
return base;
}
......
......@@ -266,6 +266,7 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
&de, &ino);
if (res == -ENOENT)
goto add;
if (res < 0)
......@@ -275,7 +276,7 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
/* try to get the inode */
res = -EACCES;
inode = iget(dir->i_sb, ino);
inode = iget(sb, ino);
if (!inode)
goto out;
if (!inode->i_sb ||
......@@ -289,9 +290,9 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
iput(inode);
goto out;
}
res = 0;
add:
d_add(dentry, inode);
res = 0;
out:
return res;
}
......@@ -446,14 +447,14 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry)
if (dir->i_dev != inode->i_dev || dir == inode)
printk("msdos_rmdir: impossible condition\n");
/*
* Prune any child dentries, then verify that
* the directory is empty and not in use.
* Check whether the directory is empty, then prune
* any child dentries and make sure it's not in use.
*/
shrink_dcache_parent(dentry);
res = msdos_empty(inode);
if (res)
goto rmdir_done;
res = -EBUSY;
shrink_dcache_parent(dentry);
if (dentry->d_count > 1) {
#ifdef MSDOS_DEBUG
printk("msdos_rmdir: %s/%s busy, d_count=%d\n",
......@@ -476,6 +477,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh, 1);
res = 0;
rmdir_done:
fat_brelse(sb, bh);
return res;
......@@ -499,18 +501,21 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
return res;
is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
fat_lock_creation();
if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) {
fat_unlock_creation();
/* N.B. does this need to be released on the other path? */
fat_brelse(sb, bh);
return -EEXIST;
}
if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0)
goto out_exist;
res = msdos_create_entry(dir,msdos_name,1,is_hid, &inode);
if (res < 0)
goto out_unlock;
dir->i_nlink++;
inode->i_nlink = 2; /* no need to mark them dirty */
MSDOS_I(inode)->i_busy = 1; /* prevent lookups */
/*
* Instantiate the dentry now, in case we need to cleanup.
*/
d_instantiate(dentry, inode);
if ((res = fat_add_cluster(inode)) < 0)
goto mkdir_error;
if ((res = msdos_create_entry(inode,MSDOS_DOT,1,0,&dot)) < 0)
......@@ -521,9 +526,9 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
dot->i_nlink = inode->i_nlink;
mark_inode_dirty(dot);
iput(dot);
if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,1,0,&dot)) < 0)
goto mkdir_error;
fat_unlock_creation();
dot->i_size = dir->i_size;
MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;
MSDOS_I(dot)->i_logstart = MSDOS_I(dir)->i_logstart;
......@@ -531,15 +536,22 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
mark_inode_dirty(dot);
MSDOS_I(inode)->i_busy = 0;
iput(dot);
d_instantiate(dentry, inode);
return 0;
res = 0;
mkdir_error:
if (msdos_rmdir(dir,dentry) < 0)
fat_fs_panic(dir->i_sb,"rmdir in mkdir failed");
out_unlock:
fat_unlock_creation();
return res;
mkdir_error:
printk("msdos_mkdir: error=%d, attempting cleanup\n", res);
if (msdos_rmdir(dir,dentry) < 0)
fat_fs_panic(dir->i_sb,"rmdir in mkdir failed");
goto out_unlock;
out_exist:
fat_brelse(sb, bh);
res = -EEXIST;
goto out_unlock;
}
/***** Unlink a file */
......@@ -636,10 +648,14 @@ static int msdos_rename_same(struct inode *old_dir,char *old_name,
if ((old_de->attr & ATTR_SYS))
goto out_error;
if (S_ISDIR(new_inode->i_mode)) {
/* make sure it's empty */
error = msdos_empty(new_inode);
if (error)
goto out_error;
#ifdef MSDOS_CHECK_BUSY
/* check for a busy dentry */
error = -EBUSY;
if (new_dentry->d_count > 1) {
/* check for a busy dentry */
error = -EBUSY;
shrink_dcache_parent(new_dentry);
if (new_dentry->d_count > 1) {
printk("msdos_rename_same: %s/%s busy, count=%d\n",
......@@ -647,20 +663,19 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
new_dentry->d_count);
goto out_error;
}
}
#endif
if (S_ISDIR(new_inode->i_mode)) {
new_dir->i_nlink--;
mark_inode_dirty(new_dir);
}
new_inode->i_nlink = 0;
MSDOS_I(new_inode)->i_busy = 1;
mark_inode_dirty(new_inode);
#ifdef MSDOS_CHECK_BUSY
/* d_delete the dentry, as we killed its inode */
d_delete(new_dentry);
#endif
/*
* Make it negative if it's not busy;
* otherwise let d_move() drop it.
*/
if (new_dentry->d_count == 1)
d_delete(new_dentry);
new_de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, new_bh, 1);
......@@ -763,16 +778,22 @@ new_dentry->d_count);
}
#endif
if (S_ISDIR(new_inode->i_mode)) {
/* make sure it's empty */
error = msdos_empty(new_inode);
if (error)
goto out_new;
new_dir->i_nlink--;
mark_inode_dirty(new_dir);
}
new_inode->i_nlink = 0;
MSDOS_I(new_inode)->i_busy = 1;
mark_inode_dirty(new_inode);
#ifdef MSDOS_CHECK_BUSY
/* d_delete the dentry, as we killed its inode */
d_delete(new_dentry);
#endif
/*
* Make it negative if it's not busy;
* otherwise let d_move() drop it.
*/
if (new_dentry->d_count == 1)
d_delete(new_dentry);
new_de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, new_bh, 1);
fat_brelse(sb, new_bh);
......@@ -804,12 +825,20 @@ new_dentry->d_count);
free_inode = iget(sb, free_ino);
if (!free_inode)
goto out_iput;
/* make sure it's not busy! */
if (MSDOS_I(free_inode)->i_busy)
printk(KERN_ERR "msdos_rename_diff: new inode %ld busy!\n",
(ino_t) free_ino);
if (!list_empty(&free_inode->i_dentry))
printk("msdos_rename_diff: free inode has aliases??\n");
msdos_read_inode(free_inode);
fat_mark_buffer_dirty(sb, free_bh, 1);
/*
* Make sure the old dentry isn't busy,
* as we need to change inodes ...
*/
error = -EBUSY;
if (old_dentry->d_count > 1) {
shrink_dcache_parent(old_dentry);
if (old_dentry->d_count > 1) {
......@@ -836,6 +865,11 @@ old_dentry->d_count);
MSDOS_I(free_inode)->i_logstart = MSDOS_I(old_inode)->i_logstart;
MSDOS_I(free_inode)->i_attrs = MSDOS_I(old_inode)->i_attrs;
/* release the old inode's resources */
MSDOS_I(old_inode)->i_start = 0;
MSDOS_I(old_inode)->i_logstart = 0;
old_inode->i_nlink = 0;
/*
* Install the new inode ...
*/
......@@ -845,7 +879,6 @@ old_dentry->d_count);
mark_inode_dirty(old_inode);
old_de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, old_bh, 1);
fat_mark_buffer_dirty(sb, free_bh, 1);
iput(old_inode);
/* a directory? */
......@@ -854,13 +887,13 @@ old_dentry->d_count);
MSDOS_I(dotdot_inode)->i_logstart = MSDOS_I(new_dir)->i_logstart;
dotdot_de->start = CT_LE_W(MSDOS_I(new_dir)->i_logstart);
dotdot_de->starthi = CT_LE_W((MSDOS_I(new_dir)->i_logstart) >> 16);
mark_inode_dirty(dotdot_inode);
fat_mark_buffer_dirty(sb, dotdot_bh, 1);
old_dir->i_nlink--;
new_dir->i_nlink++;
/* no need to mark them dirty */
dotdot_inode->i_nlink = new_dir->i_nlink;
mark_inode_dirty(dotdot_inode);
iput(dotdot_inode);
fat_mark_buffer_dirty(sb, dotdot_bh, 1);
fat_brelse(sb, dotdot_bh);
}
......
......@@ -280,7 +280,18 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
return result;
}
static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry)
/*
* The bitmask for a follow event: normal
* follow, and follow requires a directory
* entry due to a slash ('/') after the
* name, and whether to continue to parse
* the name..
*/
#define FOLLOW_LINK (1)
#define FOLLOW_DIRECTORY (2)
#define FOLLOW_CONTINUE (4)
static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry, unsigned int follow)
{
struct inode * inode = dentry->d_inode;
......@@ -290,7 +301,7 @@ static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry
current->link_count++;
/* This eats the base */
result = inode->i_op->follow_link(dentry, base);
result = inode->i_op->follow_link(dentry, base, follow);
current->link_count--;
dput(dentry);
return result;
......@@ -320,9 +331,10 @@ static inline struct dentry * follow_mount(struct dentry * dentry)
* This is the basic name resolution function, turning a pathname
* into the final dentry.
*/
struct dentry * lookup_dentry(const char * name, struct dentry * base, int follow_link)
struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned int follow_link)
{
struct dentry * dentry;
struct inode *inode;
if (*name == '/') {
if (base)
......@@ -338,35 +350,34 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
if (!*name)
goto return_base;
inode = base->d_inode;
follow_link &= FOLLOW_LINK | FOLLOW_DIRECTORY;
/* At this point we know we have a real path component. */
for(;;) {
int err;
unsigned long hash;
struct qstr this;
struct inode *inode;
char c, follow;
unsigned int follow;
unsigned int c;
dentry = ERR_PTR(-ENOENT);
inode = base->d_inode;
if (!inode)
break;
dentry = ERR_PTR(-ENOTDIR);
if (!inode->i_op || !inode->i_op->lookup)
break;
err = permission(inode, MAY_EXEC);
dentry = ERR_PTR(err);
if (err)
break;
this.name = name;
c = *name;
c = *(const unsigned char *)name;
hash = init_name_hash();
do {
name++;
hash = partial_name_hash(c, hash);
c = *++name;
c = *(const unsigned char *)name;
} while (c && (c != '/'));
this.len = name - (const char *) this.name;
this.hash = end_name_hash(hash);
......@@ -374,10 +385,14 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
/* remove trailing slashes? */
follow = follow_link;
if (c) {
follow |= c;
char tmp;
follow |= FOLLOW_DIRECTORY;
do {
c = *++name;
} while (c == '/');
tmp = *++name;
} while (tmp == '/');
if (tmp)
follow |= FOLLOW_CONTINUE;
}
/*
......@@ -410,8 +425,18 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
if (!follow)
break;
base = do_follow_link(base, dentry);
if (c && !IS_ERR(base))
base = do_follow_link(base, dentry, follow);
if (IS_ERR(base))
goto return_base;
dentry = ERR_PTR(-ENOTDIR);
inode = base->d_inode;
if (follow & FOLLOW_DIRECTORY) {
if (!inode || !inode->i_op || !inode->i_op->lookup)
break;
}
if (follow & FOLLOW_CONTINUE)
continue;
return_base:
......@@ -431,7 +456,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
* namei exists in two versions: namei/lnamei. The only difference is
* that namei follows links, while lnamei does not.
*/
struct dentry * __namei(const char *pathname, int follow_link)
struct dentry * __namei(const char *pathname, unsigned int follow_link)
{
char *name;
struct dentry *dentry;
......
......@@ -19,7 +19,7 @@
#include <asm/uaccess.h>
static int nfs_readlink(struct dentry *, char *, int);
static struct dentry *nfs_follow_link(struct dentry *, struct dentry *);
static struct dentry *nfs_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
......@@ -68,7 +68,7 @@ static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static struct dentry *
nfs_follow_link(struct dentry * dentry, struct dentry *base)
nfs_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
{
int error;
unsigned int len;
......@@ -94,7 +94,7 @@ nfs_follow_link(struct dentry * dentry, struct dentry *base)
path[len] = 0;
kfree(mem);
result = lookup_dentry(path, base, 1);
result = lookup_dentry(path, base, follow);
kfree(path);
out:
return result;
......
......@@ -92,7 +92,7 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
size_t count, loff_t *ppos)
{
struct inode * inode = filp->f_dentry->d_inode;
ssize_t chars = 0, free = 0, written = 0;
ssize_t chars = 0, free = 0, written = 0, err=0;
char *pipebuf;
if (ppos != &filp->f_pos)
......@@ -107,16 +107,26 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
free = count;
else
free = 1; /* can't do it atomically, wait for any free space */
up(&inode->i_sem);
if (down_interruptible(&inode->i_atomic_write)) {
down(&inode->i_sem);
return -ERESTARTSYS;
}
while (count>0) {
while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
if (!PIPE_READERS(*inode)) { /* no readers */
send_sig(SIGPIPE,current,0);
return written? :-EPIPE;
err = -EPIPE;
goto errout;
}
if (signal_pending(current)) {
err = -ERESTARTSYS;
goto errout;
}
if (filp->f_flags & O_NONBLOCK) {
err = -EAGAIN;
goto errout;
}
if (signal_pending(current))
return written? :-ERESTARTSYS;
if (filp->f_flags & O_NONBLOCK)
return written? :-EAGAIN;
interruptible_sleep_on(&PIPE_WAIT(*inode));
}
PIPE_LOCK(*inode)++;
......@@ -139,7 +149,10 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
}
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
mark_inode_dirty(inode);
return written;
errout:
up(&inode->i_atomic_write);
down(&inode->i_sem);
return written ? written : err;
}
static long long pipe_lseek(struct file * file, long long offset, int orig)
......
......@@ -17,7 +17,7 @@
#include <linux/stat.h>
static int proc_readlink(struct dentry *, char *, int);
static struct dentry * proc_follow_link(struct dentry *, struct dentry *);
static struct dentry * proc_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* links can't do much...
......@@ -57,7 +57,8 @@ struct inode_operations proc_link_inode_operations = {
};
static struct dentry * proc_follow_link(struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct task_struct *p;
......@@ -172,7 +173,7 @@ static int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
{
int error;
dentry = proc_follow_link(dentry, NULL);
dentry = proc_follow_link(dentry, NULL, 1);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = -ENOENT;
......
......@@ -42,7 +42,7 @@ static int property_read_proc(char *page, char **start, off_t off,
*/
static int devtree_readlink(struct dentry *, char *, int);
static struct dentry *devtree_follow_link(struct dentry *, struct dentry *);
static struct dentry *devtree_follow_link(struct dentry *, struct dentry *, unsigned int);
struct inode_operations devtree_symlink_inode_operations = {
NULL, /* no file-operations */
......@@ -66,7 +66,8 @@ struct inode_operations devtree_symlink_inode_operations = {
};
static struct dentry *devtree_follow_link(struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
......@@ -74,7 +75,7 @@ static struct dentry *devtree_follow_link(struct dentry *dentry,
de = (struct proc_dir_entry *) inode->u.generic_ip;
link = (char *) de->data;
return lookup_dentry(link, base, 1);
return lookup_dentry(link, base, follow);
}
static int devtree_readlink(struct dentry *dentry, char *buffer, int buflen)
......
......@@ -55,9 +55,6 @@ static struct file_operations proc_dir_operations = {
NULL /* can't fsync */
};
int proc_readlink(struct dentry * dentry, char * buffer, int buflen);
struct dentry * proc_follow_link(struct dentry *dentry, struct dentry *base);
/*
* proc directories can do almost nothing..
*/
......@@ -388,12 +385,13 @@ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static struct dentry * proc_self_follow_link(struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
char tmp[30];
sprintf(tmp, "%d", current->pid);
return lookup_dentry(tmp, base, 1);
return lookup_dentry(tmp, base, follow);
}
int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
......@@ -420,7 +418,7 @@ int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
return len;
}
struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base)
struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct proc_dir_entry * de;
......@@ -435,7 +433,7 @@ struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base)
if (de->readlink_proc)
len = de->readlink_proc(de, page);
d = lookup_dentry(page, base, 1);
d = lookup_dentry(page, base, follow);
free_page((unsigned long) page);
return d;
}
......
......@@ -451,7 +451,8 @@ romfs_readlink(struct dentry *dentry, char *buffer, int len)
}
static struct dentry *romfs_follow_link(struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
char *link;
......@@ -470,7 +471,7 @@ static struct dentry *romfs_follow_link(struct dentry *dentry,
} else
link[len] = 0;
dentry = lookup_dentry(link, base, 1);
dentry = lookup_dentry(link, base, follow);
kfree(link);
if (0) {
......
......@@ -21,7 +21,7 @@
#include <asm/uaccess.h>
static int sysv_readlink(struct dentry *, char *, int);
static struct dentry *sysv_follow_link(struct dentry *, struct dentry *);
static struct dentry *sysv_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
......@@ -47,7 +47,8 @@ struct inode_operations sysv_symlink_inode_operations = {
};
static struct dentry *sysv_follow_link(struct dentry * dentry,
struct dentry * base)
struct dentry * base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct buffer_head * bh;
......@@ -58,7 +59,7 @@ static struct dentry *sysv_follow_link(struct dentry * dentry,
return ERR_PTR(-EIO);
}
UPDATE_ATIME(inode);
base = lookup_dentry(bh->b_data, base, 1);
base = lookup_dentry(bh->b_data, base, follow);
brelse(bh);
return base;
}
......
......@@ -43,7 +43,7 @@
static struct dentry * ufs_follow_link(struct dentry * dentry,
struct dentry * base)
struct dentry * base, unsigned int follow)
{
struct inode * inode;
struct buffer_head * bh;
......@@ -67,7 +67,7 @@ static struct dentry * ufs_follow_link(struct dentry * dentry,
link = (char *) inode->u.ufs_i.i_u1.i_symlink;
}
UPDATE_ATIME(inode);
base = lookup_dentry(link, base, 1);
base = lookup_dentry(link, base, follow);
if (bh)
brelse(bh);
UFSD(("EXIT\n"))
......
......@@ -64,7 +64,8 @@ static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen)
/* this one mostly stolen from romfs :) */
static struct dentry *UMSDOS_followlink (struct dentry *dentry,
struct dentry *base)
struct dentry *base,
unsigned int follow)
{
struct inode *inode = dentry->d_inode;
char *symname;
......@@ -91,7 +92,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name));
}
symname[len] = 0;
dentry = lookup_dentry (symname, base, 1);
dentry = lookup_dentry (symname, base, follow);
kfree (symname);
if (0) {
......
......@@ -53,15 +53,11 @@ extern struct consw compat_con; /* console wrapper */
extern struct consw prom_con; /* SPARC PROM console */
void take_over_console(struct consw *sw, int first, int last, int deflt);
/* flag bits */
#define CON_INITED (1)
void give_up_console(struct consw *sw);
/* scroll */
#define SM_UP (1)
#define SM_DOWN (2)
#define SM_LEFT (3)
#define SM_RIGHT (4)
/* cursor */
#define CM_DRAW (1)
......
......@@ -19,7 +19,6 @@ struct vc_data {
struct consw *vc_sw;
unsigned short *vc_screenbuf; /* In-memory character/attribute buffer */
unsigned int vc_screenbuf_size;
unsigned short vc_video_erase_char; /* Background erase character */
unsigned char vc_attr; /* Current attributes */
unsigned char vc_def_color; /* Default colors */
unsigned char vc_color; /* Foreground & background */
......@@ -28,6 +27,8 @@ struct vc_data {
unsigned char vc_halfcolor; /* Color for half intensity mode */
unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
unsigned short vc_video_erase_char; /* Background erase character */
unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
unsigned int vc_x, vc_y; /* Cursor position */
unsigned int vc_top, vc_bottom; /* Scrolling region */
unsigned int vc_state; /* Escape sequence parser state */
......@@ -104,3 +105,5 @@ extern struct vc vc_cons [MAX_NR_CONSOLES];
#define CUR_SWMASK 0xfff0
#define CUR_DEFAULT CUR_UNDERLINE
#define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
......@@ -27,7 +27,7 @@ struct qstr {
#define init_name_hash() 0
/* partial hash update function. Assume roughly 4 bits per character */
static __inline__ unsigned long partial_name_hash(unsigned char c, unsigned long prevhash)
static __inline__ unsigned long partial_name_hash(unsigned long c, unsigned long prevhash)
{
prevhash = (prevhash << 4) | (prevhash >> (8*sizeof(unsigned long)-4));
return prevhash ^ c;
......
......@@ -348,6 +348,7 @@ struct inode {
unsigned long i_version;
unsigned long i_nrpages;
struct semaphore i_sem;
struct semaphore i_atomic_write;
struct inode_operations *i_op;
struct super_block *i_sb;
struct wait_queue *i_wait;
......@@ -622,7 +623,7 @@ struct inode_operations {
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char *,int);
struct dentry * (*follow_link) (struct dentry *, struct dentry *);
struct dentry * (*follow_link) (struct dentry *, struct dentry *, unsigned int);
int (*readpage) (struct file *, struct page *);
int (*writepage) (struct file *, struct page *);
int (*bmap) (struct inode *,int);
......@@ -783,8 +784,8 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *);
#define PTR_ERR(ptr) ((long)(ptr))
#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
extern struct dentry * lookup_dentry(const char *, struct dentry *, int);
extern struct dentry * __namei(const char *, int);
extern struct dentry * lookup_dentry(const char *, struct dentry *, unsigned int);
extern struct dentry * __namei(const char *, unsigned int);
#define namei(pathname) __namei(pathname, 1)
#define lnamei(pathname) __namei(pathname, 0)
......
......@@ -35,7 +35,6 @@ nbd_end_request(struct request *req)
}
#define MAX_NBD 128
#endif
struct nbd_device {
int refcnt;
......@@ -51,6 +50,7 @@ struct nbd_device {
struct request *tail;
struct semaphore queue_lock;
};
#endif
/* This now IS in some kind of include file... */
......
......@@ -21,7 +21,6 @@ extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
#define video_num_columns (vc_cons[currcons].d->vc_cols)
#define video_num_lines (vc_cons[currcons].d->vc_rows)
#define video_size_row (vc_cons[currcons].d->vc_size_row)
#define video_screen_size (vc_cons[currcons].d->vc_screenbuf_size)
#define can_do_color (vc_cons[currcons].d->vc_can_do_color)
extern int console_blanked;
......@@ -31,7 +30,6 @@ extern int default_red[];
extern int default_grn[];
extern int default_blu[];
extern void do_unblank_screen(void);
extern unsigned short *screen_pos(int currcons, int w_offset, int viewed);
extern u16 screen_glyph(int currcons, int offset);
extern void complement_pos(int currcons, int offset);
......
......@@ -9,7 +9,7 @@
* These constants are also useful for user-level apps (e.g., VC
* resizing).
*/
#define MIN_NR_CONSOLES 1 /* must be at least 1 */
#define MIN_NR_CONSOLES 1 /* must be at least 1 */
#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
/* Note: the ioctl VT_GETSTATE does not work for
......@@ -87,7 +87,10 @@ struct screen_info {
unsigned char blue_pos; /* 0x2b */
unsigned char rsvd_size; /* 0x2c */
unsigned char rsvd_pos; /* 0x2d */
/* 0x2e -- 0x3f reserved for future expansion */
unsigned short vesapm_seg; /* 0x2e */
unsigned short vesapm_off; /* 0x30 */
unsigned short pages; /* 0x32 */
/* 0x34 -- 0x3f reserved for future expansion */
};
extern struct screen_info screen_info;
......@@ -390,10 +393,6 @@ extern long serial_console_init(long kmem_start, long kmem_end);
extern int pcxe_open(struct tty_struct *tty, struct file *filp);
/* console.c */
extern void update_screen(int new_console);
/* printk.c */
extern void console_print(const char *);
......
......@@ -16,9 +16,6 @@
#include <linux/config.h>
#ifdef CONFIG_VGA_CONSOLE
#if !defined(CONFIG_FB) && !defined(CONFIG_FB_MODULE)
#define VT_BUF_VRAM_ONLY
#endif
#include <asm/vga.h>
#endif
......
......@@ -35,27 +35,29 @@ void (*kd_mksound)(unsigned int hz, unsigned int ticks);
/* console.c */
struct console_font_op;
struct consw;
int vc_allocate(unsigned int console, int init);
int vc_allocate(unsigned int console);
int vc_cons_allocated(unsigned int console);
int vc_resize(unsigned int lines, unsigned int cols,
unsigned int first, unsigned int last);
#define vc_resize_all(l, c) vc_resize(l, c, 0, MAX_NR_CONSOLES-1)
#define vc_resize_con(l, c, x) vc_resize(l, c, x, x)
void vc_disallocate(unsigned int console);
void poke_blanked_console(void);
void set_vesa_blanking(unsigned long arg);
void vesa_blank(void);
void vesa_powerdown(void);
void reset_palette(int currcons);
void set_palette(void);
void do_blank_screen(int nopowersave);
void set_palette(int currcons);
void do_blank_screen(int gfx_mode);
void unblank_screen(void);
void poke_blanked_console(void);
int con_font_op(int currcons, struct console_font_op *op);
int con_set_cmap(unsigned char *cmap);
int con_get_cmap(unsigned char *cmap);
void scrollback(int);
void scrollfront(int);
void update_region(int currcons, unsigned long start, int count);
void redraw_screen(int new_console, int is_switch);
#define update_screen(x) redraw_screen(x, 0)
#define switch_screen(x) redraw_screen(x, 1)
struct tty_struct;
int tioclinux(struct tty_struct *tty, unsigned long arg);
......@@ -75,6 +77,7 @@ int con_get_unimap(int currcons, ushort ct, ushort *uct, struct unipair *list);
int con_set_default_unimap(int currcons);
void con_free_unimap(int currcons);
void con_protect_unimap(int currcons, int rdonly);
int con_copy_unimap(int dstcons, int srccons);
/* vt.c */
......
......@@ -77,7 +77,7 @@ extern long console_init(long, long);
extern void sock_init(void);
extern void uidcache_init(void);
extern void mca_init(void);
extern long sbus_init(long, long);
extern long sbus_init(void);
extern long powermac_init(unsigned long, unsigned long);
extern void sysctl_init(void);
extern void filescache_init(void);
......
......@@ -415,15 +415,6 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
struct wait_queue wait = { current, NULL };
struct task_struct *p;
if (stat_addr) {
if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)))
return -EFAULT;
}
if (ru) {
if(verify_area(VERIFY_WRITE, ru, sizeof(*ru)))
return -EFAULT;
}
if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
return -EINVAL;
......@@ -453,21 +444,23 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED))
continue;
read_unlock(&tasklist_lock);
if (ru != NULL)
getrusage(p, RUSAGE_BOTH, ru);
if (stat_addr)
__put_user((p->exit_code << 8) | 0x7f, stat_addr);
p->exit_code = 0;
retval = p->pid;
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (!retval && stat_addr)
retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
if (!retval) {
p->exit_code = 0;
retval = p->pid;
}
goto end_wait4;
case TASK_ZOMBIE:
current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
read_unlock(&tasklist_lock);
if (ru != NULL)
getrusage(p, RUSAGE_BOTH, ru);
if (stat_addr)
__put_user(p->exit_code, stat_addr);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (!retval && stat_addr)
retval = put_user(p->exit_code, stat_addr);
if (retval)
goto end_wait4;
retval = p->pid;
if (p->p_opptr != p->p_pptr) {
write_lock_irq(&tasklist_lock);
......
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