From f454324ea25806d1c22e0ae7123bd9f0e746850a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:13:42 -0500 Subject: [PATCH] Import 2.1.48pre4 --- Documentation/Configure.help | 64 ++++- Makefile | 1 - drivers/char/lp.c | 7 +- drivers/char/pc_keyb.c | 2 + drivers/char/tty_io.c | 4 +- drivers/misc/parport_init.c | 7 +- drivers/misc/parport_pc.c | 18 +- drivers/misc/parport_procfs.c | 6 +- drivers/misc/parport_share.c | 33 ++- drivers/net/plip.c | 8 +- drivers/pnp/parport_probe.c | 6 +- drivers/scsi/Config.in | 9 +- drivers/scsi/aic7xxx_seq.h | 479 ++++++++++++++++++++++++++++++++++ drivers/scsi/ppa.c | 10 +- drivers/scsi/ppa.h | 2 +- fs/dquot.c | 8 +- fs/ext2/ialloc.c | 12 +- fs/ext2/namei.c | 12 +- fs/hpfs/hpfs_fs.c | 29 +- fs/inode.c | 18 +- fs/namei.c | 4 + fs/nfs/dir.c | 10 + fs/vfat/namei.c | 238 ++++++++--------- include/linux/msdos_fs.h | 1 - include/linux/parport.h | 8 +- include/linux/sched.h | 19 +- net/ipv4/ip_fragment.c | 3 + net/ipv4/ipip.c | 3 +- 28 files changed, 801 insertions(+), 220 deletions(-) create mode 100644 drivers/scsi/aic7xxx_seq.h diff --git a/Documentation/Configure.help b/Documentation/Configure.help index bd1cdeeb0efb..c038c87a5607 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1672,20 +1672,62 @@ CONFIG_SCSI_AHA1740 want to compile it as a module, say M here and read Documentation/modules.txt. -Adaptec AHA274X/284X/294X support +Adaptec AIC7xxx support (includes 274x/284x/294x) CONFIG_SCSI_AIC7XXX Information about this SCSI host adapter is contained in drivers/scsi/README.aic7xxx and in the SCSI-HOWTO, available via ftp - (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it - doesn't work out of the box, you may have to change some settings in - drivers/scsi/aic7xxx.h. It has been reported that the "wide - negotiation" on these cards is not quite working and should be - disabled. Note that the AHA2920 SCSI host adapter is *not* supported - by this driver; choose "Future Domain 16xx SCSI support" instead. If - you want to compile this driver a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read Documentation/modules.txt. The module will be - called aic7xxx.o. + (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that + the AHA2920 SCSI host adapter is *not* supported by this driver; choose + "Future Domain 16xx SCSI support" instead. If you want to compile this + driver as module ( = code which can be inserted in and removed from the + running kernel whenever you want), say M here and read Documentation/ + modules.txt. The module will be called aic7xxx.o. + +Enable tagged command queueing +CONFIG_AIC7XXX_TAGGED_QUEUEING + This option allows you to enable tagged command queueing for this + driver. Some scsi devices do not properly support this + feature. Tagged command queueing will improve performance. + +Maximum number of commands per LUN + CONFIG_AIC7XXX_CMDS_PER_LUN + This option allows you to set the maximum number of commands queued + per LUN. If tagged queueing is enabled, then you may want to try + increasing AIC7XXX_CMDS_PER_LUN to more than 2. By default, we limit + the SCBs per LUN to 2 with or without tagged queueing enabled. If + tagged queueing is disabled, the sequencer will keep the 2nd SCB in + the input queue until the first one completes - so it is OK to to have + more than 1 SCB queued. If tagged queueing is enabled, then the + sequencer will attempt to send the 2nd SCB to the device while the + first SCB is executing and the device is disconnected. For adapters + limited to 4 SCBs, you may want to actually decrease the commands per + LUN to 1, if you often have more than 2 devices active at the same + time. This will allocate 1 SCB for each device and ensure that there + will always be a free SCB for up to 4 devices active at the same time. + When SCB paging is enabled, set the commands per LUN to 8 or higher + (see SCB paging support below). Note that if AIC7XXX_CMDS_PER_LUN is + not defined and tagged queueing is enabled, the driver will attempt to + set the commands per LUN using its own heuristic based on the number + of available SCBs. + +Enable SCB paging +CONFIG_AIC7XXX_PAGE_ENABLE + This option enables SCB paging. This will increase performance when + tagged queueing is enabled. Note that you should increase the + AIC7XXX_CMDS_PER_LUN to 8 as most tagged queueing devices allow at + least this many. Note that EISA and VLB controllers do not support + SCB paging due to chip limitations; enabling it on these controllers + has no effect. + +Collect statistics to report in /proc +CONFIG_AIC7XXX_PROC_STATS + This option enables collection of SCSI transfer statistics for the + /proc filesystem. This does affect performance since it has to + maintain statistics. + +Delay in seconds after SCSI bus reset +CONFIG_AIC7XXX_RESET_DELAY + This option sets the delay in seconds after a SCSI bus reset. BusLogic SCSI support CONFIG_SCSI_BUSLOGIC diff --git a/Makefile b/Makefile index 60a536a02c04..af1adc51d89b 100644 --- a/Makefile +++ b/Makefile @@ -335,7 +335,6 @@ clean: archclean mrproper: clean rm -f include/linux/autoconf.h include/linux/version.h rm -f drivers/sound/local.h drivers/sound/.defines - rm -f drivers/scsi/aic7xxx_asm drivers/scsi/aic7xxx_seq.h rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash rm -f drivers/net/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h rm -f drivers/net/soundmodem/sm_tbl_{hapn4800,psk4800}.h diff --git a/drivers/char/lp.c b/drivers/char/lp.c index ce0f6b345ed9..59bb0a0a2bd2 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -652,19 +652,18 @@ void lp_setup(char *str, int *ints) #endif -int lp_wakeup(void *ref) +void lp_wakeup(void *ref) { struct lp_struct *lp_dev = (struct lp_struct *) ref; if (!lp_dev->lp_wait_q) - return 1; /* Wake up whom? */ + return; /* Wake up whom? */ /* Claim the Parport */ if (parport_claim(lp_dev->dev)) - return 1; /* Shouldn't happen */ + return; /* Shouldn't happen */ wake_up(&lp_dev->lp_wait_q); - return 0; } static int inline lp_searchfor(int list[], int a) diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index 39c35fb49044..c4089b2410d5 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -7,6 +7,8 @@ * Major cleanup by Martin Mares, May 1997 */ +#include + #include #include #include diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d63578c55ee7..4c6ecae22cc8 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -688,7 +688,6 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty) return -ENODEV; idx = MINOR(device) - driver->minor_start; - tty = driver->table[idx]; /* * Check whether we need to acquire the tty semaphore to avoid @@ -697,7 +696,8 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty) down_tty_sem(idx); /* check whether we're reopening an existing tty */ - if(tty) goto fast_track; + tty = driver->table[idx]; + if (tty) goto fast_track; /* * First time open is complex, especially for PTY devices. diff --git a/drivers/misc/parport_init.c b/drivers/misc/parport_init.c index d5a68979415b..791e58befbc2 100644 --- a/drivers/misc/parport_init.c +++ b/drivers/misc/parport_init.c @@ -56,6 +56,7 @@ __initfunc(void parport_setup(char *str, int *ints)) #ifdef MODULE int init_module(void) { + parport_proc_init(); return 0; } @@ -79,7 +80,8 @@ __initfunc(int parport_init(void)) { struct parport *pb; - if (io[0] == PARPORT_DISABLE) return 1; + if (io[0] == PARPORT_DISABLE) return 1; + parport_proc_init(); #ifdef CONFIG_PARPORT_PC parport_pc_init(io, irq, dma); #endif @@ -92,12 +94,15 @@ __initfunc(int parport_init(void)) EXPORT_SYMBOL(parport_claim); EXPORT_SYMBOL(parport_release); EXPORT_SYMBOL(parport_register_port); +EXPORT_SYMBOL(parport_unregister_port); EXPORT_SYMBOL(parport_quiesce); EXPORT_SYMBOL(parport_register_device); EXPORT_SYMBOL(parport_unregister_device); EXPORT_SYMBOL(parport_enumerate); EXPORT_SYMBOL(parport_ieee1284_nibble_mode_ok); EXPORT_SYMBOL(parport_wait_peripheral); +EXPORT_SYMBOL(parport_proc_register); +EXPORT_SYMBOL(parport_proc_unregister); void inc_parport_count(void) { diff --git a/drivers/misc/parport_pc.c b/drivers/misc/parport_pc.c index 1df2e2b465e1..0115cd4f6ea8 100644 --- a/drivers/misc/parport_pc.c +++ b/drivers/misc/parport_pc.c @@ -10,6 +10,7 @@ * and Philip Blundell */ +#include #include #include @@ -140,7 +141,7 @@ static void pc_enable_irq(struct parport *p) static void pc_release_resources(struct parport *p) { if (p->irq != PARPORT_IRQ_NONE) - free_irq(p->irq, NULL); + free_irq(p->irq, p); release_region(p->base, p->size); if (p->modes & PARPORT_MODE_PCECR) release_region(p->base+0x400, 3); @@ -439,9 +440,10 @@ static int parport_SPP_supported(struct parport *pb) */ static int parport_ECR_present(struct parport *pb) { - int r, octr = pc_read_control(pb), oecr = pc_read_econtrol(pb); + unsigned int r, octr = pc_read_control(pb), + oecr = pc_read_econtrol(pb); - r= pc_read_control(pb); + r = pc_read_control(pb); if ((pc_read_econtrol(pb) & 0x03) == (r & 0x03)) { pc_write_control(pb, r ^ 0x03 ); /* Toggle bits 0-1 */ @@ -820,7 +822,10 @@ static int probe_one_port(unsigned long int base, int irq, int dma) } if (p->irq != PARPORT_IRQ_NONE) printk(", irq %d", p->irq); - if (p->irq != PARPORT_DMA_NONE) + if (p->dma == PARPORT_DMA_AUTO) + p->dma = (p->modes & PARPORT_MODE_PCECP)? + parport_dma_probe(p):PARPORT_DMA_NONE; + if (p->dma != PARPORT_DMA_NONE) printk(", dma %d", p->dma); printk(" ["); #define printmode(x) {if(p->modes&PARPORT_MODE_PC##x){printk("%s%s",f?",":"",#x);f++;}} @@ -835,6 +840,7 @@ static int probe_one_port(unsigned long int base, int irq, int dma) } #undef printmode printk("]\n"); + parport_proc_register(p); return 1; } @@ -868,7 +874,7 @@ MODULE_PARM(dma, "1-" __MODULE_STRING(PC_MAX_PORTS) "i"); static int init_module(void) { - return (parport_pc_init(NULL, NULL, NULL)?0:1); + return (parport_pc_init(io, irq, dma)?0:1); } static void cleanup_module(void) @@ -878,6 +884,8 @@ static void cleanup_module(void) if (p->modes & PARPORT_MODE_PCSPP) { if (!(p->flags & PARPORT_FLAG_COMA)) parport_quiesce(p); + parport_proc_unregister(p); + parport_unregister_port(p); } p = p->next; } diff --git a/drivers/misc/parport_procfs.c b/drivers/misc/parport_procfs.c index 503916bfb797..ca5ef4b37181 100644 --- a/drivers/misc/parport_procfs.c +++ b/drivers/misc/parport_procfs.c @@ -8,6 +8,7 @@ * and Philip Blundell */ +#include #include #include #include @@ -130,7 +131,10 @@ static int hardware_read_proc(char *page, char **start, off_t off, len += sprintf(page+len, "irq:\tnone\n"); else len += sprintf(page+len, "irq:\t%d\n",pp->irq); - len += sprintf(page+len, "dma:\t%d\n",pp->dma); + if (pp->dma == PARPORT_DMA_NONE) + len += sprintf(page+len, "dma:\tnone\n"); + else + len += sprintf(page+len, "dma:\t%d\n",pp->dma); #if 0 diff --git a/drivers/misc/parport_share.c b/drivers/misc/parport_share.c index ea9402df999e..7ba75f696418 100644 --- a/drivers/misc/parport_share.c +++ b/drivers/misc/parport_share.c @@ -88,6 +88,23 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, return tmp; } +void parport_unregister_port(struct parport *port) +{ + struct parport *p; + kfree(port->name); + if (portlist == port) { + portlist = port->next; + } else { + for (p = portlist; (p != NULL) && (p->next != port); + p=p->next); + if (p) { + if ((p->next = port->next) == NULL) + portlist_tail = p; + } + } + kfree(port); +} + void parport_quiesce(struct parport *port) { if (port->devices) { @@ -106,7 +123,7 @@ void parport_quiesce(struct parport *port) } struct pardevice *parport_register_device(struct parport *port, const char *name, - int (*pf)(void *), int (*kf)(void *), + int (*pf)(void *), void (*kf)(void *), void (*irq_func)(int, void *, struct pt_regs *), int flags, void *handle) { @@ -223,7 +240,6 @@ int parport_claim(struct pardevice *dev) pd1 = dev->port->cad; if (dev->port->cad) { if (dev->port->cad->preempt) { - /* Now try to preempt */ if (dev->port->cad->preempt(dev->port->cad->private)) return -EAGAIN; dev->port->ops->save_state(dev->port, dev->state); @@ -301,19 +317,10 @@ void parport_release(struct pardevice *dev) } /* Now give the lurker a chance. - * There should be a wakeup callback because we checked for it + * There must be a wakeup callback because we checked for it * at registration. */ if (dev->port->lurker && (dev->port->lurker != dev)) { - if (dev->port->lurker->wakeup) { - dev->port->lurker->wakeup(dev->port->lurker->private); - } -#ifdef PARPORT_PARANOID - else { /* can't happen */ - printk(KERN_DEBUG - "%s (%s): lurker's wakeup callback went away!\n", - dev->port->name, dev->name); - } -#endif + dev->port->lurker->wakeup(dev->port->lurker->private); } } diff --git a/drivers/net/plip.c b/drivers/net/plip.c index aaab86b24868..0b688b30870f 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1045,7 +1045,7 @@ plip_preempt(void *handle) return 0; } -static int +static void plip_wakeup(void *handle) { struct device *dev = (struct device *)handle; @@ -1058,12 +1058,12 @@ plip_wakeup(void *handle) /* bus_owner is already set (but why?) */ printk(KERN_DEBUG "%s: I'm broken.\n", dev->name); else - return 1; + return; } if (!(dev->flags & IFF_UP)) /* Don't need the port when the interface is down */ - return 1; + return; if (!parport_claim(nl->pardev)) { nl->port_owner = 1; @@ -1072,7 +1072,7 @@ plip_wakeup(void *handle) outb (0x00, PAR_DATA(dev)); } - return 0; + return; } static struct net_device_stats * diff --git a/drivers/pnp/parport_probe.c b/drivers/pnp/parport_probe.c index 8e841b8e5138..310dbf2bf43d 100644 --- a/drivers/pnp/parport_probe.c +++ b/drivers/pnp/parport_probe.c @@ -86,15 +86,15 @@ static long read_polled(struct parport *port, char *buf, static struct wait_queue *wait_q = NULL; -static int wakeup(void *ref) +static void wakeup(void *ref) { struct pardevice **dev = (struct pardevice **)ref; if (!wait_q || parport_claim(*dev)) - return 1; + return; wake_up(&wait_q); - return 0; + return; } int parport_probe(struct parport *port, char *buffer, int len) diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index b57345019446..84bef138566d 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -21,7 +21,14 @@ dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST $CONFIG_SCSI dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI -dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI +dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI +if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then + bool ' Enable tagged command queueing' CONFIG_AIC7XXX_TAGGED_QUEUEING Y + int ' Maximum number of commands per LUN' CONFIG_AIC7XXX_CMDS_PER_LUN 8 + bool ' Enable SCB paging' CONFIG_AIC7XXX_PAGE_ENABLE N + bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N + int ' delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 15 +fi dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI diff --git a/drivers/scsi/aic7xxx_seq.h b/drivers/scsi/aic7xxx_seq.h new file mode 100644 index 000000000000..dda2f7a63943 --- /dev/null +++ b/drivers/scsi/aic7xxx_seq.h @@ -0,0 +1,479 @@ +/* + * DO NOT EDIT - This file is automatically generated. + */ +static u_int8_t seqprog[] = { + 0xff, 0x6a, 0x03, 0x02, + 0x12, 0x6a, 0x00, 0x00, + 0x00, 0x65, 0x6f, 0x16, + 0x40, 0x0b, 0x3c, 0x1a, + 0x20, 0x0b, 0x37, 0x1a, + 0x40, 0x00, 0x03, 0x1a, + 0x08, 0x1f, 0x1f, 0x04, + 0x40, 0x0b, 0x3c, 0x1a, + 0x20, 0x0b, 0x37, 0x1a, + 0x40, 0x00, 0x03, 0x1a, + 0x08, 0x1f, 0x1f, 0x04, + 0xff, 0x48, 0x2c, 0x18, + 0xff, 0x40, 0x64, 0x02, + 0x00, 0x9c, 0x03, 0x1e, + 0x00, 0x6a, 0xaa, 0x17, + 0xff, 0x65, 0x03, 0x1c, + 0xff, 0x9b, 0x58, 0x02, + 0xff, 0x58, 0x90, 0x02, + 0x0d, 0x6a, 0x3d, 0x00, + 0x00, 0x58, 0x74, 0x17, + 0x28, 0xa0, 0x2a, 0x1a, + 0x50, 0x6a, 0x60, 0x00, + 0xff, 0x90, 0x4a, 0x02, + 0x00, 0xa1, 0x9e, 0x17, + 0xff, 0x6c, 0x59, 0x02, + 0xff, 0x59, 0x27, 0x1c, + 0xff, 0x4a, 0x90, 0x02, + 0x00, 0x65, 0xa7, 0x17, + 0x00, 0x6a, 0x4f, 0x17, + 0xff, 0x65, 0x1f, 0x18, + 0x51, 0x6a, 0x91, 0x00, + 0xff, 0x58, 0xb3, 0x02, + 0x00, 0x65, 0xb8, 0x17, + 0x10, 0x6a, 0x60, 0x00, + 0x00, 0x65, 0x03, 0x10, + 0xff, 0x59, 0x90, 0x02, + 0xff, 0x58, 0xb3, 0x02, + 0x10, 0x6a, 0x60, 0x00, + 0x00, 0x65, 0x03, 0x10, + 0xff, 0x58, 0x6d, 0x02, + 0xff, 0x4a, 0x90, 0x02, + 0x10, 0x6a, 0x60, 0x00, + 0xff, 0x48, 0xba, 0x02, + 0xff, 0x90, 0x48, 0x02, + 0xff, 0x48, 0x90, 0x02, + 0x00, 0x65, 0x2f, 0x16, + 0x00, 0x65, 0x03, 0x10, + 0xf7, 0x1f, 0x65, 0x02, + 0x08, 0xa1, 0x64, 0x02, + 0x00, 0x65, 0x65, 0x00, + 0xff, 0x65, 0x1f, 0x02, + 0xf0, 0xa1, 0x64, 0x02, + 0x0f, 0x05, 0x05, 0x02, + 0x00, 0x05, 0x05, 0x00, + 0x5a, 0x6a, 0x00, 0x01, + 0xff, 0x6a, 0x34, 0x02, + 0x20, 0x6a, 0x0b, 0x00, + 0xf0, 0x19, 0x42, 0x02, + 0x80, 0x41, 0x41, 0x00, + 0x00, 0x65, 0x4c, 0x10, + 0x12, 0x6a, 0x00, 0x00, + 0x40, 0x6a, 0x0b, 0x00, + 0xff, 0x48, 0x90, 0x02, + 0xff, 0xba, 0x48, 0x02, + 0xff, 0xa1, 0x42, 0x02, + 0x07, 0xa1, 0x35, 0x02, + 0x40, 0xa0, 0x64, 0x02, + 0x00, 0x35, 0x35, 0x00, + 0x80, 0x35, 0x35, 0x00, + 0x01, 0x6a, 0x34, 0x00, + 0x20, 0xa0, 0x4a, 0x1e, + 0x23, 0xa0, 0x36, 0x02, + 0xff, 0xb9, 0x37, 0x02, + 0x02, 0x34, 0x34, 0x06, + 0x80, 0xa0, 0x4c, 0x1e, + 0xa1, 0x6a, 0x91, 0x00, + 0x08, 0x6a, 0x0c, 0x00, + 0x08, 0x11, 0x11, 0x00, + 0x1a, 0x01, 0x01, 0x00, + 0x31, 0x6a, 0x65, 0x00, + 0x80, 0x42, 0x52, 0x1a, + 0xff, 0x65, 0x65, 0x06, + 0xff, 0x42, 0x6e, 0x02, + 0xff, 0x6e, 0x64, 0x02, + 0x00, 0x6c, 0x56, 0x1e, + 0x20, 0x01, 0x01, 0x00, + 0x4c, 0x42, 0x64, 0x0a, + 0x08, 0x1f, 0x5a, 0x1e, + 0x08, 0x42, 0x42, 0x00, + 0x08, 0x64, 0x64, 0x00, + 0x20, 0x64, 0x65, 0x06, + 0xff, 0x6c, 0x04, 0x02, + 0x01, 0x0c, 0x5c, 0x1e, + 0x04, 0x0c, 0x5c, 0x1a, + 0xe0, 0x03, 0x64, 0x02, + 0xff, 0x64, 0x4c, 0x02, + 0xff, 0x64, 0x03, 0x02, + 0x00, 0x6a, 0x74, 0x1c, + 0x40, 0x64, 0x79, 0x1c, + 0x80, 0x64, 0xa5, 0x1c, + 0xa0, 0x64, 0xb0, 0x1c, + 0xc0, 0x64, 0xad, 0x1c, + 0xe0, 0x64, 0xc3, 0x1c, + 0x01, 0x6a, 0x91, 0x00, + 0x00, 0x65, 0x5c, 0x10, + 0xf7, 0x11, 0x11, 0x02, + 0x00, 0x65, 0x6f, 0x16, + 0xff, 0x06, 0x6a, 0x02, + 0x09, 0x0c, 0x6c, 0x1e, + 0x08, 0x0c, 0x03, 0x1a, + 0x01, 0x6a, 0x91, 0x00, + 0xff, 0x6a, 0x93, 0x02, + 0xff, 0x6a, 0x04, 0x02, + 0xdf, 0x01, 0x01, 0x02, + 0x01, 0x6a, 0x4c, 0x00, + 0x0f, 0x41, 0x41, 0x03, + 0x7d, 0x6a, 0x3d, 0x00, + 0x00, 0x65, 0x7a, 0x10, + 0x08, 0x6a, 0x66, 0x00, + 0xa9, 0x6a, 0x71, 0x17, + 0x00, 0x65, 0x82, 0x10, + 0x79, 0x6a, 0x3d, 0x00, + 0x00, 0x65, 0x4c, 0x17, + 0x10, 0x41, 0x76, 0x1a, + 0x88, 0x6a, 0x66, 0x00, + 0xac, 0x6a, 0x6d, 0x17, + 0x00, 0x65, 0x6a, 0x17, + 0xff, 0xa3, 0x43, 0x02, + 0x44, 0x6a, 0x66, 0x00, + 0xa4, 0x6a, 0x70, 0x17, + 0xff, 0x43, 0x88, 0x1a, + 0x80, 0x02, 0x02, 0x00, + 0xff, 0x6a, 0x8c, 0x00, + 0xff, 0x6a, 0x8d, 0x00, + 0xff, 0x6a, 0x8e, 0x00, + 0x00, 0x65, 0x6a, 0x17, + 0x01, 0x43, 0x8a, 0x18, + 0xbf, 0x3d, 0x3d, 0x02, + 0x00, 0x3d, 0x41, 0x17, + 0x80, 0x02, 0xa2, 0x1a, + 0xff, 0x65, 0x9c, 0x1e, + 0xff, 0x43, 0x43, 0x06, + 0xff, 0x43, 0x9c, 0x1e, + 0xff, 0x6a, 0x64, 0x02, + 0x08, 0x44, 0x44, 0x06, + 0x00, 0x45, 0x45, 0x08, + 0x88, 0x6a, 0x66, 0x00, + 0x44, 0x6a, 0x70, 0x17, + 0x08, 0x6a, 0x8c, 0x00, + 0xff, 0x6a, 0x8d, 0x02, + 0xff, 0x6a, 0x8e, 0x02, + 0x0d, 0x93, 0x93, 0x00, + 0x00, 0x65, 0x9a, 0x17, + 0x88, 0x6a, 0x92, 0x17, + 0x00, 0x65, 0x6a, 0x17, + 0x10, 0x0c, 0x82, 0x1e, + 0xff, 0x08, 0xa9, 0x02, + 0xff, 0x09, 0xaa, 0x02, + 0xff, 0x0a, 0xab, 0x02, + 0xff, 0x43, 0xa8, 0x02, + 0x10, 0x41, 0x41, 0x00, + 0x00, 0x65, 0x5c, 0x10, + 0x7f, 0x02, 0x02, 0x02, + 0xe1, 0x6a, 0x91, 0x00, + 0x00, 0x65, 0x5c, 0x10, + 0x00, 0x65, 0x4c, 0x17, + 0x88, 0x6a, 0x66, 0x00, + 0xb4, 0x6a, 0x6f, 0x17, + 0xff, 0x6a, 0x8d, 0x02, + 0xff, 0x6a, 0x8e, 0x02, + 0x00, 0x65, 0x6a, 0x17, + 0x3d, 0x6a, 0x41, 0x17, + 0x00, 0x65, 0x5c, 0x10, + 0x00, 0x65, 0x4c, 0x17, + 0xff, 0x06, 0xa2, 0x02, + 0x00, 0x65, 0x5c, 0x10, + 0xff, 0x34, 0xb2, 0x1a, + 0x08, 0x6a, 0x2f, 0x17, + 0x35, 0x6a, 0x65, 0x00, + 0xff, 0x34, 0x66, 0x02, + 0x01, 0x0c, 0xb4, 0x1e, + 0x04, 0x0c, 0xb4, 0x1a, + 0xe0, 0x03, 0x4c, 0x02, + 0xa0, 0x4c, 0xc0, 0x18, + 0xff, 0x66, 0xbb, 0x1a, + 0x10, 0x4c, 0x03, 0x00, + 0x00, 0x65, 0xb2, 0x10, + 0x01, 0x66, 0xbd, 0x18, + 0x40, 0x6a, 0x0c, 0x00, + 0xff, 0x66, 0x66, 0x06, + 0xff, 0x6c, 0x06, 0x02, + 0x00, 0x65, 0xb4, 0x10, + 0x40, 0x6a, 0x0c, 0x00, + 0xff, 0x6a, 0x34, 0x02, + 0x00, 0x65, 0x5c, 0x10, + 0x64, 0x6a, 0x3c, 0x17, + 0xff, 0x64, 0x4b, 0x02, + 0x80, 0x64, 0x0b, 0x1b, + 0x04, 0x64, 0xfe, 0x1c, + 0x02, 0x64, 0x01, 0x1d, + 0x00, 0x6a, 0xd1, 0x1c, + 0x03, 0x64, 0x09, 0x1d, + 0x01, 0x64, 0xf2, 0x1c, + 0x07, 0x64, 0x2d, 0x1d, + 0x08, 0x64, 0xcf, 0x1c, + 0x11, 0x6a, 0x91, 0x00, + 0x07, 0x6a, 0x2f, 0x17, + 0xff, 0x06, 0x6a, 0x02, + 0x00, 0x65, 0x5c, 0x10, + 0xff, 0xa8, 0xd3, 0x1a, + 0xff, 0xa2, 0xda, 0x1e, + 0x01, 0x6a, 0x3d, 0x00, + 0x00, 0xb9, 0x74, 0x17, + 0xff, 0xa2, 0xda, 0x1e, + 0x71, 0x6a, 0x91, 0x00, + 0x40, 0x59, 0xda, 0x18, + 0xff, 0xb9, 0xb3, 0x02, + 0x00, 0x65, 0xe4, 0x10, + 0x20, 0xa0, 0xe0, 0x1a, + 0xff, 0x90, 0x4a, 0x02, + 0xff, 0xb3, 0x49, 0x02, + 0x00, 0xa1, 0x9e, 0x17, + 0xff, 0x49, 0x6d, 0x02, + 0xff, 0x4a, 0x90, 0x02, + 0xff, 0xb9, 0x9d, 0x02, + 0x02, 0x6a, 0x91, 0x00, + 0x08, 0xa0, 0xe4, 0x1e, + 0x91, 0x6a, 0x91, 0x00, + 0xff, 0xb3, 0xf0, 0x1c, + 0xff, 0xb3, 0x64, 0x02, + 0x00, 0xb9, 0xea, 0x1c, + 0x00, 0x65, 0xa7, 0x17, + 0xff, 0x64, 0x90, 0x02, + 0x00, 0x65, 0xec, 0x10, + 0x0d, 0x6a, 0x3d, 0x00, + 0x00, 0xb3, 0x74, 0x17, + 0xff, 0x48, 0xba, 0x02, + 0xff, 0x90, 0x48, 0x02, + 0x00, 0x65, 0x2f, 0x16, + 0x00, 0x65, 0x69, 0x10, + 0x00, 0x65, 0xa7, 0x17, + 0x00, 0x65, 0x69, 0x10, + 0x4d, 0x6a, 0x37, 0x17, + 0xff, 0x4d, 0x64, 0x02, + 0x00, 0x66, 0x37, 0x17, + 0xff, 0x64, 0x64, 0x06, + 0x52, 0x66, 0xf8, 0x18, + 0xff, 0x66, 0x66, 0x06, + 0xff, 0x64, 0xf4, 0x1a, + 0x41, 0x6a, 0x91, 0x00, + 0x20, 0x59, 0xcd, 0x1c, + 0x80, 0x59, 0xcf, 0x18, + 0x10, 0x4c, 0x03, 0x00, + 0x00, 0x65, 0xcf, 0x10, + 0x04, 0xa0, 0xa0, 0x00, + 0x00, 0x65, 0xb8, 0x17, + 0x00, 0x65, 0x69, 0x10, + 0x10, 0x41, 0xcf, 0x1e, + 0xff, 0x43, 0xa3, 0x02, + 0xa4, 0x6a, 0x66, 0x00, + 0x44, 0x6a, 0x70, 0x17, + 0xac, 0x6a, 0x66, 0x00, + 0x14, 0x6a, 0x70, 0x17, + 0xa9, 0x6a, 0x71, 0x17, + 0x00, 0x65, 0xcf, 0x10, + 0xef, 0x41, 0x41, 0x02, + 0x00, 0x65, 0xcf, 0x10, + 0x78, 0x64, 0xcd, 0x1a, + 0x07, 0x64, 0x64, 0x02, + 0x00, 0x42, 0x42, 0x00, + 0x00, 0x42, 0x9e, 0x17, + 0xff, 0x6c, 0x59, 0x02, + 0xff, 0x59, 0x25, 0x19, + 0xff, 0x59, 0x15, 0x1d, + 0xff, 0x59, 0x90, 0x02, + 0x04, 0xa0, 0x2a, 0x1f, + 0x00, 0x65, 0x27, 0x11, + 0xff, 0x06, 0x6a, 0x02, + 0x01, 0x0c, 0x16, 0x1f, + 0x04, 0x0c, 0x16, 0x1b, + 0xe0, 0x03, 0x4c, 0x02, + 0xe0, 0x4c, 0x2a, 0x19, + 0x20, 0x12, 0x2a, 0x19, + 0x20, 0x41, 0x41, 0x00, + 0x59, 0x6a, 0x37, 0x17, + 0xff, 0x3f, 0x64, 0x02, + 0x00, 0x59, 0x65, 0x06, + 0x00, 0x65, 0x2a, 0x13, + 0xff, 0x59, 0x90, 0x02, + 0xff, 0x42, 0x64, 0x02, + 0x00, 0xa1, 0x2a, 0x19, + 0x20, 0xa0, 0x2a, 0x1f, + 0x04, 0xa0, 0x2a, 0x1f, + 0x00, 0x6a, 0x4f, 0x17, + 0xff, 0x65, 0x2a, 0x1d, + 0xfb, 0xa0, 0xa0, 0x02, + 0x40, 0x41, 0x41, 0x00, + 0x00, 0x65, 0xcf, 0x10, + 0x31, 0x6a, 0x91, 0x00, + 0x0c, 0x6a, 0x2f, 0x17, + 0x00, 0x65, 0xcf, 0x10, + 0x61, 0x6a, 0x91, 0x00, + 0x00, 0x65, 0xcf, 0x10, + 0x50, 0x6a, 0x60, 0x00, + 0xff, 0x34, 0x33, 0x1f, + 0x10, 0x6a, 0x60, 0x00, + 0xc1, 0x6a, 0x91, 0x00, + 0x10, 0x4c, 0x03, 0x00, + 0x01, 0x6a, 0x34, 0x00, + 0xff, 0x65, 0x35, 0x02, + 0x10, 0x6a, 0x60, 0x01, + 0xff, 0x06, 0x6a, 0x02, + 0x01, 0x0c, 0x38, 0x1f, + 0x04, 0x0c, 0x38, 0x1b, + 0xe0, 0x03, 0x4c, 0x02, + 0xe0, 0x4c, 0x3f, 0x19, + 0xff, 0x65, 0x66, 0x02, + 0xff, 0x12, 0x6d, 0x03, + 0xff, 0x06, 0x6a, 0x03, + 0xd1, 0x6a, 0x91, 0x00, + 0x00, 0x65, 0x5c, 0x10, + 0xff, 0x65, 0x93, 0x02, + 0x01, 0x0b, 0x49, 0x1b, + 0x10, 0x0c, 0x42, 0x1f, + 0x04, 0x0b, 0x46, 0x1b, + 0xff, 0x6a, 0x65, 0x02, + 0x04, 0x93, 0x48, 0x1b, + 0x01, 0x94, 0x47, 0x1f, + 0x10, 0x94, 0x48, 0x1b, + 0xc7, 0x93, 0x93, 0x02, + 0x38, 0x93, 0x4a, 0x1b, + 0xff, 0x6a, 0x6a, 0x03, + 0x80, 0x41, 0x4b, 0x1f, + 0x40, 0x41, 0x4b, 0x1b, + 0x21, 0x6a, 0x91, 0x01, + 0xff, 0x65, 0x90, 0x02, + 0xff, 0x59, 0x64, 0x02, + 0x00, 0xb9, 0x53, 0x19, + 0x04, 0xa0, 0x5d, 0x1b, + 0x01, 0x65, 0x65, 0x06, + 0xff, 0x3e, 0x64, 0x02, + 0x00, 0x65, 0x4f, 0x19, + 0x00, 0x6a, 0xaa, 0x17, + 0x0d, 0x6a, 0x3d, 0x00, + 0x00, 0x59, 0x74, 0x17, + 0xff, 0xa8, 0x5b, 0x1f, + 0x10, 0xa0, 0xa0, 0x00, + 0x08, 0xa0, 0x4b, 0x1f, + 0xff, 0x6a, 0x65, 0x01, + 0x08, 0xa0, 0x5c, 0x1b, + 0xff, 0xba, 0x63, 0x1d, + 0xff, 0xbb, 0x49, 0x02, + 0xff, 0xba, 0x90, 0x02, + 0xff, 0x49, 0xbb, 0x02, + 0xff, 0x65, 0x90, 0x02, + 0xff, 0xbb, 0x68, 0x1d, + 0xff, 0xba, 0x49, 0x02, + 0xff, 0xbb, 0x90, 0x02, + 0xff, 0x49, 0xba, 0x02, + 0xff, 0x65, 0x90, 0x03, + 0xff, 0xba, 0x52, 0x03, + 0xff, 0x6a, 0x6a, 0x03, + 0xff, 0x8c, 0x08, 0x02, + 0xff, 0x8d, 0x09, 0x02, + 0xff, 0x8e, 0x0a, 0x03, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x02, + 0xff, 0x6c, 0x6d, 0x03, + 0x3d, 0x65, 0x66, 0x0a, + 0x55, 0x65, 0x64, 0x0a, + 0x00, 0x54, 0x88, 0x06, + 0xff, 0x66, 0x64, 0x02, + 0x00, 0x55, 0x89, 0x08, + 0xff, 0x6a, 0x64, 0x02, + 0x00, 0x56, 0x8a, 0x08, + 0x00, 0x57, 0x8b, 0x08, + 0x1c, 0x6a, 0x8c, 0x00, + 0xff, 0x6a, 0x8d, 0x02, + 0xff, 0x6a, 0x8e, 0x02, + 0xff, 0x3d, 0x93, 0x02, + 0x04, 0x3d, 0x8c, 0x1b, + 0xa0, 0x6a, 0x65, 0x00, + 0x1c, 0x65, 0x64, 0x06, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0xff, 0x6c, 0x99, 0x02, + 0x00, 0x65, 0x83, 0x19, + 0x0a, 0x93, 0x93, 0x00, + 0x00, 0x65, 0x9a, 0x17, + 0x04, 0x3d, 0x4b, 0x1f, + 0xa0, 0x6a, 0x92, 0x17, + 0x00, 0x65, 0x93, 0x17, + 0x00, 0x65, 0x93, 0x17, + 0x00, 0x65, 0x93, 0x11, + 0xff, 0x65, 0x66, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x02, + 0xff, 0x99, 0x6d, 0x03, + 0x08, 0x94, 0x9a, 0x1f, + 0xf7, 0x93, 0x93, 0x02, + 0x08, 0x93, 0x9c, 0x1b, + 0xff, 0x6a, 0x6a, 0x03, + 0xff, 0x65, 0x66, 0x02, + 0x4c, 0x66, 0x66, 0x0a, + 0x03, 0x66, 0x66, 0x02, + 0xbc, 0x66, 0x66, 0x06, + 0x6a, 0x65, 0x64, 0x0a, + 0x08, 0x65, 0xa5, 0x1f, + 0x02, 0x64, 0x64, 0x06, + 0xff, 0x64, 0x90, 0x02, + 0xff, 0x66, 0x65, 0x03, + 0xff, 0x53, 0xba, 0x02, + 0xff, 0x6a, 0xb9, 0x00, + 0xff, 0x90, 0x53, 0x03, + 0xff, 0x53, 0xb6, 0x19, + 0xff, 0x52, 0xad, 0x19, + 0xff, 0x6a, 0x65, 0x01, + 0xff, 0x52, 0x90, 0x02, + 0x10, 0xa0, 0xb1, 0x1f, + 0xef, 0xa0, 0xa0, 0x02, + 0x00, 0x65, 0xb3, 0x11, + 0xff, 0xa8, 0xb3, 0x1b, + 0xff, 0xb3, 0xb5, 0x1d, + 0x01, 0x6a, 0x3d, 0x00, + 0x00, 0xb9, 0x74, 0x17, + 0x00, 0x90, 0x5e, 0x11, + 0xff, 0x53, 0x90, 0x02, + 0xff, 0xba, 0x53, 0x03, + 0xff, 0x6a, 0xbb, 0x00, + 0xff, 0x52, 0xba, 0x02, + 0xff, 0x90, 0x52, 0x02, + 0xff, 0xba, 0x4b, 0x1d, + 0xff, 0xba, 0x90, 0x02, + 0xff, 0x52, 0xbb, 0x02, + 0xff, 0x52, 0x90, 0x03, +}; +#define ULTRA 0x8 +#define SCB_PAGING 0x4 +#define TWIN_CHANNEL 0x2 +struct patch { + int options; + int negative; + int begin; + int end; +} patches[] = { + { 0x00000002, 0, 0x006, 0x00b }, + { 0x00000004, 0, 0x00e, 0x010 }, + { 0x00000004, 1, 0x011, 0x012 }, + { 0x00000004, 0, 0x01a, 0x023 }, + { 0x00000004, 1, 0x023, 0x027 }, + { 0x00000002, 0, 0x02f, 0x033 }, + { 0x00000008, 0, 0x04f, 0x056 }, + { 0x00000004, 1, 0x0e5, 0x0ea }, + { 0x00000004, 0, 0x0ff, 0x100 }, + { 0x00000004, 0, 0x110, 0x111 }, + { 0x00000004, 1, 0x111, 0x115 }, + { 0x00000004, 1, 0x120, 0x125 }, + { 0x00000004, 0, 0x125, 0x127 }, + { 0x00000004, 0, 0x14f, 0x169 }, + { 0x00000004, 1, 0x169, 0x16a }, + { 0x00000004, 0, 0x1aa, 0x1bf }, + { 0x00000000, 0, 0x000, 0x000 } +}; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 618c65a0746d..c2895870342b 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -210,22 +210,22 @@ static int ppa_sg = SG_ALL; /* enable/disable scatter-gather. */ #define w_fifo(x,y) outb(y, PPA_BASE(x)+0x400) #define w_ecr(x,y) outb(y, PPA_BASE(x)+0x402) -int ppa_wakeup(void *ref) +static void ppa_wakeup(void *ref) { ppa_struct *ppa_dev = (ppa_struct *) ref; if (!ppa_dev->ppa_wait_q) - return 1; /* Wake up whom ? */ + return; /* Wake up whom ? */ /* Claim the Parport */ if (parport_claim(ppa_dev->dev)) - return 1; /* Shouldn't happen */ + return; /* Shouldn't happen */ wake_up(&ppa_dev->ppa_wait_q); - return 0; + return; } -int ppa_release(struct Scsi_Host *host) +static int ppa_release(struct Scsi_Host *host) { int host_no = host->unique_id; diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index 84fa2dec8e98..cdc2fdaa60c4 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -52,7 +52,7 @@ int ppa_abort(Scsi_Cmnd *); int ppa_reset(Scsi_Cmnd *, unsigned int); int ppa_proc_info(char *, char **, off_t, int, int, int); int ppa_biosparam(Disk *, kdev_t, int*); -int ppa_release(struct Scsi_Host *); +static int ppa_release(struct Scsi_Host *); #ifndef MODULE #ifdef PPA_CODE diff --git a/fs/dquot.c b/fs/dquot.c index 9f3d186b55e7..87196ab43f78 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -20,6 +20,8 @@ * Fixes: Dmitry Gorodchanin , 11 Feb 96 * removed race conditions in dqput(), dqget() and iput(). * Andi Kleen removed all verify_area() calls, 31 Dec 96 + * Nick Kralevich , 21 Jul 97 + * Fixed a condition where user and group quotas could get mixed up. * * (C) Copyright 1994, 1995 Marco van Wieringen * @@ -555,12 +557,14 @@ static struct dquot *dqget(kdev_t dev, unsigned int id, short type) repeat: dquot = *(hash(dev, id, type)); while (dquot) { - if (dquot->dq_dev != dev || dquot->dq_id != id) { + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) { dquot = dquot->dq_hash_next; continue; } wait_on_dquot(dquot); - if (dquot->dq_dev != dev || dquot->dq_id != id) + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) goto repeat; if (!dquot->dq_count) nr_free_dquots--; diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index d39c8a907b48..833f69ff9a64 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -290,8 +290,18 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err) struct ext2_group_desc * tmp; struct ext2_super_block * es; - if (!dir || !(inode = get_empty_inode ())) + /* Cannot create files in a deleted directory */ + if (!dir || !dir->i_nlink) { + *err = -EPERM; return NULL; + } + + inode = get_empty_inode (); + if (!inode) { + *err = -ENOMEM; + return NULL; + } + sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = sb->s_flags; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 5793c98988c0..05c036fc271b 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -905,10 +905,14 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry, goto end_rename; } retval = -EPERM; - if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->fsuid != new_inode->i_uid && - current->fsuid != new_dir->i_uid && !fsuser()) - goto end_rename; + if (new_inode) { + if ((new_dir->i_mode & S_ISVTX) && + current->fsuid != new_inode->i_uid && + current->fsuid != new_dir->i_uid && !fsuser()) + goto end_rename; + if (IS_APPEND(new_inode) || IS_IMMUTABLE(new_inode)) + goto end_rename; + } if (S_ISDIR(old_inode->i_mode)) { retval = -ENOTDIR; if (new_inode && !S_ISDIR(new_inode->i_mode)) diff --git a/fs/hpfs/hpfs_fs.c b/fs/hpfs/hpfs_fs.c index 70f293821b48..46ffcaed9f4a 100644 --- a/fs/hpfs/hpfs_fs.c +++ b/fs/hpfs/hpfs_fs.c @@ -1127,13 +1127,14 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) ino_t ino; const char *name = dentry->d_name.name; int len = dentry->d_name.len; + int retval; /* In case of madness */ if (dir == 0) return -ENOENT; if (!S_ISDIR(dir->i_mode)) - goto bail; + return -ENOENT; /* * Read in the directory entry. "." is there under the name ^A^A . @@ -1153,8 +1154,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) * This is not really a bailout, just means file not found. */ + inode = NULL; if (!de) - goto bail; + goto add_dentry; /* * Get inode number, what we're after. @@ -1169,8 +1171,9 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) * Go find or make an inode. */ + retval = -EACCES; if (!(inode = iget(dir->i_sb, ino))) - goto bail1; + goto free4; /* * Fill in the info from the directory if this is a newly created @@ -1195,24 +1198,16 @@ static int hpfs_lookup(struct inode *dir, struct dentry *dentry) } } - brelse4(&qbh); - /* - * Made it. + * Add the dentry, negative or otherwise. */ + add_dentry: + d_add(dentry, inode); + retval = 0; - d_instantiate(dentry, inode); - iput(dir); - return 0; - - /* - * Didn't. - */ - bail1: + free4: brelse4(&qbh); - bail: - iput(dir); - return -ENOENT; + return retval; } /* diff --git a/fs/inode.c b/fs/inode.c index 5bddf1b44471..4e719e3df098 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -224,7 +224,6 @@ static void dispose_list(struct list_head * head) break; inode = list_entry(tmp, struct inode, i_list); truncate_inode_pages(inode, 0); - list_del(&inode->i_list); } /* Add them all to the unused list in one fell swoop */ @@ -549,7 +548,22 @@ int fs_may_umount(struct super_block *sb, struct dentry * root) return root->d_count == 1; } +/* This belongs in file_table.c, not here... */ int fs_may_remount_ro(struct super_block *sb) { - return 1; + struct file *file; + kdev_t dev = sb->s_dev; + + /* Check that no files are currently opened for writing. */ + for (file = inuse_filps; file; file = file->f_next) { + struct inode *inode; + if (!file->f_dentry) + continue; + inode = file->f_dentry->d_inode; + if (!inode || inode->i_dev != dev) + continue; + if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE) + return 0; + } + return 1; /* Tis' cool bro. */ } diff --git a/fs/namei.c b/fs/namei.c index eccde207c5b3..89eaaeb795f2 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -834,6 +834,10 @@ static inline int do_unlink(const char * name) dir = lock_parent(dentry); + error = -ENOENT; + if (!dentry->d_inode) + goto exit_lock; + error = -EROFS; if (IS_RDONLY(dir)) goto exit_lock; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index fa057d862887..83546d460f34 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -417,6 +417,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode) if (!inode) return -EACCES; + nfs_invalidate_dircache(dir); d_instantiate(dentry, inode); return 0; } @@ -456,6 +457,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde if (!inode) return -EACCES; + nfs_invalidate_dircache(dir); d_instantiate(dentry, inode); return 0; } @@ -493,6 +495,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (!inode) return -EACCES; + nfs_invalidate_dircache(dir); d_instantiate(dentry, inode); return 0; } @@ -516,6 +519,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) if (error) return error; + nfs_invalidate_dircache(dir); d_delete(dentry); return 0; } @@ -543,6 +547,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) if (error) return error; + nfs_invalidate_dircache(dir); d_delete(dentry); return 0; } @@ -583,6 +588,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym if (!inode) return -EACCES; + nfs_invalidate_dircache(dir); d_instantiate(dentry, inode); return 0; } @@ -609,6 +615,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr if (error) return error; + nfs_invalidate_dircache(dir); inode->i_count++; d_instantiate(dentry, inode); return 0; @@ -652,6 +659,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (error) return error; + nfs_invalidate_dircache(old_dir); + nfs_invalidate_dircache(new_dir); + /* Update the dcache */ d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name); d_delete(new_dentry); diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index b3263b42d026..0ab88268d089 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -69,13 +69,14 @@ void vfat_put_super(struct super_block *sb) static struct super_operations vfat_sops = { vfat_read_inode, - fat_notify_change, fat_write_inode, fat_put_inode, + fat_delete_inode, + fat_notify_change, vfat_put_super, - NULL, /* added in 0.96c */ + NULL, /* write_super */ fat_statfs, - NULL + NULL /* remount */ }; static int parse_options(char *options, struct fat_mount_options *opts) @@ -227,7 +228,7 @@ static char bad_chars[] = "*?<>|\":/\\"; static char bad_if_strict[] = "+=,; []"; static char replace_chars[] = "[];,+="; -static int vfat_find(struct inode *dir,const char *name,int len, +static int vfat_find(struct inode *dir,struct qstr* name, int find_long,int new_filename,int is_dir, struct slot_info *sinfo_out); @@ -409,6 +410,7 @@ static int vfat_create_shortname(struct inode *dir, const char *name, char buf[8]; struct slot_info sinfo; const char *name_start; + struct qstr qname; PRINTK(("Entering vfat_create_shortname: name=%s, len=%d\n", name, len)); sz = 0; /* Make compiler happy */ @@ -427,7 +429,9 @@ static int vfat_create_shortname(struct inode *dir, const char *name, res = vfat_format_name('x', msdos_name, len, name_res, 1); if (res > -1) { PRINTK(("vfat_create_shortname 1\n")); - res = vfat_find(dir, msdos_name, len, 0, 0, 0, &sinfo); + qname.name=msdos_name; + qname.len=len; + res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); PRINTK(("vfat_create_shortname 2\n")); if (res > -1) return -EEXIST; return 0; @@ -516,7 +520,9 @@ static int vfat_create_shortname(struct inode *dir, const char *name, totlen = baselen + extlen + (extlen > 0); res = 0; if (MSDOS_SB(dir->i_sb)->options.numtail == 0) { - res = vfat_find(dir, msdos_name, totlen, 0, 0, 0, &sinfo); + qname.name=msdos_name; + qname.len=totlen; + res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); } i = 0; while (res > -1) { @@ -537,7 +543,9 @@ static int vfat_create_shortname(struct inode *dir, const char *name, strcpy(&msdos_name[baselen+sz+2], ext); totlen = baselen + sz + 1 + extlen + (extlen > 0); - res = vfat_find(dir, msdos_name, totlen, 0, 0, 0, &sinfo); + qname.name=msdos_name; + qname.len=totlen; + res = vfat_find(dir, &qname, 0, 0, 0, &sinfo); } res = vfat_format_name('x', msdos_name, totlen, name_res, 1); return res; @@ -803,7 +811,7 @@ static int vfat_readdir_cb( return -1; } -static int vfat_find(struct inode *dir,const char *name,int len, +static int vfat_find(struct inode *dir,struct qstr* qname, int find_long, int new_filename,int is_dir,struct slot_info *sinfo_out) { struct super_block *sb = dir->i_sb; @@ -820,8 +828,8 @@ static int vfat_find(struct inode *dir,const char *name,int len, PRINTK(("Entering vfat_find\n")); fil.f_pos = 0; - vf.name = name; - vf.len = len; + vf.name = qname->name; + vf.len = qname->len; vf.new_filename = new_filename; vf.found = 0; vf.posix = MSDOS_SB(sb)->options.posixfs; @@ -847,7 +855,8 @@ static int vfat_find(struct inode *dir,const char *name,int len, if (!vf.found && !new_filename) return -ENOENT; - res = vfat_build_slots(dir, name, len, ds, &slots, &is_long); + res = vfat_build_slots(dir, qname->name, qname->len, ds, + &slots, &is_long); if (res < 0) return res; de = (struct msdos_dir_entry *) ds; @@ -910,71 +919,54 @@ static int vfat_find(struct inode *dir,const char *name,int len, return -ENOENT; } -int vfat_lookup(struct inode *dir,const char *name,int len, - struct inode **result) +int vfat_lookup(struct inode *dir,struct dentry *dentry) { - int res, ino; + int res; struct inode *next; struct slot_info sinfo; + struct inode *result; - PRINTK (("vfat_lookup: name=%s, len=%d\n", name, len)); + PRINTK (("vfat_lookup: name=%s, len=%d\n", + dentry->d_name.name, dentry->d_name.len)); - *result = NULL; - if (!dir) return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - PRINTK (("vfat_lookup 2\n")); - if (len == 1 && name[0] == '.') { - *result = dir; + result = NULL; + if ((res = vfat_find(dir,&dentry->d_name,1,0,0,&sinfo)) < 0) { + d_add(dentry,NULL); return 0; } - if (len == 2 && name[0] == '.' && name[1] == '.') { - ino = fat_parent_ino(dir,0); - iput(dir); - if (ino < 0) return ino; - if (!(*result = iget(dir->i_sb,ino))) return -EACCES; - return 0; - } - PRINTK (("vfat_lookup 3\n")); - if ((res = vfat_find(dir,name,len,1,0,0,&sinfo)) < 0) { - iput(dir); - return res; - } PRINTK (("vfat_lookup 4.5\n")); - if (!(*result = iget(dir->i_sb,sinfo.ino))) { - iput(dir); + if (!(result = iget(dir->i_sb,sinfo.ino))) return -EACCES; - } PRINTK (("vfat_lookup 5\n")); - if (!(*result)->i_sb || - ((*result)->i_sb->s_magic != MSDOS_SUPER_MAGIC)) { + if (!result->i_sb || + (result->i_sb->s_magic != MSDOS_SUPER_MAGIC)) { /* crossed a mount point into a non-msdos fs */ - iput(dir); + d_add(dentry,result); return 0; } - if (MSDOS_I(*result)->i_busy) { /* mkdir in progress */ - iput(*result); - iput(dir); - return -ENOENT; + if (MSDOS_I(result)->i_busy) { /* mkdir in progress */ + iput(result); + d_add(dentry,NULL); + return 0; } PRINTK (("vfat_lookup 6\n")); - while (MSDOS_I(*result)->i_old) { - next = MSDOS_I(*result)->i_old; - iput(*result); - if (!(*result = iget(next->i_sb,next->i_ino))) { + while (MSDOS_I(result)->i_old) { + next = MSDOS_I(result)->i_old; + iput(result); + if (!(result = iget(next->i_sb,next->i_ino))) { fat_fs_panic(dir->i_sb,"vfat_lookup: Can't happen"); iput(dir); return -ENOENT; } } - iput(dir); + PRINTK (("vfat_lookup 7\n")); + d_add(dentry,result); + PRINTK (("vfat_lookup 8\n")); return 0; } -static int vfat_create_entry(struct inode *dir,const char *name,int len, +static int vfat_create_entry(struct inode *dir,struct qstr* qname, int is_dir, struct inode **result) { struct super_block *sb = dir->i_sb; @@ -984,8 +976,9 @@ static int vfat_create_entry(struct inode *dir,const char *name,int len, struct msdos_dir_entry *de; struct slot_info sinfo; + *result=0; PRINTK(("vfat_create_entry 1\n")); - res = vfat_find(dir, name, len, 1, 1, is_dir, &sinfo); + res = vfat_find(dir, qname, 1, 1, is_dir, &sinfo); if (res < 0) { return res; } @@ -1017,19 +1010,18 @@ static int vfat_create_entry(struct inode *dir,const char *name,int len, return 0; } -int vfat_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result) +int vfat_create(struct inode *dir,struct dentry* dentry,int mode) { int res; + struct inode *result; - if (!dir) return -ENOENT; - + result=NULL; fat_lock_creation(); - res = vfat_create_entry(dir,name,len,0,result); + res = vfat_create_entry(dir,&dentry->d_name,0,&result); if (res < 0) PRINTK(("vfat_create: unable to get new entry\n")); fat_unlock_creation(); - iput(dir); + d_instantiate(dentry,result); return res; } @@ -1148,115 +1140,107 @@ static int vfat_empty(struct inode *dir) } static int vfat_rmdir_free_ino(struct inode *dir,struct buffer_head *bh, - struct msdos_dir_entry *de,int ino) + struct msdos_dir_entry *de,struct dentry* dentry) { struct super_block *sb = dir->i_sb; - struct inode *inode; int res; - if (ino < 0) return -EINVAL; - if (!(inode = iget(dir->i_sb,ino))) return -ENOENT; - if (!S_ISDIR(inode->i_mode)) { - iput(inode); + if (!S_ISDIR(dentry->d_inode->i_mode)) { return -ENOTDIR; } - if (dir->i_dev != inode->i_dev || dir == inode) { - iput(inode); + if (dir->i_dev != dentry->d_inode->i_dev || dir == dentry->d_inode) { return -EBUSY; } - res = vfat_empty(inode); + res = vfat_empty(dentry->d_inode); if (res) { - iput(inode); return res; } - inode->i_nlink = 0; - inode->i_mtime = dir->i_mtime = CURRENT_TIME; - inode->i_atime = dir->i_atime = CURRENT_TIME; + dentry->d_inode->i_nlink = 0; + dentry->d_inode->i_mtime = dir->i_mtime = CURRENT_TIME; + dentry->d_inode->i_atime = dir->i_atime = CURRENT_TIME; dir->i_nlink--; mark_inode_dirty(dir); - mark_inode_dirty(inode); + mark_inode_dirty(dentry->d_inode); de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh, 1); - iput(inode); return 0; } static int vfat_unlink_free_ino(struct inode *dir,struct buffer_head *bh, - struct msdos_dir_entry *de,int ino,int nospc) + struct msdos_dir_entry *de,struct dentry* dentry,int nospc) { struct super_block *sb = dir->i_sb; - struct inode *inode; - if (!(inode = iget(dir->i_sb,ino))) return -ENOENT; - if ((!S_ISREG(inode->i_mode) && nospc) || IS_IMMUTABLE(inode)) { - iput(inode); + if ((!S_ISREG(dentry->d_inode->i_mode) && nospc) || + IS_IMMUTABLE(dentry->d_inode)) { return -EPERM; } - inode->i_nlink = 0; - inode->i_mtime = dir->i_mtime = CURRENT_TIME; - inode->i_atime = dir->i_atime = CURRENT_TIME; + dentry->d_inode->i_nlink = 0; + dentry->d_inode->i_mtime = dir->i_mtime = CURRENT_TIME; + dentry->d_inode->i_atime = dir->i_atime = CURRENT_TIME; dir->i_version = ++event; - MSDOS_I(inode)->i_busy = 1; + MSDOS_I(dentry->d_inode)->i_busy = 1; mark_inode_dirty(dir); - mark_inode_dirty(inode); + mark_inode_dirty(dentry->d_inode); de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh, 1); - iput(inode); return 0; } static int vfat_remove_entry(struct inode *dir,struct slot_info *sinfo, - struct buffer_head **bh,struct msdos_dir_entry **de, + struct buffer_head **bh,struct dentry* dentry, int is_dir,int nospc) { struct super_block *sb = dir->i_sb; loff_t offset; + struct msdos_dir_entry *de; int res, i; /* remove the shortname */ offset = sinfo->shortname_offset; - res = fat_get_entry(dir, &offset, bh, de); + res = fat_get_entry(dir, &offset, bh, &de); if (res < 0) return res; if (is_dir) { - res = vfat_rmdir_free_ino(dir,*bh,*de,res); + res = vfat_rmdir_free_ino(dir,*bh,de,dentry); } else { - res = vfat_unlink_free_ino(dir,*bh,*de,res,nospc); + res = vfat_unlink_free_ino(dir,*bh,de,dentry,nospc); } if (res < 0) return res; /* remove the longname */ offset = sinfo->longname_offset; for (i = sinfo->long_slots; i > 0; --i) { - res = fat_get_entry(dir, &offset, bh, de); + res = fat_get_entry(dir, &offset, bh, &de); if (res < 0) { printk("vfat_remove_entry: problem 1\n"); continue; } - (*de)->name[0] = DELETED_FLAG; - (*de)->attr = 0; + de->name[0] = DELETED_FLAG; + de->attr = 0; fat_mark_buffer_dirty(sb, *bh, 1); } return 0; } -static int vfat_rmdirx(struct inode *dir,const char *name,int len) +static int vfat_rmdirx(struct inode *dir,struct dentry* dentry) { struct super_block *sb = dir->i_sb; int res; struct buffer_head *bh; - struct msdos_dir_entry *de; struct slot_info sinfo; bh = NULL; res = -EPERM; - if (name[0] == '.' && (len == 1 || (len == 2 && name[1] == '.'))) + if (dentry->d_name.name[0] == '.' && + (dentry->d_name.len == 1 || (dentry->d_name.len == 2 && + dentry->d_name.name[1] == '.'))) goto rmdir_done; - res = vfat_find(dir,name,len,1,0,0,&sinfo); + res = vfat_find(dir,&dentry->d_name,1,0,0,&sinfo); if (res >= 0 && sinfo.total_slots > 0) { - res = vfat_remove_entry(dir,&sinfo,&bh,&de,1,0); + res = vfat_remove_entry(dir,&sinfo,&bh,dentry,1,0); if (res > 0) { res = 0; } @@ -1271,33 +1255,31 @@ rmdir_done: } /***** Remove a directory */ -int vfat_rmdir(struct inode *dir,const char *name,int len) +int vfat_rmdir(struct inode *dir,struct dentry* dentry) { int res; - res = vfat_rmdirx(dir, name, len); - iput(dir); + res = vfat_rmdirx(dir, dentry); + d_delete(dentry); return res; } static int vfat_unlinkx( struct inode *dir, - const char *name, - int len, + struct dentry* dentry, int nospc) /* Flag special file ? */ { struct super_block *sb = dir->i_sb; int res; struct buffer_head *bh; - struct msdos_dir_entry *de; struct slot_info sinfo; bh = NULL; - if ((res = vfat_find(dir,name,len,1,0,0,&sinfo)) < 0) + if ((res = vfat_find(dir,&dentry->d_name,1,0,0,&sinfo)) < 0) goto unlink_done; if (res >= 0 && sinfo.total_slots > 0) { - res = vfat_remove_entry(dir,&sinfo,&bh,&de,0,nospc); + res = vfat_remove_entry(dir,&sinfo,&bh,dentry,0,nospc); if (res > 0) { res = 0; } @@ -1311,15 +1293,14 @@ unlink_done: } -int vfat_mkdir(struct inode *dir,const char *name,int len,int mode) +int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode) { struct inode *inode; int res; fat_lock_creation(); - if ((res = vfat_create_entry(dir,name,len,1,&inode)) < 0) { + if ((res = vfat_create_entry(dir,&dentry->d_name,1,&inode)) < 0) { fat_unlock_creation(); - iput(dir); return res; } @@ -1330,28 +1311,27 @@ int vfat_mkdir(struct inode *dir,const char *name,int len,int mode) res = vfat_create_dotdirs(inode, dir); fat_unlock_creation(); MSDOS_I(inode)->i_busy = 0; - iput(inode); - iput(dir); + d_instantiate(dentry,inode); if (res < 0) { - if (vfat_rmdir(dir,name,len) < 0) + if (vfat_rmdir(dir,dentry) < 0) fat_fs_panic(dir->i_sb,"rmdir in mkdir failed"); } return res; } /***** Unlink, as called for msdosfs */ -int vfat_unlink(struct inode *dir,const char *name,int len) +int vfat_unlink(struct inode *dir,struct dentry* dentry) { int res; - res = vfat_unlinkx (dir,name,len,1); - iput(dir); + res = vfat_unlinkx (dir,dentry,1); + d_delete(dentry); return res; } -int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len) +int vfat_rename(struct inode *old_dir,struct dentry *old_dentry, + struct inode *new_dir,struct dentry *new_dentry) { struct super_block *sb = old_dir->i_sb; struct buffer_head *old_bh,*new_bh,*dotdot_bh; @@ -1364,13 +1344,15 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, struct slot_info sinfo; PRINTK(("vfat_rename 1\n")); - if (old_dir == new_dir && old_len == new_len && - strncmp(old_name, new_name, old_len) == 0) + if (old_dir == new_dir && + old_dentry->d_name.len == new_dentry->d_name.len && + strncmp(old_dentry->d_name.name, new_dentry->d_name.name, + old_dentry->d_name.len) == 0) return 0; old_bh = new_bh = NULL; old_inode = new_inode = NULL; - res = vfat_find(old_dir,old_name,old_len,1,0,0,&sinfo); + res = vfat_find(old_dir,&old_dentry->d_name,1,0,0,&sinfo); PRINTK(("vfat_rename 2\n")); if (res < 0) goto rename_done; @@ -1383,8 +1365,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, if (res < 0) goto rename_done; res = -ENOENT; - if (!(old_inode = iget(old_dir->i_sb,old_ino))) - goto rename_done; + old_inode = old_dentry->d_inode; is_dir = S_ISDIR(old_inode->i_mode); if (is_dir) { if ((old_dir->i_dev != new_dir->i_dev) || @@ -1413,7 +1394,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, iput(walk); } - res = vfat_find(new_dir,new_name,new_len,1,0,is_dir,&sinfo); + res = vfat_find(new_dir,&new_dentry->d_name,1,0,is_dir,&sinfo); PRINTK(("vfat_rename 4\n")); if (res > -1) { @@ -1432,12 +1413,12 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, iput(new_inode); if (new_is_dir) { PRINTK(("vfat_rename 7\n")); - res = vfat_rmdirx(new_dir,new_name,new_len); + res = vfat_rmdirx(new_dir,&new_dentry); PRINTK(("vfat_rename 8\n")); if (res < 0) goto rename_done; } else { PRINTK(("vfat_rename 9\n")); - res = vfat_unlinkx(new_dir,new_name,new_len,1); + res = vfat_unlinkx(new_dir,new_dentry,1); PRINTK(("vfat_rename 10\n")); if (res < 0) goto rename_done; } @@ -1445,7 +1426,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, PRINTK(("vfat_rename 11\n")); fat_lock_creation(); locked = 1; - res = vfat_find(new_dir,new_name,new_len,1,1,is_dir,&sinfo); + res = vfat_find(new_dir,&new_dentry->d_name,1,1,is_dir,&sinfo); PRINTK(("vfat_rename 12\n")); if (res < 0) goto rename_done; @@ -1524,6 +1505,8 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len, } if (res > 0) res = 0; + d_instantiate(new_dentry,new_inode); + d_delete(old_dentry); rename_done: if (locked) @@ -1532,10 +1515,6 @@ rename_done: fat_brelse(sb, old_bh); if (new_bh) fat_brelse(sb, new_bh); - if (old_inode) - iput(old_inode); - iput(old_dir); - iput(new_dir); return res; } @@ -1554,6 +1533,7 @@ struct inode_operations vfat_dir_inode_operations = { NULL, /* mknod */ vfat_rename, /* rename */ NULL, /* readlink */ + NULL, /* followlink */ NULL, /* readpage */ NULL, /* writepage */ fat_bmap, /* bmap */ diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index a3ea8815edec..dba07c796f88 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -7,7 +7,6 @@ #include #include #include -#include #include diff --git a/include/linux/parport.h b/include/linux/parport.h index 45c55f5a3f5f..3e1057729cfc 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -130,8 +130,7 @@ struct parport_device_info { * * 2) a wake-up function, called by the resource manager to tell drivers * that the port is available to be claimed. If a driver wants to use - * the port, it should call parport_claim() here. The return value from - * this function is ignored. + * the port, it should call parport_claim() here. */ /* A parallel port device */ @@ -187,6 +186,9 @@ struct parport { struct parport *parport_register_port(unsigned long base, int irq, int dma, struct parport_operations *ops); +/* Unregister a port. */ +void parport_unregister_port(struct parport *port); + /* parport_in_use returns nonzero if there are devices attached to a port. */ #define parport_in_use(x) ((x)->devices != NULL) @@ -209,7 +211,7 @@ struct parport *parport_enumerate(void); */ struct pardevice *parport_register_device(struct parport *port, const char *name, - int (*pf)(void *), int (*kf)(void *), + int (*pf)(void *), void (*kf)(void *), void (*irq_func)(int, void *, struct pt_regs *), int flags, void *handle); diff --git a/include/linux/sched.h b/include/linux/sched.h index 361498eadb4f..ffca93266fdd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -384,33 +384,36 @@ extern spinlock_t pidhash_lock; extern __inline__ void hash_pid(struct task_struct *p) { struct task_struct **htable = &pidhash[pid_hashfn(p->pid)]; + unsigned long flags; - spin_lock(&pidhash_lock); + spin_lock_irqsave(&pidhash_lock, flags); if((p->pidhash_next = *htable) != NULL) (*htable)->pidhash_pprev = &p->pidhash_next; *htable = p; p->pidhash_pprev = htable; - spin_unlock(&pidhash_lock); + spin_unlock_irqrestore(&pidhash_lock, flags); } extern __inline__ void unhash_pid(struct task_struct *p) { - spin_lock(&pidhash_lock); + unsigned long flags; + + spin_lock_irqsave(&pidhash_lock, flags); if(p->pidhash_next) p->pidhash_next->pidhash_pprev = p->pidhash_pprev; *p->pidhash_pprev = p->pidhash_next; - spin_unlock(&pidhash_lock); + spin_unlock_irqrestore(&pidhash_lock, flags); } extern __inline__ struct task_struct *find_task_by_pid(int pid) { - struct task_struct **htable = &pidhash[pid_hashfn(pid)]; - struct task_struct *p; + struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)]; + unsigned long flags; - spin_lock(&pidhash_lock); + spin_lock_irqsave(&pidhash_lock, flags); for(p = *htable; p && p->pid != pid; p = p->pidhash_next) ; - spin_unlock(&pidhash_lock); + spin_unlock_irqrestore(&pidhash_lock, flags); return p; } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index e4fe370fd7a9..5f5815e3d113 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -358,6 +358,9 @@ static struct sk_buff *ip_glue(struct ipq *qp) fp = fp->next; } + skb->pkt_type = qp->fragments->skb->pkt_type; + skb->protocol = qp->fragments->skb->protocol; + /* We glued together all fragments, so remove the queue entry. */ ip_free(qp); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 75346d6dc370..31e1258e8812 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -65,7 +65,8 @@ int ipip_rcv(struct sk_buff *skb, unsigned short len) /* * Discard the original IP header */ - + + skb->mac.raw = skb->data; skb_pull(skb, skb->h.raw - skb->nh.raw); /* -- 2.39.5