Commit 95c2f4d9 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 667b591e 669e7461
......@@ -1753,6 +1753,12 @@ L: selinux@tycho.nsa.gov (general discussion)
W: http://www.nsa.gov/selinux
S: Supported
SGI SN-IA64 (Altix) SERIAL CONSOLE DRIVER
P: Pat Gefre
M: pfg@sgi.com
L: linux-ia64@vger.kernel.org
S: Supported
SGI VISUAL WORKSTATION 320 AND 540
P: Andrey Panin
M: pazke@donpac.ru
......
......@@ -324,8 +324,8 @@ static int find_matching_ucodes (void)
/* check extended table checksum */
if (ext_table_size) {
int ext_table_sum = 0;
i = ext_table_size / DWSIZE;
int * ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size);
i = ext_table_size / DWSIZE;
while (i--) ext_table_sum += ext_tablep[i];
if (ext_table_sum) {
printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n");
......
......@@ -139,22 +139,23 @@ static void __init probe_roms(void)
probe_extension_roms(roms);
}
static void __init limit_regions (unsigned long long size)
static void __init limit_regions(unsigned long long size)
{
unsigned long long current_addr = 0;
int i;
unsigned long long current_size = 0;
for (i = 0; i < e820.nr_map; i++) {
if (e820.map[i].type == E820_RAM) {
current_size += e820.map[i].size;
if (current_size >= size) {
e820.map[i].size -= current_size-size;
current_addr = e820.map[i].addr + e820.map[i].size;
if (current_addr >= size) {
e820.map[i].size -= current_addr-size;
e820.nr_map = i + 1;
return;
}
}
}
}
static void __init add_memory_region(unsigned long long start,
unsigned long long size, int type)
{
......@@ -964,7 +965,6 @@ void __init setup_arch(char **cmdline_p)
apm_info.bios = APM_BIOS_INFO;
ist_info = IST_INFO;
saved_videomode = VIDEO_MODE;
printk("Video mode to be used for restore is %lx\n", saved_videomode);
if( SYS_DESC_TABLE.length != 0 ) {
MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
machine_id = SYS_DESC_TABLE.table[0];
......
......@@ -104,6 +104,15 @@ void do_gettimeofday(struct timeval *tv)
lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
if (unlikely(time_adjust < 0) && usec > tickadj)
usec = tickadj;
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry(&xtime_lock, seq));
......
......@@ -114,22 +114,10 @@ void __init mach_get_physical_ram (unsigned long *ram_start,
void __init mach_reserve_bootmem ()
{
extern char _root_fs_image_start, _root_fs_image_end;
u32 root_fs_image_start = (u32)&_root_fs_image_start;
u32 root_fs_image_end = (u32)&_root_fs_image_end;
if (SDRAM_ADDR < RAM_END && SDRAM_ADDR > RAM_START)
/* We can't use the space between SRAM and SDRAM, so
prevent the kernel from trying. */
reserve_bootmem (SRAM_END, SDRAM_ADDR - SRAM_END);
/* Reserve the memory used by the root filesystem image if it's
in RAM. */
if (root_fs_image_end > root_fs_image_start
&& root_fs_image_start >= RAM_START
&& root_fs_image_start < RAM_END)
reserve_bootmem (root_fs_image_start,
root_fs_image_end - root_fs_image_start);
}
void mach_gettimeofday (struct timespec *tv)
......
......@@ -53,19 +53,6 @@ void __init mach_get_physical_ram (unsigned long *ram_start,
*ram_len = RAM_END - RAM_START;
}
void __init mach_reserve_bootmem ()
{
extern char _root_fs_image_start, _root_fs_image_end;
u32 root_fs_image_start = (u32)&_root_fs_image_start;
u32 root_fs_image_end = (u32)&_root_fs_image_end;
/* Reserve the memory used by the root filesystem image if it's
in RAM. */
if (root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
reserve_bootmem (root_fs_image_start,
root_fs_image_end - root_fs_image_start);
}
void mach_gettimeofday (struct timespec *tv)
{
tv->tv_sec = 0;
......@@ -230,8 +217,10 @@ void cb_pic_shutdown_irq (unsigned irq)
CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
}
static void cb_pic_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t cb_pic_handle_irq (int irq, void *dev_id,
struct pt_regs *regs)
{
irqreturn_t rval = IRQ_NONE;
unsigned status = CB_PIC_INTR;
unsigned enable = CB_PIC_INT1M;
......@@ -257,13 +246,16 @@ static void cb_pic_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
/* Recursively call handle_irq to handle it. */
handle_irq (irq, regs);
rval = IRQ_HANDLED;
} while (status);
}
CB_PIC_INTEN |= CB_PIC_INT1EN;
}
return rval;
}
static void irq_nop (unsigned irq) { }
static unsigned cb_pic_startup_irq (unsigned irq)
......
......@@ -54,21 +54,6 @@ void __init mach_get_physical_ram (unsigned long *ram_start,
*ram_len = SDRAM_SIZE;
}
void __init mach_reserve_bootmem ()
{
extern char _root_fs_image_start, _root_fs_image_end;
u32 root_fs_image_start = (u32)&_root_fs_image_start;
u32 root_fs_image_end = (u32)&_root_fs_image_end;
/* Reserve the memory used by the root filesystem image if it's
in SDRAM. */
if (root_fs_image_end > root_fs_image_start
&& root_fs_image_start >= SDRAM_ADDR
&& root_fs_image_start < (SDRAM_ADDR + SDRAM_SIZE))
reserve_bootmem (root_fs_image_start,
root_fs_image_end - root_fs_image_start);
}
void mach_gettimeofday (struct timespec *tv)
{
tv->tv_sec = 0;
......
......@@ -150,21 +150,6 @@ void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
*ram_len = RAM_END - RAM_START;
}
void __init mach_reserve_bootmem ()
{
extern char _root_fs_image_start, _root_fs_image_end;
u32 root_fs_image_start = (u32)&_root_fs_image_start;
u32 root_fs_image_end = (u32)&_root_fs_image_end;
/* Reserve the memory used by the root filesystem image if it's
in RAM. */
if (root_fs_image_end > root_fs_image_start
&& root_fs_image_start >= RAM_START
&& root_fs_image_start < RAM_END)
reserve_bootmem (root_fs_image_start,
root_fs_image_end - root_fs_image_start);
}
void __init mach_sched_init (struct irqaction *timer_action)
{
/* The simulator actually cycles through all interrupts
......
......@@ -104,7 +104,14 @@ int __init simcons_tty_init (void)
tty_driver = driver;
return 0;
}
__initcall (simcons_tty_init);
/* We use `late_initcall' instead of just `__initcall' as a workaround for
the fact that (1) simcons_tty_init can't be called before tty_init,
(2) tty_init is called via `module_init', (3) if statically linked,
module_init == device_init, and (4) there's no ordering of init lists.
We can do this easily because simcons is always statically linked, but
other tty drivers that depend on tty_init and which must use
`module_init' to declare their init routines are likely to be broken. */
late_initcall(simcons_tty_init);
/* Poll for input on the console, and if there's any, deliver it to the
tty driver. */
......
......@@ -23,10 +23,18 @@ EXPORT_SYMBOL(cpu_sysdev_class);
*/
int __init register_cpu(struct cpu *cpu, int num, struct node *root)
{
int error;
cpu->node_id = cpu_to_node(num);
cpu->sysdev.id = num;
cpu->sysdev.cls = &cpu_sysdev_class;
return sys_device_register(&cpu->sysdev);
error = sys_device_register(&cpu->sysdev);
if (!error && root)
error = sysfs_create_link(&root->sysdev.kobj,
&cpu->sysdev.kobj,
kobject_name(&cpu->sysdev.kobj));
return error;
}
......
......@@ -1718,6 +1718,7 @@ static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
if (arq) {
memset(arq, 0, sizeof(*arq));
RB_CLEAR(&arq->rb_node);
arq->request = rq;
arq->state = AS_RQ_NEW;
......
......@@ -765,6 +765,7 @@ deadline_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
drq = mempool_alloc(dd->drq_pool, gfp_mask);
if (drq) {
memset(drq, 0, sizeof(*drq));
RB_CLEAR(&drq->rb_node);
drq->request = rq;
......
......@@ -373,6 +373,22 @@ config AU1000_UART
If you have an Alchemy AU1000 processor (MIPS based) and you want
to use serial ports, say Y. Otherwise, say N.
config SGI_L1_SERIAL
bool "SGI Altix L1 serial support"
depends on SERIAL_NONSTANDARD && IA64
help
If you have an SGI Altix and you want to use the serial port
connected to the system controller (you want this!), say Y.
Otherwise, say N.
config SGI_L1_SERIAL_CONSOLE
bool "SGI Altix L1 serial console support"
depends on SGI_L1_SERIAL
help
If you have an SGI Altix and you would like to use the system
controller serial port as your console (you want this!),
say Y. Otherwise, say N.
config AU1000_SERIAL_CONSOLE
bool "Enable Au1000 serial console"
depends on AU1000_UART
......
......@@ -42,6 +42,7 @@ obj-$(CONFIG_RIO) += rio/ generic_serial.o
obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
......
......@@ -638,7 +638,7 @@ static int __init drm_init( void )
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
DRM(stub_unregister)(DRM(minor)[i]);
DRM(takedown)( dev );
return -ENOMEM;
return -EINVAL;
}
#endif
#if __REALLY_HAVE_MTRR
......
......@@ -79,6 +79,22 @@ static inline int uncached_access(struct file *file, unsigned long addr)
#endif
}
#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
{
unsigned long end_mem;
end_mem = __pa(high_memory);
if (addr >= end_mem)
return 0;
if (*count > end_mem - addr)
*count = end_mem - addr;
return 1;
}
#endif
static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
const char * buf, size_t count, loff_t *ppos)
{
......@@ -113,14 +129,10 @@ static ssize_t read_mem(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned long end_mem;
ssize_t read;
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
if (count > end_mem - p)
count = end_mem - p;
if (!valid_phys_addr_range(p, &count))
return -EFAULT;
read = 0;
#if defined(__sparc__) || (defined(__mc68000__) && defined(CONFIG_MMU))
/* we don't have page 0 mapped on sparc and m68k.. */
......@@ -149,13 +161,9 @@ static ssize_t write_mem(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned long end_mem;
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
if (count > end_mem - p)
count = end_mem - p;
if (!valid_phys_addr_range(p, &count))
return -EFAULT;
return do_write_mem(file, __va(p), p, buf, count, ppos);
}
......
This diff is collapsed.
......@@ -292,7 +292,7 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
* Print the information for /proc/toshiba
*/
#ifdef CONFIG_PROC_FS
int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
static int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
{
char *temp;
int key;
......
......@@ -140,7 +140,7 @@ static struct pci_driver fm801_gp_driver = {
.name = "FM801 GP",
.id_table = fm801_gp_id_table,
.probe = fm801_gp_probe,
.remove = fm801_gp_remove,
.remove = __devexit_p(fm801_gp_remove),
};
int __init fm801_gp_init(void)
......
......@@ -168,7 +168,7 @@ static struct pci_driver vortex_driver = {
.name = "vortex",
.id_table = vortex_id_table,
.probe = vortex_probe,
.remove = vortex_remove,
.remove = __devexit_p(vortex_remove),
};
int __init vortex_init(void)
......
......@@ -79,7 +79,6 @@ capi_ctr_get(struct capi_ctr *card)
{
if (!try_module_get(card->owner))
return NULL;
DBG("Reserve module: %s", card->owner->name);
return card;
}
......@@ -87,7 +86,6 @@ static inline void
capi_ctr_put(struct capi_ctr *card)
{
module_put(card->owner);
DBG("Release module: %s", card->owner->name);
}
/* ------------------------------------------------------------- */
......
......@@ -32,9 +32,11 @@ int mca_register_driver(struct mca_driver *mca_drv)
{
int r;
mca_drv->driver.bus = &mca_bus_type;
if ((r = driver_register(&mca_drv->driver)) < 0)
return r;
if (MCA_bus) {
mca_drv->driver.bus = &mca_bus_type;
if ((r = driver_register(&mca_drv->driver)) < 0)
return r;
}
return 0;
}
......@@ -42,6 +44,7 @@ EXPORT_SYMBOL(mca_register_driver);
void mca_unregister_driver(struct mca_driver *mca_drv)
{
driver_unregister(&mca_drv->driver);
if (MCA_bus)
driver_unregister(&mca_drv->driver);
}
EXPORT_SYMBOL(mca_unregister_driver);
......@@ -123,7 +123,7 @@ int mca_find_unused_adapter(int id, int start)
{
struct mca_find_adapter_info info = { 0 };
if(id == 0xffff)
if (!MCA_bus || id == 0xffff)
return MCA_NOTFOUND;
info.slot = start;
......
......@@ -757,7 +757,7 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
u8 eccbuf[6];
char *p, *pend;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%d,"
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%ld,"
"buffer=0x%x)\n", (int)inftl, block, (int)buffer);
/* Is block all zero? */
......@@ -803,7 +803,7 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
struct inftl_bci bci;
size_t retlen;
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%d,"
DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%ld,"
"buffer=0x%x)\n", (int)inftl, block, (int)buffer);
while (thisEUN < inftl->nb_blocks) {
......
......@@ -1229,7 +1229,7 @@ static ctl_table arlan_root_table[] =
//};
#ifdef CONFIG_PROC_FS
static struct ctl_table_header *arlan_device_sysctl_header;
int __init init_arlan_proc(void)
......@@ -1254,3 +1254,4 @@ void __exit cleanup_arlan_proc(void)
arlan_device_sysctl_header = NULL;
}
#endif
......@@ -2358,7 +2358,11 @@ struct parport *parport_pc_probe_port (unsigned long int base,
release_region(base_hi, 3);
ECR_res = NULL;
}
/* Likewise for EEP ports */
if (EPP_res && (p->modes & PARPORT_MODE_EPP) == 0) {
release_region(base+3, 5);
EPP_res = NULL;
}
if (p->irq != PARPORT_IRQ_NONE) {
if (request_irq (p->irq, parport_pc_interrupt,
0, p->name, p)) {
......
......@@ -2335,11 +2335,8 @@ static int atp870u_detect(Scsi_Host_Template * tpnt)
break;
}
}
for (h = 0; h < MAX_ATP; h++) {
for (h = 0; h < card; h++) {
struct atp_unit tmp, *dev;
if (pdev[h] == NULL) {
return count;
}
/* Found an atp870u/w. */
base_io = pci_resource_start(pdev[h], 0);
......
......@@ -289,12 +289,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
if (rq_data_dir(rq) == WRITE)
if (!rq->data_len)
SCpnt->sc_data_direction = SCSI_DATA_NONE;
else if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
else if (rq->data_len)
SCpnt->sc_data_direction = SCSI_DATA_READ;
else
SCpnt->sc_data_direction = SCSI_DATA_NONE;
SCpnt->sc_data_direction = SCSI_DATA_READ;
this_count = rq->data_len;
if (rq->timeout)
......
......@@ -2086,6 +2086,9 @@ int register_serial(struct serial_struct *req)
int __init early_serial_setup(struct uart_port *port)
{
if (port->line >= ARRAY_SIZE(serial8250_ports))
return -ENODEV;
serial8250_isa_init_ports();
serial8250_ports[port->line].port = *port;
serial8250_ports[port->line].port.ops = &serial8250_pops;
......
......@@ -1728,8 +1728,8 @@ dbg( "digi_startup: TOP" );
init_waitqueue_head( &priv->dp_flush_wait );
priv->dp_in_close = 0;
init_waitqueue_head( &priv->dp_close_wait );
INIT_WORK(&priv->dp_wakeup_work, (void *)digi_wakeup_write_lock,
(void *)(&serial->port[i]));
INIT_WORK(&priv->dp_wakeup_work,
digi_wakeup_write_lock, serial->port[i]);
/* initialize write wait queue for this port */
init_waitqueue_head( &serial->port[i]->write_wait );
......
......@@ -673,14 +673,15 @@ befs_nls2utf(struct super_block *sb, const char *in,
*
*/
enum {
Opt_uid, Opt_gid, Opt_charset, Opt_debug,
Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err,
};
static match_table_t befs_tokens = {
{Opt_uid, "uid=%d"},
{Opt_gid, "gid=%d"},
{Opt_charset, "iocharset=%s"},
{Opt_debug, "debug"}
{Opt_debug, "debug"},
{Opt_err, NULL}
};
static int
......
......@@ -602,6 +602,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
// printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
interpreter_type = INTERPRETER_ELF;
}
/* Verify the interpreter has a valid arch */
if ((interpreter_type == INTERPRETER_ELF) &&
!elf_check_arch(&interp_elf_ex))
goto out_free_dentry;
} else {
/* Executables without an interpreter also need a personality */
SET_PERSONALITY(elf_ex, ibcs2_interpreter);
......
......@@ -826,28 +826,49 @@ void dquot_initialize(struct inode *inode, int type)
}
/*
* Release all quota for the specified inode.
*
* Note: this is a blocking operation.
* Remove references to quota from inode
* This function needs dqptr_sem for writing
*/
static void dquot_drop_nolock(struct inode *inode)
static void dquot_drop_iupdate(struct inode *inode, struct dquot **to_drop)
{
int cnt;
inode->i_flags &= ~S_QUOTA;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
continue;
dqput(inode->i_dquot[cnt]);
to_drop[cnt] = inode->i_dquot[cnt];
inode->i_dquot[cnt] = NODQUOT;
}
}
/*
* Release all quotas referenced by inode
*/
void dquot_drop(struct inode *inode)
{
struct dquot *to_drop[MAXQUOTAS];
int cnt;
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
dquot_drop_nolock(inode);
dquot_drop_iupdate(inode, to_drop);
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (to_drop[cnt] != NODQUOT)
dqput(to_drop[cnt]);
}
/*
* Release all quotas referenced by inode.
* This function assumes dqptr_sem for writing
*/
void dquot_drop_nolock(struct inode *inode)
{
struct dquot *to_drop[MAXQUOTAS];
int cnt;
dquot_drop_iupdate(inode, to_drop);
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (to_drop[cnt] != NODQUOT)
dqput(to_drop[cnt]);
}
/*
......@@ -862,6 +883,10 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
warntype[cnt] = NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return QUOTA_OK;
}
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -894,6 +919,10 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return QUOTA_OK;
}
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -923,6 +952,10 @@ void dquot_free_space(struct inode *inode, qsize_t number)
unsigned int cnt;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return;
}
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......@@ -942,6 +975,10 @@ void dquot_free_inode(const struct inode *inode, unsigned long number)
unsigned int cnt;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return;
}
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT)
......
......@@ -412,10 +412,18 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
static int hugetlbfs_mknod(struct inode *dir,
struct dentry *dentry, int mode, dev_t dev)
{
struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
current->fsgid, mode, dev);
struct inode *inode;
int error = -ENOSPC;
gid_t gid;
if (dir->i_mode & S_ISGID) {
gid = dir->i_gid;
if (S_ISDIR(mode))
mode |= S_ISGID;
} else {
gid = current->fsgid;
}
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, gid, mode, dev);
if (inode) {
dir->i_size += PSEUDO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
......@@ -444,9 +452,15 @@ static int hugetlbfs_symlink(struct inode *dir,
{
struct inode *inode;
int error = -ENOSPC;
gid_t gid;
if (dir->i_mode & S_ISGID)
gid = dir->i_gid;
else
gid = current->fsgid;
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
current->fsgid, S_IFLNK|S_IRWXUGO, 0);
gid, S_IFLNK|S_IRWXUGO, 0);
if (inode) {
int l = strlen(symname)+1;
error = page_symlink(inode, symname, l);
......
......@@ -172,6 +172,14 @@ void journal_commit_transaction(journal_t *journal)
while (commit_transaction->t_reserved_list) {
jh = commit_transaction->t_reserved_list;
JBUFFER_TRACE(jh, "reserved, unused: refile");
/*
* A journal_get_undo_access()+journal_release_buffer() may
* leave undo-committed data.
*/
if (jh->b_committed_data) {
kfree(jh->b_committed_data);
jh->b_committed_data = NULL;
}
journal_refile_buffer(journal, jh);
}
......
......@@ -342,7 +342,7 @@ int journal_write_metadata_buffer(transaction_t *transaction,
tmp = jbd_rep_kmalloc(bh_in->b_size, GFP_NOFS);
jbd_lock_bh_state(bh_in);
if (jh_in->b_frozen_data) {
kfree(new_page);
kfree(tmp);
goto repeat;
}
......@@ -1729,6 +1729,8 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
J_ASSERT_BH(bh, buffer_jbd(bh));
J_ASSERT_BH(bh, jh2bh(jh) == bh);
BUFFER_TRACE(bh, "remove journal_head");
J_ASSERT_BH(bh, !jh->b_frozen_data);
J_ASSERT_BH(bh, !jh->b_committed_data);
bh->b_private = NULL;
jh->b_bh = NULL; /* debug, really */
clear_buffer_jbd(bh);
......
......@@ -32,6 +32,8 @@ int simple_statfs(struct super_block *sb, struct kstatfs *buf)
struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
if (dentry->d_name.len > NAME_MAX)
return ERR_PTR(-ENAMETOOLONG);
d_add(dentry, NULL);
return NULL;
}
......
......@@ -95,6 +95,11 @@ ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int error = -ENOSPC;
if (inode) {
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
inode->i_mode |= S_ISGID;
}
d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */
error = 0;
......@@ -125,6 +130,8 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char *
int l = strlen(symname)+1;
error = page_symlink(inode, symname, l);
if (!error) {
if (dir->i_mode & S_ISGID)
inode->i_gid = dir->i_gid;
d_instantiate(dentry, inode);
dget(dentry);
} else
......
......@@ -101,7 +101,7 @@ static inline void console_verbose(void)
extern void bust_spinlocks(int yes);
extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */
extern int panic_on_oops;
extern int system_running;
extern int tainted;
extern const char *print_tainted(void);
#define TAINT_PROPRIETARY_MODULE (1<<0)
......
......@@ -302,6 +302,7 @@ extern long time_adj; /* tick adjust (scaled 1 / HZ) */
extern long time_reftime; /* time at last adjustment (s) */
extern long time_adjust; /* The amount of adjtime left */
extern long time_next_adjust; /* Value for time_adjust at next tick */
/* interface variables pps->timer interrupt */
extern long pps_offset; /* pps time offset (us) */
......
......@@ -33,13 +33,4 @@ typedef struct {
unsigned int edi __attribute__ ((packed));
} SMMRegisters;
#ifdef CONFIG_PROC_FS
static int tosh_get_info(char *, char **, off_t, int);
#else /* !CONFIG_PROC_FS */
inline int tosh_get_info(char *buffer, char **start, off_t fpos, int lenght)
{
return 0;
}
#endif /* CONFIG_PROC_FS */
#endif
......@@ -94,7 +94,7 @@ extern void tc_init(void);
* Are we up and running (ie do we have all the infrastructure
* set up)
*/
int system_running = 0;
int system_running;
/*
* Boot command-line arguments
......
......@@ -837,11 +837,20 @@ asmlinkage long sys_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,
msg_unlock(msq);
schedule();
current->state = TASK_RUNNING;
/*
* The below optimisation is buggy. A sleeping thread that is
* woken up checks if it got a message and if so, copies it to
* userspace and just returns without taking any locks.
* But this return to user space can be faster than the message
* send, and if the receiver immediately exits the
* wake_up_process performed by the sender will oops.
*/
#if 0
msg = (struct msg_msg*) msr_d.r_msg;
if(!IS_ERR(msg))
goto out_success;
#endif
msq = msg_lock(msqid);
msg = (struct msg_msg*)msr_d.r_msg;
......
......@@ -36,7 +36,7 @@
#include <linux/kernel.h>
#include <asm/uaccess.h>
extern int max_threads, system_running;
extern int max_threads;
#ifdef CONFIG_KMOD
......
......@@ -2848,7 +2848,7 @@ void __might_sleep(char *file, int line)
#if defined(in_atomic)
static unsigned long prev_jiffy; /* ratelimiting */
if (in_atomic() || irqs_disabled()) {
if ((in_atomic() || irqs_disabled()) && system_running) {
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
return;
prev_jiffy = jiffies;
......
......@@ -78,8 +78,6 @@ EXPORT_SYMBOL(fs_overflowgid);
int C_A_D = 1;
int cad_pid = 1;
extern int system_running;
/*
* Notifier list for kernel code which wants to be called
* at shutdown. This is used to stop any idling DMA operations
......
......@@ -236,7 +236,7 @@ int do_adjtimex(struct timex *txc)
result = time_state; /* mostly `TIME_OK' */
/* Save for later - semantics of adjtime is to return old value */
save_adjust = time_adjust;
save_adjust = time_next_adjust ? time_next_adjust : time_adjust;
#if 0 /* STA_CLOCKERR is never set yet */
time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
......@@ -283,7 +283,8 @@ int do_adjtimex(struct timex *txc)
if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
/* adjtime() is independent from ntp_adjtime() */
time_adjust = txc->offset;
if ((time_next_adjust = txc->offset) == 0)
time_adjust = 0;
}
else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
......
......@@ -474,6 +474,7 @@ long time_freq = (((NSEC_PER_SEC + HZ/2) % HZ - HZ/2) << SHIFT_USEC) / NSEC_PER_
long time_adj; /* tick adjust (scaled 1 / HZ) */
long time_reftime; /* time at last adjustment (s) */
long time_adjust;
long time_next_adjust;
/*
* this routine handles the overflow of the microsecond field
......@@ -654,6 +655,12 @@ static void update_wall_time_one_tick(void)
}
xtime.tv_nsec += delta_nsec;
time_interpolator_update(delta_nsec);
/* Changes by adjtime() do not take effect till next tick. */
if (time_next_adjust != 0) {
time_adjust = time_next_adjust;
time_next_adjust = 0;
}
}
/*
......
......@@ -348,7 +348,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
case 's':
s = va_arg(args, char *);
if (!s)
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
len = strnlen(s, precision);
......
......@@ -61,6 +61,9 @@
* ->swap_device_lock (exclusive_swap_page, others)
* ->mapping->page_lock
*
* ->i_sem
* ->i_shared_sem (truncate->invalidate_mmap_range)
*
* ->mmap_sem
* ->i_shared_sem (various places)
*
......
......@@ -525,7 +525,7 @@ int unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm,
unsigned long end_addr, unsigned long *nr_accounted)
{
unsigned long zap_bytes = ZAP_BLOCK_SIZE;
unsigned long tlb_start; /* For tlb_finish_mmu */
unsigned long tlb_start = 0; /* For tlb_finish_mmu */
int tlb_start_valid = 0;
int ret = 0;
......
......@@ -279,6 +279,26 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
validate_mm(mm);
}
/*
* Insert vm structure into process list sorted by address and into the inode's
* i_mmap ring. The caller should hold mm->page_table_lock and
* ->f_mappping->i_shared_sem if vm_file is non-NULL.
*/
static void
__insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
{
struct vm_area_struct * __vma, * prev;
struct rb_node ** rb_link, * rb_parent;
__vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent);
if (__vma && __vma->vm_start < vma->vm_end)
BUG();
__vma_link(mm, vma, prev, rb_link, rb_parent);
mark_mm_hugetlb(mm, vma);
mm->map_count++;
validate_mm(mm);
}
/*
* If the vma has a ->close operation then the driver probably needs to release
* per-vma resources, so we don't attempt to merge those.
......@@ -351,7 +371,9 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
unsigned long end, unsigned long vm_flags,
struct file *file, unsigned long pgoff)
{
spinlock_t * lock = &mm->page_table_lock;
spinlock_t *lock = &mm->page_table_lock;
struct inode *inode = file ? file->f_dentry->d_inode : NULL;
struct semaphore *i_shared_sem;
/*
* We later require that vma->vm_flags == vm_flags, so this tests
......@@ -360,6 +382,8 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
if (vm_flags & VM_SPECIAL)
return 0;
i_shared_sem = file ? &inode->i_mapping->i_shared_sem : NULL;
if (!prev) {
prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
goto merge_next;
......@@ -372,12 +396,11 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
is_mergeable_vma(prev, file, vm_flags) &&
can_vma_merge_after(prev, vm_flags, file, pgoff)) {
struct vm_area_struct *next;
struct inode *inode = file ? file->f_dentry->d_inode : NULL;
int need_up = 0;
if (unlikely(file && prev->vm_next &&
prev->vm_next->vm_file == file)) {
down(&inode->i_mapping->i_shared_sem);
down(i_shared_sem);
need_up = 1;
}
spin_lock(lock);
......@@ -395,7 +418,7 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
__remove_shared_vm_struct(next, inode);
spin_unlock(lock);
if (need_up)
up(&inode->i_mapping->i_shared_sem);
up(i_shared_sem);
if (file)
fput(file);
......@@ -405,7 +428,7 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
}
spin_unlock(lock);
if (need_up)
up(&inode->i_mapping->i_shared_sem);
up(i_shared_sem);
return 1;
}
......@@ -419,10 +442,14 @@ static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
pgoff, (end - addr) >> PAGE_SHIFT))
return 0;
if (end == prev->vm_start) {
if (file)
down(i_shared_sem);
spin_lock(lock);
prev->vm_start = addr;
prev->vm_pgoff -= (end - addr) >> PAGE_SHIFT;
spin_unlock(lock);
if (file)
up(i_shared_sem);
return 1;
}
}
......@@ -1142,6 +1169,7 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
unsigned long addr, int new_below)
{
struct vm_area_struct *new;
struct address_space *mapping = NULL;
if (mm->map_count >= MAX_MAP_COUNT)
return -ENOMEM;
......@@ -1155,12 +1183,9 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
INIT_LIST_HEAD(&new->shared);
if (new_below) {
if (new_below)
new->vm_end = addr;
vma->vm_start = addr;
vma->vm_pgoff += ((addr - new->vm_start) >> PAGE_SHIFT);
} else {
vma->vm_end = addr;
else {
new->vm_start = addr;
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
......@@ -1171,7 +1196,25 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
if (new->vm_ops && new->vm_ops->open)
new->vm_ops->open(new);
insert_vm_struct(mm, new);
if (vma->vm_file)
mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
if (mapping)
down(&mapping->i_shared_sem);
spin_lock(&mm->page_table_lock);
if (new_below) {
vma->vm_start = addr;
vma->vm_pgoff += ((addr - new->vm_start) >> PAGE_SHIFT);
} else
vma->vm_end = addr;
__insert_vm_struct(mm, new);
spin_unlock(&mm->page_table_lock);
if (mapping)
up(&mapping->i_shared_sem);
return 0;
}
......
......@@ -52,6 +52,10 @@
#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
/* info->flags needs VM_flags to handle pagein/truncate races efficiently */
#define SHMEM_PAGEIN VM_READ
#define SHMEM_TRUNCATE VM_WRITE
/* Pretend that each entry is of this size in directory's i_size */
#define BOGO_DIRENT_SIZE 20
......@@ -390,6 +394,7 @@ static void shmem_truncate(struct inode *inode)
return;
spin_lock(&info->lock);
info->flags |= SHMEM_TRUNCATE;
limit = info->next_index;
info->next_index = idx;
if (info->swapped && idx < SHMEM_NR_DIRECT) {
......@@ -490,6 +495,19 @@ static void shmem_truncate(struct inode *inode)
}
done2:
BUG_ON(info->swapped > info->next_index);
if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
/*
* Call truncate_inode_pages again: racing shmem_unuse_inode
* may have swizzled a page in from swap since vmtruncate or
* generic_delete_inode did it, before we lowered next_index.
* Also, though shmem_getpage checks i_size before adding to
* cache, no recheck after: so fix the narrow window there too.
*/
spin_unlock(&info->lock);
truncate_inode_pages(inode->i_mapping, inode->i_size);
spin_lock(&info->lock);
}
info->flags &= ~SHMEM_TRUNCATE;
shmem_recalc_inode(inode);
spin_unlock(&info->lock);
}
......@@ -524,6 +542,19 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
attr->ia_size>>PAGE_CACHE_SHIFT,
&page, SGP_READ);
}
/*
* Reset SHMEM_PAGEIN flag so that shmem_truncate can
* detect if any pages might have been added to cache
* after truncate_inode_pages. But we needn't bother
* if it's being fully truncated to zero-length: the
* nrpages check is efficient enough in that case.
*/
if (attr->ia_size) {
struct shmem_inode_info *info = SHMEM_I(inode);
spin_lock(&info->lock);
info->flags &= ~SHMEM_PAGEIN;
spin_unlock(&info->lock);
}
}
}
......@@ -638,14 +669,10 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
found:
idx += offset;
inode = &info->vfs_inode;
/* Racing against delete or truncate? Must leave out of page cache */
limit = (inode->i_state & I_FREEING)? 0:
(i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (idx >= limit ||
move_from_swap_cache(page, idx, inode->i_mapping) == 0)
if (move_from_swap_cache(page, idx, inode->i_mapping) == 0) {
info->flags |= SHMEM_PAGEIN;
shmem_swp_set(info, ptr + offset, 0);
}
shmem_swp_unmap(ptr);
spin_unlock(&info->lock);
/*
......@@ -653,7 +680,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
* try_to_unuse will skip over mms, then reincrement count.
*/
swap_free(entry);
return idx < limit;
return 1;
}
/*
......@@ -706,7 +733,10 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
spin_lock(&info->lock);
shmem_recalc_inode(inode);
BUG_ON(index >= info->next_index);
if (index >= info->next_index) {
BUG_ON(!(info->flags & SHMEM_TRUNCATE));
goto unlock;
}
entry = shmem_swp_entry(info, index, NULL);
BUG_ON(!entry);
BUG_ON(entry->val);
......@@ -720,6 +750,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
}
shmem_swp_unmap(entry);
unlock:
spin_unlock(&info->lock);
swap_free(swap);
redirty:
......@@ -841,6 +872,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **p
swap_free(swap);
} else if (!(error = move_from_swap_cache(
swappage, idx, mapping))) {
info->flags |= SHMEM_PAGEIN;
shmem_swp_set(info, entry, 0);
shmem_swp_unmap(entry);
spin_unlock(&info->lock);
......@@ -910,6 +942,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **p
goto failed;
goto repeat;
}
info->flags |= SHMEM_PAGEIN;
}
info->alloced++;
......@@ -1206,12 +1239,11 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t
pos += bytes;
buf += bytes;
if (pos > inode->i_size)
inode->i_size = pos;
i_size_write(inode, pos);
flush_dcache_page(page);
set_page_dirty(page);
if (!PageReferenced(page))
SetPageReferenced(page);
mark_page_accessed(page);
page_cache_release(page);
if (left) {
......@@ -1395,6 +1427,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int error = -ENOSPC;
if (inode) {
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
inode->i_mode |= S_ISGID;
}
dir->i_size += BOGO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode);
......@@ -1531,6 +1568,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
set_page_dirty(page);
page_cache_release(page);
}
if (dir->i_mode & S_ISGID)
inode->i_gid = dir->i_gid;
dir->i_size += BOGO_DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode);
......
......@@ -793,42 +793,42 @@ int __init cpucache_init(void)
__initcall(cpucache_init);
/* Interface to system's page allocator. No need to hold the cache-lock.
/*
* Interface to system's page allocator. No need to hold the cache-lock.
*
* If we requested dmaable memory, we will get it. Even if we
* did not request dmaable memory, we might get it, but that
* would be relatively rare and ignorable.
*/
static inline void * kmem_getpages (kmem_cache_t *cachep, unsigned long flags)
static inline void *kmem_getpages(kmem_cache_t *cachep, unsigned long flags)
{
void *addr;
void *addr;
/*
* If we requested dmaable memory, we will get it. Even if we
* did not request dmaable memory, we might get it, but that
* would be relatively rare and ignorable.
*/
flags |= cachep->gfpflags;
if ( cachep->flags & SLAB_RECLAIM_ACCOUNT)
if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
atomic_add(1<<cachep->gfporder, &slab_reclaim_pages);
addr = (void*) __get_free_pages(flags, cachep->gfporder);
/* Assume that now we have the pages no one else can legally
* messes with the 'struct page's.
* However vm_scan() might try to test the structure to see if
* it is a named-page or buffer-page. The members it tests are
* of no interest here.....
*/
addr = (void*)__get_free_pages(flags, cachep->gfporder);
if (addr) {
int i = (1 << cachep->gfporder);
struct page *page = virt_to_page(addr);
while (i--) {
SetPageSlab(page);
page++;
}
}
return addr;
}
/* Interface to system's page release. */
static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
/*
* Interface to system's page release.
*/
static inline void kmem_freepages(kmem_cache_t *cachep, void *addr)
{
unsigned long i = (1<<cachep->gfporder);
struct page *page = virt_to_page(addr);
const unsigned long nr_freed = i;
/* free_pages() does not clear the type bit - we do that.
* The pages have been unlinked from their cache-slab,
* but their 'struct page's might be accessed in
* vm_scan(). Shouldn't be a worry.
*/
while (i--) {
if (!TestClearPageSlab(page))
BUG();
......@@ -1608,7 +1608,6 @@ static int cache_grow (kmem_cache_t * cachep, int flags)
do {
SET_PAGE_CACHE(page, cachep);
SET_PAGE_SLAB(page, slabp);
SetPageSlab(page);
inc_page_state(nr_slab);
page++;
} while (--i);
......
......@@ -56,9 +56,7 @@
#define BT_DBG( A... )
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_bt;
#endif
/* Bluetooth sockets */
#define BT_MAX_PROTO 5
......
......@@ -1982,9 +1982,9 @@ int snd_pcm_open(struct inode *inode, struct file *file)
}
}
remove_wait_queue(&pcm->open_wait, &wait);
up(&pcm->open_mutex);
if (err < 0)
goto __error;
up(&pcm->open_mutex);
return err;
__error:
......
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