From: Chris Wright Date: Fri, 2 Feb 2007 23:22:34 +0000 (-0800) Subject: another batch of 2.6.19 -stable patches X-Git-Tag: v2.6.19.3~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6db9fb4da4ebc9d9cd7bef4d2c3f273a6fc0195f;p=thirdparty%2Fkernel%2Fstable-queue.git another batch of 2.6.19 -stable patches --- diff --git a/queue-2.6.19/af_packet-check-device-down-state-before-hard-header-callbacks.patch b/queue-2.6.19/af_packet-check-device-down-state-before-hard-header-callbacks.patch new file mode 100644 index 00000000000..da095235eef --- /dev/null +++ b/queue-2.6.19/af_packet-check-device-down-state-before-hard-header-callbacks.patch @@ -0,0 +1,67 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:11:36 2007 +Date: Fri, 02 Feb 2007 13:01:28 -0800 (PST) +Message-Id: <20070202.130128.59684656.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: AF_PACKET: Check device down state before hard header callbacks. + +From: David S. Miller + +If the device is down, invoking the device hard header callbacks +is not legal, so check it early. + +Based upon a shaper OOPS report from Frederik Deweerdt. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/packet/af_packet.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- linux-2.6.19.2.orig/net/packet/af_packet.c ++++ linux-2.6.19.2/net/packet/af_packet.c +@@ -358,6 +358,10 @@ static int packet_sendmsg_spkt(struct ki + if (dev == NULL) + goto out_unlock; + ++ err = -ENETDOWN; ++ if (!(dev->flags & IFF_UP)) ++ goto out_unlock; ++ + /* + * You may not queue a frame bigger than the mtu. This is the lowest level + * raw protocol and you must do your own fragmentation at this level. +@@ -406,10 +410,6 @@ static int packet_sendmsg_spkt(struct ki + if (err) + goto out_free; + +- err = -ENETDOWN; +- if (!(dev->flags & IFF_UP)) +- goto out_free; +- + /* + * Now send it + */ +@@ -737,6 +737,10 @@ static int packet_sendmsg(struct kiocb * + if (sock->type == SOCK_RAW) + reserve = dev->hard_header_len; + ++ err = -ENETDOWN; ++ if (!(dev->flags & IFF_UP)) ++ goto out_unlock; ++ + err = -EMSGSIZE; + if (len > dev->mtu+reserve) + goto out_unlock; +@@ -769,10 +773,6 @@ static int packet_sendmsg(struct kiocb * + skb->dev = dev; + skb->priority = sk->sk_priority; + +- err = -ENETDOWN; +- if (!(dev->flags & IFF_UP)) +- goto out_free; +- + /* + * Now send it + */ diff --git a/queue-2.6.19/af_packet-fix-bpf-handling.patch b/queue-2.6.19/af_packet-fix-bpf-handling.patch new file mode 100644 index 00000000000..d9f7b36ed82 --- /dev/null +++ b/queue-2.6.19/af_packet-fix-bpf-handling.patch @@ -0,0 +1,111 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:16:09 2007 +Date: Fri, 02 Feb 2007 13:06:03 -0800 (PST) +Message-Id: <20070202.130603.115939909.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: AF_PACKET: Fix BPF handling. + +From: David S. Miller + +This fixes a bug introduced by: + +commit fda9ef5d679b07c9d9097aaf6ef7f069d794a8f9 +Author: Dmitry Mishin +Date: Thu Aug 31 15:28:39 2006 -0700 + + [NET]: Fix sk->sk_filter field access + +sk_run_filter() returns either 0 or an unsigned 32-bit +length which says how much of the packet to retain. +If that 32-bit unsigned integer is larger than the packet, +this is fine we just leave the packet unchanged. + +The above commit caused all filter return values which +were negative when interpreted as a signed integer to +indicate a packet drop, which is wrong. + +Based upon a report and initial patch by Raivis Bucis. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/packet/af_packet.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- linux-2.6.19.2.orig/net/packet/af_packet.c ++++ linux-2.6.19.2/net/packet/af_packet.c +@@ -427,24 +427,18 @@ out_unlock: + } + #endif + +-static inline int run_filter(struct sk_buff *skb, struct sock *sk, +- unsigned *snaplen) ++static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, ++ unsigned int res) + { + struct sk_filter *filter; +- int err = 0; + + rcu_read_lock_bh(); + filter = rcu_dereference(sk->sk_filter); +- if (filter != NULL) { +- err = sk_run_filter(skb, filter->insns, filter->len); +- if (!err) +- err = -EPERM; +- else if (*snaplen > err) +- *snaplen = err; +- } ++ if (filter != NULL) ++ res = sk_run_filter(skb, filter->insns, filter->len); + rcu_read_unlock_bh(); + +- return err; ++ return res; + } + + /* +@@ -466,7 +460,7 @@ static int packet_rcv(struct sk_buff *sk + struct packet_sock *po; + u8 * skb_head = skb->data; + int skb_len = skb->len; +- unsigned snaplen; ++ unsigned int snaplen, res; + + if (skb->pkt_type == PACKET_LOOPBACK) + goto drop; +@@ -494,8 +488,11 @@ static int packet_rcv(struct sk_buff *sk + + snaplen = skb->len; + +- if (run_filter(skb, sk, &snaplen) < 0) ++ res = run_filter(skb, sk, snaplen); ++ if (!res) + goto drop_n_restore; ++ if (snaplen > res) ++ snaplen = res; + + if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= + (unsigned)sk->sk_rcvbuf) +@@ -567,7 +564,7 @@ static int tpacket_rcv(struct sk_buff *s + struct tpacket_hdr *h; + u8 * skb_head = skb->data; + int skb_len = skb->len; +- unsigned snaplen; ++ unsigned int snaplen, res; + unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER; + unsigned short macoff, netoff; + struct sk_buff *copy_skb = NULL; +@@ -591,8 +588,11 @@ static int tpacket_rcv(struct sk_buff *s + + snaplen = skb->len; + +- if (run_filter(skb, sk, &snaplen) < 0) ++ res = run_filter(skb, sk, snaplen); ++ if (!res) + goto drop_n_restore; ++ if (snaplen > res) ++ snaplen = res; + + if (sk->sk_type == SOCK_DGRAM) { + macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; diff --git a/queue-2.6.19/bonding-arp-monitoring-broken-on-x86_64.patch b/queue-2.6.19/bonding-arp-monitoring-broken-on-x86_64.patch new file mode 100644 index 00000000000..19af28cc6a0 --- /dev/null +++ b/queue-2.6.19/bonding-arp-monitoring-broken-on-x86_64.patch @@ -0,0 +1,44 @@ +From f8a8ccd56d82bd4f4b5c7c2e7eb758c7764d98e1 Mon Sep 17 00:00:00 2001 +From: Andy Gospodarek +Date: Mon, 29 Jan 2007 12:08:38 -0800 +Subject: bonding: ARP monitoring broken on x86_64 + +While working with the latest bonding code I noticed a nasty problem that +will prevent arp monitoring from always functioning correctly on x86_64 +systems. Comparing ints to longs and expecting reliable results on x86_64 +is a bad idea. With this patch, arp monitoring works correctly again. + +Signed-off-by: Andy Gospodarek +Cc: "David S. Miller" +Cc: Stephen Hemminger +Cc: Jeff Garzik +Signed-off-by: Andrew Morton +Signed-off-by: Jeff Garzik +Signed-off-by: Chris Wright +--- + drivers/net/bonding/bonding.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- linux-2.6.19.2.orig/drivers/net/bonding/bonding.h ++++ linux-2.6.19.2/drivers/net/bonding/bonding.h +@@ -151,8 +151,8 @@ struct slave { + struct slave *next; + struct slave *prev; + int delay; +- u32 jiffies; +- u32 last_arp_rx; ++ unsigned long jiffies; ++ unsigned long last_arp_rx; + s8 link; /* one of BOND_LINK_XXXX */ + s8 state; /* one of BOND_STATE_XXXX */ + u32 original_flags; +@@ -242,7 +242,8 @@ extern inline int slave_do_arp_validate( + return bond->params.arp_validate & (1 << slave->state); + } + +-extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave) ++extern inline unsigned long slave_last_rx(struct bonding *bond, ++ struct slave *slave) + { + if (slave_do_arp_validate(bond, slave)) + return slave->last_arp_rx; diff --git a/queue-2.6.19/decnet-handle-a-failure-in-neigh_parms_alloc.patch b/queue-2.6.19/decnet-handle-a-failure-in-neigh_parms_alloc.patch new file mode 100644 index 00000000000..64371882920 --- /dev/null +++ b/queue-2.6.19/decnet-handle-a-failure-in-neigh_parms_alloc.patch @@ -0,0 +1,51 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:00:30 2007 +Date: Fri, 02 Feb 2007 12:50:23 -0800 (PST) +Message-Id: <20070202.125023.78737954.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: DECNET: Handle a failure in neigh_parms_alloc (take 2) + +From: Eric W. Biederman + +While enhancing the neighbour code to handle multiple network +namespaces I noticed that decnet is assuming neigh_parms_alloc +will allways succeed, which is clearly wrong. So handle the +failure. + +Signed-off-by: Eric W. Biederman +Acked-by: Steven Whitehouse +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/decnet/dn_dev.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- linux-2.6.19.2.orig/net/decnet/dn_dev.c ++++ linux-2.6.19.2/net/decnet/dn_dev.c +@@ -1116,16 +1116,23 @@ struct dn_dev *dn_dev_create(struct net_ + init_timer(&dn_db->timer); + + dn_db->uptime = jiffies; ++ ++ dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); ++ if (!dn_db->neigh_parms) { ++ dev->dn_ptr = NULL; ++ kfree(dn_db); ++ return NULL; ++ } ++ + if (dn_db->parms.up) { + if (dn_db->parms.up(dev) < 0) { ++ neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); + dev->dn_ptr = NULL; + kfree(dn_db); + return NULL; + } + } + +- dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); +- + dn_dev_sysctl_register(dev, &dn_db->parms); + + dn_dev_set_timer(dev); diff --git a/queue-2.6.19/don-t-allow-the-stack-to-grow-into-hugetlb-reserved-regions.patch b/queue-2.6.19/don-t-allow-the-stack-to-grow-into-hugetlb-reserved-regions.patch new file mode 100644 index 00000000000..0e2fa6a41f5 --- /dev/null +++ b/queue-2.6.19/don-t-allow-the-stack-to-grow-into-hugetlb-reserved-regions.patch @@ -0,0 +1,50 @@ +From stable-bounces@linux.kernel.org Tue Jan 30 14:46:08 2007 +Message-Id: <200701302235.l0UMZe6b031632@shell0.pdx.osdl.net> +To: torvalds@linux-foundation.org +From: akpm@osdl.org +Date: Tue, 30 Jan 2007 14:35:39 -0800 +Cc: akpm@osdl.org, wli@holomorphy.com, agl@us.ibm.com, hugh@veritas.com, stable@kernel.org, david@gibson.dropbear.id.au +Subject: Don't allow the stack to grow into hugetlb reserved regions + +From: Adam Litke + +When expanding the stack, we don't currently check if the VMA will cross +into an area of the address space that is reserved for hugetlb pages. +Subsequent faults on the expanded portion of such a VMA will confuse the +low-level MMU code, resulting in an OOPS. Check for this. + +Signed-off-by: Adam Litke +Cc: David Gibson +Cc: William Lee Irwin III +Cc: Hugh Dickins +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + mm/mmap.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- linux-2.6.19.2.orig/mm/mmap.c ++++ linux-2.6.19.2/mm/mmap.c +@@ -1477,6 +1477,7 @@ static int acct_stack_growth(struct vm_a + { + struct mm_struct *mm = vma->vm_mm; + struct rlimit *rlim = current->signal->rlim; ++ unsigned long new_start; + + /* address space limit tests */ + if (!may_expand_vm(mm, grow)) +@@ -1496,6 +1497,12 @@ static int acct_stack_growth(struct vm_a + return -ENOMEM; + } + ++ /* Check to ensure the stack will not grow into a hugetlb-only region */ ++ new_start = (vma->vm_flags & VM_GROWSUP) ? vma->vm_start : ++ vma->vm_end - size; ++ if (is_hugepage_only_range(vma->vm_mm, new_start, size)) ++ return -EFAULT; ++ + /* + * Overcommit.. This must be the final test, as it will + * update security statistics. diff --git a/queue-2.6.19/ipv4-fix-single-entry-proc-net-fib_trie-output.patch b/queue-2.6.19/ipv4-fix-single-entry-proc-net-fib_trie-output.patch new file mode 100644 index 00000000000..c5f2cfc3e77 --- /dev/null +++ b/queue-2.6.19/ipv4-fix-single-entry-proc-net-fib_trie-output.patch @@ -0,0 +1,47 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:09:04 2007 +Date: Fri, 02 Feb 2007 12:58:58 -0800 (PST) +Message-Id: <20070202.125858.39188000.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: IPV4: Fix single-entry /proc/net/fib_trie output. + +From: Robert Olsson + +When main table is just a single leaf this gets printed as belonging to the +local table in /proc/net/fib_trie. A fix is below. + +Signed-off-by: Robert Olsson +Acked-by: Eric W. Biederman +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/ipv4/fib_trie.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- linux-2.6.19.2.orig/net/ipv4/fib_trie.c ++++ linux-2.6.19.2/net/ipv4/fib_trie.c +@@ -2290,16 +2290,17 @@ static int fib_trie_seq_show(struct seq_ + if (v == SEQ_START_TOKEN) + return 0; + ++ if (!NODE_PARENT(n)) { ++ if (iter->trie == trie_local) ++ seq_puts(seq, ":\n"); ++ else ++ seq_puts(seq, "
:\n"); ++ } ++ + if (IS_TNODE(n)) { + struct tnode *tn = (struct tnode *) n; + __be32 prf = htonl(MASK_PFX(tn->key, tn->pos)); + +- if (!NODE_PARENT(n)) { +- if (iter->trie == trie_local) +- seq_puts(seq, ":\n"); +- else +- seq_puts(seq, "
:\n"); +- } + seq_indent(seq, iter->depth-1); + seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n", + NIPQUAD(prf), tn->pos, tn->bits, tn->full_children, diff --git a/queue-2.6.19/ipv4-fix-the-fib-trie-iterator-to-work-with-a-single-entry-routing-tables.patch b/queue-2.6.19/ipv4-fix-the-fib-trie-iterator-to-work-with-a-single-entry-routing-tables.patch new file mode 100644 index 00000000000..08d5a600b0e --- /dev/null +++ b/queue-2.6.19/ipv4-fix-the-fib-trie-iterator-to-work-with-a-single-entry-routing-tables.patch @@ -0,0 +1,69 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:07:25 2007 +Date: Fri, 02 Feb 2007 12:57:16 -0800 (PST) +Message-Id: <20070202.125716.85380813.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: IPV4: Fix the fib trie iterator to work with a single entry routing tables + +From: Eric W. Biederman + +In a kernel with trie routing enabled I had a simple routing setup +with only a single route to the outside world and no default +route. "ip route table list main" showed my the route just fine but +/proc/net/route was an empty file. What was going on? + +Thinking it was a bug in something I did and I looked deeper. Eventually +I setup a second route and everything looked correct, huh? Finally I +realized that the it was just the iterator pair in fib_trie_get_first, +fib_trie_get_next just could not handle a routing table with a single entry. + +So to save myself and others further confusion, here is a simple fix for +the fib proc iterator so it works even when there is only a single route +in a routing table. + +Signed-off-by: Eric W. Biederman +Signed-off-by: Robert Olsson +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/ipv4/fib_trie.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +--- linux-2.6.19.2.orig/net/ipv4/fib_trie.c ++++ linux-2.6.19.2/net/ipv4/fib_trie.c +@@ -1989,6 +1989,10 @@ static struct node *fib_trie_get_next(st + unsigned cindex = iter->index; + struct tnode *p; + ++ /* A single entry routing table */ ++ if (!tn) ++ return NULL; ++ + pr_debug("get_next iter={node=%p index=%d depth=%d}\n", + iter->tnode, iter->index, iter->depth); + rescan: +@@ -2037,11 +2041,18 @@ static struct node *fib_trie_get_first(s + if(!iter) + return NULL; + +- if (n && IS_TNODE(n)) { +- iter->tnode = (struct tnode *) n; +- iter->trie = t; +- iter->index = 0; +- iter->depth = 1; ++ if (n) { ++ if (IS_TNODE(n)) { ++ iter->tnode = (struct tnode *) n; ++ iter->trie = t; ++ iter->index = 0; ++ iter->depth = 1; ++ } else { ++ iter->tnode = NULL; ++ iter->trie = t; ++ iter->index = 0; ++ iter->depth = 0; ++ } + return n; + } + return NULL; diff --git a/queue-2.6.19/jmicron-40-80pin-primary-detection.patch b/queue-2.6.19/jmicron-40-80pin-primary-detection.patch new file mode 100644 index 00000000000..a5d43807700 --- /dev/null +++ b/queue-2.6.19/jmicron-40-80pin-primary-detection.patch @@ -0,0 +1,66 @@ +From 99abaf51e25f7d4ac2081e5cdc1f01baa0543514 Mon Sep 17 00:00:00 2001 +From: ethanhsiao@jmicron.com +Date: Tue, 30 Jan 2007 14:36:13 -0800 +Message-ID: <45C20C38.2010607@redhat.com> +Subject: jmicron: 40/80pin primary detection + +jmicron module detects all JMB36x as JMB361 and PATA0 has wrong pin status +of XICBLID. + +Cc: Jeff Garzik +Cc: Alan Cox +Cc: Bartlomiej Zolnierkiewicz +Cc: Sergei Shtylyov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds + +cebbert@redhat.com: I folded in the warning fix (a51545ab25) because +otherwise it makes the tester think the patch caused the warning +that was already there. + +Cc: Dave Jones +Signed-off-by: Chuck Ebbert +Signed-off-by: Chris Wright +--- + drivers/ide/pci/jmicron.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- linux-2.6.19.2.orig/drivers/ide/pci/jmicron.c ++++ linux-2.6.19.2/drivers/ide/pci/jmicron.c +@@ -86,15 +86,16 @@ static int __devinit ata66_jmicron(ide_h + { + case PORT_PATA0: + if (control & (1 << 3)) /* 40/80 pin primary */ +- return 1; +- return 0; ++ return 0; ++ return 1; + case PORT_PATA1: + if (control5 & (1 << 19)) /* 40/80 pin secondary */ + return 0; + return 1; + case PORT_SATA: +- return 1; ++ break; + } ++ return 1; /* Avoid bogus "control reaches end of non-void function" */ + } + + static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) +@@ -240,11 +241,11 @@ static int __devinit jmicron_init_one(st + } + + static struct pci_device_id jmicron_pci_tbl[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0}, +- { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1}, +- { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2}, +- { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3}, +- { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4}, ++ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, ++ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, ++ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, ++ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + { 0, }, + }; + diff --git a/queue-2.6.19/knfsd-fix-an-nfsd-bug-with-full-sized-non-page-aligned-reads.patch b/queue-2.6.19/knfsd-fix-an-nfsd-bug-with-full-sized-non-page-aligned-reads.patch new file mode 100644 index 00000000000..616db49066a --- /dev/null +++ b/queue-2.6.19/knfsd-fix-an-nfsd-bug-with-full-sized-non-page-aligned-reads.patch @@ -0,0 +1,66 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:45:09 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:08 +1100 +Message-Id: <1070125043508.19561@suse.de> +Subject: knfsd: fix an NFSD bug with full sized, non-page-aligned reads. + +NFSd assumes that largest number of pages that will be needed +for a request+response is 2+N where N pages is the size of the largest +permitted read/write request. The '2' are 1 for the non-data part of +the request, and 1 for the non-data part of the reply. + +However, when a read request is not page-aligned, and we choose to use +->sendfile to send it directly from the page cache, we may need N+1 +pages to hold the whole reply. This can overflow and array and cause +an Oops. + +This patch increases size of the array for holding pages by one and +makes sure that entry is NULL when it is not in use. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + fs/nfsd/vfs.c | 3 ++- + include/linux/sunrpc/svc.h | 5 ++++- + net/sunrpc/svcsock.c | 2 ++ + 3 files changed, 8 insertions(+), 2 deletions(-) + +--- linux-2.6.19.2.orig/fs/nfsd/vfs.c ++++ linux-2.6.19.2/fs/nfsd/vfs.c +@@ -822,7 +822,8 @@ nfsd_read_actor(read_descriptor_t *desc, + rqstp->rq_res.page_len = size; + } else if (page != pp[-1]) { + get_page(page); +- put_page(*pp); ++ if (*pp) ++ put_page(*pp); + *pp = page; + rqstp->rq_resused++; + rqstp->rq_res.page_len += size; +--- linux-2.6.19.2.orig/include/linux/sunrpc/svc.h ++++ linux-2.6.19.2/include/linux/sunrpc/svc.h +@@ -144,8 +144,11 @@ extern u32 svc_max_payload(const struct + * + * Each request/reply pair can have at most one "payload", plus two pages, + * one for the request, and one for the reply. ++ * We using ->sendfile to return read data, we might need one extra page ++ * if the request is not page-aligned. So add another '1'. + */ +-#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) ++#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE \ ++ + 2 + 1) + + static inline u32 svc_getnl(struct kvec *iov) + { +--- linux-2.6.19.2.orig/net/sunrpc/svcsock.c ++++ linux-2.6.19.2/net/sunrpc/svcsock.c +@@ -1248,6 +1248,8 @@ svc_recv(struct svc_rqst *rqstp, long ti + schedule_timeout_uninterruptible(msecs_to_jiffies(500)); + rqstp->rq_pages[i] = p; + } ++ rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ ++ BUG_ON(pages >= RPCSVC_MAXPAGES); + + /* Make arg->head point to first page and arg->pages point to rest */ + arg = &rqstp->rq_arg; diff --git a/queue-2.6.19/knfsd-fix-setting-of-acl-server-versions.patch b/queue-2.6.19/knfsd-fix-setting-of-acl-server-versions.patch new file mode 100644 index 00000000000..8a4913525af --- /dev/null +++ b/queue-2.6.19/knfsd-fix-setting-of-acl-server-versions.patch @@ -0,0 +1,63 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:44:56 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:01 +1100 +Message-Id: <1070125043501.19547@suse.de> +Subject: knfsd: fix setting of ACL server versions. + +Due to silly typos, if the nfs versions are explicitly set, +no NFSACL versions get enabled. + +Also improve an error message that would have made this bug +a little easier to find. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + fs/nfsd/nfssvc.c | 8 ++++---- + net/sunrpc/svc.c | 3 ++- + 2 files changed, 6 insertions(+), 5 deletions(-) + +--- linux-2.6.19.2.orig/fs/nfsd/nfssvc.c ++++ linux-2.6.19.2/fs/nfsd/nfssvc.c +@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_progr + .pg_prog = NFS_ACL_PROGRAM, + .pg_nvers = NFSD_ACL_NRVERS, + .pg_vers = nfsd_acl_versions, +- .pg_name = "nfsd", ++ .pg_name = "nfsacl", + .pg_class = "nfsd", + .pg_stats = &nfsd_acl_svcstats, + .pg_authenticate = &svc_set_client, +@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op cha + switch(change) { + case NFSD_SET: + nfsd_versions[vers] = nfsd_version[vers]; +- break; + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + if (vers < NFSD_ACL_NRVERS) +- nfsd_acl_version[vers] = nfsd_acl_version[vers]; ++ nfsd_acl_versions[vers] = nfsd_acl_version[vers]; + #endif ++ break; + case NFSD_CLEAR: + nfsd_versions[vers] = NULL; + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + if (vers < NFSD_ACL_NRVERS) +- nfsd_acl_version[vers] = NULL; ++ nfsd_acl_versions[vers] = NULL; + #endif + break; + case NFSD_TEST: +--- linux-2.6.19.2.orig/net/sunrpc/svc.c ++++ linux-2.6.19.2/net/sunrpc/svc.c +@@ -910,7 +910,8 @@ err_bad_prog: + + err_bad_vers: + #ifdef RPC_PARANOIA +- printk("svc: unknown version (%d)\n", vers); ++ printk("svc: unknown version (%d for prog %d, %s)\n", ++ vers, prog, progp->pg_name); + #endif + serv->sv_stats->rpcbadfmt++; + svc_putnl(resv, RPC_PROG_MISMATCH); diff --git a/queue-2.6.19/knfsd-fix-type-mismatch-with-filldir_t-used-by-nfsd.patch b/queue-2.6.19/knfsd-fix-type-mismatch-with-filldir_t-used-by-nfsd.patch new file mode 100644 index 00000000000..4c62e43e40a --- /dev/null +++ b/queue-2.6.19/knfsd-fix-type-mismatch-with-filldir_t-used-by-nfsd.patch @@ -0,0 +1,160 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:45:20 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:12 +1100 +Message-Id: <1070125043512.19573@suse.de> +Subject: knfsd: fix type mismatch with filldir_t used by nfsd. + +nfsd defines a type 'encode_dent_fn' which is much like 'filldir_t' +except that the first pointer is 'struct readdir_cd *' rather than +'void *'. It then casts encode_dent_fn points to 'filldir_t' as +needed. This hides any other type mismatches between the two such as +the fact that the 'ino' arg recently changed from ino_t to u64. + +So: get rid of 'encode_dent_fn', get rid of the cast of the function +type, change the first arg of various functions from 'struct readdir_cd *' +to 'void *', and live with the fact that we have a little less type +checking on the calling of these functions now. +Less internal (to nfsd) checking offset by more external checking, which +is more important. + +Thanks to Gabriel Paubert for discovering this and +providing an initial patch. + +Signed-off-by: Gabriel Paubert +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + fs/nfsd/nfs3xdr.c | 9 +++++---- + fs/nfsd/nfs4xdr.c | 5 +++-- + fs/nfsd/nfsxdr.c | 5 +++-- + fs/nfsd/vfs.c | 4 ++-- + include/linux/nfsd/nfsd.h | 4 +--- + include/linux/nfsd/xdr.h | 4 ++-- + include/linux/nfsd/xdr3.h | 8 ++++---- + 7 files changed, 20 insertions(+), 19 deletions(-) + +--- linux-2.6.19.2.orig/fs/nfsd/nfs3xdr.c ++++ linux-2.6.19.2/fs/nfsd/nfs3xdr.c +@@ -994,15 +994,16 @@ encode_entry(struct readdir_cd *ccd, con + } + + int +-nfs3svc_encode_entry(struct readdir_cd *cd, const char *name, +- int namlen, loff_t offset, ino_t ino, unsigned int d_type) ++nfs3svc_encode_entry(void *cd, const char *name, ++ int namlen, loff_t offset, u64 ino, unsigned int d_type) + { + return encode_entry(cd, name, namlen, offset, ino, d_type, 0); + } + + int +-nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, +- int namlen, loff_t offset, ino_t ino, unsigned int d_type) ++nfs3svc_encode_entry_plus(void *cd, const char *name, ++ int namlen, loff_t offset, u64 ino, ++ unsigned int d_type) + { + return encode_entry(cd, name, namlen, offset, ino, d_type, 1); + } +--- linux-2.6.19.2.orig/fs/nfsd/nfs4xdr.c ++++ linux-2.6.19.2/fs/nfsd/nfs4xdr.c +@@ -1884,9 +1884,10 @@ nfsd4_encode_rdattr_error(__be32 *p, int + } + + static int +-nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, +- loff_t offset, ino_t ino, unsigned int d_type) ++nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, ++ loff_t offset, u64 ino, unsigned int d_type) + { ++ struct readdir_cd *ccd = ccdv; + struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); + int buflen; + __be32 *p = cd->buffer; +--- linux-2.6.19.2.orig/fs/nfsd/nfsxdr.c ++++ linux-2.6.19.2/fs/nfsd/nfsxdr.c +@@ -467,9 +467,10 @@ nfssvc_encode_statfsres(struct svc_rqst + } + + int +-nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, +- int namlen, loff_t offset, ino_t ino, unsigned int d_type) ++nfssvc_encode_entry(void *ccdv, const char *name, ++ int namlen, loff_t offset, u64 ino, unsigned int d_type) + { ++ struct readdir_cd *ccd = ccdv; + struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); + __be32 *p = cd->buffer; + int buflen, slen; +--- linux-2.6.19.2.orig/fs/nfsd/vfs.c ++++ linux-2.6.19.2/fs/nfsd/vfs.c +@@ -1727,7 +1727,7 @@ out: + */ + __be32 + nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, +- struct readdir_cd *cdp, encode_dent_fn func) ++ struct readdir_cd *cdp, filldir_t func) + { + __be32 err; + int host_err; +@@ -1752,7 +1752,7 @@ nfsd_readdir(struct svc_rqst *rqstp, str + + do { + cdp->err = nfserr_eof; /* will be cleared on successful read */ +- host_err = vfs_readdir(file, (filldir_t) func, cdp); ++ host_err = vfs_readdir(file, func, cdp); + } while (host_err >=0 && cdp->err == nfs_ok); + if (host_err) + err = nfserrno(host_err); +--- linux-2.6.19.2.orig/include/linux/nfsd/nfsd.h ++++ linux-2.6.19.2/include/linux/nfsd/nfsd.h +@@ -52,8 +52,6 @@ + struct readdir_cd { + __be32 err; /* 0, nfserr, or nfserr_eof */ + }; +-typedef int (*encode_dent_fn)(struct readdir_cd *, const char *, +- int, loff_t, ino_t, unsigned int); + typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); + + extern struct svc_program nfsd_program; +@@ -117,7 +115,7 @@ __be32 nfsd_unlink(struct svc_rqst *, s + int nfsd_truncate(struct svc_rqst *, struct svc_fh *, + unsigned long size); + __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, +- loff_t *, struct readdir_cd *, encode_dent_fn); ++ loff_t *, struct readdir_cd *, filldir_t); + __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, + struct kstatfs *); + +--- linux-2.6.19.2.orig/include/linux/nfsd/xdr3.h ++++ linux-2.6.19.2/include/linux/nfsd/xdr3.h +@@ -331,11 +331,11 @@ int nfs3svc_release_fhandle(struct svc_r + struct nfsd3_attrstat *); + int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, + struct nfsd3_fhandle_pair *); +-int nfs3svc_encode_entry(struct readdir_cd *, const char *name, +- int namlen, loff_t offset, ino_t ino, ++int nfs3svc_encode_entry(void *, const char *name, ++ int namlen, loff_t offset, u64 ino, + unsigned int); +-int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, +- int namlen, loff_t offset, ino_t ino, ++int nfs3svc_encode_entry_plus(void *, const char *name, ++ int namlen, loff_t offset, u64 ino, + unsigned int); + /* Helper functions for NFSv3 ACL code */ + __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, +--- linux-2.6.19.2.orig/include/linux/nfsd/xdr.h ++++ linux-2.6.19.2/include/linux/nfsd/xdr.h +@@ -165,8 +165,8 @@ int nfssvc_encode_readres(struct svc_rqs + int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); + int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); + +-int nfssvc_encode_entry(struct readdir_cd *, const char *name, +- int namlen, loff_t offset, ino_t ino, unsigned int); ++int nfssvc_encode_entry(void *, const char *name, ++ int namlen, loff_t offset, u64 ino, unsigned int); + + int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); + diff --git a/queue-2.6.19/knfsd-fix-up-some-bit-rot-in-exp_export.patch b/queue-2.6.19/knfsd-fix-up-some-bit-rot-in-exp_export.patch new file mode 100644 index 00000000000..81ff84bda5d --- /dev/null +++ b/queue-2.6.19/knfsd-fix-up-some-bit-rot-in-exp_export.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:45:28 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:17 +1100 +Message-Id: <1070125043517.19586@suse.de> +Subject: knfsd: fix up some bit-rot in exp_export + +The nfsservctl systemcall isn't used but recent nfs-utils releases for +exporting filesystems, and consequently the code that is uses - +exp_export - has suffered some bitrot. + +Particular: + - some newly added fields in 'struct svc_export' are being initialised + properly. + - the return value is now always -ENOMEM ... + +This patch fixes both these problems. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + fs/nfsd/export.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- linux-2.6.19.2.orig/fs/nfsd/export.c ++++ linux-2.6.19.2/fs/nfsd/export.c +@@ -950,6 +950,8 @@ exp_export(struct nfsctl_export *nxp) + + exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); + ++ memset(&new, 0, sizeof(new)); ++ + /* must make sure there won't be an ex_fsid clash */ + if ((nxp->ex_flags & NFSEXP_FSID) && + (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && +@@ -980,6 +982,9 @@ exp_export(struct nfsctl_export *nxp) + + new.h.expiry_time = NEVER; + new.h.flags = 0; ++ new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); ++ if (!new.ex_path) ++ goto finish; + new.ex_client = clp; + new.ex_mnt = nd.mnt; + new.ex_dentry = nd.dentry; +@@ -1000,10 +1005,11 @@ exp_export(struct nfsctl_export *nxp) + /* failed to create at least one index */ + exp_do_unexport(exp); + cache_flush(); +- err = -ENOMEM; +- } +- ++ } else ++ err = 0; + finish: ++ if (new.ex_path) ++ kfree(new.ex_path); + if (exp) + exp_put(exp); + if (fsid_key && !IS_ERR(fsid_key)) diff --git a/queue-2.6.19/md-assorted-md-and-raid1-one-liners.patch b/queue-2.6.19/md-assorted-md-and-raid1-one-liners.patch new file mode 100644 index 00000000000..86613bd8ac5 --- /dev/null +++ b/queue-2.6.19/md-assorted-md-and-raid1-one-liners.patch @@ -0,0 +1,68 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:45:34 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:21 +1100 +Message-Id: <1070125043521.19602@suse.de> +Subject: md: assorted md and raid1 one-liners + +Fix few bugs that meant that: + - superblocks weren't alway written at exactly the right time (this + could show up if the array was not written to - writting to the array + causes lots of superblock updates and so hides these errors). + + - restarting device recovery after a clean shutdown (version-1 metadata + only) didn't work as intended (or at all). + +1/ Ensure superblock is updated when a new device is added. +2/ Remove an inappropriate test on MD_RECOVERY_SYNC in md_do_sync. + The body of this if takes one of two branches depending on whether + MD_RECOVERY_SYNC is set, so testing it in the clause of the if + is wrong. +3/ Flag superblock for updating after a resync/recovery finishes. +4/ If we find the neeed to restart a recovery in the middle (version-1 + metadata only) make sure a full recovery (not just as guided by + bitmaps) does get done. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + drivers/md/md.c | 3 ++- + drivers/md/raid1.c | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/drivers/md/md.c ++++ linux-2.6.19.2/drivers/md/md.c +@@ -3722,6 +3722,7 @@ static int add_new_disk(mddev_t * mddev, + if (err) + export_rdev(rdev); + ++ md_update_sb(mddev, 1); + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + md_wakeup_thread(mddev->thread); + return err; +@@ -5273,7 +5274,6 @@ void md_do_sync(mddev_t *mddev) + mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); + + if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && +- test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && + !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && + mddev->curr_resync > 2) { + if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { +@@ -5297,6 +5297,7 @@ void md_do_sync(mddev_t *mddev) + rdev->recovery_offset = mddev->curr_resync; + } + } ++ set_bit(MD_CHANGE_DEVS, &mddev->flags); + + skip: + mddev->curr_resync = 0; +--- linux-2.6.19.2.orig/drivers/md/raid1.c ++++ linux-2.6.19.2/drivers/md/raid1.c +@@ -1956,6 +1956,7 @@ static int run(mddev_t *mddev) + !test_bit(In_sync, &disk->rdev->flags)) { + disk->head_position = 0; + mddev->degraded++; ++ conf->fullsync = 1; + } + } + if (mddev->degraded == conf->raid_disks) { diff --git a/queue-2.6.19/md-fix-a-few-problems-with-the-interface-to-md.patch b/queue-2.6.19/md-fix-a-few-problems-with-the-interface-to-md.patch new file mode 100644 index 00000000000..2602be98f8b --- /dev/null +++ b/queue-2.6.19/md-fix-a-few-problems-with-the-interface-to-md.patch @@ -0,0 +1,89 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:45:45 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:29 +1100 +Message-Id: <1070125043529.19626@suse.de> +Subject: md: fix a few problems with the interface (sysfs and ioctl) to md. + +While developing more functionality in mdadm I found some bugs in md... + +- When we remove a device from an inactive array (write 'remove' to + the 'state' sysfs file - see 'state_store') would should not + update the superblock information - as we may not have + read and processed it all properly yet. + +- initialise all raid_disk entries to '-1' else the 'slot sysfs file + will claim '0' for all devices in an array before the array is + started. + +- all '\n' not to be present at the end of words written to + sysfs files +- when we use SET_ARRAY_INFO to set the md metadata version, + set the flag to say that there is persistant metadata. +- allow GET_BITMAP_FILE to be called on an array that hasn't + been started yet. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + drivers/md/md.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- linux-2.6.19.2.orig/drivers/md/md.c ++++ linux-2.6.19.2/drivers/md/md.c +@@ -1792,7 +1792,8 @@ state_store(mdk_rdev_t *rdev, const char + else { + mddev_t *mddev = rdev->mddev; + kick_rdev_from_array(rdev); +- md_update_sb(mddev, 1); ++ if (mddev->pers) ++ md_update_sb(mddev, 1); + md_new_event(mddev); + err = 0; + } +@@ -2004,6 +2005,7 @@ static mdk_rdev_t *md_import_device(dev_ + + rdev->desc_nr = -1; + rdev->saved_raid_disk = -1; ++ rdev->raid_disk = -1; + rdev->flags = 0; + rdev->data_offset = 0; + rdev->sb_events = 0; +@@ -2233,7 +2235,6 @@ static int update_raid_disks(mddev_t *md + static ssize_t + raid_disks_store(mddev_t *mddev, const char *buf, size_t len) + { +- /* can only set raid_disks if array is not yet active */ + char *e; + int rv = 0; + unsigned long n = simple_strtoul(buf, &e, 10); +@@ -2631,7 +2632,7 @@ metadata_store(mddev_t *mddev, const cha + return -EINVAL; + buf = e+1; + minor = simple_strtoul(buf, &e, 10); +- if (e==buf || *e != '\n') ++ if (e==buf || (*e && *e != '\n') ) + return -EINVAL; + if (major >= sizeof(super_types)/sizeof(super_types[0]) || + super_types[major].name == NULL) +@@ -3978,6 +3979,7 @@ static int set_array_info(mddev_t * mdde + mddev->major_version = info->major_version; + mddev->minor_version = info->minor_version; + mddev->patch_version = info->patch_version; ++ mddev->persistent = ! info->not_persistent; + return 0; + } + mddev->major_version = MD_MAJOR_VERSION; +@@ -4302,9 +4304,10 @@ static int md_ioctl(struct inode *inode, + * Commands querying/configuring an existing array: + */ + /* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY, +- * RUN_ARRAY, and SET_BITMAP_FILE are allowed */ ++ * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */ + if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY +- && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) { ++ && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE ++ && cmd != GET_BITMAP_FILE) { + err = -ENODEV; + goto abort_unlock; + } diff --git a/queue-2.6.19/md-fix-potential-memalloc-deadlock-in-md.patch b/queue-2.6.19/md-fix-potential-memalloc-deadlock-in-md.patch new file mode 100644 index 00000000000..b3346db0cc3 --- /dev/null +++ b/queue-2.6.19/md-fix-potential-memalloc-deadlock-in-md.patch @@ -0,0 +1,112 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:46:19 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:34 +1100 +Message-Id: <1070125043534.19638@suse.de> +Subject: md: fix potential memalloc deadlock in md + +If a GFP_KERNEL allocation is attempted in md while the mddev_lock is +held, it is possible for a deadlock to eventuate. +This happens if the array was marked 'clean', and the memalloc triggers +a write-out to the md device. +For the writeout to succeed, the array must be marked 'dirty', and that +requires getting the mddev_lock. + +So, before attempting a GFP_KERNEL alloction while holding the lock, +make sure the array is marked 'dirty' (unless it is currently read-only). + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + drivers/md/md.c | 29 +++++++++++++++++++++++++++++ + drivers/md/raid1.c | 2 ++ + drivers/md/raid5.c | 3 +++ + include/linux/raid/md.h | 2 +- + 4 files changed, 35 insertions(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/drivers/md/md.c ++++ linux-2.6.19.2/drivers/md/md.c +@@ -3561,6 +3561,8 @@ static int get_bitmap_file(mddev_t * mdd + char *ptr, *buf = NULL; + int err = -ENOMEM; + ++ md_allow_write(mddev); ++ + file = kmalloc(sizeof(*file), GFP_KERNEL); + if (!file) + goto out; +@@ -5029,6 +5031,33 @@ void md_write_end(mddev_t *mddev) + } + } + ++/* md_allow_write(mddev) ++ * Calling this ensures that the array is marked 'active' so that writes ++ * may proceed without blocking. It is important to call this before ++ * attempting a GFP_KERNEL allocation while holding the mddev lock. ++ * Must be called with mddev_lock held. ++ */ ++void md_allow_write(mddev_t *mddev) ++{ ++ if (!mddev->pers) ++ return; ++ if (mddev->ro) ++ return; ++ ++ spin_lock_irq(&mddev->write_lock); ++ if (mddev->in_sync) { ++ mddev->in_sync = 0; ++ set_bit(MD_CHANGE_CLEAN, &mddev->flags); ++ if (mddev->safemode_delay && ++ mddev->safemode == 0) ++ mddev->safemode = 1; ++ spin_unlock_irq(&mddev->write_lock); ++ md_update_sb(mddev, 0); ++ } else ++ spin_unlock_irq(&mddev->write_lock); ++} ++EXPORT_SYMBOL_GPL(md_allow_write); ++ + static DECLARE_WAIT_QUEUE_HEAD(resync_wait); + + #define SYNC_MARKS 10 +--- linux-2.6.19.2.orig/drivers/md/raid1.c ++++ linux-2.6.19.2/drivers/md/raid1.c +@@ -2104,6 +2104,8 @@ static int raid1_reshape(mddev_t *mddev) + return -EINVAL; + } + ++ md_allow_write(mddev); ++ + raid_disks = mddev->raid_disks + mddev->delta_disks; + + if (raid_disks < conf->raid_disks) { +--- linux-2.6.19.2.orig/drivers/md/raid5.c ++++ linux-2.6.19.2/drivers/md/raid5.c +@@ -403,6 +403,8 @@ static int resize_stripes(raid5_conf_t * + if (newsize <= conf->pool_size) + return 0; /* never bother to shrink */ + ++ md_allow_write(conf->mddev); ++ + /* Step 1 */ + sc = kmem_cache_create(conf->cache_name[1-conf->active_name], + sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), +@@ -3045,6 +3047,7 @@ raid5_store_stripe_cache_size(mddev_t *m + else + break; + } ++ md_allow_write(mddev); + while (new > conf->max_nr_stripes) { + if (grow_one_stripe(conf)) + conf->max_nr_stripes++; +--- linux-2.6.19.2.orig/include/linux/raid/md.h ++++ linux-2.6.19.2/include/linux/raid/md.h +@@ -94,7 +94,7 @@ extern int sync_page_io(struct block_dev + struct page *page, int rw); + extern void md_do_sync(mddev_t *mddev); + extern void md_new_event(mddev_t *mddev); +- ++extern void md_allow_write(mddev_t *mddev); + + #endif /* CONFIG_MD */ + #endif diff --git a/queue-2.6.19/md-make-repair-actually-work-for-raid1.patch b/queue-2.6.19/md-make-repair-actually-work-for-raid1.patch new file mode 100644 index 00000000000..30d15bee6c7 --- /dev/null +++ b/queue-2.6.19/md-make-repair-actually-work-for-raid1.patch @@ -0,0 +1,32 @@ +From stable-bounces@linux.kernel.org Wed Jan 24 20:46:14 2007 +From: NeilBrown +To: stable@kernel.org +Date: Thu, 25 Jan 2007 15:35:25 +1100 +Message-Id: <1070125043525.19614@suse.de> +Subject: md: make 'repair' actually work for raid1. + +When 'repair' finds a block that is different one the various +parts of the mirror. it is meant to write a chosen good version +to the others. However it currently writes out the original data +to each. The memcpy to make all the data the same is missing. + +Signed-off-by: Neil Brown +Signed-off-by: Chris Wright +--- + drivers/md/raid1.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- linux-2.6.19.2.orig/drivers/md/raid1.c ++++ linux-2.6.19.2/drivers/md/raid1.c +@@ -1266,6 +1266,11 @@ static void sync_request_write(mddev_t * + sbio->bi_sector = r1_bio->sector + + conf->mirrors[i].rdev->data_offset; + sbio->bi_bdev = conf->mirrors[i].rdev->bdev; ++ for (j = 0; j < vcnt ; j++) ++ memcpy(page_address(sbio->bi_io_vec[j].bv_page), ++ page_address(pbio->bi_io_vec[j].bv_page), ++ PAGE_SIZE); ++ + } + } + } diff --git a/queue-2.6.19/remove-__devinit-markings-from-rtc_sysfs_add_device.patch b/queue-2.6.19/remove-__devinit-markings-from-rtc_sysfs_add_device.patch new file mode 100644 index 00000000000..dd49c17932f --- /dev/null +++ b/queue-2.6.19/remove-__devinit-markings-from-rtc_sysfs_add_device.patch @@ -0,0 +1,29 @@ +From a8d814b5dd7a1bc5c19ae32d35b8bd4d8a510eae Mon Sep 17 00:00:00 2001 +Message-Id: <200701260857.l0Q8v8co012068@shell0.pdx.osdl.net> +From: Mike Frysinger +Date: Fri, 26 Jan 2007 00:57:08 -0800 +Subject: remove __devinit markings from rtc_sysfs_add_device() + +rtc_sysfs_add_device is needed even after dev initialization, so drop __devinit. + +Signed-off-by: Mike Frysinger +Acked-by: Alessandro Zummo +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- + drivers/rtc/rtc-sysfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/drivers/rtc/rtc-sysfs.c ++++ linux-2.6.19.2/drivers/rtc/rtc-sysfs.c +@@ -78,7 +78,7 @@ static struct attribute_group rtc_attr_g + .attrs = rtc_attrs, + }; + +-static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, ++static int rtc_sysfs_add_device(struct class_device *class_dev, + struct class_interface *class_intf) + { + int err; diff --git a/queue-2.6.19/series b/queue-2.6.19/series index a86218fb957..003b553893d 100644 --- a/queue-2.6.19/series +++ b/queue-2.6.19/series @@ -28,4 +28,29 @@ x86-work-around-gcc-4.2-over-aggressive-optimizer.patch netfilter-fix-iptables-abi-breakage-on-cris.patch elevator-move-clearing-of-unplug-flag-earlier.patch revert-fix-up-mmap_kmem.patch +remove-__devinit-markings-from-rtc_sysfs_add_device.patch +sparc64-set-g4-g5-properly-in-sun4v-dtlb-prot-handling.patch +sis190-failure-to-set-the-mac-address-from-eeprom.patch +knfsd-fix-setting-of-acl-server-versions.patch +knfsd-fix-an-nfsd-bug-with-full-sized-non-page-aligned-reads.patch +knfsd-fix-type-mismatch-with-filldir_t-used-by-nfsd.patch +knfsd-fix-up-some-bit-rot-in-exp_export.patch +md-assorted-md-and-raid1-one-liners.patch +md-make-repair-actually-work-for-raid1.patch +md-fix-a-few-problems-with-the-interface-to-md.patch +md-fix-potential-memalloc-deadlock-in-md.patch +use-kmap_atomic-in-scsi-simulator.patch +don-t-allow-the-stack-to-grow-into-hugetlb-reserved-regions.patch +uml-fix-signal-frame-alignment.patch +bonding-arp-monitoring-broken-on-x86_64.patch +jmicron-40-80pin-primary-detection.patch +decnet-handle-a-failure-in-neigh_parms_alloc.patch +sparc32-fix-over-optimization-by-gcc-near-ip_fast_csum.patch +ipv4-fix-the-fib-trie-iterator-to-work-with-a-single-entry-routing-tables.patch +ipv4-fix-single-entry-proc-net-fib_trie-output.patch +af_packet-fix-bpf-handling.patch +af_packet-check-device-down-state-before-hard-header-callbacks.patch +tcp-rare-bad-tcp-checksum-with-2.6.19.patch +tcp-fix-sorting-of-sack-blocks.patch +tcp-skb-is-unexpectedly-freed.patch sunrpc-give-cloned-rpc-clients-their-own-rpc_pipefs-directory.patch diff --git a/queue-2.6.19/sis190-failure-to-set-the-mac-address-from-eeprom.patch b/queue-2.6.19/sis190-failure-to-set-the-mac-address-from-eeprom.patch new file mode 100644 index 00000000000..631b11e023a --- /dev/null +++ b/queue-2.6.19/sis190-failure-to-set-the-mac-address-from-eeprom.patch @@ -0,0 +1,27 @@ +From 7939aae0c08412138a827e0af6f16fc19c346353 Mon Sep 17 00:00:00 2001 +From: Francois Romieu +Date: Thu, 18 Jan 2007 23:22:23 +0100 +Subject: sis190: failure to set the MAC address from EEPROM + +Fix from http://bugzilla.kernel.org/show_bug.cgi?id=7747 + +Signed-off-by: Andrew Morton +Cc: +Signed-off-by: Francois Romieu +Signed-off-by: Jeff Garzik +Signed-off-by: Chris Wright +--- + drivers/net/sis190.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/drivers/net/sis190.c ++++ linux-2.6.19.2/drivers/net/sis190.c +@@ -1559,7 +1559,7 @@ static int __devinit sis190_get_mac_addr + for (i = 0; i < MAC_ADDR_LEN / 2; i++) { + __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i); + +- ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); ++ ((u16 *)dev->dev_addr)[i] = le16_to_cpu(w); + } + + sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo)); diff --git a/queue-2.6.19/sparc32-fix-over-optimization-by-gcc-near-ip_fast_csum.patch b/queue-2.6.19/sparc32-fix-over-optimization-by-gcc-near-ip_fast_csum.patch new file mode 100644 index 00000000000..5535f7ff15a --- /dev/null +++ b/queue-2.6.19/sparc32-fix-over-optimization-by-gcc-near-ip_fast_csum.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:02:21 2007 +Date: Fri, 02 Feb 2007 12:52:15 -0800 (PST) +Message-Id: <20070202.125215.79038605.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: SPARC32: Fix over-optimization by GCC near ip_fast_csum. + +From: Bob Breuer + +In some cases such as: + iph->check = 0; + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); +GCC may optimize out the previous store. + +Observed as a failure of NFS over udp (bad checksums on ip fragments) +when compiled with GCC 3.4.2. + +Signed-off-by: Bob Breuer +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + include/asm-sparc/checksum.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/include/asm-sparc/checksum.h ++++ linux-2.6.19.2/include/asm-sparc/checksum.h +@@ -159,7 +159,7 @@ static inline unsigned short ip_fast_csu + "xnor\t%%g0, %0, %0" + : "=r" (sum), "=&r" (iph) + : "r" (ihl), "1" (iph) +- : "g2", "g3", "g4", "cc"); ++ : "g2", "g3", "g4", "cc", "memory"); + return sum; + } + diff --git a/queue-2.6.19/sparc64-set-g4-g5-properly-in-sun4v-dtlb-prot-handling.patch b/queue-2.6.19/sparc64-set-g4-g5-properly-in-sun4v-dtlb-prot-handling.patch new file mode 100644 index 00000000000..ac509468252 --- /dev/null +++ b/queue-2.6.19/sparc64-set-g4-g5-properly-in-sun4v-dtlb-prot-handling.patch @@ -0,0 +1,51 @@ +From stable-bounces@linux.kernel.org Fri Jan 26 19:26:52 2007 +Date: Fri, 26 Jan 2007 19:17:10 -0800 (PST) +Message-Id: <20070126.191710.105430954.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: SPARC64: Set g4/g5 properly in sun4v dtlb-prot handling. + +From: David S. Miller + +Mirror the logic in the sun4u handler, we have to update +both registers even when we branch out to window fault +fixup handling. + +The way it works is that if we are in etrap processing a +fault already, g4/g5 holds the original fault information. +If we take a window spill fault while doing etrap, then +we put the window spill fault info into g4/g5 and this is +what the top-level fault handler ends up processing first. + +Then we retry the originally faulting instruction, and +process the original fault at that time. + +This is all necessary because of how constrained the trap +registers are in these code paths. These cases trigger +very rarely, so even if there is some performance implication +it's doesn't happen very often. In fact the rarity is why +it took so long to trigger and find this particular bug. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + +--- + arch/sparc64/kernel/sun4v_tlb_miss.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.19.2.orig/arch/sparc64/kernel/sun4v_tlb_miss.S ++++ linux-2.6.19.2/arch/sparc64/kernel/sun4v_tlb_miss.S +@@ -142,9 +142,9 @@ sun4v_dtlb_prot: + rdpr %tl, %g1 + cmp %g1, 1 + bgu,pn %xcc, winfix_trampoline +- nop +- ba,pt %xcc, sparc64_realfault_common + mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 ++ ba,pt %xcc, sparc64_realfault_common ++ nop + + /* Called from trap table: + * %g4: vaddr diff --git a/queue-2.6.19/tcp-fix-sorting-of-sack-blocks.patch b/queue-2.6.19/tcp-fix-sorting-of-sack-blocks.patch new file mode 100644 index 00000000000..04b6eafb5a6 --- /dev/null +++ b/queue-2.6.19/tcp-fix-sorting-of-sack-blocks.patch @@ -0,0 +1,43 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:26:17 2007 +Date: Fri, 02 Feb 2007 13:16:09 -0800 (PST) +Message-Id: <20070202.131609.21897957.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: TCP: Fix sorting of SACK blocks. + +From: Baruch Even + +The sorting of SACK blocks actually munges them rather than sort, +causing the TCP stack to ignore some SACK information and breaking the +assumption of ordered SACK blocks after sorting. + +The sort takes the data from a second buffer which isn't moved causing +subsequent data moves to occur from the wrong location. The fix is to +use a temporary buffer as a normal sort does. + +Signed-off-By: Baruch Even +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/ipv4/tcp_input.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- linux-2.6.19.2.orig/net/ipv4/tcp_input.c ++++ linux-2.6.19.2/net/ipv4/tcp_input.c +@@ -1011,10 +1011,11 @@ tcp_sacktag_write_queue(struct sock *sk, + for (j = 0; j < i; j++){ + if (after(ntohl(sp[j].start_seq), + ntohl(sp[j+1].start_seq))){ +- sp[j].start_seq = htonl(tp->recv_sack_cache[j+1].start_seq); +- sp[j].end_seq = htonl(tp->recv_sack_cache[j+1].end_seq); +- sp[j+1].start_seq = htonl(tp->recv_sack_cache[j].start_seq); +- sp[j+1].end_seq = htonl(tp->recv_sack_cache[j].end_seq); ++ struct tcp_sack_block_wire tmp; ++ ++ tmp = sp[j]; ++ sp[j] = sp[j+1]; ++ sp[j+1] = tmp; + } + + } diff --git a/queue-2.6.19/tcp-rare-bad-tcp-checksum-with-2.6.19.patch b/queue-2.6.19/tcp-rare-bad-tcp-checksum-with-2.6.19.patch new file mode 100644 index 00000000000..18b701a9105 --- /dev/null +++ b/queue-2.6.19/tcp-rare-bad-tcp-checksum-with-2.6.19.patch @@ -0,0 +1,38 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:25:10 2007 +Date: Fri, 02 Feb 2007 13:15:00 -0800 (PST) +Message-Id: <20070202.131500.08351780.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: TCP: rare bad TCP checksum with 2.6.19 + +From: Jarek Poplawski + +The patch "Replace CHECKSUM_HW by CHECKSUM_PARTIAL/CHECKSUM_COMPLETE" +changed to unconditional copying of ip_summed field from collapsed +skb. This patch reverts this change. + +The majority of substantial work including heavy testing +and diagnosing by: Michael Tokarev +Possible reasons pointed by: Herbert Xu and Patrick McHardy. + +Signed-off-by: Jarek Poplawski +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/ipv4/tcp_output.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- linux-2.6.19.2.orig/net/ipv4/tcp_output.c ++++ linux-2.6.19.2/net/ipv4/tcp_output.c +@@ -1590,7 +1590,8 @@ static void tcp_retrans_try_collapse(str + + memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); + +- skb->ip_summed = next_skb->ip_summed; ++ if (next_skb->ip_summed == CHECKSUM_PARTIAL) ++ skb->ip_summed = CHECKSUM_PARTIAL; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size); diff --git a/queue-2.6.19/tcp-skb-is-unexpectedly-freed.patch b/queue-2.6.19/tcp-skb-is-unexpectedly-freed.patch new file mode 100644 index 00000000000..f878c0ece40 --- /dev/null +++ b/queue-2.6.19/tcp-skb-is-unexpectedly-freed.patch @@ -0,0 +1,59 @@ +From stable-bounces@linux.kernel.org Fri Feb 2 13:27:19 2007 +Date: Fri, 02 Feb 2007 13:17:13 -0800 (PST) +Message-Id: <20070202.131713.28817849.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: TCP: skb is unexpectedly freed. + +From: Masayuki Nakagawa + +I encountered a kernel panic with my test program, which is a very +simple IPv6 client-server program. + +The server side sets IPV6_RECVPKTINFO on a listening socket, and the +client side just sends a message to the server. Then the kernel panic +occurs on the server. (If you need the test program, please let me +know. I can provide it.) + +This problem happens because a skb is forcibly freed in +tcp_rcv_state_process(). + +When a socket in listening state(TCP_LISTEN) receives a syn packet, +then tcp_v6_conn_request() will be called from +tcp_rcv_state_process(). If the tcp_v6_conn_request() successfully +returns, the skb would be discarded by __kfree_skb(). + +However, in case of a listening socket which was already set +IPV6_RECVPKTINFO, an address of the skb will be stored in +treq->pktopts and a ref count of the skb will be incremented in +tcp_v6_conn_request(). But, even if the skb is still in use, the skb +will be freed. Then someone still using the freed skb will cause the +kernel panic. + +I suggest to use kfree_skb() instead of __kfree_skb(). + +Signed-off-by: Masayuki Nakagawa +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- + net/ipv4/tcp_input.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- linux-2.6.19.2.orig/net/ipv4/tcp_input.c ++++ linux-2.6.19.2/net/ipv4/tcp_input.c +@@ -4411,9 +4411,11 @@ int tcp_rcv_state_process(struct sock *s + * But, this leaves one open to an easy denial of + * service attack, and SYN cookies can't defend + * against this problem. So, we drop the data +- * in the interest of security over speed. ++ * in the interest of security over speed unless ++ * it's still in use. + */ +- goto discard; ++ kfree_skb(skb); ++ return 0; + } + goto discard; + diff --git a/queue-2.6.19/uml-fix-signal-frame-alignment.patch b/queue-2.6.19/uml-fix-signal-frame-alignment.patch new file mode 100644 index 00000000000..4ff055e82eb --- /dev/null +++ b/queue-2.6.19/uml-fix-signal-frame-alignment.patch @@ -0,0 +1,55 @@ +From stable-bounces@linux.kernel.org Tue Jan 30 14:46:20 2007 +Message-Id: <200701302236.l0UMaIuI031666@shell0.pdx.osdl.net> +To: torvalds@linux-foundation.org +From: akpm@osdl.org +Date: Tue, 30 Jan 2007 14:36:17 -0800 +Cc: akpm@osdl.org, jdike@addtoit.com, blaisorblade@yahoo.it, bunk@stusta.de, antoine@nagafix.co.uk, stable@kernel.org +Subject: uml: fix signal frame alignment + +From: Jeff Dike + +Use the same signal frame alignment calculations as the underlying +architecture. x86_64 appeared to do this, but the "- 8" was really +subtracting 8 * sizeof(struct rt_sigframe) rather than 8 bytes. + +UML/i386 might have been OK, but I changed the calculation to match +i386 just to be sure. + +Signed-off-by: Jeff Dike +Cc: +Cc: Adrian Bunk +Cc: Paolo 'Blaisorblade' Giarrusso +Acked-by: Antoine Martin +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + arch/um/sys-i386/signal.c | 3 ++- + arch/um/sys-x86_64/signal.c | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- linux-2.6.19.2.orig/arch/um/sys-i386/signal.c ++++ linux-2.6.19.2/arch/um/sys-i386/signal.c +@@ -219,7 +219,8 @@ int setup_signal_stack_sc(unsigned long + unsigned long save_sp = PT_REGS_SP(regs); + int err = 0; + +- stack_top &= -8UL; ++ /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ ++ stack_top = ((stack_top + 4) & -16UL) - 4; + frame = (struct sigframe __user *) stack_top - 1; + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + return 1; +--- linux-2.6.19.2.orig/arch/um/sys-x86_64/signal.c ++++ linux-2.6.19.2/arch/um/sys-x86_64/signal.c +@@ -191,8 +191,9 @@ int setup_signal_stack_si(unsigned long + struct task_struct *me = current; + + frame = (struct rt_sigframe __user *) +- round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; +- frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128); ++ round_down(stack_top - sizeof(struct rt_sigframe), 16); ++ /* Subtract 128 for a red zone and 8 for proper alignment */ ++ frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); + + if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) + goto out; diff --git a/queue-2.6.19/use-kmap_atomic-in-scsi-simulator.patch b/queue-2.6.19/use-kmap_atomic-in-scsi-simulator.patch new file mode 100644 index 00000000000..ee8c3ce413d --- /dev/null +++ b/queue-2.6.19/use-kmap_atomic-in-scsi-simulator.patch @@ -0,0 +1,47 @@ +From da02d2a16ef3accd625f9e6e7bf83bb0f946ff62 Mon Sep 17 00:00:00 2001 +From: Jeff Garzik +Date: Mon, 11 Dec 2006 11:05:53 -0500 +Subject: [libata] use kmap_atomic(KM_IRQ0) in SCSI simulator + +We are inside spin_lock_irqsave(). quoth akpm's debug facility: + + [ 231.948000] SCSI device sda: 195371568 512-byte hdwr sectors (100030 MB) + [ 232.232000] ata1.00: configured for UDMA/33 + [ 232.404000] WARNING (1) at arch/i386/mm/highmem.c:47 kmap_atomic() + [ 232.404000] [] kmap_atomic+0xa9/0x1ab + [ 232.404000] [] ata_scsi_rbuf_get+0x1c/0x30 + [ 232.404000] [] ata_scsi_rbuf_fill+0x1a/0x87 + [ 232.404000] [] ata_scsiop_mode_sense+0x0/0x309 + [ 232.404000] [] end_bio_bh_io_sync+0x0/0x37 + [ 232.404000] [] scsi_done+0x0/0x16 + [ 232.404000] [] scsi_done+0x0/0x16 + [ 232.404000] [] ata_scsi_simulate+0xb0/0x13f +[...] + +Signed-off-by: Jeff Garzik +Cc: Andrew Morton +Signed-off-by: Chris Wright +--- + drivers/ata/libata-scsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.19.2.orig/drivers/ata/libata-scsi.c ++++ linux-2.6.19.2/drivers/ata/libata-scsi.c +@@ -1648,7 +1648,7 @@ static unsigned int ata_scsi_rbuf_get(st + struct scatterlist *sg; + + sg = (struct scatterlist *) cmd->request_buffer; +- buf = kmap_atomic(sg->page, KM_USER0) + sg->offset; ++ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + buflen = sg->length; + } else { + buf = cmd->request_buffer; +@@ -1676,7 +1676,7 @@ static inline void ata_scsi_rbuf_put(str + struct scatterlist *sg; + + sg = (struct scatterlist *) cmd->request_buffer; +- kunmap_atomic(buf - sg->offset, KM_USER0); ++ kunmap_atomic(buf - sg->offset, KM_IRQ0); + } + } +