diff -Nru a/Makefile b/Makefile --- a/Makefile Wed Dec 17 19:00:07 2003 +++ b/Makefile Wed Dec 17 19:00:07 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -test11 +EXTRAVERSION = # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c --- a/arch/i386/mm/fault.c Wed Dec 17 19:00:07 2003 +++ b/arch/i386/mm/fault.c Wed Dec 17 19:00:07 2003 @@ -359,7 +359,8 @@ return; tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; info.si_signo = SIGSEGV; info.si_errno = 0; diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c --- a/drivers/block/scsi_ioctl.c Wed Dec 17 19:00:07 2003 +++ b/drivers/block/scsi_ioctl.c Wed Dec 17 19:00:07 2003 @@ -432,12 +432,23 @@ break; case SG_IO: { struct sg_io_hdr hdr; + unsigned char cdb[BLK_MAX_CDB], *old_cdb; - if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) { - err = -EFAULT; + err = -EFAULT; + if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) break; - } + err = -EINVAL; + if (hdr.cmd_len > sizeof(rq->cmd)) + break; + err = -EFAULT; + if (copy_from_user(cdb, hdr.cmdp, hdr.cmd_len)) + break; + + old_cdb = hdr.cmdp; + hdr.cmdp = cdb; err = sg_io(q, bdev, &hdr); + + hdr.cmdp = old_cdb; if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr))) err = -EFAULT; break; diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c --- a/drivers/i2c/busses/i2c-nforce2.c Wed Dec 17 19:00:07 2003 +++ b/drivers/i2c/busses/i2c-nforce2.c Wed Dec 17 19:00:07 2003 @@ -147,7 +147,7 @@ case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) - outb_p(data->byte, NVIDIA_SMB_DATA); + outb_p(command, NVIDIA_SMB_CMD); protocol |= NVIDIA_SMB_PRTCL_BYTE; break; diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c --- a/drivers/ide/ide-cd.c Wed Dec 17 19:00:07 2003 +++ b/drivers/ide/ide-cd.c Wed Dec 17 19:00:07 2003 @@ -799,6 +799,10 @@ * sector... If we got here the error is not correctable */ ide_dump_status (drive, "media error (bad sector)", stat); do_end_request = 1; + } else if (sense_key == BLANK_CHECK) { + /* Disk appears blank ?? */ + ide_dump_status (drive, "media error (blank)", stat); + do_end_request = 1; } else if ((err & ~ABRT_ERR) != 0) { /* Go to the default handler for other errors. */ diff -Nru a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h --- a/drivers/ide/ide-cd.h Wed Dec 17 19:00:07 2003 +++ b/drivers/ide/ide-cd.h Wed Dec 17 19:00:07 2003 @@ -501,6 +501,7 @@ #define ILLEGAL_REQUEST 0x05 #define UNIT_ATTENTION 0x06 #define DATA_PROTECT 0x07 +#define BLANK_CHECK 0x08 #define ABORTED_COMMAND 0x0b #define MISCOMPARE 0x0e @@ -578,7 +579,7 @@ "Illegal request", "Unit attention", "Data protect", - "(reserved)", + "Blank check", "(reserved)", "(reserved)", "Aborted command", diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c --- a/drivers/md/raid5.c Wed Dec 17 19:00:07 2003 +++ b/drivers/md/raid5.c Wed Dec 17 19:00:07 2003 @@ -40,6 +40,16 @@ #define stripe_hash(conf, sect) ((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK]) +/* bio's attached to a stripe+device for I/O are linked together in bi_sector + * order without overlap. There may be several bio's per stripe+device, and + * a bio could span several devices. + * When walking this list for a particular stripe+device, we must never proceed + * beyond a bio that extends past this device, as the next bio might no longer + * be valid. + * This macro is used to determine the 'next' bio in the list, given the sector + * of the current stripe+device + */ +#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL) /* * The following can be used to debug the driver */ @@ -613,7 +623,7 @@ int i; for (;bio && bio->bi_sector < sector+STRIPE_SECTORS; - bio = bio->bi_next) { + bio = r5_next_bio(bio, sector) ) { int page_offset; if (bio->bi_sector >= sector) page_offset = (signed)(bio->bi_sector - sector) * 512; @@ -738,7 +748,11 @@ for (i = disks; i--;) if (sh->dev[i].written) { sector_t sector = sh->dev[i].sector; - copy_data(1, sh->dev[i].written, sh->dev[i].page, sector); + struct bio *wbi = sh->dev[i].written; + while (wbi && wbi->bi_sector < sector + STRIPE_SECTORS) { + copy_data(1, wbi, sh->dev[i].page, sector); + wbi = r5_next_bio(wbi, sector); + } set_bit(R5_LOCKED, &sh->dev[i].flags); set_bit(R5_UPTODATE, &sh->dev[i].flags); @@ -791,8 +805,10 @@ bip = &sh->dev[dd_idx].towrite; else bip = &sh->dev[dd_idx].toread; - while (*bip && (*bip)->bi_sector < bi->bi_sector) + while (*bip && (*bip)->bi_sector < bi->bi_sector) { + BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector); bip = & (*bip)->bi_next; + } /* FIXME do I need to worry about overlapping bion */ if (*bip && bi->bi_next && (*bip) != bi->bi_next) BUG(); @@ -813,7 +829,7 @@ for (bi=sh->dev[dd_idx].towrite; sector < sh->dev[dd_idx].sector + STRIPE_SECTORS && bi && bi->bi_sector <= sector; - bi = bi->bi_next) { + bi = r5_next_bio(bi, sh->dev[dd_idx].sector)) { if (bi->bi_sector + (bi->bi_size>>9) >= sector) sector = bi->bi_sector + (bi->bi_size>>9); } @@ -883,7 +899,7 @@ spin_unlock_irq(&conf->device_lock); while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) { copy_data(0, rbi, dev->page, dev->sector); - rbi2 = rbi->bi_next; + rbi2 = r5_next_bio(rbi, dev->sector); spin_lock_irq(&conf->device_lock); if (--rbi->bi_phys_segments == 0) { rbi->bi_next = return_bi; @@ -928,7 +944,7 @@ if (bi) to_write--; while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ - struct bio *nextbi = bi->bi_next; + struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); clear_bit(BIO_UPTODATE, &bi->bi_flags); if (--bi->bi_phys_segments == 0) { md_write_end(conf->mddev); @@ -941,7 +957,7 @@ bi = sh->dev[i].written; sh->dev[i].written = NULL; while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) { - struct bio *bi2 = bi->bi_next; + struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector); clear_bit(BIO_UPTODATE, &bi->bi_flags); if (--bi->bi_phys_segments == 0) { md_write_end(conf->mddev); @@ -957,7 +973,7 @@ sh->dev[i].toread = NULL; if (bi) to_read--; while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ - struct bio *nextbi = bi->bi_next; + struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); clear_bit(BIO_UPTODATE, &bi->bi_flags); if (--bi->bi_phys_segments == 0) { bi->bi_next = return_bi; @@ -1000,7 +1016,7 @@ wbi = dev->written; dev->written = NULL; while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) { - wbi2 = wbi->bi_next; + wbi2 = r5_next_bio(wbi, dev->sector); if (--wbi->bi_phys_segments == 0) { md_write_end(conf->mddev); wbi->bi_next = return_bi; diff -Nru a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c --- a/drivers/net/pci-skeleton.c Wed Dec 17 19:00:07 2003 +++ b/drivers/net/pci-skeleton.c Wed Dec 17 19:00:07 2003 @@ -864,13 +864,6 @@ pci_release_regions (pdev); -#ifndef NETDRV_NDEBUG - /* poison memory before freeing */ - memset (dev, 0xBC, - sizeof (struct net_device) + - sizeof (struct netdrv_private)); -#endif /* NETDRV_NDEBUG */ - free_netdev (dev); pci_set_drvdata (pdev, NULL); diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c --- a/drivers/net/pcnet32.c Wed Dec 17 19:00:07 2003 +++ b/drivers/net/pcnet32.c Wed Dec 17 19:00:07 2003 @@ -1766,8 +1766,6 @@ next_dev = lp->next; unregister_netdev(pcnet32_dev); release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); - if (lp->pci_dev) - pci_unregister_driver(&pcnet32_driver); pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); free_netdev(pcnet32_dev); pcnet32_dev = next_dev; diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c --- a/drivers/net/r8169.c Wed Dec 17 19:00:07 2003 +++ b/drivers/net/r8169.c Wed Dec 17 19:00:07 2003 @@ -642,10 +642,6 @@ iounmap(tp->mmio_addr); pci_release_regions(pdev); - // poison memory before freeing - memset(dev, 0xBC, - sizeof (struct net_device) + sizeof (struct rtl8169_private)); - pci_disable_device(pdev); free_netdev(dev); pci_set_drvdata(pdev, NULL); diff -Nru a/drivers/net/sis190.c b/drivers/net/sis190.c --- a/drivers/net/sis190.c Wed Dec 17 19:00:08 2003 +++ b/drivers/net/sis190.c Wed Dec 17 19:00:08 2003 @@ -703,10 +703,6 @@ iounmap(tp->mmio_addr); pci_release_regions(pdev); - // poison memory before freeing - memset(dev, 0xBC, - sizeof (struct net_device) + sizeof (struct sis190_private)); - free_netdev(dev); pci_set_drvdata(pdev, NULL); } diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Wed Dec 17 19:00:07 2003 +++ b/drivers/net/wireless/airo.c Wed Dec 17 19:00:07 2003 @@ -2466,11 +2466,8 @@ OUT4500( apriv, EVACK, EV_MIC ); #ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { - if (down_trylock(&apriv->sem) != 0) { - set_bit(JOB_MIC, &apriv->flags); - wake_up_interruptible(&apriv->thr_wait); - } else - micinit (apriv); + set_bit(JOB_MIC, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); } #endif } diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c --- a/drivers/scsi/ide-scsi.c Wed Dec 17 19:00:07 2003 +++ b/drivers/scsi/ide-scsi.c Wed Dec 17 19:00:07 2003 @@ -517,6 +517,7 @@ pc->current_position=pc->buffer; bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ + feature.all = 0; if (drive->using_dma && rq->bio) { if (test_bit(PC_WRITING, &pc->flags)) feature.b.dma = !HWIF(drive)->ide_dma_write(drive); diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c Wed Dec 17 19:00:07 2003 +++ b/drivers/scsi/libata-core.c Wed Dec 17 19:00:07 2003 @@ -3224,8 +3224,6 @@ scsi_host_put(ap->host); /* FIXME: check return val */ } - kfree(host_set); - pci_release_regions(pdev); for (i = 0; i < host_set->n_ports; i++) { @@ -3242,6 +3240,7 @@ } } + kfree(host_set); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Wed Dec 17 19:00:07 2003 +++ b/drivers/scsi/qla1280.c Wed Dec 17 19:00:07 2003 @@ -16,9 +16,13 @@ * General Public License for more details. * ******************************************************************************/ -#define QLA1280_VERSION "3.23.37" +#define QLA1280_VERSION "3.23.37.1" /***************************************************************************** Revision History: + Rev 3.23.37.1 December 17, 2003, Jes Sorensen + - Delete completion queue from srb if mailbox command failed to + to avoid qla1280_done completeting qla1280_error_action's + obsolete context Rev 3.23.37 October 1, 2003, Jes Sorensen - Make MMIO depend on CONFIG_X86_VISWS instead of yet another random CONFIG option @@ -1464,8 +1468,15 @@ /* If we didn't manage to issue the action, or we have no * command to wait for, exit here */ if (result == FAILED || handle == NULL || - handle == (unsigned char *)INVALID_HANDLE) + handle == (unsigned char *)INVALID_HANDLE) { + /* + * Clear completion queue to avoid qla1280_done() trying + * to complete the command at a later stage after we + * have exited the current context + */ + sp->wait = NULL; goto leave; + } /* set up a timer just in case we're really jammed */ init_timer(&timer); diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c --- a/drivers/usb/core/devio.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/core/devio.c Wed Dec 17 19:00:07 2003 @@ -261,7 +261,6 @@ spin_lock(&ps->lock); list_move_tail(&as->asynclist, &ps->async_completed); spin_unlock(&ps->lock); - wake_up(&ps->wait); if (as->signr) { sinfo.si_signo = as->signr; sinfo.si_errno = as->urb->status; @@ -269,6 +268,7 @@ sinfo.si_addr = (void *)as->userurb; send_sig_info(as->signr, &sinfo, as->task); } + wake_up(&ps->wait); } static void destroy_async (struct dev_state *ps, struct list_head *list) diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/core/hub.c Wed Dec 17 19:00:07 2003 @@ -692,6 +692,9 @@ struct usb_hub *hub = usb_get_intfdata(dev->actconfig->interface[0]); int ret; + if (!hub) + return -ENODEV; + ret = get_port_status(dev, port + 1, &hub->status->port); if (ret < 0) dev_err (hubdev (dev), @@ -926,7 +929,6 @@ break; } - hub->children[port] = dev; dev->state = USB_STATE_POWERED; /* Reset the device, and detect its speed */ @@ -979,8 +981,10 @@ dev->dev.parent = dev->parent->dev.parent->parent; /* Run it through the hoops (find a driver, etc) */ - if (!usb_new_device(dev, &hub->dev)) + if (!usb_new_device(dev, &hub->dev)) { + hub->children[port] = dev; goto done; + } /* Free the configuration if there was an error */ usb_put_dev(dev); @@ -989,7 +993,6 @@ delay = HUB_LONG_RESET_TIME; } - hub->children[port] = NULL; hub_port_disable(hub, port); done: up(&usb_address0_sem); @@ -1342,6 +1345,7 @@ dev->devpath, ret); return ret; } + dev->state = USB_STATE_CONFIGURED; for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = dev->actconfig->interface[i]; diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/core/usb.c Wed Dec 17 19:00:07 2003 @@ -1120,6 +1120,7 @@ if (err) { dev_err(&dev->dev, "can't set config #%d, error %d\n", dev->config[0].desc.bConfigurationValue, err); + device_del(&dev->dev); goto fail; } diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig --- a/drivers/usb/image/Kconfig Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/image/Kconfig Wed Dec 17 19:00:07 2003 @@ -18,12 +18,14 @@ module will be called mdc800. config USB_SCANNER - tristate "USB Scanner support" + tristate "USB Scanner support (OBSOLETE)" depends on USB help Say Y here if you want to connect a USB scanner to your computer's USB port. Please read for more information. + + This driver has been obsoleted by support via libusb. To compile this driver as a module, choose M here: the module will be called scanner. diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c --- a/drivers/usb/misc/auerswald.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/misc/auerswald.c Wed Dec 17 19:00:07 2003 @@ -324,7 +324,7 @@ urb = acep->urbp; dbg ("auerchain_complete: submitting next urb from chain"); urb->status = 0; /* needed! */ - result = usb_submit_urb(urb, GFP_KERNEL); + result = usb_submit_urb(urb, GFP_ATOMIC); /* check for submit errors */ if (result) { @@ -402,7 +402,7 @@ if (acep) { dbg("submitting urb immediate"); urb->status = 0; /* needed! */ - result = usb_submit_urb(urb, GFP_KERNEL); + result = usb_submit_urb(urb, GFP_ATOMIC); /* check for submit errors */ if (result) { urb->status = result; diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/serial/usb-serial.c Wed Dec 17 19:00:07 2003 @@ -493,12 +493,15 @@ return retval; } -static void __serial_close(struct usb_serial_port *port, struct file *filp) +static void serial_close(struct tty_struct *tty, struct file * filp) { - if (!port->open_count) { - dbg ("%s - port not opened", __FUNCTION__); + struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; + struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); + + if (!serial) return; - } + + dbg("%s - port %d", __FUNCTION__, port->number); --port->open_count; if (port->open_count <= 0) { @@ -506,30 +509,18 @@ * port is being closed by the last owner */ port->serial->type->close(port, filp); port->open_count = 0; + + if (port->tty) { + if (port->tty->driver_data) + port->tty->driver_data = NULL; + port->tty = NULL; + } } module_put(port->serial->type->owner); kobject_put(&port->serial->kobj); } -static void serial_close(struct tty_struct *tty, struct file * filp) -{ - struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; - struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); - - if (!serial) - return; - - dbg("%s - port %d", __FUNCTION__, port->number); - - /* if disconnect beat us to the punch here, there's nothing to do */ - if (tty && tty->driver_data) { - __serial_close(port, filp); - tty->driver_data = NULL; - } - port->tty = NULL; -} - static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; @@ -848,19 +839,6 @@ dbg ("%s - %s", __FUNCTION__, kobj->name); serial = to_usb_serial(kobj); - - /* fail all future close/read/write/ioctl/etc calls */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port->tty != NULL) { - port->tty->driver_data = NULL; - while (port->open_count > 0) { - __serial_close(port, NULL); - } - port->tty = NULL; - } - } - serial_shutdown (serial); /* return the minor range that this device had */ @@ -1242,7 +1220,7 @@ /* register all of the individual ports with the driver core */ for (i = 0; i < num_ports; ++i) { port = serial->port[i]; - port->dev.parent = &serial->dev->dev; + port->dev.parent = &interface->dev; port->dev.driver = NULL; port->dev.bus = &usb_serial_bus_type; port->dev.release = &port_release; diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c --- a/drivers/usb/storage/datafab.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/storage/datafab.c Wed Dec 17 19:00:07 2003 @@ -387,7 +387,7 @@ // we'll go ahead and extract the media capacity while we're here... // - rc = datafab_bulk_read(us, reply, sizeof(reply)); + rc = datafab_bulk_read(us, reply, 512); if (rc == USB_STOR_XFER_GOOD) { // capacity is at word offset 57-58 // diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c --- a/drivers/usb/storage/jumpshot.c Wed Dec 17 19:00:07 2003 +++ b/drivers/usb/storage/jumpshot.c Wed Dec 17 19:00:07 2003 @@ -317,7 +317,7 @@ } // read the reply - rc = jumpshot_bulk_read(us, reply, sizeof(reply)); + rc = jumpshot_bulk_read(us, reply, 512); if (rc != USB_STOR_XFER_GOOD) { rc = USB_STOR_TRANSPORT_ERROR; goto leave; diff -Nru a/fs/hpfs/dir.c b/fs/hpfs/dir.c --- a/fs/hpfs/dir.c Wed Dec 17 19:00:07 2003 +++ b/fs/hpfs/dir.c Wed Dec 17 19:00:07 2003 @@ -65,6 +65,8 @@ int c1, c2 = 0; int ret = 0; + lock_kernel(); + if (hpfs_sb(inode->i_sb)->sb_chk) { if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) { ret = -EFSERROR; diff -Nru a/fs/libfs.c b/fs/libfs.c --- a/fs/libfs.c Wed Dec 17 19:00:07 2003 +++ b/fs/libfs.c Wed Dec 17 19:00:07 2003 @@ -79,6 +79,7 @@ loff_t n = file->f_pos - 2; spin_lock(&dcache_lock); + list_del(&cursor->d_child); p = file->f_dentry->d_subdirs.next; while (n && p != &file->f_dentry->d_subdirs) { struct dentry *next; @@ -87,7 +88,6 @@ n--; p = p->next; } - list_del(&cursor->d_child); list_add_tail(&cursor->d_child, p); spin_unlock(&dcache_lock); } diff -Nru a/fs/proc/base.c b/fs/proc/base.c --- a/fs/proc/base.c Wed Dec 17 19:00:07 2003 +++ b/fs/proc/base.c Wed Dec 17 19:00:07 2003 @@ -1666,10 +1666,14 @@ index -= 2; read_lock(&tasklist_lock); - do { + /* + * The starting point task (leader_task) might be an already + * unlinked task, which cannot be used to access the task-list + * via next_thread(). + */ + if (pid_alive(task)) do { int tid = task->pid; - if (!pid_alive(task)) - continue; + if (--index >= 0) continue; tids[nr_tids] = tid; diff -Nru a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h --- a/include/asm-x86_64/msr.h Wed Dec 17 19:00:07 2003 +++ b/include/asm-x86_64/msr.h Wed Dec 17 19:00:07 2003 @@ -50,9 +50,9 @@ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") #define rdtscll(val) do { \ - unsigned int a,d; \ - asm volatile("rdtsc" : "=a" (a), "=d" (d)); \ - (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \ + unsigned int __a,__d; \ + asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ + (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) #define rdpmc(counter,low,high) \ diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Wed Dec 17 19:00:07 2003 +++ b/include/linux/blkdev.h Wed Dec 17 19:00:07 2003 @@ -82,6 +82,8 @@ wait_queue_head_t wait[2]; }; +#define BLK_MAX_CDB 16 + /* * try to put the fields that are referenced together in the same cacheline */ @@ -147,7 +149,7 @@ * when request is used as a packet command carrier */ unsigned int cmd_len; - unsigned char cmd[16]; + unsigned char cmd[BLK_MAX_CDB]; unsigned int data_len; void *data; diff -Nru a/include/linux/list.h b/include/linux/list.h --- a/include/linux/list.h Wed Dec 17 19:00:07 2003 +++ b/include/linux/list.h Wed Dec 17 19:00:07 2003 @@ -208,6 +208,18 @@ return head->next == head; } +/** + * list_empty_careful - tests whether a list is + * empty _and_ checks that no other CPU might be + * in the process of still modifying either member + * @head: the list to test. + */ +static inline int list_empty_careful(const struct list_head *head) +{ + struct list_head *next = head->next; + return (next == head) && (next == head->prev); +} + static inline void __list_splice(struct list_head *list, struct list_head *head) { diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h --- a/include/linux/rtnetlink.h Wed Dec 17 19:00:07 2003 +++ b/include/linux/rtnetlink.h Wed Dec 17 19:00:07 2003 @@ -138,6 +138,7 @@ #define RTPROT_ZEBRA 11 /* Zebra */ #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +#define RTPROT_XORP 14 /* XORP */ /* rtm_scope diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Wed Dec 17 19:00:07 2003 +++ b/kernel/exit.c Wed Dec 17 19:00:07 2003 @@ -49,9 +49,11 @@ void release_task(struct task_struct * p) { + int zap_leader; task_t *leader; struct dentry *proc_dentry; - + +repeat: BUG_ON(p->state < TASK_ZOMBIE); atomic_dec(&p->user->processes); @@ -70,10 +72,21 @@ * group, and the leader is zombie, then notify the * group leader's parent process. (if it wants notification.) */ + zap_leader = 0; leader = p->group_leader; - if (leader != p && thread_group_empty(leader) && - leader->state == TASK_ZOMBIE && leader->exit_signal != -1) + if (leader != p && thread_group_empty(leader) && leader->state == TASK_ZOMBIE) { + BUG_ON(leader->exit_signal == -1); do_notify_parent(leader, leader->exit_signal); + /* + * If we were the last child thread and the leader has + * exited already, and the leader's parent ignores SIGCHLD, + * then we are the one who should release the leader. + * + * do_notify_parent() will have marked it self-reaping in + * that case. + */ + zap_leader = (leader->exit_signal == -1); + } p->parent->cutime += p->utime + p->cutime; p->parent->cstime += p->stime + p->cstime; @@ -88,6 +101,10 @@ proc_pid_flush(proc_dentry); release_thread(p); put_task_struct(p); + + p = leader; + if (unlikely(zap_leader)) + goto repeat; } /* we are using it only for SMP init */ diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Wed Dec 17 19:00:07 2003 +++ b/kernel/fork.c Wed Dec 17 19:00:07 2003 @@ -125,15 +125,28 @@ EXPORT_SYMBOL(remove_wait_queue); + +/* + * Note: we use "set_current_state()" _after_ the wait-queue add, + * because we need a memory barrier there on SMP, so that any + * wake-function that tests for the wait-queue being active + * will be guaranteed to see waitqueue addition _or_ subsequent + * tests in this thread will see the wakeup having taken place. + * + * The spin_unlock() itself is semi-permeable and only protects + * one way (it only protects stuff inside the critical region and + * stops them from bleeding out - it would still allow subsequent + * loads to move into the the critical region). + */ void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) { unsigned long flags; - __set_current_state(state); wait->flags &= ~WQ_FLAG_EXCLUSIVE; spin_lock_irqsave(&q->lock, flags); if (list_empty(&wait->task_list)) __add_wait_queue(q, wait); + set_current_state(state); spin_unlock_irqrestore(&q->lock, flags); } @@ -144,11 +157,11 @@ { unsigned long flags; - __set_current_state(state); wait->flags |= WQ_FLAG_EXCLUSIVE; spin_lock_irqsave(&q->lock, flags); if (list_empty(&wait->task_list)) __add_wait_queue_tail(q, wait); + set_current_state(state); spin_unlock_irqrestore(&q->lock, flags); } @@ -159,7 +172,20 @@ unsigned long flags; __set_current_state(TASK_RUNNING); - if (!list_empty(&wait->task_list)) { + /* + * We can check for list emptiness outside the lock + * IFF: + * - we use the "careful" check that verifies both + * the next and prev pointers, so that there cannot + * be any half-pending updates in progress on other + * CPU's that we haven't seen yet (and that might + * still change the stack area. + * and + * - all other users take the lock (ie we can only + * have _one_ other CPU that looks at or modifies + * the list). + */ + if (!list_empty_careful(&wait->task_list)) { spin_lock_irqsave(&q->lock, flags); list_del_init(&wait->task_list); spin_unlock_irqrestore(&q->lock, flags); diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Wed Dec 17 19:00:07 2003 +++ b/kernel/sched.c Wed Dec 17 19:00:07 2003 @@ -646,7 +646,7 @@ */ p->activated = -1; } - if (sync) + if (sync && (task_cpu(p) == smp_processor_id())) __activate_task(p, rq); else { activate_task(p, rq); diff -Nru a/lib/kobject.c b/lib/kobject.c --- a/lib/kobject.c Wed Dec 17 19:00:07 2003 +++ b/lib/kobject.c Wed Dec 17 19:00:07 2003 @@ -236,8 +236,6 @@ list_del_init(&kobj->entry); up_write(&kobj->kset->subsys->rwsem); } - if (kobj->parent) - kobject_put(kobj->parent); kobject_put(kobj); } @@ -274,9 +272,11 @@ kobj->parent = parent; error = create_dir(kobj); - if (error) + if (error) { unlink(kobj); - else { + if (parent) + kobject_put(parent); + } else { /* If this kobj does not belong to a kset, try to find a parent that does. */ top_kobj = kobj; @@ -452,6 +452,7 @@ { struct kobj_type * t = get_ktype(kobj); struct kset * s = kobj->kset; + struct kobject * parent = kobj->parent; pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); if (kobj->k_name != kobj->name) @@ -461,6 +462,8 @@ t->release(kobj); if (s) kset_put(s); + if (parent) + kobject_put(parent); } /** diff -Nru a/mm/mmap.c b/mm/mmap.c --- a/mm/mmap.c Wed Dec 17 19:00:07 2003 +++ b/mm/mmap.c Wed Dec 17 19:00:07 2003 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -474,8 +475,13 @@ struct rb_node ** rb_link, * rb_parent; unsigned long charged = 0; - if (file && (!file->f_op || !file->f_op->mmap)) - return -ENODEV; + if (file) { + if (!file->f_op || !file->f_op->mmap) + return -ENODEV; + + if ((prot & PROT_EXEC) && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)) + return -EPERM; + } if (!len) return addr; diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c --- a/net/bridge/br_netfilter.c Wed Dec 17 19:00:07 2003 +++ b/net/bridge/br_netfilter.c Wed Dec 17 19:00:07 2003 @@ -180,7 +180,7 @@ struct rtable *rt; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0 , - .tos = iph->tos} }, .proto = 0}; + .tos = RT_TOS(iph->tos)} }, .proto = 0}; if (!ip_route_output_key(&rt, &fl)) { /* Bridged-and-DNAT'ed traffic doesn't diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Wed Dec 17 19:00:07 2003 +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Wed Dec 17 19:00:07 2003 @@ -53,7 +53,7 @@ unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS; unsigned long ip_ct_tcp_timeout_established = 5 DAYS; unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS; -unsigned long ip_ct_tcp_timeout_close_wait = 3 DAYS; +unsigned long ip_ct_tcp_timeout_close_wait = 60 SECS; unsigned long ip_ct_tcp_timeout_last_ack = 30 SECS; unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS; unsigned long ip_ct_tcp_timeout_close = 10 SECS; diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c --- a/net/ipv4/netfilter/ip_conntrack_standalone.c Wed Dec 17 19:00:07 2003 +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c Wed Dec 17 19:00:07 2003 @@ -201,7 +201,8 @@ /* Local packets are never produced too large for their interface. We degfragment them at LOCAL_OUT, however, so we have to refragment them here. */ - if ((*pskb)->len > dst_pmtu(&rt->u.dst)) { + if ((*pskb)->len > dst_pmtu(&rt->u.dst) && + !skb_shinfo(*pskb)->tso_size) { /* No hook can be after us, so this should be OK. */ ip_fragment(*pskb, okfn); return NF_STOLEN; diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c --- a/net/ipv4/tcp_ipv4.c Wed Dec 17 19:00:07 2003 +++ b/net/ipv4/tcp_ipv4.c Wed Dec 17 19:00:07 2003 @@ -2356,6 +2356,7 @@ static void *tcp_seq_start(struct seq_file *seq, loff_t *pos) { struct tcp_iter_state* st = seq->private; + st->state = TCP_SEQ_STATE_LISTENING; st->num = 0; return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c --- a/net/ipv6/tcp_ipv6.c Wed Dec 17 19:00:07 2003 +++ b/net/ipv6/tcp_ipv6.c Wed Dec 17 19:00:07 2003 @@ -222,7 +222,7 @@ write_lock(lock); } - sk_add_node(sk, list); + __sk_add_node(sk, list); sock_prot_inc_use(sk->sk_prot); write_unlock(lock); } diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c --- a/net/ipv6/udp.c Wed Dec 17 19:00:07 2003 +++ b/net/ipv6/udp.c Wed Dec 17 19:00:07 2003 @@ -825,7 +825,7 @@ struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = sin6 ? sin6->sin6_port : inet->dport; - sin.sin_addr.s_addr = daddr->s6_addr[3]; + sin.sin_addr.s_addr = daddr->s6_addr32[3]; msg->msg_name = &sin; msg->msg_namelen = sizeof(sin); do_udp_sendmsg: diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c --- a/net/sched/sch_htb.c Wed Dec 17 19:00:07 2003 +++ b/net/sched/sch_htb.c Wed Dec 17 19:00:07 2003 @@ -74,7 +74,7 @@ #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) -#define HTB_VER 0x3000d /* major must be matched with number suplied by TC as version */ +#define HTB_VER 0x3000e /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER #error "Mismatched sch_htb.c and pkt_sch.h" @@ -290,6 +290,11 @@ * then finish and return direct queue. */ #define HTB_DIRECT (struct htb_class*)-1 +static inline u32 htb_classid(struct htb_class *cl) +{ + return (cl && cl != HTB_DIRECT) ? cl->classid : TC_H_UNSPEC; +} + static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch) { struct htb_sched *q = (struct htb_sched *)sch->data; @@ -703,7 +708,7 @@ sch->q.qlen++; sch->stats.packets++; sch->stats.bytes += skb->len; - HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); + HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",htb_classid(cl),skb); return NET_XMIT_SUCCESS; } @@ -731,7 +736,7 @@ htb_activate (q,cl); sch->q.qlen++; - HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); + HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",htb_classid(cl),skb); return NET_XMIT_SUCCESS; } @@ -1381,11 +1386,16 @@ #ifdef HTB_RATECM del_timer_sync (&q->rttim); #endif + /* This line used to be after htb_destroy_class call below + and surprisingly it worked in 2.4. But it must precede it + because filter need its target class alive to be able to call + unbind_filter on it (without Oops). */ + htb_destroy_filters(&q->filter_list); + while (!list_empty(&q->root)) htb_destroy_class (sch,list_entry(q->root.next, struct htb_class,sibling)); - htb_destroy_filters(&q->filter_list); __skb_queue_purge(&q->direct_queue); } diff -Nru a/scripts/file2alias.c b/scripts/file2alias.c --- a/scripts/file2alias.c Wed Dec 17 19:00:07 2003 +++ b/scripts/file2alias.c Wed Dec 17 19:00:07 2003 @@ -52,6 +52,13 @@ id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo); id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi); + /* + * Some modules (visor) have empty slots as placeholder for + * run-time specification that results in catch-all alias + */ + if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass)) + return 1; + strcpy(alias, "usb:"); ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR, id->idVendor);