From 724170c9cea9669aa3b30643b64969bcdb4b3b5a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:18:12 -0500 Subject: [PATCH] Linux 2.2.2pre4 In a superhuman effort to not get killed by my wife, I delayed the latest release for a day. And in fact, it's still just a pre-release, because I wanted to check with Ingo that I have his latest IO-APIC code with the proper handling of ExtINT. Ingo? Anyway, the "not quite valentine days release" (also known as the "horny greased weasel", aka "presidents day" release ;), is right now a pre-patch on ftp.kernel.org: /pub/linux/kernel/testing/pre-patch-2.2.2-4.gz. Happily, I haven't heard of any new real show-stoppers, which is good (especially considering the fact that I gave it an extra week just to hear if somebody could come up with some new problems). The things fixed relative to 2.2.1 are: - the inode thing. If you don't know, don't worry. - config scripts updated - IO-APIC cleanups and fixes, so that people with strange motherboards should be able to reboot cleanly and not get unexpected interrupts. - 2kB sector media (ie mostly MO) fixes. See all the warnings on the lists about fdisk confusion etc if you have one of these things. - IDE disk cleanups/fixes (geometry and autodetection) - PS/2 mouse hides ACK's again - pty crash fix - some network driver fixes (out-of-memory and shared interrupts) - some sound and video updates. - lockd cookie fixes - nfsd readdir reply cache fix - filesystem/VM deadlock avoidance (new deamon: kpiod) - SMP scheduler race condition (which nobody has probably ever seen) - TCP socket locking fix Most of the above are really hard to see in the first place, and not something most people would ever hit (with the possible exception of the inode thang). But it would be good to have a really rock solid 2.2.2, so if people could just bother to check that it works for them, and I'll make this official tomorrow. Linus --- CREDITS | 7 ++ Documentation/Configure.help | 7 +- Documentation/fb/vesafb.txt | 4 +- Documentation/proc.txt | 12 +- Documentation/video4linux/bttv/INSTALL | 3 + Documentation/video4linux/bttv/README.FIRST | 2 +- MAINTAINERS | 6 + drivers/block/ide-probe.c | 4 + drivers/block/ide.h | 1 + drivers/char/bttv.c | 2 + drivers/char/pc_keyb.c | 116 +++++++++++++------- drivers/char/pc_keyb.h | 6 +- drivers/char/pty.c | 2 +- drivers/net/defxx.c | 32 ++++-- drivers/net/eepro100.c | 7 +- drivers/net/smc-ultra.c | 2 + drivers/net/syncppp.c | 20 ++++ drivers/net/syncppp.h | 1 + drivers/net/tlan.c | 42 ++++--- drivers/net/z85230.c | 31 +++++- drivers/scsi/atp870u.c | 4 +- drivers/scsi/ide-scsi.c | 9 +- drivers/scsi/imm.c | 23 ++-- drivers/scsi/ncr53c8xx.c | 2 + drivers/scsi/ppa.h | 2 +- drivers/scsi/sd.c | 4 +- drivers/sound/sb_ess.c | 5 +- drivers/sound/sound_core.c | 10 +- fs/affs/inode.c | 2 +- fs/buffer.c | 29 +++-- fs/coda/sysctl.c | 11 ++ fs/inode.c | 57 ++++++---- fs/lockd/clntproc.c | 52 +++++++-- fs/lockd/svc.c | 3 +- fs/lockd/svclock.c | 26 +++-- fs/lockd/svcproc.c | 3 +- fs/lockd/xdr.c | 50 +++++---- include/linux/fs.h | 1 + include/linux/lockd/lockd.h | 2 +- include/linux/lockd/xdr.h | 15 ++- include/linux/smb_fs.h | 2 +- kernel/sched.c | 3 +- kernel/sysctl.c | 19 ++-- mm/filemap.c | 25 +++-- net/Makefile | 2 + net/core/skbuff.c | 6 + net/ipv4/fib_semantics.c | 2 +- net/ipv4/ip_masq_mfw.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/proc.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_ipv4.c | 4 +- net/ipv6/tcp_ipv6.c | 24 ++-- net/sunrpc/svcsock.c | 9 +- scripts/ver_linux | 1 + 55 files changed, 485 insertions(+), 237 deletions(-) diff --git a/CREDITS b/CREDITS index 3edb6965a969..3984ee2778bd 100644 --- a/CREDITS +++ b/CREDITS @@ -1403,6 +1403,13 @@ S: Dragonvagen 1 A 13 S: FIN-00330 Helsingfors S: Finland +N: Trond Myklebust +E: trond.myklebust@fys.uio.no +D: current NFS client hacker. +S: Dagaliveien 31e +S: N-0391 Oslo +S: Norway + N: Matija Nalis E: mnalis@jagor.srce.hr E: mnalis@voyager.hr diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 404ed6b1aacf..bc1ccb663e24 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -2330,8 +2330,8 @@ CONFIG_IP_FIREWALL IP: firewall packet netlink device CONFIG_IP_FIREWALL_NETLINK - If you say Y here, then the first 128 bytes of each packet that hit - your Linux firewall and was blocked are passed on to optional user + If you say Y here, you can use the ipchains tool to copy all or part of + any packet you specify that hits your Linux firewall to optional user space monitoring software that can then look for attacks and take actions such as paging the administrator of the site. @@ -2340,9 +2340,6 @@ CONFIG_IP_FIREWALL_NETLINK and you need (to write) a program that reads from that device and takes appropriate action. - With the ipchains tool you can specify which packets you want to go - to this device, as well as how many bytes from each packet. - IP: kernel level autoconfiguration CONFIG_IP_PNP This enables automatic configuration of IP addresses of devices and diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt index 999d8b030fe0..22408703d3b8 100644 --- a/Documentation/fb/vesafb.txt +++ b/Documentation/fb/vesafb.txt @@ -11,7 +11,7 @@ of the BIOS, and use this as framebuffer device /dev/fb0, like the m68k This means we decide at boot time whenever we want to run in text or graphics mode. Switching mode later on (in protected mode) is impossible; BIOS calls work in real mode only. VESA BIOS Extentions -Version 2.0 are required, becauce we need a linear frame buffer. +Version 2.0 are required, because we need a linear frame buffer. Advantages: @@ -75,7 +75,7 @@ Extentions v2.0 are required, 1.2 is NOT sufficient. You will get a 1. Note: LILO cannot handle hex, for booting directly with "vga=mode-number" you have to transform the numbers to decimal. 2. Note: Some newer versions of LILO appear to work with those hex values, - if you set the 0x infront of the numbers. + if you set the 0x in front of the numbers. X11 === diff --git a/Documentation/proc.txt b/Documentation/proc.txt index 20ea0d8ba2d6..ef2246d02935 100644 --- a/Documentation/proc.txt +++ b/Documentation/proc.txt @@ -50,7 +50,7 @@ available sources to write this chapter, it seems only fair to give the work back to the Linux community. This work is based on the 2.1.132 and 2.2.0-pre-kernel versions. I'm afraid it's still far from complete, but we hope it will be useful. As far as we know, it is the -first 'all-in-one’ document about the /proc file system. It is +first 'all-in-one' document about the /proc file system. It is focused on the Intel x86 hardware, so if you are looking for PPC, ARM, SPARC, APX, etc., features, you probably won't find what you are looking for. It also only covers IPv4 networking, not IPv6 nor other @@ -657,7 +657,7 @@ printk sg-big-buff This file shows the size of the generic SCSI (sg) buffer. At this - point, you can’t tune it yet, but you can change it at compile time + point, you can't tune it yet, but you can change it at compile time by editing include/scsi/sg.h and changing the value of SG_BIG_BUFF. @@ -794,9 +794,9 @@ kswapd swap_cluster This is probably the greatest influence on system performance. swap_cluster is the number of pages kswapd writes in - one turn. You’ll want this value to be large so that kswapd does - its I/O in large chunks and the disk doesn’t have to seek as - often., but you don’t want it to be too large since that would + one turn. You'll want this value to be large so that kswapd does + its I/O in large chunks and the disk doesn't have to seek as + often., but you don't want it to be too large since that would flood the request queue. overcommit_memory @@ -1140,7 +1140,7 @@ accept_redirects accept_source_route Should source routed packages be accepted or declined. The default is dependent on the kernel configuration. It's 'yes' for - routers and 'np' for hosts. + routers and 'no' for hosts. bootp_relay Accept packets with source address 0.b.c.d destined not to this diff --git a/Documentation/video4linux/bttv/INSTALL b/Documentation/video4linux/bttv/INSTALL index 9b5de6cb6545..c42560dbfadc 100644 --- a/Documentation/video4linux/bttv/INSTALL +++ b/Documentation/video4linux/bttv/INSTALL @@ -41,6 +41,9 @@ 10: Newer Hauppage (Bt878) 11: Miro PCTV Pro 12: ADS Tech Channel Surfer TV (and maybe TV+FM) + 13: AVerMedia TVCapture 98 + 14: Aimslab VHX + 15: Zoltrix TV-Max - You may have to adjust BTTV_MAJOR to a different number depending on your kernel version. The official number 81 does not work on some setups. diff --git a/Documentation/video4linux/bttv/README.FIRST b/Documentation/video4linux/bttv/README.FIRST index ea68726a64e0..2029ab5213ed 100644 --- a/Documentation/video4linux/bttv/README.FIRST +++ b/Documentation/video4linux/bttv/README.FIRST @@ -1,4 +1,4 @@ o Please direct queries about the in kernel version of this driver to Alan Cox first not to Ralph, or better yet join the video4linux mailing - list (mail majordomo@phunk.org with "subscribe video4linux") + list (mail video4linux-list-request@redhat.com with "subscribe") diff --git a/MAINTAINERS b/MAINTAINERS index 6030898f5dce..9520dc5ef934 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -530,6 +530,12 @@ M: kuznet@ms2.inr.ac.ru L: netdev@roxanne.nuclecu.unam.mx S: Maintained +NFS CLIENT +P: Trond Myklebust +M: trond.myklebust@fys.uio.no +L: linux-kernel@vger.rutgers.edu +S: Maintained + NI5010 NETWORK DRIVER P: Jan-Pascal van Best and Andreas Mohr M: jvbest@qv3pluto.leidenuniv.nl (Best) diff --git a/drivers/block/ide-probe.c b/drivers/block/ide-probe.c index 2cf54ce334dd..f2ed73f31a62 100644 --- a/drivers/block/ide-probe.c +++ b/drivers/block/ide-probe.c @@ -124,6 +124,10 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) case ide_tape: printk ("TAPE"); break; + case ide_optical: + printk ("OPTICAL"); + drive->removable = 1; + break; default: printk("UNKNOWN (type %d)", type); break; diff --git a/drivers/block/ide.h b/drivers/block/ide.h index f9c7bbbeb1df..b57dea3ba801 100644 --- a/drivers/block/ide.h +++ b/drivers/block/ide.h @@ -182,6 +182,7 @@ typedef unsigned char byte; /* used everywhere */ #define ide_scsi 0x21 #define ide_disk 0x20 +#define ide_optical 0x7 #define ide_cdrom 0x5 #define ide_tape 0x1 #define ide_floppy 0x0 diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index 86230813ab8f..c9ce18f018f8 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -537,6 +537,8 @@ static struct tvcard tvcards[] = { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0}, /* Aimslab VHX */ { 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}}, + /* Zoltrix TV-Max */ + { 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}}, }; #define TVCARDS (sizeof(tvcards)/sizeof(tvcard)) diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index b20d517b616d..b1793daf0890 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -10,6 +10,9 @@ * because they share the same hardware. * Johan Myreen 1998-10-08. * + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian 1999-01-29. + * */ #include @@ -74,6 +77,8 @@ static int __init psaux_init(void); static struct aux_queue *queue; /* Mouse data buffer. */ static int aux_count = 0; +/* used when we send commands to the mouse that expect an ACK. */ +static unsigned char mouse_reply_expected = 0; #define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) #define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) @@ -99,7 +104,7 @@ static int aux_count = 0; * Controller Status register are set 0." */ -static inline void kb_wait(void) +static void kb_wait(void) { unsigned long timeout = KBC_TIMEOUT; @@ -400,6 +405,33 @@ char pckbd_unexpected_up(unsigned char keycode) return 0200; } +static inline void handle_mouse_event(unsigned char scancode) +{ +#ifdef CONFIG_PSMOUSE + if (mouse_reply_expected) { + if (scancode == AUX_ACK) { + mouse_reply_expected--; + return; + } + mouse_reply_expected = 0; + } + + add_mouse_randomness(scancode); + if (aux_count) { + int head = queue->head; + + queue->buf[head] = scancode; + head = (head + 1) & (AUX_BUF_SIZE-1); + if (head != queue->tail) { + queue->head = head; + if (queue->fasync) + kill_fasync(queue->fasync, SIGIO); + wake_up_interruptible(&queue->proc_list); + } + } +#endif +} + /* * This reads the keyboard status port, and does the * appropriate action. @@ -417,21 +449,7 @@ static unsigned char handle_kbd_event(void) scancode = inb(KBD_DATA_REG); if (status & KBD_STAT_MOUSE_OBF) { -#ifdef CONFIG_PSMOUSE - /* Mouse data. */ - if (aux_count) { - int head = queue->head; - queue->buf[head] = scancode; - add_mouse_randomness(scancode); - head = (head + 1) & (AUX_BUF_SIZE-1); - if (head != queue->tail) { - queue->head = head; - if (queue->fasync) - kill_fasync(queue->fasync, SIGIO); - wake_up_interruptible(&queue->proc_list); - } - } -#endif + handle_mouse_event(scancode); } else { if (do_acknowledge(scancode)) handle_scancode(scancode); @@ -716,9 +734,7 @@ void __init pckbd_init_hw(void) static int __init detect_auxiliary_port(void) { unsigned long flags; - unsigned char status; - unsigned char val; - int loops = 5; + int loops = 10; int retval = 0; spin_lock_irqsave(&kbd_controller_lock, flags); @@ -736,20 +752,19 @@ static int __init detect_auxiliary_port(void) kb_wait(); outb(0x5a, KBD_DATA_REG); /* 0x5a is a random dummy value. */ - status = inb(KBD_STATUS_REG); - while (!(status & KBD_STAT_OBF) && loops--) { - mdelay(1); - status = inb(KBD_STATUS_REG); - } + do { + unsigned char status = inb(KBD_STATUS_REG); - if (status & KBD_STAT_OBF) { - val = inb(KBD_DATA_REG); - if (status & KBD_STAT_MOUSE_OBF) { - printk(KERN_INFO "Detected PS/2 Mouse Port.\n"); - retval = 1; + if (status & KBD_STAT_OBF) { + (void) inb(KBD_DATA_REG); + if (status & KBD_STAT_MOUSE_OBF) { + printk(KERN_INFO "Detected PS/2 Mouse Port.\n"); + retval = 1; + } + break; } - } - + mdelay(1); + } while (--loops); spin_unlock_irqrestore(&kbd_controller_lock, flags); return retval; @@ -770,16 +785,33 @@ static void aux_write_dev(int val) spin_unlock_irqrestore(&kbd_controller_lock, flags); } -static unsigned int get_from_queue(void) +/* + * Send a byte to the mouse & handle returned ack + */ +static void aux_write_ack(int val) +{ + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + kb_wait(); + outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); + kb_wait(); + outb(val, KBD_DATA_REG); + /* we expect an ACK in response. */ + mouse_reply_expected++; + kb_wait(); + spin_unlock_irqrestore(&kbd_controller_lock, flags); +} + +static unsigned char get_from_queue(void) { - unsigned int result; + unsigned char result; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&kbd_controller_lock, flags); result = queue->buf[queue->tail]; queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); - restore_flags(flags); + spin_unlock_irqrestore(&kbd_controller_lock, flags); return result; } @@ -834,7 +866,7 @@ static int open_aux(struct inode * inode, struct file * file) kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on controller. */ - aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */ + aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */ return 0; @@ -951,11 +983,11 @@ static int __init psaux_init(void) #ifdef INITIALIZE_MOUSE kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ - aux_write_dev(AUX_SET_SAMPLE); - aux_write_dev(100); /* 100 samples/sec */ - aux_write_dev(AUX_SET_RES); - aux_write_dev(3); /* 8 counts per mm */ - aux_write_dev(AUX_SET_SCALE21); /* 2:1 scaling */ + aux_write_ack(AUX_SET_SAMPLE); + aux_write_ack(100); /* 100 samples/sec */ + aux_write_ack(AUX_SET_RES); + aux_write_ack(3); /* 8 counts per mm */ + aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */ #endif /* INITIALIZE_MOUSE */ kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ diff --git a/drivers/char/pc_keyb.h b/drivers/char/pc_keyb.h index 37bfcd9e9b32..256b4788bbc2 100644 --- a/drivers/char/pc_keyb.h +++ b/drivers/char/pc_keyb.h @@ -114,8 +114,12 @@ extern unsigned char aux_device_present; #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ #define AUX_RESET 0xFF /* Reset aux device */ +#define AUX_ACK 0xFA /* Command byte ACK. */ -#define AUX_BUF_SIZE 2048 +#define AUX_BUF_SIZE 2048 /* This might be better divisible by + three to make overruns stay in sync + but then the read function would need + a lock etc - ick */ struct aux_queue { unsigned long head; diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 0b27057a17a6..48e81fc614ce 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -84,7 +84,6 @@ static void pty_close(struct tty_struct * tty, struct file * filp) wake_up_interruptible(&tty->link->write_wait); set_bit(TTY_OTHER_CLOSED, &tty->link->flags); if (tty->driver.subtype == PTY_TYPE_MASTER) { - tty_hangup(tty->link); set_bit(TTY_OTHER_CLOSED, &tty->flags); #ifdef CONFIG_UNIX98_PTYS { @@ -95,6 +94,7 @@ static void pty_close(struct tty_struct * tty, struct file * filp) } } #endif + tty_vhangup(tty->link); } } diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index abca38d8363e..c919cc96f80d 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -2881,6 +2881,22 @@ int dfx_hw_dma_uninit( return(DFX_K_SUCCESS); } + +/* + * Align an sk_buff to a boundary power of 2 + * + */ + +void my_skb_align(struct sk_buff *skb, int n) +{ + u32 x=(u32)skb->data; /* We only want the low bits .. */ + u32 v; + + v=(x+n-1)&~(n-1); /* Where we want to be */ + + skb_reserve(skb, v-x); +} + /* * ================ @@ -2950,8 +2966,8 @@ void dfx_rcv_init( * align to 128 bytes for compatibility with * the old EISA boards. */ - newskb->data = (char *)((unsigned long) - (newskb->data+127) & ~127); + + my_skb_align(newskb,128); bp->descr_block_virt->rcv_data[i+j].long_1 = virt_to_bus(newskb->data); /* * p_rcv_buff_va is only used inside the @@ -3062,10 +3078,10 @@ void dfx_rcv_queue_process( newskb = dev_alloc_skb(NEW_SKB_SIZE); if (newskb){ rx_in_place = 1; - - newskb->data = (char *)((unsigned long)(newskb->data+127) & ~127); + + my_skb_align(newskb, 128); skb = (struct sk_buff *)bp->p_rcv_buff_va[entry]; - skb->data += RCV_BUFF_K_PADDING; + skb_reserve(skb, RCV_BUFF_K_PADDING); bp->p_rcv_buff_va[entry] = (char *)newskb; bp->descr_block_virt->rcv_data[entry].long_1 = virt_to_bus(newskb->data); } else @@ -3088,9 +3104,9 @@ void dfx_rcv_queue_process( memcpy(skb->data, p_buff + RCV_BUFF_K_PADDING, pkt_len+3); } - - skb->data += 3; /* adjust data field so that it points to FC byte */ - skb->len = pkt_len; /* pass up packet length, NOT including CRC */ + + skb_reserve(skb,3); /* adjust data field so that it points to FC byte */ + skb_put(skb, pkt_len); /* pass up packet length, NOT including CRC */ skb->dev = bp->dev; /* pass up device pointer */ skb->protocol = fddi_type_trans(skb, bp->dev); diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 94546d995ac8..56858bc45ed5 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -842,9 +842,6 @@ speedo_open(struct device *dev) wait_for_cmd_done(ioaddr + SCBCmd); outw(CU_DUMPSTATS, ioaddr + SCBCmd); - /* No need to wait for the command unit to accept here. */ - if ((sp->phy[0] & 0x8000) == 0) - mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); /* * Request the IRQ last, after we have set up all data structures. @@ -855,6 +852,10 @@ speedo_open(struct device *dev) return -EAGAIN; } + /* No need to wait for the command unit to accept here. */ + if ((sp->phy[0] & 0x8000) == 0) + mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); + MOD_INC_USE_COUNT; /* Set the timer. The timer serves a dual purpose: diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index dbb30af09f3d..75c0f35019c2 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -440,6 +440,8 @@ static int irq[MAX_ULTRA_CARDS] = { 0, }; MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); +EXPORT_NO_SYMBOLS; + /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ int diff --git a/drivers/net/syncppp.c b/drivers/net/syncppp.c index 328878c730a7..d2daea0a3020 100644 --- a/drivers/net/syncppp.c +++ b/drivers/net/syncppp.c @@ -380,6 +380,7 @@ static void sppp_keepalive (unsigned long dummy) if_down (dev); if (! (sp->pp_flags & PP_CISCO)) { /* Shut down the PPP link. */ + sp->lcp.magic = jiffies; sp->lcp.state = LCP_STATE_CLOSED; sp->ipcp.state = IPCP_STATE_CLOSED; sppp_clear_timeout (sp); @@ -842,6 +843,25 @@ int sppp_open (struct device *dev) EXPORT_SYMBOL(sppp_open); +int sppp_reopen (struct device *dev) +{ + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + sppp_close(dev); + dev->flags |= IFF_RUNNING; + if (!(sp->pp_flags & PP_CISCO)) + { + sp->lcp.magic = jiffies; + ++sp->pp_seq; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Give it a moment for the line to settle then go */ + sppp_set_timeout (sp, 1); + } + return 0; +} + +EXPORT_SYMBOL(sppp_reopen); + int sppp_change_mtu(struct device *dev, int new_mtu) { if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP)) diff --git a/drivers/net/syncppp.h b/drivers/net/syncppp.h index 1309bc9728e5..98f16aa0c40a 100644 --- a/drivers/net/syncppp.h +++ b/drivers/net/syncppp.h @@ -80,6 +80,7 @@ struct sk_buff *sppp_dequeue (struct device *dev); int sppp_isempty (struct device *dev); void sppp_flush (struct device *dev); int sppp_open (struct device *dev); +int sppp_reopen (struct device *dev); int sppp_close (struct device *dev); #endif diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index d3d2fba46ef2..8094f8b801a0 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -29,6 +29,8 @@ * * Tigran Aivazian : TLan_PciProbe() now uses * new PCI BIOS interface. + * Alan Cox : Fixed the out of memory + * handling. * ********************************************************************/ @@ -1250,28 +1252,36 @@ u32 TLan_HandleRxEOF( struct device *dev, u16 host_int ) netif_rx( skb ); } } else { - skb = (struct sk_buff *) head_list->buffer[9].address; - head_list->buffer[9].address = 0; - skb_trim( skb, head_list->frameSize ); - + struct sk_buff *new_skb; + + /* + * I changed the algorithm here. What we now do + * is allocate the new frame. If this fails we + * simply recycle the frame. + */ + + new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 ); + if ( new_skb != NULL ) { + /* If this ever happened it would be a problem */ + /* not any more - ac */ + skb = (struct sk_buff *) head_list->buffer[9].address; + head_list->buffer[9].address = 0; + skb_trim( skb, head_list->frameSize ); #if LINUX_KERNEL_VERSION > 0x20100 priv->stats->rx_bytes += head_list->frameSize; #endif - skb->protocol = eth_type_trans( skb, dev ); - netif_rx( skb ); - - skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 ); - if ( skb == NULL ) { - printk( "TLAN: Couldn't allocate memory for received data.\n" ); - /* If this ever happened it would be a problem */ - } else { - skb->dev = dev; - skb_reserve( skb, 2 ); - t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE ); + skb->protocol = eth_type_trans( skb, dev ); + netif_rx( skb ); + + new_skb->dev = dev; + skb_reserve( new_skb, 2 ); + t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE ); head_list->buffer[0].address = virt_to_bus( t ); - head_list->buffer[9].address = (u32) skb; + head_list->buffer[9].address = (u32) new_skb; } + else + printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" ); } head_list->forward = 0; diff --git a/drivers/net/z85230.c b/drivers/net/z85230.c index 7e7cc5d14f1d..aea2aef27edc 100644 --- a/drivers/net/z85230.c +++ b/drivers/net/z85230.c @@ -349,6 +349,7 @@ static void z8530_status(struct z8530_channel *chan) if(status&TxEOM) { /* printk("%s: Tx underrun.\n", chan->dev->name); */ + chan->stats.tx_fifo_errors++; write_zsctrl(chan, ERR_RES); z8530_tx_done(chan); } @@ -359,6 +360,8 @@ static void z8530_status(struct z8530_channel *chan) { printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3]|RxENABLE); + if(chan->netdevice) + sppp_reopen(chan->netdevice); } else { @@ -450,6 +453,8 @@ static void z8530_dma_status(struct z8530_channel *chan) { printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); write_zsreg(chan, R3, chan->regs[3]|RxENABLE); + if(chan->netdevice) + sppp_reopen(chan->netdevice); } else { @@ -1107,6 +1112,14 @@ static void z8530_tx_begin(struct z8530_channel *c) { flags=claim_dma_lock(); disable_dma(c->txdma); + /* + * Check if we crapped out. + */ + if(get_dma_residue(c->txdma)) + { + c->stats.tx_dropped++; + c->stats.tx_fifo_errors++; + } release_dma_lock(flags); } c->txcount=0; @@ -1133,6 +1146,7 @@ static void z8530_tx_begin(struct z8530_channel *c) set_dma_count(c->txdma, c->txcount); enable_dma(c->txdma); release_dma_lock(flags); + write_zsctrl(c, RES_EOM_L); write_zsreg(c, R5, c->regs[R5]|TxENAB); } else @@ -1173,6 +1187,8 @@ static void z8530_tx_done(struct z8530_channel *c) c->tx_skb=NULL; z8530_tx_begin(c); spin_unlock_irqrestore(&z8530_buffer_lock, flags); + c->stats.tx_packets++; + c->stats.tx_bytes+=skb->len; dev_kfree_skb(skb); } @@ -1255,11 +1271,16 @@ static void z8530_rx_done(struct z8530_channel *c) skb=dev_alloc_skb(ct); if(skb==NULL) - printk("%s: Memory squeeze.\n", c->netdevice->name); + { + c->stats.rx_dropped++; + printk(KERN_WARNING "%s: Memory squeeze.\n", c->netdevice->name); + } else { skb_put(skb, ct); memcpy(skb->data, rxb, ct); + c->stats.rx_packets++; + c->stats.rx_bytes+=ct; } c->dma_ready=1; } @@ -1305,6 +1326,9 @@ static void z8530_rx_done(struct z8530_channel *c) { skb_put(c->skb2,c->mtu); } + c->stats.rx_packets++; + c->stats.rx_bytes+=ct; + } /* * If we received a frame we must now process it. @@ -1315,7 +1339,10 @@ static void z8530_rx_done(struct z8530_channel *c) c->rx_function(c,skb); } else - printk("Lost a frame\n"); + { + c->stats.rx_dropped++; + printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name); + } } /* diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 96280a8c3931..1d253608bad7 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1720,8 +1720,8 @@ int atp870u_detect(Scsi_Host_Template * tpnt) h=0; while ( devid[h] != 0 ) { - pci_find_device(0x1191,devid[h],pdev); - if (pdev == NULL); { + pdev = pci_find_device(0x1191,devid[h],pdev); + if (pdev == NULL) { h++; index=0; continue; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 4f7315e04d33..83ff0fd850fc 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -23,8 +23,9 @@ * Ver 0.6 Jan 27 98 Allow disabling of SCSI command translation layer * for access through /dev/sg. * Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation. - * Ver 0.7 Dev 04 98 Ignore commands where lun != 0 to avoid multiple + * Ver 0.7 Dec 04 98 Ignore commands where lun != 0 to avoid multiple * detection of devices with CONFIG_SCSI_MULTI_LUN + * Ver 0.8 Feb 05 99 Optical media need translation too. */ #define IDESCSI_VERSION "0.6" @@ -178,7 +179,7 @@ static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc) if (!test_bit(PC_TRANSFORM, &pc->flags)) return; - if (drive->media == ide_cdrom) { + if (drive->media == ide_cdrom || drive->media == ide_optical) { if (c[0] == READ_6 || c[0] == WRITE_6) { c[8] = c[4]; c[5] = c[3]; c[4] = c[2]; c[3] = c[1] & 0x1f; c[2] = 0; c[1] &= 0xe0; @@ -217,7 +218,7 @@ static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc) if (!test_bit(PC_TRANSFORM, &pc->flags)) return; - if (drive->media == ide_cdrom) { + if (drive->media == ide_cdrom || drive->media == ide_optical) { if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) { scsi_buf[0] = atapi_buf[1]; /* Mode data length */ scsi_buf[1] = atapi_buf[2]; /* Medium type */ @@ -794,7 +795,7 @@ int idescsi_abort (Scsi_Cmnd *cmd) int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags) { - return SCSI_RESET_PUNT; + return SCSI_RESET_SUCCESS; } int idescsi_bios (Disk *disk, kdev_t dev, int *parm) diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index deddc28ba8f5..beda7319efd0 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1204,19 +1204,16 @@ static int device_check(int host_no) status = imm_out(host_no, &cmd[l << 1], 2); if (!status) { - imm_disconnect(host_no); - imm_connect(host_no, CONNECT_EPP_MAYBE); - w_dtr(ppb, 0x40); - w_ctr(ppb, 0x08); - udelay(30); - w_ctr(ppb, 0x0c); - udelay(1000); - imm_disconnect(host_no); - udelay(1000); - if (imm_hosts[host_no].mode == IMM_EPP_32) { - imm_hosts[host_no].mode = old_mode; - goto second_pass; - } + imm_disconnect(host_no); + imm_connect(host_no, CONNECT_EPP_MAYBE); + imm_reset_pulse(IMM_BASE(host_no)); + udelay(1000); + imm_disconnect(host_no); + udelay(1000); + if (imm_hosts[host_no].mode == IMM_EPP_32) { + imm_hosts[host_no].mode = old_mode; + goto second_pass; + } printk("imm: Unable to establish communication, aborting driver load.\n"); return 1; } diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 9196cbeacb52..d6cbbcded52b 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -9633,6 +9633,8 @@ static int ncr53c8xx_pci_init(Scsi_Host_Template *tpnt, base = pdev->base_address[1]; base_2 = pdev->base_address[2]; irq = pdev->irq; + if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) + base_2 = pdev->base_address[3]; #else (void) pcibios_read_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0, &io_port); diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index b3beb9f5d7b6..58aba3473e29 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -10,7 +10,7 @@ #ifndef _PPA_H #define _PPA_H -#define PPA_VERSION "2.03 (for Linux 2.0.0)" +#define PPA_VERSION "2.03 (for Linux 2.2.x)" /* * this driver has been hacked by Matteo Frigo (athena@theory.lcs.mit.edu) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 13f511b961dc..f67041c7b3bd 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -708,14 +708,14 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt) */ if (rscsi_disks[dev].sector_size == 1024) if((block & 1) || (SCpnt->request.nr_sectors & 1)) { - printk("sd.c:Bad block number requested"); + printk("sd.c:Bad block number/count requested"); SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); goto repeat; } if (rscsi_disks[dev].sector_size == 2048) if((block & 3) || (SCpnt->request.nr_sectors & 3)) { - printk("sd.c:Bad block number requested"); + printk("sd.c:Bad block number/count requested"); SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); goto repeat; } diff --git a/drivers/sound/sb_ess.c b/drivers/sound/sb_ess.c index 0d12349c4b8c..319addd4de9e 100644 --- a/drivers/sound/sb_ess.c +++ b/drivers/sound/sb_ess.c @@ -25,9 +25,9 @@ * Audio 1 and Audio 2 at the same time. * (Jan 9 1999): Put all ESS stuff into sb_ess.[ch], this * includes both the ESS stuff that has been in - * sb_*[ch] before I touched it and the ESS suppor + * sb_*[ch] before I touched it and the ESS support * I added later - * (Jan 23 1998): Full Duplex seems to work. I wrote a small + * (Jan 23 1999): Full Duplex seems to work. I wrote a small * test proggy which works OK. Haven't found * any applications to test it though. So why did * I bother to create it anyway?? :) Just for @@ -171,7 +171,6 @@ * ES1946 yes This is a PCI chip; not handled by this driver */ -#include #include #include "sound_config.h" diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index 95c332208476..115b9e33dd04 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -63,6 +63,10 @@ static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, int n=low; if (index < 0) { /* first free */ + + while (*list && (*list)->unit_minornext); + while(n=top) - return -ENOMEM; + return -ENOENT; } else { n = low+(index*16); while (*list) { @@ -141,13 +145,13 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f int r; struct sound_unit *s=(struct sound_unit *)kmalloc(sizeof(struct sound_unit), GFP_KERNEL); if(s==NULL) - return -1; + return -ENOMEM; spin_lock(&sound_loader_lock); r=__sound_insert_unit(s,list,fops,index,low,top); spin_unlock(&sound_loader_lock); - if(r==-1) + if(r<0) kfree(s); return r; } diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 80aad129c8d6..c23e3b1b94b9 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -293,7 +293,7 @@ affs_new_inode(const struct inode *dir) sb = dir->i_sb; inode->i_sb = sb; - inode->i_flags = sb->s_flags; + inode->i_flags = 0; if (!(block = affs_new_header((struct inode *)dir))) { iput(inode); diff --git a/fs/buffer.c b/fs/buffer.c index 2c874f742efd..a3c1936f4566 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -74,6 +74,7 @@ static struct wait_queue * buffer_wait = NULL; static int nr_buffers = 0; static int nr_buffers_type[NR_LIST] = {0,}; +static int size_buffers_type[NR_LIST] = {0,}; static int nr_buffer_heads = 0; static int nr_unused_buffer_heads = 0; @@ -99,7 +100,8 @@ union bdflush_param{ each time we call refill */ int nref_dirt; /* Dirty buffer threshold for activating bdflush when trying to refill buffers. */ - int dummy1; /* unused */ + int pct_dirt; /* Max %age of mem for dirty buffers before + activating bdflush */ int age_buffer; /* Time for normal buffer to age before we flush it */ int age_super; /* Time for superblock to age before we @@ -478,6 +480,7 @@ static void remove_from_queues(struct buffer_head * bh) return; } nr_buffers_type[bh->b_list]--; + size_buffers_type[bh->b_list] -= bh->b_size; remove_from_hash_queue(bh); remove_from_lru_list(bh); } @@ -551,6 +554,7 @@ static void insert_into_queues(struct buffer_head * bh) (*bhp)->b_prev_free = bh; nr_buffers_type[bh->b_list]++; + size_buffers_type[bh->b_list] += bh->b_size; /* Put the buffer in new hash-queue if it has a device. */ bh->b_next = NULL; @@ -802,13 +806,19 @@ void refile_buffer(struct buffer_head * buf) file_buffer(buf, dispose); if(dispose == BUF_DIRTY) { int too_many = (nr_buffers * bdf_prm.b_un.nfract/100); + int too_large = (num_physpages * bdf_prm.b_un.pct_dirt/100); /* This buffer is dirty, maybe we need to start flushing. * If too high a percentage of the buffers are dirty... */ - if (nr_buffers_type[BUF_DIRTY] > too_many) - wakeup_bdflush(0); - + if (nr_buffers_type[BUF_DIRTY] > too_many || + (size_buffers_type[BUF_DIRTY] + size_buffers_type[BUF_LOCKED])/PAGE_SIZE > too_large) { + if (nr_buffers_type[BUF_LOCKED] > 2 * bdf_prm.b_un.ndirty) + wakeup_bdflush(1); + else + wakeup_bdflush(0); + } + /* If this is a loop device, and * more than half of the buffers are dirty... * (Prevents no-free-buffers deadlock with loop device.) @@ -1604,7 +1614,7 @@ static int sync_old_buffers(void) #ifdef DEBUG for(nlist = 0; nlist < NR_LIST; nlist++) #else - for(nlist = BUF_DIRTY; nlist <= BUF_DIRTY; nlist++) + for(nlist = BUF_LOCKED; nlist <= BUF_DIRTY; nlist++) #endif { ndirty = 0; @@ -1623,8 +1633,13 @@ static int sync_old_buffers(void) } /* Clean buffer on dirty list? Refile it */ - if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh)) - { + if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh)) { + refile_buffer(bh); + continue; + } + + /* Unlocked buffer on locked list? Refile it */ + if (nlist == BUF_LOCKED && !buffer_locked(bh)) { refile_buffer(bh); continue; } diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c index 8f3bd532a2b8..79a4c7ebbdb6 100644 --- a/fs/coda/sysctl.c +++ b/fs/coda/sysctl.c @@ -24,6 +24,8 @@ #include #include #include +#define __NO_VERSION__ +#include #include #include @@ -491,6 +493,14 @@ struct proc_dir_entry proc_coda_cache_inv = { coda_cache_inv_stats_get_info }; +static void coda_proc_modcount(struct inode *inode, int fill) +{ + if (fill) + MOD_INC_USE_COUNT; + else + MOD_DEC_USE_COUNT; +} + #endif @@ -504,6 +514,7 @@ void coda_sysctl_init() #ifdef CONFIG_PROC_FS proc_register(&proc_root_fs,&proc_fs_coda); + proc_fs_coda.fill_inode = &coda_proc_modcount; proc_register(&proc_fs_coda,&proc_coda_vfs); proc_register(&proc_fs_coda,&proc_coda_upcall); proc_register(&proc_fs_coda,&proc_coda_permission); diff --git a/fs/inode.c b/fs/inode.c index 347e88d37d01..83554caa9612 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -62,9 +62,8 @@ spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; struct { int nr_inodes; int nr_free_inodes; - int preshrink; /* pre-shrink dcache? */ - int dummy[4]; -} inodes_stat = {0, 0, 0,}; + int dummy[5]; +} inodes_stat = {0, 0,}; int max_inodes; @@ -195,6 +194,19 @@ void sync_inodes(kdev_t dev) spin_unlock(&inode_lock); } +/* + * Called with the spinlock already held.. + */ +static void sync_all_inodes(void) +{ + struct super_block * sb = sb_entry(super_blocks.next); + for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) { + if (!sb->s_dev) + continue; + sync_list(&sb->s_dirty); + } +} + /* * Needed by knfsd */ @@ -355,18 +367,6 @@ static int free_inodes(void) return found; } -static void shrink_dentry_inodes(int goal) -{ - int found; - - spin_unlock(&inode_lock); - found = select_dcache(goal, 0); - if (found < goal) - found = goal; - prune_dcache(found); - spin_lock(&inode_lock); -} - /* * Searches the inodes list for freeable inodes, * shrinking the dcache before (and possible after, @@ -374,9 +374,22 @@ static void shrink_dentry_inodes(int goal) */ static void try_to_free_inodes(int goal) { - shrink_dentry_inodes(goal); - if (!free_inodes()) - shrink_dentry_inodes(goal); + /* + * First stry to just get rid of unused inodes. + * + * If we can't reach our goal that way, we'll have + * to try to shrink the dcache and sync existing + * inodes.. + */ + free_inodes(); + goal -= inodes_stat.nr_free_inodes; + if (goal > 0) { + spin_unlock(&inode_lock); + prune_dcache(goal); + spin_lock(&inode_lock); + sync_all_inodes(); + free_inodes(); + } } /* @@ -404,9 +417,9 @@ static struct inode * grow_inodes(void) /* * Check whether to restock the unused list. */ - if (inodes_stat.preshrink) { + if (inodes_stat.nr_inodes > max_inodes) { struct list_head *tmp; - try_to_free_inodes(8); + try_to_free_inodes(inodes_stat.nr_inodes >> 2); tmp = inode_unused.next; if (tmp != &inode_unused) { inodes_stat.nr_free_inodes--; @@ -437,9 +450,6 @@ static struct inode * grow_inodes(void) */ inodes_stat.nr_inodes += INODES_PER_PAGE; inodes_stat.nr_free_inodes += INODES_PER_PAGE - 1; - inodes_stat.preshrink = 0; - if (inodes_stat.nr_inodes > max_inodes) - inodes_stat.preshrink = 1; return inode; } @@ -448,7 +458,6 @@ static struct inode * grow_inodes(void) * the dcache and then try again to free some inodes. */ prune_dcache(inodes_stat.nr_inodes >> 2); - inodes_stat.preshrink = 1; spin_lock(&inode_lock); free_inodes(); diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index d50df7eacd4b..c34f37aa95e6 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -30,6 +30,14 @@ static int nlm_stat_to_errno(u32 stat); */ static u32 nlm_cookie = 0x1234; +static inline void nlmclnt_next_cookie(struct nlm_cookie *c) +{ + memcpy(c->data, &nlm_cookie, 4); + memset(c->data+4, 0, 4); + c->len=4; + nlm_cookie++; +} + /* * Initialize arguments for TEST/LOCK/UNLOCK/CANCEL calls */ @@ -40,7 +48,7 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) struct nlm_lock *lock = &argp->lock; memset(argp, 0, sizeof(*argp)); - argp->cookie = nlm_cookie++; + nlmclnt_next_cookie(&argp->cookie); argp->state = nsm_local_state; lock->fh = *NFS_FH(fl->fl_file->f_dentry); lock->caller = system_utsname.nodename; @@ -57,7 +65,7 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) int nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { - call->a_args.cookie = nlm_cookie++; + nlmclnt_next_cookie(&call->a_args.cookie); call->a_args.lock = *lock; call->a_args.lock.caller = system_utsname.nodename; @@ -230,9 +238,24 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) /* Perform the RPC call. If an error occurs, try again */ if ((status = rpc_call(clnt, proc, argp, resp, 0)) < 0) { dprintk("lockd: rpc_call returned error %d\n", -status); - if (status == -ERESTARTSYS) - return status; - nlm_rebind_host(host); + switch (status) { + case -EPROTONOSUPPORT: + status = -EINVAL; + break; + case -ECONNREFUSED: + case -ETIMEDOUT: + case -ENOTCONN: + status = -EAGAIN; + break; + case -ERESTARTSYS: + return signalled () ? -EINTR : status; + default: + break; + } + if (req->a_args.block) + nlm_rebind_host(host); + else + break; } else if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) { dprintk("lockd: server in grace period\n"); @@ -248,9 +271,18 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) /* Back off a little and try again */ interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ); - } while (!signalled()); - return -ERESTARTSYS; + /* When the lock requested by F_SETLKW isn't available, + we will wait until the request can be satisfied. If + a signal is received during wait, we should return + -EINTR. */ + if (signalled ()) { + status = -EINTR; + break; + } + } while (1); + + return status; } /* @@ -446,7 +478,7 @@ nlmclnt_unlock_callback(struct rpc_task *task) int status = req->a_res.status; if (RPC_ASSASSINATED(task)) - goto die; + return; if (task->tk_status < 0) { dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status); @@ -458,9 +490,6 @@ nlmclnt_unlock_callback(struct rpc_task *task) && status != NLM_LCK_DENIED_GRACE_PERIOD) { printk("lockd: unexpected unlock status: %d\n", status); } - -die: - rpc_release_task(task); } /* @@ -536,7 +565,6 @@ nlmclnt_cancel_callback(struct rpc_task *task) } die: - rpc_release_task(task); nlm_release_host(req->a_host); kfree(req); return; diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index be9e0a5f35e6..d61db4302b47 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -64,6 +64,7 @@ lockd(struct svc_rqst *rqstp) { struct svc_serv *serv = rqstp->rq_server; int err = 0; + unsigned long grace_period_expire; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; @@ -111,7 +112,7 @@ lockd(struct svc_rqst *rqstp) } #endif - nlmsvc_grace_period += jiffies; + grace_period_expire = nlmsvc_grace_period + jiffies; nlmsvc_timeout = nlm_timeout * HZ; /* diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index b1f1f55888cd..49f3244d2b4f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -111,16 +111,25 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) return NULL; } +static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b) +{ + if(a->len != b->len) + return 0; + if(memcmp(a->data,b->data,a->len)) + return 0; + return 1; +} + /* * Find a block with a given NLM cookie. */ static inline struct nlm_block * -nlmsvc_find_block(u32 cookie) +nlmsvc_find_block(struct nlm_cookie *cookie) { struct nlm_block *block; for (block = nlm_blocked; block; block = block->b_next) { - if (block->b_call.a_args.cookie == cookie) + if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie)) break; } @@ -139,7 +148,7 @@ nlmsvc_find_block(u32 cookie) */ static inline struct nlm_block * nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, - struct nlm_lock *lock, u32 cookie) + struct nlm_lock *lock, struct nlm_cookie *cookie) { struct nlm_block *block; struct nlm_host *host; @@ -160,7 +169,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, lock->fl.fl_notify = nlmsvc_notify_blocked; if (!nlmclnt_setgrantargs(&block->b_call, lock)) goto failed_free; - block->b_call.a_args.cookie = cookie; /* see above */ + block->b_call.a_args.cookie = *cookie; /* see above */ dprintk("lockd: created block %p...\n", block); @@ -267,7 +276,7 @@ nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) */ u32 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, - struct nlm_lock *lock, int wait, u32 cookie) + struct nlm_lock *lock, int wait, struct nlm_cookie *cookie) { struct file_lock *conflock; struct nlm_block *block; @@ -529,8 +538,8 @@ nlmsvc_grant_callback(struct rpc_task *task) unsigned long timeout; dprintk("lockd: GRANT_MSG RPC callback\n"); - if (!(block = nlmsvc_find_block(call->a_args.cookie))) { - dprintk("lockd: no block for cookie %x\n", call->a_args.cookie); + if (!(block = nlmsvc_find_block(&call->a_args.cookie))) { + dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data)); return; } @@ -552,7 +561,6 @@ nlmsvc_grant_callback(struct rpc_task *task) block->b_incall = 0; nlm_release_host(call->a_host); - rpc_release_task(task); } /* @@ -560,7 +568,7 @@ nlmsvc_grant_callback(struct rpc_task *task) * block. */ void -nlmsvc_grant_reply(u32 cookie, u32 status) +nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) { struct nlm_block *block; struct nlm_file *file; diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 2077752f4295..bab2915f1dcc 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -151,7 +151,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Now try to lock the file */ resp->status = nlmsvc_lock(rqstp, file, &argp->lock, - argp->block, argp->cookie); + argp->block, &argp->cookie); dprintk("lockd: LOCK status %ld\n", ntohl(resp->status)); nlm_release_host(host); @@ -492,7 +492,6 @@ nlmsvc_callback_exit(struct rpc_task *task) task->tk_pid, -task->tk_status); } nlm_release_host(call->a_host); - rpc_release_task(task); kfree(call); } diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 7d41c8a663f2..85fb7c729090 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -53,28 +53,38 @@ nlmxdr_init(void) /* * XDR functions for basic NLM types */ -static inline u32 * -nlm_decode_cookie(u32 *p, u32 *c) +static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c) { unsigned int len; - if ((len = ntohl(*p++)) == 4) { - *c = ntohl(*p++); - } else if (len == 0) { /* hockeypux brain damage */ - *c = 0; - } else { + len = ntohl(*p++); + + if(len==0) + { + c->len=4; + memset(c->data, 0, 4); /* hockeypux brain damage */ + } + else if(len<=8) + { + c->len=len; + memcpy(c->data, p, len); + p+=(len+3)>>2; + } + else + { printk(KERN_NOTICE - "lockd: bad cookie size %d (should be 4)\n", len); + "lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len); return NULL; } return p; } static inline u32 * -nlm_encode_cookie(u32 *p, u32 c) +nlm_encode_cookie(u32 *p, struct nlm_cookie *c) { - *p++ = htonl(sizeof(c)); - *p++ = htonl(c); + *p++ = htonl(c->len); + memcpy(p, c->data, c->len); + p+=(c->len+3)>>2; return p; } @@ -168,7 +178,7 @@ nlm_encode_lock(u32 *p, struct nlm_lock *lock) static u32 * nlm_encode_testres(u32 *p, struct nlm_res *resp) { - if (!(p = nlm_encode_cookie(p, resp->cookie))) + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; @@ -308,7 +318,7 @@ nlmsvc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) int nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { - if (!(p = nlm_encode_cookie(p, resp->cookie))) + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; *p++ = xdr_zero; /* sequence argument */ @@ -318,7 +328,7 @@ nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) int nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { - if (!(p = nlm_encode_cookie(p, resp->cookie))) + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; return xdr_ressize_check(rqstp, p); @@ -388,7 +398,7 @@ nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; - if (!(p = nlm_encode_cookie(p, argp->cookie))) + if (!(p = nlm_encode_cookie(p, &argp->cookie))) return -EIO; *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; if (!(p = nlm_encode_lock(p, lock))) @@ -429,7 +439,7 @@ nlmclt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; - if (!(p = nlm_encode_cookie(p, argp->cookie))) + if (!(p = nlm_encode_cookie(p, &argp->cookie))) return -EIO; *p++ = argp->block? xdr_one : xdr_zero; *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; @@ -446,7 +456,7 @@ nlmclt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; - if (!(p = nlm_encode_cookie(p, argp->cookie))) + if (!(p = nlm_encode_cookie(p, &argp->cookie))) return -EIO; *p++ = argp->block? xdr_one : xdr_zero; *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; @@ -461,7 +471,7 @@ nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; - if (!(p = nlm_encode_cookie(p, argp->cookie))) + if (!(p = nlm_encode_cookie(p, &argp->cookie))) return -EIO; if (!(p = nlm_encode_lock(p, lock))) return -EIO; @@ -472,7 +482,7 @@ nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) static int nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { - if (!(p = nlm_encode_cookie(p, resp->cookie))) + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return -EIO; *p++ = resp->status; req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); @@ -501,7 +511,7 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) * Buffer requirements for NLM */ #define NLM_void_sz 0 -#define NLM_cookie_sz 2 +#define NLM_cookie_sz 3 /* 1 len , 2 data */ #define NLM_caller_sz 1+QUADLEN(sizeof(system_utsname.nodename)) #define NLM_netobj_sz 1+QUADLEN(XDR_MAX_NETOBJ) /* #define NLM_owner_sz 1+QUADLEN(NLM_MAXOWNER) */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 80ab953ab989..1caeb606b210 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -150,6 +150,7 @@ extern int max_super_blocks, nr_super_blocks; #define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */ #define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */ #define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */ +#define BLKSSZGET _IO(0x12,104)/* get block device sector size (reserved for) */ #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 5c1d0e4cc791..384e14689182 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -145,7 +145,7 @@ void nlm_shutdown_hosts(void); * Server-side lock handling */ u32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, - struct nlm_lock *, int, u32); + struct nlm_lock *, int, struct nlm_cookie *); u32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); u32 nlmsvc_testlock(struct nlm_file *, struct nlm_lock *, struct nlm_lock *); diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h index 631a8fba8bba..f397306c4855 100644 --- a/include/linux/lockd/xdr.h +++ b/include/linux/lockd/xdr.h @@ -24,11 +24,22 @@ struct nlm_lock { struct file_lock fl; }; +/* + * NLM cookies. Technically they can be 1K, Nobody uses over 8 bytes + * however. + */ + +struct nlm_cookie +{ + unsigned char data[8]; + unsigned int len; +}; + /* * Generic lockd arguments for all but sm_notify */ struct nlm_args { - u32 cookie; + struct nlm_cookie cookie; struct nlm_lock lock; u32 block; u32 reclaim; @@ -42,7 +53,7 @@ struct nlm_args { * Generic lockd result */ struct nlm_res { - u32 cookie; + struct nlm_cookie cookie; u32 status; struct nlm_lock lock; }; diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h index 35478fe4d113..a151a75e6640 100644 --- a/include/linux/smb_fs.h +++ b/include/linux/smb_fs.h @@ -14,7 +14,7 @@ /* * ioctl commands */ -#define SMB_IOC_GETMOUNTUID _IOR('u', 1, uid_t) +#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t) #define SMB_IOC_NEWCONN _IOW('u', 2, struct smb_conn_opt) #ifdef __KERNEL__ diff --git a/kernel/sched.c b/kernel/sched.c index 513ef16f92e8..8752473683c9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -639,6 +639,8 @@ asmlinkage void schedule(void) struct task_struct * prev, * next; int this_cpu; + run_task_queue(&tq_scheduler); + prev = current; this_cpu = prev->processor; /* @@ -654,7 +656,6 @@ asmlinkage void schedule(void) /* Do "administrative" work here while we don't hold any locks */ if (bh_active & bh_mask) do_bottom_half(); - run_task_queue(&tq_scheduler); spin_lock(&scheduler_lock); spin_lock_irq(&runqueue_lock); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 44a62a9e99a5..ed98241366b9 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -557,14 +557,19 @@ static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root continue; } unregister_proc_table(table->child, de); + + /* Don't unregister directories which still have entries.. */ + if (de->subdir) + continue; } - /* Don't unregister proc directories which still have - entries... */ - if (!((de->mode & S_IFDIR) && de->subdir)) { - proc_unregister(root, de->low_ino); - table->de = NULL; - kfree(de); - } + + /* Don't unregoster proc entries that are still being used.. */ + if (de->count) + continue; + + proc_unregister(root, de->low_ino); + table->de = NULL; + kfree(de); } } diff --git a/mm/filemap.c b/mm/filemap.c index 849c2a93cabb..71bfcf8a9603 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1676,16 +1676,23 @@ static inline void make_pio_request(struct file *file, int kpiod(void * unused) { - struct wait_queue wait = {current}; + struct task_struct *tsk = current; + struct wait_queue wait = { tsk, }; struct inode * inode; struct dentry * dentry; struct pio_request * p; - current->session = 1; - current->pgrp = 1; - strcpy(current->comm, "kpiod"); - sigfillset(¤t->blocked); + tsk->session = 1; + tsk->pgrp = 1; + strcpy(tsk->comm, "kpiod"); + sigfillset(&tsk->blocked); init_waitqueue(&pio_wait); + /* + * Mark this task as a memory allocator - we don't want to get caught + * up in the regular mm freeing frenzy if we have to allocate memory + * in order to write stuff out. + */ + tsk->flags |= PF_MEMALLOC; lock_kernel(); @@ -1695,14 +1702,14 @@ int kpiod(void * unused) NULL, NULL); if (!pio_request_cache) panic ("Could not create pio_request slab cache"); - + while (1) { - current->state = TASK_INTERRUPTIBLE; + tsk->state = TASK_INTERRUPTIBLE; add_wait_queue(&pio_wait, &wait); - while (!pio_first) + if (!pio_first) schedule(); remove_wait_queue(&pio_wait, &wait); - current->state = TASK_RUNNING; + tsk->state = TASK_RUNNING; while (pio_first) { p = get_pio_request(); diff --git a/net/Makefile b/net/Makefile index 9131266d122c..6e0971c7af42 100644 --- a/net/Makefile +++ b/net/Makefile @@ -127,6 +127,8 @@ endif ifeq ($(CONFIG_IRDA),y) SUB_DIRS += irda +# There might be some irda features that are compiled as modules +MOD_SUB_DIRS += irda else ifeq ($(CONFIG_IRDA),m) MOD_SUB_DIRS += irda diff --git a/net/core/skbuff.c b/net/core/skbuff.c index a03d284e75f9..b40bc8f82f06 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -304,6 +304,9 @@ struct sk_buff *skb_copy(struct sk_buff *skb, int gfp_mask) n->stamp=skb->stamp; n->destructor = NULL; n->security=skb->security; +#ifdef CONFIG_IP_FIREWALL + n->fwmark = skb->fwmark; +#endif return n; } @@ -350,6 +353,9 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) n->stamp=skb->stamp; n->destructor = NULL; n->security=skb->security; +#ifdef CONFIG_IP_FIREWALL + n->fwmark = skb->fwmark; +#endif return n; } diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 7bff3609537d..bd35f7bb3d52 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -5,7 +5,7 @@ * * IPv4 Forwarding Information Base: semantics. * - * Version: $Id: fib_semantics.c,v 1.11 1998/10/03 09:37:12 davem Exp $ + * Version: $Id: fib_semantics.c,v 1.12 1999/01/26 05:33:44 davem Exp $ * * Authors: Alexey Kuznetsov, * diff --git a/net/ipv4/ip_masq_mfw.c b/net/ipv4/ip_masq_mfw.c index e3903c0cb9d1..dc38b1712d1b 100644 --- a/net/ipv4/ip_masq_mfw.c +++ b/net/ipv4/ip_masq_mfw.c @@ -3,7 +3,7 @@ * * Does (reverse-masq) forwarding based on skb->fwmark value * - * $Id: ip_masq_mfw.c,v 1.2 1998/12/12 02:40:42 davem Exp $ + * $Id: ip_masq_mfw.c,v 1.3 1999/01/26 05:33:47 davem Exp $ * * Author: Juan Jose Ciarlante * based on Steven Clarke's portfw diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ce027c3744c6..d684c9c7e86c 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) output module. * - * Version: $Id: ip_output.c,v 1.64 1999/01/04 20:05:33 davem Exp $ + * Version: $Id: ip_output.c,v 1.65 1999/01/21 13:37:34 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index d21b1065308b..1640a0560752 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -7,7 +7,7 @@ * PROC file system. It is mainly used for debugging and * statistics. * - * Version: $Id: proc.c,v 1.33 1998/10/21 05:44:35 davem Exp $ + * Version: $Id: proc.c,v 1.34 1999/02/08 11:20:34 davem Exp $ * * Authors: Fred N. van Kempen, * Gerald J. Heim, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index aca7026b901f..e6ebfec82d73 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.153 1999/01/20 07:20:03 davem Exp $ + * Version: $Id: tcp_input.c,v 1.155 1999/01/26 05:33:50 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 18a058c3189a..914c515d71c1 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.164 1999/01/04 20:36:55 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.165 1999/02/08 11:19:56 davem Exp $ * * IPv4 specific functions * @@ -751,7 +751,6 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip) if (sk->ip_pmtudisc != IP_PMTUDISC_DONT && sk->dst_cache) { if (tp->pmtu_cookie > sk->dst_cache->pmtu && !atomic_read(&sk->sock_readers)) { - lock_sock(sk); tcp_sync_mss(sk, sk->dst_cache->pmtu); /* Resend the TCP packet because it's @@ -760,7 +759,6 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip) * discovery. */ tcp_simple_retransmit(sk); - release_sock(sk); } /* else let the usual retransmit timer handle it */ } } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a95698db5a80..00d9b099e741 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $Id: tcp_ipv6.c,v 1.94 1998/11/07 11:50:33 davem Exp $ + * $Id: tcp_ipv6.c,v 1.95 1999/02/08 11:20:03 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -641,10 +641,8 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr, sk->err_soft = -dst->error; } else if (tp->pmtu_cookie > dst->pmtu && !atomic_read(&sk->sock_readers)) { - lock_sock(sk); tcp_sync_mss(sk, dst->pmtu); tcp_simple_retransmit(sk); - release_sock(sk); } /* else let the usual retransmit timer handle it */ dst_release(dst); return; @@ -1210,11 +1208,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) ipv6_statistics.Ip6InDelivers++; - /* XXX We need to think more about socket locking - * XXX wrt. backlog queues, __release_sock(), etc. -DaveM - */ - lock_sock(sk); - /* * This doesn't check if the socket has enough room for the packet. * Either process the packet _without_ queueing it and then free it, @@ -1255,8 +1248,16 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) nsk = tcp_v6_hnd_req(sk, skb); if (!nsk) goto discard; - lock_sock(nsk); - release_sock(sk); + + /* + * Queue it on the new socket if the new socket is active, + * otherwise we just shortcircuit this and continue with + * the new socket.. + */ + if (atomic_read(&nsk->sock_readers)) { + __skb_queue_tail(&nsk->back_log, skb); + return 0; + } sk = nsk; } @@ -1264,7 +1265,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) goto reset; if (users) goto ipv6_pktoptions; - release_sock(sk); return 0; reset: @@ -1273,7 +1273,6 @@ discard: if (users) kfree_skb(skb); kfree_skb(skb); - release_sock(sk); return 0; ipv6_pktoptions: @@ -1303,7 +1302,6 @@ ipv6_pktoptions: if (skb) kfree_skb(skb); - release_sock(sk); return 0; } diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 4e0acee239ae..3ffebce52deb 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -546,14 +547,14 @@ svc_tcp_accept(struct svc_sock *svsk) * we just punt connects from unprivileged ports. */ if (ntohs(sin.sin_port) >= 1024) { printk(KERN_WARNING - "%s: connect from unprivileged port: %08lx:%d", + "%s: connect from unprivileged port: %s:%d", serv->sv_name, - ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port)); + in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port)); goto failed; } - dprintk("%s: connect from %08lx:%04x\n", serv->sv_name, - ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port)); + dprintk("%s: connect from %s:%04x\n", serv->sv_name, + in_ntoa(sin.sin_addr.s_addr), ntohs(sin.sin_port)); if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0))) goto failed; diff --git a/scripts/ver_linux b/scripts/ver_linux index 42c582eab0c9..090fba4dce8f 100644 --- a/scripts/ver_linux +++ b/scripts/ver_linux @@ -4,6 +4,7 @@ # /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may # differ on your system. # +PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH echo '-- Versions installed: (if some fields are empty or looks' echo '-- unusual then possibly you have very old versions)' uname -a -- 2.39.5