--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: AF_PACKET: Check device down state before hard header callbacks.
+
+From: David S. Miller <davem@sunset.davemloft.net>
+
+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 <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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
+ */
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: AF_PACKET: Fix BPF handling.
+
+From: David S. Miller <davem@sunset.davemloft.net>
+
+This fixes a bug introduced by:
+
+commit fda9ef5d679b07c9d9097aaf6ef7f069d794a8f9
+Author: Dmitry Mishin <dim@openvz.org>
+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 <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
--- /dev/null
+From f8a8ccd56d82bd4f4b5c7c2e7eb758c7764d98e1 Mon Sep 17 00:00:00 2001
+From: Andy Gospodarek <andy@greyhouse.net>
+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 <andy@greyhouse.net>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Stephen Hemminger <shemminger@osdl.org>
+Cc: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: DECNET: Handle a failure in neigh_parms_alloc (take 2)
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+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 <ebiederm@xmission.com>
+Acked-by: Steven Whitehouse <steve@chygwyn.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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);
--- /dev/null
+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 <agl@us.ibm.com>
+
+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 <agl@us.ibm.com>
+Cc: David Gibson <david@gibson.dropbear.id.au>
+Cc: William Lee Irwin III <wli@holomorphy.com>
+Cc: Hugh Dickins <hugh@veritas.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ 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.
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: IPV4: Fix single-entry /proc/net/fib_trie output.
+
+From: Robert Olsson <robert.olsson@its.uu.se>
+
+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 <robert.olsson@its.uu.se>
+Acked-by: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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, "<local>:\n");
++ else
++ seq_puts(seq, "<main>:\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, "<local>:\n");
+- else
+- seq_puts(seq, "<main>:\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,
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: IPV4: Fix the fib trie iterator to work with a single entry routing tables
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+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 <ebiederm@xmission.com>
+Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
--- /dev/null
+From 99abaf51e25f7d4ac2081e5cdc1f01baa0543514 Mon Sep 17 00:00:00 2001
+From: ethanhsiao@jmicron.com <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 <jeff@garzik.org>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+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 <davej@redhat.com>
+Signed-off-by: Chuck Ebbert <cebbert@redhat.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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, },
+ };
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:45:09 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:44:56 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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);
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:45:20 2007
+From: NeilBrown <neilb@suse.de>
+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 <paubert@iram.es> for discovering this and
+providing an initial patch.
+
+Signed-off-by: Gabriel Paubert <paubert@iram.es>
+Signed-off-by: Neil Brown <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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 *);
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:45:28 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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))
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:45:34 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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) {
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:45:45 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:46:19 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jan 24 20:46:14 2007
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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);
++
+ }
+ }
+ }
--- /dev/null
+From a8d814b5dd7a1bc5c19ae32d35b8bd4d8a510eae Mon Sep 17 00:00:00 2001
+Message-Id: <200701260857.l0Q8v8co012068@shell0.pdx.osdl.net>
+From: Mike Frysinger <vapier@gentoo.org>
+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 <vapier@gentoo.org>
+Acked-by: Alessandro Zummo <a.zummo@towertech.it>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
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
--- /dev/null
+From 7939aae0c08412138a827e0af6f16fc19c346353 Mon Sep 17 00:00:00 2001
+From: Francois Romieu <romieu@fr.zoreil.com>
+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 <akpm@osdl.org>
+Cc: <sleepy@mike-neko.net>
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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));
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC32: Fix over-optimization by GCC near ip_fast_csum.
+
+From: Bob Breuer <breuerr@mc.net>
+
+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 <breuerr@mc.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
+ }
+
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC64: Set g4/g5 properly in sun4v dtlb-prot handling.
+
+From: David S. Miller <davem@sunset.davemloft.net>
+
+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 <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+---
+ 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
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: TCP: Fix sorting of SACK blocks.
+
+From: Baruch Even <baruch@ev-en.org>
+
+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 <baruch@ev-en.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
+ }
+
+ }
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: TCP: rare bad TCP checksum with 2.6.19
+
+From: Jarek Poplawski <jarkao2@o2.pl>
+
+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 <mjt@tls.msk.ru>
+Possible reasons pointed by: Herbert Xu and Patrick McHardy.
+
+Signed-off-by: Jarek Poplawski <jarkao2@o2.pl>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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);
--- /dev/null
+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 <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: TCP: skb is unexpectedly freed.
+
+From: Masayuki Nakagawa <nakagawa.msy@ncos.nec.co.jp>
+
+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 <nakagawa.msy@ncos.nec.co.jp>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ 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;
+
--- /dev/null
+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 <jdike@addtoit.com>
+
+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 <jdike@addtoit.com>
+Cc: <stable@kernel.org>
+Cc: Adrian Bunk <bunk@stusta.de>
+Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+Acked-by: Antoine Martin <antoine@nagafix.co.uk>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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;
--- /dev/null
+From da02d2a16ef3accd625f9e6e7bf83bb0f946ff62 Mon Sep 17 00:00:00 2001
+From: Jeff Garzik <jeff@garzik.org>
+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] [<c01162e6>] kmap_atomic+0xa9/0x1ab
+ [ 232.404000] [<c0242c81>] ata_scsi_rbuf_get+0x1c/0x30
+ [ 232.404000] [<c0242caf>] ata_scsi_rbuf_fill+0x1a/0x87
+ [ 232.404000] [<c0243ab2>] ata_scsiop_mode_sense+0x0/0x309
+ [ 232.404000] [<c01729d5>] end_bio_bh_io_sync+0x0/0x37
+ [ 232.404000] [<c02311c6>] scsi_done+0x0/0x16
+ [ 232.404000] [<c02311c6>] scsi_done+0x0/0x16
+ [ 232.404000] [<c0242dcc>] ata_scsi_simulate+0xb0/0x13f
+[...]
+
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ 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);
+ }
+ }
+