]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
lots of .28 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 29 Apr 2009 01:50:30 +0000 (18:50 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 29 Apr 2009 01:50:30 +0000 (18:50 -0700)
53 files changed:
queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch [new file with mode: 0644]
queue-2.6.28/0008-USB-EHCI-add-software-retry-for-transaction-errors.patch
queue-2.6.28/0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch
queue-2.6.28/0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch
queue-2.6.28/0011-USB-gadget-fix-rndis-regression.patch
queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch [new file with mode: 0644]
queue-2.6.28/0012-USB-add-quirk-to-avoid-config-and-interface-strings.patch
queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch [new file with mode: 0644]
queue-2.6.28/0016-cifs-fix-buffer-format-byte-on-NT-Rename-hardlink.patch
queue-2.6.28/0019-b43-fix-b43_plcp_get_bitrate_idx_ofdm-return-type.patch
queue-2.6.28/0022-CIFS-Fix-memory-overwrite-when-saving-nativeFileSys.patch
queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch [new file with mode: 0644]
queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch [new file with mode: 0644]
queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch [new file with mode: 0644]
queue-2.6.28/0032-Add-a-missing-unlock_kernel-in-raw_open.patch
queue-2.6.28/0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch
queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch [new file with mode: 0644]
queue-2.6.28/0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch
queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch [new file with mode: 0644]
queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch [new file with mode: 0644]
queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch [new file with mode: 0644]
queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch [new file with mode: 0644]
queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch [new file with mode: 0644]
queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch [new file with mode: 0644]
queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch [new file with mode: 0644]
queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch [new file with mode: 0644]
queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch [new file with mode: 0644]
queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch [new file with mode: 0644]
queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch [new file with mode: 0644]
queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch [new file with mode: 0644]
queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch [new file with mode: 0644]
queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch [new file with mode: 0644]
queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch [new file with mode: 0644]
queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch [new file with mode: 0644]
queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch [new file with mode: 0644]
queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch [new file with mode: 0644]
queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch [new file with mode: 0644]
queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch [new file with mode: 0644]
queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch [new file with mode: 0644]
queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch [new file with mode: 0644]
queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch [new file with mode: 0644]
queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch [new file with mode: 0644]
queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch [new file with mode: 0644]
queue-2.6.28/bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch
queue-2.6.28/bonding-fix-updating-of-speed-duplex-changes.patch
queue-2.6.28/bridge-bad-error-handling-when-adding-invalid-ether-address.patch
queue-2.6.28/ipv6-don-t-use-tw-net-when-accounting-for-recycled-tw.patch
queue-2.6.28/ipv6-plug-sk_buff-leak-in-ipv6_rcv.patch
queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch [new file with mode: 0644]
queue-2.6.28/net-fix-sctp-breakage.patch
queue-2.6.28/netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch
queue-2.6.28/series
queue-2.6.28/xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch

diff --git a/queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch b/queue-2.6.28/0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch
new file mode 100644 (file)
index 0000000..89d41bb
--- /dev/null
@@ -0,0 +1,42 @@
+From 97ecdadc284e820931f27c6345b0ff8b85792346 Mon Sep 17 00:00:00 2001
+From: Etienne Basset <etienne.basset@numericable.fr>
+Date: Tue, 31 Mar 2009 23:54:11 +0200
+Subject: security/smack: fix oops when setting a size 0 SMACK64 xattr
+
+From: Etienne Basset <etienne.basset@numericable.fr>
+
+upstream commit: 4303154e86597885bc3cbc178a48ccbc8213875f
+
+this patch fix an oops in smack when setting a size 0 SMACK64 xattr eg
+attr -S -s SMACK64  -V '' somefile
+This oops because smk_import_entry treats a 0 length as SMK_MAXLEN
+
+Signed-off-by: Etienne Basset <etienne.basset@numericable.fr>
+Reviewed-by: James Morris <jmorris@namei.org>
+Acked-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ security/smack/smack_lsm.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -604,6 +604,8 @@ static int smack_inode_setxattr(struct d
+           strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
+               if (!capable(CAP_MAC_ADMIN))
+                       rc = -EPERM;
++              if (size == 0)
++                      rc = -EINVAL;
+       } else
+               rc = cap_inode_setxattr(dentry, name, value, size, flags);
+@@ -1360,7 +1362,7 @@ static int smack_inode_setsecurity(struc
+       struct socket *sock;
+       int rc = 0;
+-      if (value == NULL || size > SMK_LABELLEN)
++      if (value == NULL || size > SMK_LABELLEN || size == 0)
+               return -EACCES;
+       sp = smk_import(value, size);
index 541ab48af2b549ac8b559be4caee22f20bdd82e1..b2a26f75184496c1cf611c31f78a1de5c6e7027b 100644 (file)
@@ -3,6 +3,8 @@ From: Alan Stern <stern@rowland.harvard.edu>
 Date: Thu, 26 Mar 2009 18:25:05 +0000
 Subject: USB: EHCI: add software retry for transaction errors
 
+From: Alan Stern <stern@rowland.harvard.edu>
+
 upstream commit: a2c2706e1043c17139c2dafd171c4a5cf008ef7e
 
 This patch (as1204) adds a software retry mechanism to ehci-hcd.  It
index cceda4569961c9185a7393d244915b60a572f2e4..23cac33d3d174bf26c6ceada89454840f19f8341 100644 (file)
@@ -3,6 +3,8 @@ From: Boaz Harrosh <bharrosh@panasas.com>
 Date: Thu, 26 Mar 2009 18:25:07 +0000
 Subject: USB: fix USB_STORAGE_CYPRESS_ATACB
 
+From: Boaz Harrosh <bharrosh@panasas.com>
+
 upstream commit: 1f4159c1620f74377e26d8a569d10ca5907ef475
 
 commit 64a87b24: [SCSI] Let scsi_cmnd->cmnd use request->cmd buffer
index 69930b904d3c21181ac7c3914b1585cabe1d4fe0..05b18683367c235077b710197c86dccb02f7b09c 100644 (file)
@@ -3,6 +3,8 @@ From: Alan Stern <stern@rowland.harvard.edu>
 Date: Thu, 26 Mar 2009 18:25:09 +0000
 Subject: USB: usb-storage: increase max_sectors for tape drives
 
+From: Alan Stern <stern@rowland.harvard.edu>
+'
 upstream commit: 5c16034d73da2c1b663aa25dedadbc533b3d811c
 
 This patch (as1203) increases the max_sector limit for USB tape
index a84663eae004df39218c7047847c2054752632f0..1b7ab0c1b610ca69a935d74019a2fc64b016bb07 100644 (file)
@@ -3,6 +3,8 @@ From: David Brownell <dbrownell@users.sourceforge.net>
 Date: Thu, 26 Mar 2009 18:25:12 +0000
 Subject: USB: gadget: fix rndis regression
 
+From: David Brownell <dbrownell@users.sourceforge.net>
+
 upstream commit: 090b90118207e786d2990310d063fda5d52cce6e
 
 Restore some code that was wrongly dropped from the RNDIS
diff --git a/queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch b/queue-2.6.28/0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch
new file mode 100644 (file)
index 0000000..5b70bdb
--- /dev/null
@@ -0,0 +1,45 @@
+From 32626208c6548358e28b0857ad030b8a3fa12d86 Mon Sep 17 00:00:00 2001
+From: Michael K. Johnson <johnsonm@rpath.com>
+Date: Wed, 1 Apr 2009 20:40:02 +0000
+Subject: x86, setup: mark %esi as clobbered in E820 BIOS call
+
+From: Michael K. Johnson <johnsonm@rpath.com>
+
+upstream commit: 01522df346f846906eaf6ca57148641476209909
+
+Jordan Hargrave diagnosed a BIOS clobbering %esi in the E820 call.
+That particular BIOS has been fixed, but there is a possibility that
+this is responsible for other occasional reports of early boot
+failure, and it does not hurt to add %esi to the clobbers.
+
+-stable candidate patch.
+
+Cc: Justin Forbes <jmforbes@linuxtx.org>
+Signed-off-by: Michael K Johnson <johnsonm@rpath.com>
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/x86/boot/memory.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/boot/memory.c
++++ b/arch/x86/boot/memory.c
+@@ -27,13 +27,14 @@ static int detect_memory_e820(void)
+       do {
+               size = sizeof(struct e820entry);
+-              /* Important: %edx is clobbered by some BIOSes,
+-                 so it must be either used for the error output
++              /* Important: %edx and %esi are clobbered by some BIOSes,
++                 so they must be either used for the error output
+                  or explicitly marked clobbered. */
+               asm("int $0x15; setc %0"
+                   : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
+                     "=m" (*desc)
+-                  : "D" (desc), "d" (SMAP), "a" (0xe820));
++                  : "D" (desc), "d" (SMAP), "a" (0xe820)
++                  : "esi");
+               /* BIOSes which terminate the chain with CF = 1 as opposed
+                  to %ebx = 0 don't always report the SMAP signature on
index fbac1d6d4588e9bb601e31f1b5b7b1abff3d432f..243077cace382dbd98dbd2d0a97928c400d9b67c 100644 (file)
@@ -3,6 +3,8 @@ From: Alan Stern <stern@rowland.harvard.edu>
 Date: Thu, 26 Mar 2009 18:25:19 +0000
 Subject: USB: add quirk to avoid config and interface strings
 
+From: Alan Stern <stern@rowland.harvard.edu>
+
 upstream commit: 1662e3a7f076e51e3073faf9ce77157b529c475b
 
 Apparently the Configuration and Interface strings aren't used as
diff --git a/queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch b/queue-2.6.28/0013-dock-fix-dereference-after-kfree.patch
new file mode 100644 (file)
index 0000000..114175b
--- /dev/null
@@ -0,0 +1,36 @@
+From 538c7aac35f4282d7674c473f099b323b1e020dd Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Mon, 6 Apr 2009 23:56:46 -0400
+Subject: dock: fix dereference after kfree()
+
+From: Dan Carpenter <error27@gmail.com>
+
+upstream commit: f240729832dff3785104d950dad2d3ced4387f6d
+
+dock_remove() calls kfree() on dock_station so we should use
+list_for_each_entry_safe() to avoid dereferencing freed memory.
+
+Found by smatch (http://repo.or.cz/w/smatch.git/).  Compile tested.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/acpi/dock.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/acpi/dock.c
++++ b/drivers/acpi/dock.c
+@@ -1146,9 +1146,10 @@ static int __init dock_init(void)
+ static void __exit dock_exit(void)
+ {
+       struct dock_station *dock_station;
++      struct dock_station *tmp;
+       unregister_acpi_bus_notifier(&dock_acpi_notifier);
+-      list_for_each_entry(dock_station, &dock_stations, sibiling)
++      list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
+               dock_remove(dock_station);
+ }
index a0a4ae56b2792b9be8b6b7935ad7e7b04c4a45cf..8c6823c15e5ca79c5e656d9d6a4d7c703285c5e7 100644 (file)
@@ -3,6 +3,8 @@ From: Jeff Layton <jlayton@tupile.poochiereds.net>
 Date: Thu, 26 Mar 2009 23:05:21 +0000
 Subject: cifs: fix buffer format byte on NT Rename/hardlink
 
+From: Jeff Layton <jlayton@tupile.poochiereds.net>
+
 upstream commit: fcc7c09d94be7b75c9ea2beb22d0fae191c6b4b9
 
 Discovered at Connnectathon 2009...
@@ -12,10 +14,10 @@ The buffer format byte and the pad are transposed in NT_RENAME calls
 fact, but NetApp filers throw back an error due to this problem. This
 patch fixes it.
 
-CC: Stable <stable@kernel.org>
 Signed-off-by: Jeff Layton <jlayton@redhat.com>
 Signed-off-by: Steve French <sfrench@us.ibm.com>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  fs/cifs/cifssmb.c |    6 ++++--
  1 file changed, 4 insertions(+), 2 deletions(-)
index 5d24ec46884ce16c21345b4f26eb4d4ff40a8ed0..6fa57ee3f2b258a26eefe44362d277bb4afe7289 100644 (file)
@@ -3,6 +3,8 @@ From: Lorenzo Nava <navalorenx@gmail.com>
 Date: Sat, 28 Mar 2009 01:45:06 +0000
 Subject: b43: fix b43_plcp_get_bitrate_idx_ofdm return type
 
+From: Lorenzo Nava <navalorenx@gmail.com>
+
 upstream commit: a3c0b87c4f21911fb7185902dd13f0e3cd7f33f7
 
 This patch fixes the return type of b43_plcp_get_bitrate_idx_ofdm. If
@@ -10,11 +12,11 @@ the plcp contains an error, the function return value is 255 instead
 of -1, and the packet was not dropped. This causes a warning in
 __ieee80211_rx function because rate idx is out of range.
 
-Cc: stable@kernel.org
 Signed-off-by: Lorenzo Nava <navalorenx@gmail.com>
 Signed-off-by: Michael Buesch <mb@bu3sch.de>
 Signed-off-by: John W. Linville <linville@tuxdriver.com>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  drivers/net/wireless/b43/xmit.c |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
index d436e33f07e680e3f088860c81353e0d44ece36f..cc6fe1516c401f05d9bbc5965a817cb16bd8bf93 100644 (file)
@@ -3,6 +3,8 @@ From: Steve French <sfrench@us.ibm.com>
 Date: Thu, 26 Mar 2009 23:05:15 +0000
 Subject: CIFS: Fix memory overwrite when saving nativeFileSystem field during mount
 
+From: Steve French <sfrench@us.ibm.com>
+
 upstream commit: b363b3304bcf68c4541683b2eff70b29f0446a5b
 
 CIFS can allocate a few bytes to little for the nativeFileSystem field
@@ -11,10 +13,10 @@ in a "Redzone overwritten" message to be logged.
 
 Signed-off-by: Sridhar Vinay <vinaysridhar@in.ibm.com>
 Acked-by: Shirish Pargaonkar <shirishp@us.ibm.com>
-CC: Stable <stable@kernel.org>
 Signed-off-by: Steve French <sfrench@us.ibm.com>
 [chrisw: minor backport to CHANGES file]
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  fs/cifs/CHANGES   |    3 +++
  fs/cifs/connect.c |    2 +-
diff --git a/queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch b/queue-2.6.28/0024-r8169-Reset-IntrStatus-after-chip-reset.patch
new file mode 100644 (file)
index 0000000..346c2ea
--- /dev/null
@@ -0,0 +1,54 @@
+From 98bf3a0cf25dbd438500d9c9fcf583d7a2b97825 Mon Sep 17 00:00:00 2001
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Mon, 6 Apr 2009 23:35:13 +0200
+Subject: r8169: Reset IntrStatus after chip reset
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+upstream commit: d78ad8cbfe73ad568de38814a75e9c92ad0a907c
+
+Original comment (Karsten):
+On a MSI MS-6702E mainboard, when in rtl8169_init_one() for the first time
+after BIOS has run, IntrStatus reads 5 after chip has been reset.
+IntrStatus should equal 0 there, so patch changes IntrStatus reset to happen
+after chip reset instead of before.
+
+Remark (Francois):
+Assuming that the loglevel of the driver is increased above NETIF_MSG_INTR,
+the bug reveals itself with a typical "interrupt 0025 in poll" message
+at startup. In retrospect, the message should had been read as an hint of
+an unexpected hardware state several months ago :o(
+
+Fixes (at least part of) https://bugzilla.redhat.com/show_bug.cgi?id=460747
+
+Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Tested-by: Josep <josep.puigdemont@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/r8169.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -2026,8 +2026,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
+       if (!tp->pcie_cap && netif_msg_probe(tp))
+               dev_info(&pdev->dev, "no PCI Express capability\n");
+-      /* Unneeded ? Don't mess with Mrs. Murphy. */
+-      rtl8169_irq_mask_and_ack(ioaddr);
++      RTL_W16(IntrMask, 0x0000);
+       /* Soft reset the chip. */
+       RTL_W8(ChipCmd, CmdReset);
+@@ -2039,6 +2038,8 @@ rtl8169_init_one(struct pci_dev *pdev, c
+               msleep_interruptible(1);
+       }
++      RTL_W16(IntrStatus, 0xffff);
++
+       /* Identify chip attached to board */
+       rtl8169_get_mac_version(tp, ioaddr);
diff --git a/queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch b/queue-2.6.28/0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch
new file mode 100644 (file)
index 0000000..c5564e4
--- /dev/null
@@ -0,0 +1,58 @@
+From ee21b9af3d0b0b3261daba2f669e7e9aeda1eaa2 Mon Sep 17 00:00:00 2001
+From: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
+Date: Fri, 3 Apr 2009 04:35:10 +0000
+Subject: mm: define a UNIQUE value for AS_UNEVICTABLE flag
+
+From: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
+
+upstream commit: 9a896c9a48ac6704c0ce8ee081b836644d0afe40
+
+A new "address_space flag"--AS_MM_ALL_LOCKS--was defined to use the next
+available AS flag while the Unevictable LRU was under development.  The
+Unevictable LRU was using the same flag and "no one" noticed.  Current
+mainline, since 2.6.28, has same value for two symbolic flag names.
+
+So, define a unique flag value for AS_UNEVICTABLE--up close to the other
+flags, [at the cost of an additional #ifdef] so we'll notice next time.
+Note that #ifdef is not actually required, if we don't mind having the
+unused flag value defined.
+
+Replace #defines with an enum.
+
+Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/pagemap.h |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/include/linux/pagemap.h
++++ b/include/linux/pagemap.h
+@@ -18,9 +18,14 @@
+  * Bits in mapping->flags.  The lower __GFP_BITS_SHIFT bits are the page
+  * allocation mode flags.
+  */
+-#define       AS_EIO          (__GFP_BITS_SHIFT + 0)  /* IO error on async write */
+-#define AS_ENOSPC     (__GFP_BITS_SHIFT + 1)  /* ENOSPC on async write */
+-#define AS_MM_ALL_LOCKS       (__GFP_BITS_SHIFT + 2)  /* under mm_take_all_locks() */
++enum mapping_flags {
++      AS_EIO          = __GFP_BITS_SHIFT + 0, /* IO error on async write */
++      AS_ENOSPC       = __GFP_BITS_SHIFT + 1, /* ENOSPC on async write */
++      AS_MM_ALL_LOCKS = __GFP_BITS_SHIFT + 2, /* under mm_take_all_locks() */
++#ifdef CONFIG_UNEVICTABLE_LRU
++      AS_UNEVICTABLE  = __GFP_BITS_SHIFT + 3, /* e.g., ramdisk, SHM_LOCK */
++#endif
++};
+ static inline void mapping_set_error(struct address_space *mapping, int error)
+ {
+@@ -33,7 +38,6 @@ static inline void mapping_set_error(str
+ }
+ #ifdef CONFIG_UNEVICTABLE_LRU
+-#define AS_UNEVICTABLE        (__GFP_BITS_SHIFT + 2)  /* e.g., ramdisk, SHM_LOCK */
+ static inline void mapping_set_unevictable(struct address_space *mapping)
+ {
diff --git a/queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch b/queue-2.6.28/0031-mm-do_xip_mapping_read-fix-length-calculation.patch
new file mode 100644 (file)
index 0000000..cf6cdec
--- /dev/null
@@ -0,0 +1,66 @@
+From d4a0936d21ddba01f85daf686625f0004b896aae Mon Sep 17 00:00:00 2001
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Fri, 3 Apr 2009 04:35:12 +0000
+Subject: mm: do_xip_mapping_read: fix length calculation
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+upstream commit: 58984ce21d315b70df1a43644df7416ea7c9bfd8
+
+The calculation of the value nr in do_xip_mapping_read is incorrect.  If
+the copy required more than one iteration in the do while loop the copies
+variable will be non-zero.  The maximum length that may be passed to the
+call to copy_to_user(buf+copied, xip_mem+offset, nr) is len-copied but the
+check only compares against (nr > len).
+
+This bug is the cause for the heap corruption Carsten has been chasing
+for so long:
+
+ *** glibc detected *** /bin/bash: free(): invalid next size (normal): 0x00000000800e39f0 ***
+ ======= Backtrace: =========
+/lib64/libc.so.6[0x200000b9b44]
+/lib64/libc.so.6(cfree+0x8e)[0x200000bdade]
+/bin/bash(free_buffered_stream+0x32)[0x80050e4e]
+/bin/bash(close_buffered_stream+0x1c)[0x80050ea4]
+/bin/bash(unset_bash_input+0x2a)[0x8001c366]
+/bin/bash(make_child+0x1d4)[0x8004115c]
+/bin/bash[0x8002fc3c]
+/bin/bash(execute_command_internal+0x656)[0x8003048e]
+/bin/bash(execute_command+0x5e)[0x80031e1e]
+/bin/bash(execute_command_internal+0x79a)[0x800305d2]
+/bin/bash(execute_command+0x5e)[0x80031e1e]
+/bin/bash(reader_loop+0x270)[0x8001efe0]
+/bin/bash(main+0x1328)[0x8001e960]
+/lib64/libc.so.6(__libc_start_main+0x100)[0x200000592a8]
+/bin/bash(clearerr+0x5e)[0x8001c092]
+
+With this bug fix the commit 0e4a9b59282914fe057ab17027f55123964bc2e2
+"ext2/xip: refuse to change xip flag during remount with busy inodes" can
+be removed again.
+
+Cc: Carsten Otte <cotte@de.ibm.com>
+Cc: Nick Piggin <npiggin@suse.de>
+Cc: Jared Hulbert <jaredeh@gmail.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/filemap_xip.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/mm/filemap_xip.c
++++ b/mm/filemap_xip.c
+@@ -89,8 +89,8 @@ do_xip_mapping_read(struct address_space
+                       }
+               }
+               nr = nr - offset;
+-              if (nr > len)
+-                      nr = len;
++              if (nr > len - copied)
++                      nr = len - copied;
+               error = mapping->a_ops->get_xip_mem(mapping, index, 0,
+                                                       &xip_mem, &xip_pfn);
index a13bddfd9d7b188c22623a29382f3c8c41d71801..816c7c7b591283ee74b2de5332df266373d3fe33 100644 (file)
@@ -3,12 +3,14 @@ From: Dan Carpenter <error27@gmail.com>
 Date: Mon, 30 Mar 2009 18:50:16 +0000
 Subject: Add a missing unlock_kernel() in raw_open()
 
+From: Dan Carpenter <error27@gmail.com>
+
 upstream commit: 996ff68d8b358885c1de82a45517c607999947c7
 
-Cc: stable@kernel.org
 Signed-off-by: Dan Carpenter <error27@gmail.com>
 Signed-off-by: Jonathan Corbet <corbet@lwn.net>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  drivers/char/raw.c |    1 +
  1 file changed, 1 insertion(+)
index 55575cb96b484c5587dda26fed2353e7aebeeeef..190a9d4181db38bd5233468bb227b51cc6c96a93 100644 (file)
@@ -3,6 +3,8 @@ From: Pallipadi, Venkatesh <venkatesh.pallipadi@intel.com>
 Date: Mon, 30 Mar 2009 18:50:19 +0000
 Subject: x86, PAT, PCI: Change vma prot in pci_mmap to reflect inherited prot
 
+From: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+
 upstream commit: 9cdec049389ce2c324fd1ec508a71528a27d4a07
 
 While looking at the issue in the thread:
@@ -22,10 +24,10 @@ Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
 Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
 Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
 Cc: Dave Airlie <airlied@redhat.com>
-Cc: <stable@kernel.org>
 LKML-Reference: <20090323190720.GA16831@linux-os.sc.intel.com>
 Signed-off-by: Ingo Molnar <mingo@elte.hu>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  arch/x86/pci/i386.c |    3 +++
  1 file changed, 3 insertions(+)
diff --git a/queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch b/queue-2.6.28/0034-vfs-skip-I_CLEAR-state-inodes.patch
new file mode 100644 (file)
index 0000000..b26082f
--- /dev/null
@@ -0,0 +1,94 @@
+From 187ab6618c3afae07d5ca0727966ea461e5d07a7 Mon Sep 17 00:00:00 2001
+From: Wu Fengguang <fengguang.wu@intel.com>
+Date: Fri, 3 Apr 2009 04:35:14 +0000
+Subject: vfs: skip I_CLEAR state inodes
+
+From: Wu Fengguang <fengguang.wu@intel.com>
+
+upstream commit: b6fac63cc1f52ec27f29fe6c6c8494a2ffac33fd
+
+clear_inode() will switch inode state from I_FREEING to I_CLEAR, and do so
+_outside_ of inode_lock.  So any I_FREEING testing is incomplete without a
+coupled testing of I_CLEAR.
+
+So add I_CLEAR tests to drop_pagecache_sb(), generic_sync_sb_inodes() and
+add_dquot_ref().
+
+Masayoshi MIZUMA discovered the bug in drop_pagecache_sb() and Jan Kara
+reminds fixing the other two cases.
+
+Masayoshi MIZUMA has a nice panic flow:
+
+=====================================================================
+            [process A]               |        [process B]
+ |                                    |
+ |    prune_icache()                  | drop_pagecache()
+ |      spin_lock(&inode_lock)        |   drop_pagecache_sb()
+ |      inode->i_state |= I_FREEING;  |       |
+ |      spin_unlock(&inode_lock)      |       V
+ |          |                         |     spin_lock(&inode_lock)
+ |          V                         |         |
+ |      dispose_list()                |         |
+ |        list_del()                  |         |
+ |        clear_inode()               |         |
+ |          inode->i_state = I_CLEAR  |         |
+ |            |                       |         V
+ |            |                       |      if (inode->i_state & (I_FREEING|I_WILL_FREE))
+ |            |                       |              continue;           <==== NOT MATCH
+ |            |                       |
+ |            |                       | (DANGER from here on! Accessing disposing inode!)
+ |            |                       |
+ |            |                       |      __iget()
+ |            |                       |        list_move() <===== PANIC on poisoned list !!
+ V            V                       |
+(time)
+=====================================================================
+
+Reported-by: Masayoshi MIZUMA <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[chrisw: backport to 2.6.29]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/dquot.c        |    2 +-
+ fs/drop_caches.c  |    2 +-
+ fs/fs-writeback.c |    3 ++-
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/fs/dquot.c
++++ b/fs/dquot.c
+@@ -724,7 +724,7 @@ static void add_dquot_ref(struct super_b
+                       continue;
+               if (!dqinit_needed(inode, type))
+                       continue;
+-              if (inode->i_state & (I_FREEING|I_WILL_FREE))
++              if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                       continue;
+               __iget(inode);
+--- a/fs/drop_caches.c
++++ b/fs/drop_caches.c
+@@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct sup
+       spin_lock(&inode_lock);
+       list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+-              if (inode->i_state & (I_FREEING|I_WILL_FREE))
++              if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+                       continue;
+               if (inode->i_mapping->nrpages == 0)
+                       continue;
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -538,7 +538,8 @@ void generic_sync_sb_inodes(struct super
+               list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+                       struct address_space *mapping;
+-                      if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
++                      if (inode->i_state &
++                                      (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
+                               continue;
+                       mapping = inode->i_mapping;
+                       if (mapping->nrpages == 0)
index e919ec0959a907bb1ab3bb8282248fbdff59a962..0c193564355d83d153d0d81e52170fb66a930549 100644 (file)
@@ -3,6 +3,8 @@ From: Andreas Herrmann <andreas.herrmann3@amd.com>
 Date: Mon, 30 Mar 2009 18:50:32 +0000
 Subject: x86: mtrr: don't modify RdDram/WrDram bits of fixed MTRRs
 
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+
 upstream commit: 3ff42da5048649503e343a32be37b14a6a4e8aaf
 
 Impact: bug fix + BIOS workaround
@@ -63,9 +65,9 @@ Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
 Cc: trenn@suse.de
 Cc: Yinghai Lu <yinghai@kernel.org>
 LKML-Reference: <20090312163937.GH20716@alberich.amd.com>
-Cc: <stable@kernel.org>
 Signed-off-by: Ingo Molnar <mingo@elte.hu>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 ---
  arch/x86/kernel/cpu/mtrr/generic.c |   51 +++++++++++++++++++++----------------
  1 file changed, 30 insertions(+), 21 deletions(-)
diff --git a/queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch b/queue-2.6.28/0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch
new file mode 100644 (file)
index 0000000..425ff6e
--- /dev/null
@@ -0,0 +1,68 @@
+From 33d06566b593703a972da232d08b6a12176f1854 Mon Sep 17 00:00:00 2001
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Date: Fri, 27 Mar 2009 00:28:21 -0700
+Subject: af_rose/x25: Sanity check the maximum user frame size
+
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+
+upstream commit: 83e0bbcbe2145f160fbaa109b0439dae7f4a38a9
+
+CVE-2009-0795.
+
+Otherwise we can wrap the sizes and end up sending garbage.
+
+Closes #10423
+
+Signed-off-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/netrom/af_netrom.c |    6 +++++-
+ net/rose/af_rose.c     |    4 ++++
+ net/x25/af_x25.c       |    6 ++++++
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -1082,7 +1082,11 @@ static int nr_sendmsg(struct kiocb *iocb
+       SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n");
+-      /* Build a packet */
++      /* Build a packet - the conventional user limit is 236 bytes. We can
++         do ludicrously large NetROM frames but must not overflow */
++      if (len > 65536)
++              return -EMSGSIZE;
++
+       SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n");
+       size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -1124,6 +1124,10 @@ static int rose_sendmsg(struct kiocb *io
+       /* Build a packet */
+       SOCK_DEBUG(sk, "ROSE: sendto: building packet.\n");
++      /* Sanity check the packet size */
++      if (len > 65535)
++              return -EMSGSIZE;
++
+       size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
+       if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -1037,6 +1037,12 @@ static int x25_sendmsg(struct kiocb *ioc
+               sx25.sx25_addr   = x25->dest_addr;
+       }
++      /* Sanity check the packet size */
++      if (len > 65535) {
++              rc = -EMSGSIZE;
++              goto out;
++      }
++
+       SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
+       /* Build a packet */
diff --git a/queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch b/queue-2.6.28/0044-net-netrom-Fix-socket-locking.patch
new file mode 100644 (file)
index 0000000..6dbbd1e
--- /dev/null
@@ -0,0 +1,37 @@
+From df5b6025d1a9e2e61dde1fd28257082751264c07 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Wed, 22 Apr 2009 00:49:51 -0700
+Subject: net/netrom: Fix socket locking
+
+From: Jean Delvare <jdelvare@suse.de>
+
+upstream commit: cc29c70dd581f85ee7a3e7980fb031f90b90a2ab
+
+Patch "af_rose/x25: Sanity check the maximum user frame size"
+(commit 83e0bbcbe2145f160fbaa109b0439dae7f4a38a9) from Alan Cox got
+locking wrong. If we bail out due to user frame size being too large,
+we must unlock the socket beforehand.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/netrom/af_netrom.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -1084,8 +1084,10 @@ static int nr_sendmsg(struct kiocb *iocb
+       /* Build a packet - the conventional user limit is 236 bytes. We can
+          do ludicrously large NetROM frames but must not overflow */
+-      if (len > 65536)
+-              return -EMSGSIZE;
++      if (len > 65536) {
++              err = -EMSGSIZE;
++              goto out;
++      }
+       SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n");
+       size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
diff --git a/queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch b/queue-2.6.28/0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch
new file mode 100644 (file)
index 0000000..9811f2e
--- /dev/null
@@ -0,0 +1,70 @@
+From 6bc1b5deb47f0fc3d697abd2fcd417618cf07e3f Mon Sep 17 00:00:00 2001
+From: Patrick McHardy <kaber@trash.net>
+Date: Mon, 6 Apr 2009 17:31:29 +0200
+Subject: netfilter: {ip, ip6, arp}_tables: fix incorrect loop detection
+
+From: Patrick McHardy <kaber@trash.net>
+
+upstream commit: 1f9352ae2253a97b07b34dcf16ffa3b4ca12c558
+
+Commit e1b4b9f ([NETFILTER]: {ip,ip6,arp}_tables: fix exponential worst-case
+search for loops) introduced a regression in the loop detection algorithm,
+causing sporadic incorrectly detected loops.
+
+When a chain has already been visited during the check, it is treated as
+having a standard target containing a RETURN verdict directly at the
+beginning in order to not check it again. The real target of the first
+rule is then incorrectly treated as STANDARD target and checked not to
+contain invalid verdicts.
+
+Fix by making sure the rule does actually contain a standard target.
+
+Based on patch by Francis Dupont <Francis_Dupont@isc.org>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/netfilter/arp_tables.c |    4 +++-
+ net/ipv4/netfilter/ip_tables.c  |    4 +++-
+ net/ipv6/netfilter/ip6_tables.c |    4 +++-
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -374,7 +374,9 @@ static int mark_source_chains(struct xt_
+                           && unconditional(&e->arp)) || visited) {
+                               unsigned int oldpos, size;
+-                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                              if ((strcmp(t->target.u.user.name,
++                                          ARPT_STANDARD_TARGET) == 0) &&
++                                  t->verdict < -NF_MAX_VERDICT - 1) {
+                                       duprintf("mark_source_chains: bad "
+                                               "negative verdict (%i)\n",
+                                                               t->verdict);
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -500,7 +500,9 @@ mark_source_chains(struct xt_table_info 
+                           && unconditional(&e->ip)) || visited) {
+                               unsigned int oldpos, size;
+-                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                              if ((strcmp(t->target.u.user.name,
++                                          IPT_STANDARD_TARGET) == 0) &&
++                                  t->verdict < -NF_MAX_VERDICT - 1) {
+                                       duprintf("mark_source_chains: bad "
+                                               "negative verdict (%i)\n",
+                                                               t->verdict);
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -525,7 +525,9 @@ mark_source_chains(struct xt_table_info 
+                           && unconditional(&e->ipv6)) || visited) {
+                               unsigned int oldpos, size;
+-                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                              if ((strcmp(t->target.u.user.name,
++                                          IP6T_STANDARD_TARGET) == 0) &&
++                                  t->verdict < -NF_MAX_VERDICT - 1) {
+                                       duprintf("mark_source_chains: bad "
+                                               "negative verdict (%i)\n",
+                                                               t->verdict);
diff --git a/queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch b/queue-2.6.28/0049-splice-fix-deadlock-in-splicing-to-file.patch
new file mode 100644 (file)
index 0000000..24e2d06
--- /dev/null
@@ -0,0 +1,117 @@
+From ed960ac61e12e298d1cdcd52b21b9ee07d36755c Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Tue, 7 Apr 2009 16:25:02 +0000
+Subject: splice: fix deadlock in splicing to file
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+upstream commit: 7bfac9ecf0585962fe13584f5cf526d8c8e76f17
+
+There's a possible deadlock in generic_file_splice_write(),
+splice_from_pipe() and ocfs2_file_splice_write():
+
+ - task A calls generic_file_splice_write()
+ - this calls inode_double_lock(), which locks i_mutex on both
+   pipe->inode and target inode
+ - ordering depends on inode pointers, can happen that pipe->inode is
+   locked first
+ - __splice_from_pipe() needs more data, calls pipe_wait()
+ - this releases lock on pipe->inode, goes to interruptible sleep
+ - task B calls generic_file_splice_write(), similarly to the first
+ - this locks pipe->inode, then tries to lock inode, but that is
+   already held by task A
+ - task A is interrupted, it tries to lock pipe->inode, but fails, as
+   it is already held by task B
+ - ABBA deadlock
+
+Fix this by explicitly ordering locks: the outer lock must be on
+target inode and the inner lock (which is later unlocked and relocked)
+must be on pipe->inode.  This is OK, pipe inodes and target inodes
+form two nonoverlapping sets, generic_file_splice_write() and friends
+are not called with a target which is a pipe.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Acked-by: Mark Fasheh <mfasheh@suse.com>
+Acked-by: Jens Axboe <jens.axboe@oracle.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/ocfs2/file.c |    8 ++++++--
+ fs/splice.c     |   25 ++++++++++++++++++++-----
+ 2 files changed, 26 insertions(+), 7 deletions(-)
+
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -1943,7 +1943,7 @@ static ssize_t ocfs2_file_splice_write(s
+                  out->f_path.dentry->d_name.len,
+                  out->f_path.dentry->d_name.name);
+-      inode_double_lock(inode, pipe->inode);
++      mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+       ret = ocfs2_rw_lock(inode, 1);
+       if (ret < 0) {
+@@ -1958,12 +1958,16 @@ static ssize_t ocfs2_file_splice_write(s
+               goto out_unlock;
+       }
++      if (pipe->inode)
++              mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+       ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
++      if (pipe->inode)
++              mutex_unlock(&pipe->inode->i_mutex);
+ out_unlock:
+       ocfs2_rw_unlock(inode, 1);
+ out:
+-      inode_double_unlock(inode, pipe->inode);
++      mutex_unlock(&inode->i_mutex);
+       mlog_exit(ret);
+       return ret;
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -735,10 +735,19 @@ ssize_t splice_from_pipe(struct pipe_ino
+        * ->write_end. Most of the time, these expect i_mutex to
+        * be held. Since this may result in an ABBA deadlock with
+        * pipe->inode, we have to order lock acquiry here.
++       *
++       * Outer lock must be inode->i_mutex, as pipe_wait() will
++       * release and reacquire pipe->inode->i_mutex, AND inode must
++       * never be a pipe.
+        */
+-      inode_double_lock(inode, pipe->inode);
++      WARN_ON(S_ISFIFO(inode->i_mode));
++      mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
++      if (pipe->inode)
++              mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+       ret = __splice_from_pipe(pipe, &sd, actor);
+-      inode_double_unlock(inode, pipe->inode);
++      if (pipe->inode)
++              mutex_unlock(&pipe->inode->i_mutex);
++      mutex_unlock(&inode->i_mutex);
+       return ret;
+ }
+@@ -829,11 +838,17 @@ generic_file_splice_write(struct pipe_in
+       };
+       ssize_t ret;
+-      inode_double_lock(inode, pipe->inode);
++      WARN_ON(S_ISFIFO(inode->i_mode));
++      mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+       ret = file_remove_suid(out);
+-      if (likely(!ret))
++      if (likely(!ret)) {
++              if (pipe->inode)
++                      mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+               ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
+-      inode_double_unlock(inode, pipe->inode);
++              if (pipe->inode)
++                      mutex_unlock(&pipe->inode->i_mutex);
++      }
++      mutex_unlock(&inode->i_mutex);
+       if (ret > 0) {
+               unsigned long nr_pages;
diff --git a/queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch b/queue-2.6.28/0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch
new file mode 100644 (file)
index 0000000..8734fc7
--- /dev/null
@@ -0,0 +1,28 @@
+From 37a8bca218bf6c4cad295b7d250c3590f57e3cf6 Mon Sep 17 00:00:00 2001
+From: Akinobu Mita <akinobu.mita@gmail.com>
+Date: Tue, 7 Apr 2009 16:25:04 +0000
+Subject: ALSA: hda - add missing comma in ad1884_slave_vols
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+upstream commit: bca68467b59a24396554d8dd5979ee363c174854
+
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ sound/pci/hda/patch_analog.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_analog.c
++++ b/sound/pci/hda/patch_analog.c
+@@ -3233,7 +3233,7 @@ static const char *ad1884_slave_vols[] =
+       "Mic Playback Volume",
+       "CD Playback Volume",
+       "Internal Mic Playback Volume",
+-      "Docking Mic Playback Volume"
++      "Docking Mic Playback Volume",
+       "Beep Playback Volume",
+       "IEC958 Playback Volume",
+       NULL
diff --git a/queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch b/queue-2.6.28/0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch
new file mode 100644 (file)
index 0000000..7c2c274
--- /dev/null
@@ -0,0 +1,47 @@
+From 10b9c3cd8848919561d16570759c0146988cb8d5 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Thu, 5 Mar 2009 14:45:55 -0600
+Subject: SCSI: libiscsi: fix iscsi pool error path
+
+From: Jean Delvare <jdelvare@suse.de>
+
+upstream commit: f474a37bc48667595b5653a983b635c95ed82a3b
+
+Memory freeing in iscsi_pool_free() looks wrong to me. Either q->pool
+can be NULL and this should be tested before dereferencing it, or it
+can't be NULL and it shouldn't be tested at all. As far as I can see,
+the only case where q->pool is NULL is on early error in
+iscsi_pool_init(). One possible way to fix the bug is thus to not
+call iscsi_pool_free() in this case (nothing needs to be freed anyway)
+and then we can get rid of the q->pool check.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/scsi/libiscsi.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -1862,7 +1862,7 @@ iscsi_pool_init(struct iscsi_pool *q, in
+               num_arrays++;
+       q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL);
+       if (q->pool == NULL)
+-              goto enomem;
++              return -ENOMEM;
+       q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
+                             GFP_KERNEL, NULL);
+@@ -1897,8 +1897,7 @@ void iscsi_pool_free(struct iscsi_pool *
+       for (i = 0; i < q->max; i++)
+               kfree(q->pool[i]);
+-      if (q->pool)
+-              kfree(q->pool);
++      kfree(q->pool);
+       kfree(q->queue);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_pool_free);
diff --git a/queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch b/queue-2.6.28/0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch
new file mode 100644 (file)
index 0000000..0751ec7
--- /dev/null
@@ -0,0 +1,50 @@
+From b76d2b612cd5c0c6fb82340f9ec241ca75b942f9 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Wed, 1 Apr 2009 13:11:29 -0500
+Subject: SCSI: libiscsi: fix iscsi pool error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+From: Jean Delvare <jdelvare@suse.de>
+
+upstream commit: fd6e1c14b73dbab89cb76af895d5612e4a8b5522
+
+Le lundi 30 mars 2009, Chris Wright a Ã©crit :
+> q->queue could be ERR_PTR(-ENOMEM) which will break unwinding
+> on error.  Make iscsi_pool_free more defensive.
+>
+
+Making the freeing of q->queue dependent on q->pool being set looks
+really weird (although it is correct at the moment. But this seems
+to be fixable in a much simpler way.
+
+With the benefit that only the error case is slowed down. In both
+cases we have a problem if q->queue contains an error value but it's
+not -ENOMEM. Apparently this can't happen today, but it doesn't feel
+right to assume this will always be true. Maybe it's the right time
+to fix this as well.
+
+Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+[chrisw: this is a fixlet to f474a37b, also in -stable]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/scsi/libiscsi.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -1866,8 +1866,10 @@ iscsi_pool_init(struct iscsi_pool *q, in
+       q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
+                             GFP_KERNEL, NULL);
+-      if (q->queue == ERR_PTR(-ENOMEM))
++      if (IS_ERR(q->queue)) {
++              q->queue = NULL;
+               goto enomem;
++      }
+       for (i = 0; i < max; i++) {
+               q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff --git a/queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch b/queue-2.6.28/0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch
new file mode 100644 (file)
index 0000000..6b84e9f
--- /dev/null
@@ -0,0 +1,163 @@
+From 39cd13c96cfc4d9d5992e93625fe6d6cb4fe3991 Mon Sep 17 00:00:00 2001
+From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+Date: Thu, 9 Apr 2009 18:20:12 +0000
+Subject: posixtimers, sched: Fix posix clock monotonicity
+
+From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+
+upstream commit: c5f8d99585d7b5b7e857fabf8aefd0174903a98c
+
+Impact: Regression fix (against clock_gettime() backwarding bug)
+
+This patch re-introduces a couple of functions, task_sched_runtime
+and thread_group_sched_runtime, which was once removed at the
+time of 2.6.28-rc1.
+
+These functions protect the sampling of thread/process clock with
+rq lock.  This rq lock is required not to update rq->clock during
+the sampling.
+
+i.e.
+  The clock_gettime() may return
+   ((accounted runtime before update) + (delta after update))
+  that is less than what it should be.
+
+v2 -> v3:
+       - Rename static helper function __task_delta_exec()
+         to do_task_delta_exec() since -tip tree already has
+         a __task_delta_exec() of different version.
+
+v1 -> v2:
+       - Revises comments of function and patch description.
+       - Add note about accuracy of thread group's runtime.
+
+Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+LKML-Reference: <49D1CC93.4080401@jp.fujitsu.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ kernel/posix-cpu-timers.c |    7 ++--
+ kernel/sched.c            |   65 ++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 61 insertions(+), 11 deletions(-)
+
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -294,7 +294,7 @@ static int cpu_clock_sample(const clocki
+               cpu->cpu = virt_ticks(p);
+               break;
+       case CPUCLOCK_SCHED:
+-              cpu->sched = p->se.sum_exec_runtime + task_delta_exec(p);
++              cpu->sched = task_sched_runtime(p);
+               break;
+       }
+       return 0;
+@@ -310,18 +310,19 @@ static int cpu_clock_sample_group(const 
+ {
+       struct task_cputime cputime;
+-      thread_group_cputime(p, &cputime);
+       switch (CPUCLOCK_WHICH(which_clock)) {
+       default:
+               return -EINVAL;
+       case CPUCLOCK_PROF:
++              thread_group_cputime(p, &cputime);
+               cpu->cpu = cputime_add(cputime.utime, cputime.stime);
+               break;
+       case CPUCLOCK_VIRT:
++              thread_group_cputime(p, &cputime);
+               cpu->cpu = cputime.utime;
+               break;
+       case CPUCLOCK_SCHED:
+-              cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
++              cpu->sched = thread_group_sched_runtime(p);
+               break;
+       }
+       return 0;
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -4064,9 +4064,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat
+ EXPORT_PER_CPU_SYMBOL(kstat);
+ /*
+- * Return any ns on the sched_clock that have not yet been banked in
++ * Return any ns on the sched_clock that have not yet been accounted in
+  * @p in case that task is currently running.
++ *
++ * Called with task_rq_lock() held on @rq.
+  */
++static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
++{
++      u64 ns = 0;
++
++      if (task_current(rq, p)) {
++              update_rq_clock(rq);
++              ns = rq->clock - p->se.exec_start;
++              if ((s64)ns < 0)
++                      ns = 0;
++      }
++
++      return ns;
++}
++
+ unsigned long long task_delta_exec(struct task_struct *p)
+ {
+       unsigned long flags;
+@@ -4074,16 +4090,49 @@ unsigned long long task_delta_exec(struc
+       u64 ns = 0;
+       rq = task_rq_lock(p, &flags);
++      ns = do_task_delta_exec(p, rq);
++      task_rq_unlock(rq, &flags);
+-      if (task_current(rq, p)) {
+-              u64 delta_exec;
++      return ns;
++}
+-              update_rq_clock(rq);
+-              delta_exec = rq->clock - p->se.exec_start;
+-              if ((s64)delta_exec > 0)
+-                      ns = delta_exec;
+-      }
++/*
++ * Return accounted runtime for the task.
++ * In case the task is currently running, return the runtime plus current's
++ * pending runtime that have not been accounted yet.
++ */
++unsigned long long task_sched_runtime(struct task_struct *p)
++{
++      unsigned long flags;
++      struct rq *rq;
++      u64 ns = 0;
++
++      rq = task_rq_lock(p, &flags);
++      ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
++      task_rq_unlock(rq, &flags);
++
++      return ns;
++}
++/*
++ * Return sum_exec_runtime for the thread group.
++ * In case the task is currently running, return the sum plus current's
++ * pending runtime that have not been accounted yet.
++ *
++ * Note that the thread group might have other running tasks as well,
++ * so the return value not includes other pending runtime that other
++ * running tasks might have.
++ */
++unsigned long long thread_group_sched_runtime(struct task_struct *p)
++{
++      struct task_cputime totals;
++      unsigned long flags;
++      struct rq *rq;
++      u64 ns;
++
++      rq = task_rq_lock(p, &flags);
++      thread_group_cputime(p, &totals);
++      ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq);
+       task_rq_unlock(rq, &flags);
+       return ns;
diff --git a/queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch b/queue-2.6.28/0060-sched-do-not-count-frozen-tasks-toward-load.patch
new file mode 100644 (file)
index 0000000..bdd4735
--- /dev/null
@@ -0,0 +1,52 @@
+From 3f22ebd2f4d191631a7b867addc8bd99e948873f Mon Sep 17 00:00:00 2001
+From: Nathan Lynch <ntl@pobox.com>
+Date: Thu, 9 Apr 2009 18:20:02 +0000
+Subject: sched: do not count frozen tasks toward load
+
+From: Nathan Lynch <ntl@pobox.com>
+
+upstream commit: e3c8ca8336707062f3f7cb1cd7e6b3c753baccdd
+
+Freezing tasks via the cgroup freezer causes the load average to climb
+because the freezer's current implementation puts frozen tasks in
+uninterruptible sleep (D state).
+
+Some applications which perform job-scheduling functions consult the
+load average when making decisions.  If a cgroup is frozen, the load
+average does not provide a useful measure of the system's utilization
+to such applications.  This is especially inconvenient if the job
+scheduler employs the cgroup freezer as a mechanism for preempting low
+priority jobs.  Contrast this with using SIGSTOP for the same purpose:
+the stopped tasks do not count toward system load.
+
+Change task_contributes_to_load() to return false if the task is
+frozen.  This results in /proc/loadavg behavior that better meets
+users' expectations.
+
+Signed-off-by: Nathan Lynch <ntl@pobox.com>
+Acked-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Nigel Cunningham <nigel@tuxonice.net>
+Tested-by: Nigel Cunningham <nigel@tuxonice.net>
+Cc: containers@lists.linux-foundation.org
+Cc: linux-pm@lists.linux-foundation.org
+Cc: Matt Helsley <matthltc@us.ibm.com>
+LKML-Reference: <20090408194512.47a99b95@manatee.lan>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/sched.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -201,7 +201,8 @@ extern unsigned long long time_sync_thre
+ #define task_is_stopped_or_traced(task)       \
+                       ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
+ #define task_contributes_to_load(task)        \
+-                              ((task->state & TASK_UNINTERRUPTIBLE) != 0)
++                              ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \
++                               (task->flags & PF_FROZEN) == 0)
+ #define __set_task_state(tsk, state_value)            \
+       do { (tsk)->state = (state_value); } while (0)
diff --git a/queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch b/queue-2.6.28/0063-add-some-long-missing-capabilities-to-fs_mask.patch
new file mode 100644 (file)
index 0000000..e2c968b
--- /dev/null
@@ -0,0 +1,80 @@
+From d11a29e323dfd141183cdc918e31acdff02ef450 Mon Sep 17 00:00:00 2001
+From: Serge E. Hallyn <serue@us.ibm.com>
+Date: Mon, 13 Apr 2009 17:25:03 +0000
+Subject: add some long-missing capabilities to fs_mask
+
+From: Serge E. Hallyn <serue@us.ibm.com>
+
+upstream commit: 0ad30b8fd5fe798aae80df6344b415d8309342cc
+
+When POSIX capabilities were introduced during the 2.1 Linux
+cycle, the fs mask, which represents the capabilities which having
+fsuid==0 is supposed to grant, did not include CAP_MKNOD and
+CAP_LINUX_IMMUTABLE.  However, before capabilities the privilege
+to call these did in fact depend upon fsuid==0.
+
+This patch introduces those capabilities into the fsmask,
+restoring the old behavior.
+
+See the thread starting at http://lkml.org/lkml/2009/3/11/157 for
+reference.
+
+Note that if this fix is deemed valid, then earlier kernel versions (2.4
+and 2.2) ought to be fixed too.
+
+Changelog:
+       [Mar 23] Actually delete old CAP_FS_SET definition...
+       [Mar 20] Updated against J. Bruce Fields's patch
+
+Reported-by: Igor Zhbanov <izh1979@gmail.com>
+Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
+Cc: stable@kernel.org
+Cc: J. Bruce Fields <bfields@citi.umich.edu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/capability.h |   23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -366,7 +366,21 @@ typedef struct kernel_cap_struct {
+ #define CAP_FOR_EACH_U32(__capi)  \
+       for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi)
++/*
++ * CAP_FS_MASK and CAP_NFSD_MASKS:
++ *
++ * The fs mask is all the privileges that fsuid==0 historically meant.
++ * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE.
++ *
++ * It has never meant setting security.* and trusted.* xattrs.
++ *
++ * We could also define fsmask as follows:
++ *   1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions
++ *   2. The security.* and trusted.* xattrs are fs-related MAC permissions
++ */
++
+ # define CAP_FS_MASK_B0     (CAP_TO_MASK(CAP_CHOWN)           \
++                          | CAP_TO_MASK(CAP_MKNOD)            \
+                           | CAP_TO_MASK(CAP_DAC_OVERRIDE)     \
+                           | CAP_TO_MASK(CAP_DAC_READ_SEARCH)  \
+                           | CAP_TO_MASK(CAP_FOWNER)           \
+@@ -381,11 +395,12 @@ typedef struct kernel_cap_struct {
+ # define CAP_EMPTY_SET    ((kernel_cap_t){{ 0, 0 }})
+ # define CAP_FULL_SET     ((kernel_cap_t){{ ~0, ~0 }})
+ # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }})
+-# define CAP_FS_SET       ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } })
++# define CAP_FS_SET       ((kernel_cap_t){{ CAP_FS_MASK_B0 \
++                                  | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
++                                  CAP_FS_MASK_B1 } })
+ # define CAP_NFSD_SET     ((kernel_cap_t){{ CAP_FS_MASK_B0 \
+-                                          | CAP_TO_MASK(CAP_SYS_RESOURCE) \
+-                                          | CAP_TO_MASK(CAP_MKNOD), \
+-                                          CAP_FS_MASK_B1 } })
++                                  | CAP_TO_MASK(CAP_SYS_RESOURCE), \
++                                  CAP_FS_MASK_B1 } })
+ #endif /* _KERNEL_CAPABILITY_U32S != 2 */
diff --git a/queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch b/queue-2.6.28/0064-spi-spi_write_then_read-bugfixes.patch
new file mode 100644 (file)
index 0000000..3a5fa0a
--- /dev/null
@@ -0,0 +1,81 @@
+From 68890fb0bae12f076377dd6a9371be0289b98b7b Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell@users.sourceforge.net>
+Date: Mon, 13 Apr 2009 22:35:03 +0000
+Subject: spi: spi_write_then_read() bugfixes
+
+From: David Brownell <dbrownell@users.sourceforge.net>
+
+upstream commit: bdff549ebeff92b1a6952e5501caf16a6f8898c8
+
+The "simplify spi_write_then_read()" patch included two regressions from
+the 2.6.27 behaviors:
+
+ - The data it wrote out during the (full duplex) read side
+   of the transfer was not zeroed.
+
+ - It fails completely on half duplex hardware, such as
+   Microwire and most "3-wire" SPI variants.
+
+So, revert that patch.  A revised version should be submitted at some
+point, which can get the speedup on standard hardware (full duplex)
+without breaking on less-capable half-duplex stuff.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/spi/spi.c |   22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_devic
+       int                     status;
+       struct spi_message      message;
+-      struct spi_transfer     x;
++      struct spi_transfer     x[2];
+       u8                      *local_buf;
+       /* Use preallocated DMA-safe buffer.  We can't avoid copying here,
+@@ -671,9 +671,15 @@ int spi_write_then_read(struct spi_devic
+               return -EINVAL;
+       spi_message_init(&message);
+-      memset(&x, 0, sizeof x);
+-      x.len = n_tx + n_rx;
+-      spi_message_add_tail(&x, &message);
++      memset(x, 0, sizeof x);
++      if (n_tx) {
++              x[0].len = n_tx;
++              spi_message_add_tail(&x[0], &message);
++      }
++      if (n_rx) {
++              x[1].len = n_rx;
++              spi_message_add_tail(&x[1], &message);
++      }
+       /* ... unless someone else is using the pre-allocated buffer */
+       if (!mutex_trylock(&lock)) {
+@@ -684,15 +690,15 @@ int spi_write_then_read(struct spi_devic
+               local_buf = buf;
+       memcpy(local_buf, txbuf, n_tx);
+-      x.tx_buf = local_buf;
+-      x.rx_buf = local_buf;
++      x[0].tx_buf = local_buf;
++      x[1].rx_buf = local_buf + n_tx;
+       /* do the i/o */
+       status = spi_sync(spi, &message);
+       if (status == 0)
+-              memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
++              memcpy(rxbuf, x[1].rx_buf, n_rx);
+-      if (x.tx_buf == buf)
++      if (x[0].tx_buf == buf)
+               mutex_unlock(&lock);
+       else
+               kfree(local_buf);
diff --git a/queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch b/queue-2.6.28/0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch
new file mode 100644 (file)
index 0000000..acfe0ae
--- /dev/null
@@ -0,0 +1,62 @@
+From 6c6737beae9981a707c1a4e1e9f1baf7cc47ce5f Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@samba.org>
+Date: Wed, 15 Apr 2009 17:25:05 +0000
+Subject: powerpc: Fix data-corrupting bug in __futex_atomic_op
+
+From: Paul Mackerras <paulus@samba.org>
+
+upstream commit: 306a82881b14d950d59e0b59a55093a07d82aa9a
+
+Richard Henderson pointed out that the powerpc __futex_atomic_op has a
+bug: it will write the wrong value if the stwcx. fails and it has to
+retry the lwarx/stwcx. loop, since 'oparg' will have been overwritten
+by the result from the first time around the loop.  This happens
+because it uses the same register for 'oparg' (an input) as it uses
+for the result.
+
+This fixes it by using separate registers for 'oparg' and 'ret'.
+
+Cc: stable@kernel.org
+Signed-off-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/powerpc/include/asm/futex.h |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/powerpc/include/asm/futex.h
++++ b/arch/powerpc/include/asm/futex.h
+@@ -27,7 +27,7 @@
+       PPC_LONG "1b,4b,2b,4b\n" \
+       ".previous" \
+       : "=&r" (oldval), "=&r" (ret) \
+-      : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
++      : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
+       : "cr0", "memory")
+ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+@@ -47,19 +47,19 @@ static inline int futex_atomic_op_inuser
+       switch (op) {
+       case FUTEX_OP_SET:
+-              __futex_atomic_op("", ret, oldval, uaddr, oparg);
++              __futex_atomic_op("mr %1,%4\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ADD:
+-              __futex_atomic_op("add %1,%0,%1\n", ret, oldval, uaddr, oparg);
++              __futex_atomic_op("add %1,%0,%4\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_OR:
+-              __futex_atomic_op("or %1,%0,%1\n", ret, oldval, uaddr, oparg);
++              __futex_atomic_op("or %1,%0,%4\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ANDN:
+-              __futex_atomic_op("andc %1,%0,%1\n", ret, oldval, uaddr, oparg);
++              __futex_atomic_op("andc %1,%0,%4\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_XOR:
+-              __futex_atomic_op("xor %1,%0,%1\n", ret, oldval, uaddr, oparg);
++              __futex_atomic_op("xor %1,%0,%4\n", ret, oldval, uaddr, oparg);
+               break;
+       default:
+               ret = -ENOSYS;
diff --git a/queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch b/queue-2.6.28/0069-hpt366-fix-HPT370-DMA-timeouts.patch
new file mode 100644 (file)
index 0000000..26b5c74
--- /dev/null
@@ -0,0 +1,46 @@
+From 2a3403fd95cbf6f548198be0fd37a056d12a56fe Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Sat, 18 Apr 2009 17:42:19 +0200
+Subject: hpt366: fix HPT370 DMA timeouts
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+upstream commit: c018f1ee5cf81e58b93d9e93a2ee39cad13dc1ac
+
+The big driver change in 2.4.19-rc1 introduced a regression for many HPT370[A]
+chips -- DMA stopped to work completely, only causing endless timeouts...
+
+The culprit has been identified (at last!): it turned to be the code resetting
+the DMA state machine before each transfer. Stop doing it now as this counter-
+measure has clearly caused more harm than good.
+
+This should fix the kernel.org bug #7703.
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ide/hpt366.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/ide/hpt366.c
++++ b/drivers/ide/hpt366.c
+@@ -114,6 +114,8 @@
+  *   the register setting lists into the table indexed by the clock selected
+  * - set the correct hwif->ultra_mask for each individual chip
+  * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
++ * - stop resetting HPT370's state machine before each DMA transfer as that has
++ *   caused more harm than good
+  *    Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
+  */
+@@ -133,7 +135,7 @@
+ #define DRV_NAME "hpt366"
+ /* various tuning parameters */
+-#define HPT_RESET_STATE_ENGINE
++#undef        HPT_RESET_STATE_ENGINE
+ #undef        HPT_DELAY_INTERRUPT
+ #define HPT_SERIALIZE_IO      0
diff --git a/queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch b/queue-2.6.28/0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch
new file mode 100644 (file)
index 0000000..072d650
--- /dev/null
@@ -0,0 +1,73 @@
+From d683876908060916ada0091d1db3b09afccb1517 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Tue, 14 Apr 2009 18:39:14 +0400
+Subject: pata_hpt37x: fix HPT370 DMA timeouts
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+upstream commit: 265b7215aed36941620b65ecfff516200fb190c1
+
+The libata driver has copied the code from the IDE driver which caused a post
+2.4.18 regression on many HPT370[A] chips -- DMA stopped to work completely,
+only causing timeouts.  Now remove hpt370_bmdma_start() for good...
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ata/pata_hpt37x.c |   22 ++--------------------
+ 1 file changed, 2 insertions(+), 20 deletions(-)
+
+--- a/drivers/ata/pata_hpt37x.c
++++ b/drivers/ata/pata_hpt37x.c
+@@ -8,7 +8,7 @@
+  * Copyright (C) 1999-2003            Andre Hedrick <andre@linux-ide.org>
+  * Portions Copyright (C) 2001                Sun Microsystems, Inc.
+  * Portions Copyright (C) 2003                Red Hat Inc
+- * Portions Copyright (C) 2005-2007   MontaVista Software, Inc.
++ * Portions Copyright (C) 2005-2009   MontaVista Software, Inc.
+  *
+  * TODO
+  *    Look into engine reset on timeout errors. Should not be required.
+@@ -24,7 +24,7 @@
+ #include <linux/libata.h>
+ #define DRV_NAME      "pata_hpt37x"
+-#define DRV_VERSION   "0.6.11"
++#define DRV_VERSION   "0.6.12"
+ struct hpt_clock {
+       u8      xfer_speed;
+@@ -445,23 +445,6 @@ static void hpt370_set_dmamode(struct at
+ }
+ /**
+- *    hpt370_bmdma_start              -       DMA engine begin
+- *    @qc: ATA command
+- *
+- *    The 370 and 370A want us to reset the DMA engine each time we
+- *    use it. The 372 and later are fine.
+- */
+-
+-static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
+-{
+-      struct ata_port *ap = qc->ap;
+-      struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+-      pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
+-      udelay(10);
+-      ata_bmdma_start(qc);
+-}
+-
+-/**
+  *    hpt370_bmdma_end                -       DMA engine stop
+  *    @qc: ATA command
+  *
+@@ -598,7 +581,6 @@ static struct scsi_host_template hpt37x_
+ static struct ata_port_operations hpt370_port_ops = {
+       .inherits       = &ata_bmdma_port_ops,
+-      .bmdma_start    = hpt370_bmdma_start,
+       .bmdma_stop     = hpt370_bmdma_stop,
+       .mode_filter    = hpt370_filter,
diff --git a/queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch b/queue-2.6.28/0071-mm-pass-correct-mm-when-growing-stack.patch
new file mode 100644 (file)
index 0000000..b6de878
--- /dev/null
@@ -0,0 +1,39 @@
+From 14be1689c96842bd93cbcda4cb0bd4c5cc15a5a0 Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hugh@veritas.com>
+Date: Thu, 16 Apr 2009 21:45:05 +0000
+Subject: mm: pass correct mm when growing stack
+
+From: Hugh Dickins <hugh@veritas.com>
+
+upstream commit: 05fa199d45c54a9bda7aa3ae6537253d6f097aa9
+
+Tetsuo Handa reports seeing the WARN_ON(current->mm == NULL) in
+security_vm_enough_memory(), when do_execve() is touching the
+target mm's stack, to set up its args and environment.
+
+Yes, a UMH_NO_WAIT or UMH_WAIT_PROC call_usermodehelper() spawns
+an mm-less kernel thread to do the exec.  And in any case, that
+vm_enough_memory check when growing stack ought to be done on the
+target mm, not on the execer's mm (though apart from the warning,
+it only makes a slight tweak to OVERCOMMIT_NEVER behaviour).
+
+Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Signed-off-by: Hugh Dickins <hugh@veritas.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ mm/mmap.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1580,7 +1580,7 @@ static int acct_stack_growth(struct vm_a
+        * Overcommit..  This must be the final test, as it will
+        * update security statistics.
+        */
+-      if (security_vm_enough_memory(grow))
++      if (security_vm_enough_memory_mm(mm, grow))
+               return -ENOMEM;
+       /* Ok, everything looks good - let it rip */
diff --git a/queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch b/queue-2.6.28/0072-SCSI-sg-fix-races-during-device-removal.patch
new file mode 100644 (file)
index 0000000..cfc2170
--- /dev/null
@@ -0,0 +1,741 @@
+From b21c6d2897cd455fa396f4041a0c8165784e949f Mon Sep 17 00:00:00 2001
+From: Tony Battersby <tonyb@cybernetics.com>
+Date: Wed, 21 Jan 2009 14:45:50 -0500
+Subject: SCSI: sg: fix races during device removal
+
+From: Tony Battersby <tonyb@cybernetics.com>
+
+upstream commit: c6517b7942fad663cc1cf3235cbe4207cf769332
+
+sg has the following problems related to device removal:
+
+* opening a sg fd races with removing a device
+* closing a sg fd races with removing a device
+* /proc/scsi/sg/* access races with removing a device
+* command completion races with removing a device
+* command completion races with closing a sg fd
+* can rmmod sg with active commands
+
+These problems can cause kernel oopses, memory-use-after-free, or
+double-free errors.  This patch fixes these problems by using krefs
+to manage the lifetime of sg_device and sg_fd.
+
+Each command submitted to the midlevel holds a reference to sg_fd
+until the completion callback.  This ensures that sg_fd doesn't go
+away if the fd is closed with commands still outstanding.
+
+sg_fd gets the reference of sg_device (with scsi_device) and also
+makes sure that the sg module doesn't go away.
+
+/proc/scsi/sg/* functions don't play nicely with krefs because they
+give information about sg_fds which have been closed but not yet
+freed due to still having outstanding commands and sg_devices which
+have been removed but not yet freed due to still being referenced
+by one or more sg_fds.  To deal with this safely without removing
+functionality, /proc functions now access sg_device and sg_fd while
+holding a lock instead of using kref_get()/kref_put().
+
+Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+[chrisw: big for -stable, helps fix real bug, and made it through rc2 upstream]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/scsi/sg.c |  418 +++++++++++++++++++++++++-----------------------------
+ 1 file changed, 201 insertions(+), 217 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -101,6 +101,7 @@ static int scatter_elem_sz_prev = SG_SCA
+ #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
+ static int sg_add(struct device *, struct class_interface *);
++static void sg_device_destroy(struct kref *kref);
+ static void sg_remove(struct device *, struct class_interface *);
+ static DEFINE_IDR(sg_index_idr);
+@@ -158,6 +159,8 @@ typedef struct sg_fd {             /* holds the sta
+       char next_cmd_len;      /* 0 -> automatic (def), >0 -> use on next write() */
+       char keep_orphan;       /* 0 -> drop orphan (def), 1 -> keep for read() */
+       char mmap_called;       /* 0 -> mmap() never called on this fd */
++      struct kref f_ref;
++      struct execute_work ew;
+ } Sg_fd;
+ typedef struct sg_device { /* holds the state of each scsi generic device */
+@@ -171,6 +174,7 @@ typedef struct sg_device { /* holds the 
+       char sgdebug;           /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
+       struct gendisk *disk;
+       struct cdev * cdev;     /* char_dev [sysfs: /sys/cdev/major/sg<n>] */
++      struct kref d_ref;
+ } Sg_device;
+ static int sg_fasync(int fd, struct file *filp, int mode);
+@@ -194,13 +198,14 @@ static void sg_build_reserve(Sg_fd * sfp
+ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
+ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
+ static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
+-static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
+-static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
++static void sg_remove_sfp(struct kref *);
+ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
+ static Sg_request *sg_add_request(Sg_fd * sfp);
+ static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
+ static int sg_res_in_use(Sg_fd * sfp);
++static Sg_device *sg_lookup_dev(int dev);
+ static Sg_device *sg_get_dev(int dev);
++static void sg_put_dev(Sg_device *sdp);
+ #ifdef CONFIG_SCSI_PROC_FS
+ static int sg_last_dev(void);
+ #endif
+@@ -237,22 +242,17 @@ sg_open(struct inode *inode, struct file
+       nonseekable_open(inode, filp);
+       SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
+       sdp = sg_get_dev(dev);
+-      if ((!sdp) || (!sdp->device)) {
+-              unlock_kernel();
+-              return -ENXIO;
+-      }
+-      if (sdp->detached) {
+-              unlock_kernel();
+-              return -ENODEV;
++      if (IS_ERR(sdp)) {
++              retval = PTR_ERR(sdp);
++              sdp = NULL;
++              goto sg_put;
+       }
+       /* This driver's module count bumped by fops_get in <linux/fs.h> */
+       /* Prevent the device driver from vanishing while we sleep */
+       retval = scsi_device_get(sdp->device);
+-      if (retval) {
+-              unlock_kernel();
+-              return retval;
+-      }
++      if (retval)
++              goto sg_put;
+       if (!((flags & O_NONBLOCK) ||
+             scsi_block_when_processing_errors(sdp->device))) {
+@@ -303,16 +303,20 @@ sg_open(struct inode *inode, struct file
+       if ((sfp = sg_add_sfp(sdp, dev)))
+               filp->private_data = sfp;
+       else {
+-              if (flags & O_EXCL)
++              if (flags & O_EXCL) {
+                       sdp->exclude = 0;       /* undo if error */
++                      wake_up_interruptible(&sdp->o_excl_wait);
++              }
+               retval = -ENOMEM;
+               goto error_out;
+       }
+-      unlock_kernel();
+-      return 0;
+-
+-      error_out:
+-      scsi_device_put(sdp->device);
++      retval = 0;
++error_out:
++      if (retval)
++              scsi_device_put(sdp->device);
++sg_put:
++      if (sdp)
++              sg_put_dev(sdp);
+       unlock_kernel();
+       return retval;
+ }
+@@ -327,13 +331,13 @@ sg_release(struct inode *inode, struct f
+       if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
+               return -ENXIO;
+       SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name));
+-      if (0 == sg_remove_sfp(sdp, sfp)) {     /* Returns 1 when sdp gone */
+-              if (!sdp->detached) {
+-                      scsi_device_put(sdp->device);
+-              }
+-              sdp->exclude = 0;
+-              wake_up_interruptible(&sdp->o_excl_wait);
+-      }
++
++      sfp->closed = 1;
++
++      sdp->exclude = 0;
++      wake_up_interruptible(&sdp->o_excl_wait);
++
++      kref_put(&sfp->f_ref, sg_remove_sfp);
+       return 0;
+ }
+@@ -755,6 +759,7 @@ sg_common_write(Sg_fd * sfp, Sg_request 
+       hp->duration = jiffies_to_msecs(jiffies);
+       srp->rq->timeout = timeout;
++      kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
+       blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
+                             srp->rq, 1, sg_rq_end_io);
+       return 0;
+@@ -1247,24 +1252,23 @@ sg_mmap(struct file *filp, struct vm_are
+ static void sg_rq_end_io(struct request *rq, int uptodate)
+ {
+       struct sg_request *srp = rq->end_io_data;
+-      Sg_device *sdp = NULL;
++      Sg_device *sdp;
+       Sg_fd *sfp;
+       unsigned long iflags;
+       unsigned int ms;
+       char *sense;
+-      int result, resid;
++      int result, resid, done = 1;
+-      if (NULL == srp) {
+-              printk(KERN_ERR "sg_cmd_done: NULL request\n");
++      if (WARN_ON(srp->done != 0))
+               return;
+-      }
++
+       sfp = srp->parentfp;
+-      if (sfp)
+-              sdp = sfp->parentdp;
+-      if ((NULL == sdp) || sdp->detached) {
+-              printk(KERN_INFO "sg_cmd_done: device detached\n");
++      if (WARN_ON(sfp == NULL))
+               return;
+-      }
++
++      sdp = sfp->parentdp;
++      if (unlikely(sdp->detached))
++              printk(KERN_INFO "sg_rq_end_io: device detached\n");
+       sense = rq->sense;
+       result = rq->errors;
+@@ -1303,33 +1307,26 @@ static void sg_rq_end_io(struct request 
+       }
+       /* Rely on write phase to clean out srp status values, so no "else" */
+-      if (sfp->closed) {      /* whoops this fd already released, cleanup */
+-              SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n"));
+-              sg_finish_rem_req(srp);
+-              srp = NULL;
+-              if (NULL == sfp->headrp) {
+-                      SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n"));
+-                      if (0 == sg_remove_sfp(sdp, sfp)) {     /* device still present */
+-                              scsi_device_put(sdp->device);
+-                      }
+-                      sfp = NULL;
+-              }
+-      } else if (srp && srp->orphan) {
++      write_lock_irqsave(&sfp->rq_list_lock, iflags);
++      if (unlikely(srp->orphan)) {
+               if (sfp->keep_orphan)
+                       srp->sg_io_owned = 0;
+-              else {
+-                      sg_finish_rem_req(srp);
+-                      srp = NULL;
+-              }
++              else
++                      done = 0;
+       }
+-      if (sfp && srp) {
+-              /* Now wake up any sg_read() that is waiting for this packet. */
+-              kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
+-              write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-              srp->done = 1;
++      srp->done = done;
++      write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++
++      if (likely(done)) {
++              /* Now wake up any sg_read() that is waiting for this
++               * packet.
++               */
+               wake_up_interruptible(&sfp->read_wait);
+-              write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-      }
++              kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
++      } else
++              sg_finish_rem_req(srp); /* call with srp->done == 0 */
++
++      kref_put(&sfp->f_ref, sg_remove_sfp);
+ }
+ static struct file_operations sg_fops = {
+@@ -1364,17 +1361,18 @@ static Sg_device *sg_alloc(struct gendis
+               printk(KERN_WARNING "kmalloc Sg_device failure\n");
+               return ERR_PTR(-ENOMEM);
+       }
+-      error = -ENOMEM;
++
+       if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) {
+               printk(KERN_WARNING "idr expansion Sg_device failure\n");
++              error = -ENOMEM;
+               goto out;
+       }
+       write_lock_irqsave(&sg_index_lock, iflags);
+-      error = idr_get_new(&sg_index_idr, sdp, &k);
+-      write_unlock_irqrestore(&sg_index_lock, iflags);
++      error = idr_get_new(&sg_index_idr, sdp, &k);
+       if (error) {
++              write_unlock_irqrestore(&sg_index_lock, iflags);
+               printk(KERN_WARNING "idr allocation Sg_device failure: %d\n",
+                      error);
+               goto out;
+@@ -1391,6 +1389,9 @@ static Sg_device *sg_alloc(struct gendis
+       init_waitqueue_head(&sdp->o_excl_wait);
+       sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
+       sdp->index = k;
++      kref_init(&sdp->d_ref);
++
++      write_unlock_irqrestore(&sg_index_lock, iflags);
+       error = 0;
+  out:
+@@ -1401,6 +1402,8 @@ static Sg_device *sg_alloc(struct gendis
+       return sdp;
+  overflow:
++      idr_remove(&sg_index_idr, k);
++      write_unlock_irqrestore(&sg_index_lock, iflags);
+       sdev_printk(KERN_WARNING, scsidp,
+                   "Unable to attach sg device type=%d, minor "
+                   "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1);
+@@ -1488,49 +1491,46 @@ out:
+       return error;
+ }
+-static void
+-sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
++static void sg_device_destroy(struct kref *kref)
++{
++      struct sg_device *sdp = container_of(kref, struct sg_device, d_ref);
++      unsigned long flags;
++
++      /* CAUTION!  Note that the device can still be found via idr_find()
++       * even though the refcount is 0.  Therefore, do idr_remove() BEFORE
++       * any other cleanup.
++       */
++
++      write_lock_irqsave(&sg_index_lock, flags);
++      idr_remove(&sg_index_idr, sdp->index);
++      write_unlock_irqrestore(&sg_index_lock, flags);
++
++      SCSI_LOG_TIMEOUT(3,
++              printk("sg_device_destroy: %s\n",
++                      sdp->disk->disk_name));
++
++      put_disk(sdp->disk);
++      kfree(sdp);
++}
++
++static void sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
+ {
+       struct scsi_device *scsidp = to_scsi_device(cl_dev->parent);
+       Sg_device *sdp = dev_get_drvdata(cl_dev);
+       unsigned long iflags;
+       Sg_fd *sfp;
+-      Sg_fd *tsfp;
+-      Sg_request *srp;
+-      Sg_request *tsrp;
+-      int delay;
+-      if (!sdp)
++      if (!sdp || sdp->detached)
+               return;
+-      delay = 0;
++      SCSI_LOG_TIMEOUT(3, printk("sg_remove: %s\n", sdp->disk->disk_name));
++
++      /* Need a write lock to set sdp->detached. */
+       write_lock_irqsave(&sg_index_lock, iflags);
+-      if (sdp->headfp) {
+-              sdp->detached = 1;
+-              for (sfp = sdp->headfp; sfp; sfp = tsfp) {
+-                      tsfp = sfp->nextfp;
+-                      for (srp = sfp->headrp; srp; srp = tsrp) {
+-                              tsrp = srp->nextrp;
+-                              if (sfp->closed || (0 == sg_srp_done(srp, sfp)))
+-                                      sg_finish_rem_req(srp);
+-                      }
+-                      if (sfp->closed) {
+-                              scsi_device_put(sdp->device);
+-                              __sg_remove_sfp(sdp, sfp);
+-                      } else {
+-                              delay = 1;
+-                              wake_up_interruptible(&sfp->read_wait);
+-                              kill_fasync(&sfp->async_qp, SIGPOLL,
+-                                          POLL_HUP);
+-                      }
+-              }
+-              SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index));
+-              if (NULL == sdp->headfp) {
+-                      idr_remove(&sg_index_idr, sdp->index);
+-              }
+-      } else {        /* nothing active, simple case */
+-              SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index));
+-              idr_remove(&sg_index_idr, sdp->index);
++      sdp->detached = 1;
++      for (sfp = sdp->headfp; sfp; sfp = sfp->nextfp) {
++              wake_up_interruptible(&sfp->read_wait);
++              kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP);
+       }
+       write_unlock_irqrestore(&sg_index_lock, iflags);
+@@ -1538,13 +1538,8 @@ sg_remove(struct device *cl_dev, struct 
+       device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index));
+       cdev_del(sdp->cdev);
+       sdp->cdev = NULL;
+-      put_disk(sdp->disk);
+-      sdp->disk = NULL;
+-      if (NULL == sdp->headfp)
+-              kfree(sdp);
+-      if (delay)
+-              msleep(10);     /* dirty detach so delay device destruction */
++      sg_put_dev(sdp);
+ }
+ module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
+@@ -1939,22 +1934,6 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
+       return resp;
+ }
+-#ifdef CONFIG_SCSI_PROC_FS
+-static Sg_request *
+-sg_get_nth_request(Sg_fd * sfp, int nth)
+-{
+-      Sg_request *resp;
+-      unsigned long iflags;
+-      int k;
+-
+-      read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      for (k = 0, resp = sfp->headrp; resp && (k < nth);
+-           ++k, resp = resp->nextrp) ;
+-      read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-      return resp;
+-}
+-#endif
+-
+ /* always adds to end of list */
+ static Sg_request *
+ sg_add_request(Sg_fd * sfp)
+@@ -2030,22 +2009,6 @@ sg_remove_request(Sg_fd * sfp, Sg_reques
+       return res;
+ }
+-#ifdef CONFIG_SCSI_PROC_FS
+-static Sg_fd *
+-sg_get_nth_sfp(Sg_device * sdp, int nth)
+-{
+-      Sg_fd *resp;
+-      unsigned long iflags;
+-      int k;
+-
+-      read_lock_irqsave(&sg_index_lock, iflags);
+-      for (k = 0, resp = sdp->headfp; resp && (k < nth);
+-           ++k, resp = resp->nextfp) ;
+-      read_unlock_irqrestore(&sg_index_lock, iflags);
+-      return resp;
+-}
+-#endif
+-
+ static Sg_fd *
+ sg_add_sfp(Sg_device * sdp, int dev)
+ {
+@@ -2060,6 +2023,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
+       init_waitqueue_head(&sfp->read_wait);
+       rwlock_init(&sfp->rq_list_lock);
++      kref_init(&sfp->f_ref);
+       sfp->timeout = SG_DEFAULT_TIMEOUT;
+       sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER;
+       sfp->force_packid = SG_DEF_FORCE_PACK_ID;
+@@ -2087,15 +2051,54 @@ sg_add_sfp(Sg_device * sdp, int dev)
+       sg_build_reserve(sfp, bufflen);
+       SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp:   bufflen=%d, k_use_sg=%d\n",
+                          sfp->reserve.bufflen, sfp->reserve.k_use_sg));
++
++      kref_get(&sdp->d_ref);
++      __module_get(THIS_MODULE);
+       return sfp;
+ }
+-static void
+-__sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
++static void sg_remove_sfp_usercontext(struct work_struct *work)
++{
++      struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
++      struct sg_device *sdp = sfp->parentdp;
++
++      /* Cleanup any responses which were never read(). */
++      while (sfp->headrp)
++              sg_finish_rem_req(sfp->headrp);
++
++      if (sfp->reserve.bufflen > 0) {
++              SCSI_LOG_TIMEOUT(6,
++                      printk("sg_remove_sfp:    bufflen=%d, k_use_sg=%d\n",
++                              (int) sfp->reserve.bufflen,
++                              (int) sfp->reserve.k_use_sg));
++              sg_remove_scat(&sfp->reserve);
++      }
++
++      SCSI_LOG_TIMEOUT(6,
++              printk("sg_remove_sfp: %s, sfp=0x%p\n",
++                      sdp->disk->disk_name,
++                      sfp));
++      kfree(sfp);
++
++      scsi_device_put(sdp->device);
++      sg_put_dev(sdp);
++      module_put(THIS_MODULE);
++}
++
++static void sg_remove_sfp(struct kref *kref)
+ {
++      struct sg_fd *sfp = container_of(kref, struct sg_fd, f_ref);
++      struct sg_device *sdp = sfp->parentdp;
+       Sg_fd *fp;
+       Sg_fd *prev_fp;
++      unsigned long iflags;
++
++      /* CAUTION!  Note that sfp can still be found by walking sdp->headfp
++       * even though the refcount is now 0.  Therefore, unlink sfp from
++       * sdp->headfp BEFORE doing any other cleanup.
++       */
++      write_lock_irqsave(&sg_index_lock, iflags);
+       prev_fp = sdp->headfp;
+       if (sfp == prev_fp)
+               sdp->headfp = prev_fp->nextfp;
+@@ -2108,54 +2111,10 @@ __sg_remove_sfp(Sg_device * sdp, Sg_fd *
+                       prev_fp = fp;
+               }
+       }
+-      if (sfp->reserve.bufflen > 0) {
+-              SCSI_LOG_TIMEOUT(6, 
+-                      printk("__sg_remove_sfp:    bufflen=%d, k_use_sg=%d\n",
+-                      (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg));
+-              sg_remove_scat(&sfp->reserve);
+-      }
+-      sfp->parentdp = NULL;
+-      SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    sfp=0x%p\n", sfp));
+-      kfree(sfp);
+-}
+-
+-/* Returns 0 in normal case, 1 when detached and sdp object removed */
+-static int
+-sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
+-{
+-      Sg_request *srp;
+-      Sg_request *tsrp;
+-      int dirty = 0;
+-      int res = 0;
+-
+-      for (srp = sfp->headrp; srp; srp = tsrp) {
+-              tsrp = srp->nextrp;
+-              if (sg_srp_done(srp, sfp))
+-                      sg_finish_rem_req(srp);
+-              else
+-                      ++dirty;
+-      }
+-      if (0 == dirty) {
+-              unsigned long iflags;
++      write_unlock_irqrestore(&sg_index_lock, iflags);
++      wake_up_interruptible(&sdp->o_excl_wait);
+-              write_lock_irqsave(&sg_index_lock, iflags);
+-              __sg_remove_sfp(sdp, sfp);
+-              if (sdp->detached && (NULL == sdp->headfp)) {
+-                      idr_remove(&sg_index_idr, sdp->index);
+-                      kfree(sdp);
+-                      res = 1;
+-              }
+-              write_unlock_irqrestore(&sg_index_lock, iflags);
+-      } else {
+-              /* MOD_INC's to inhibit unloading sg and associated adapter driver */
+-              /* only bump the access_count if we actually succeeded in
+-               * throwing another counter on the host module */
+-              scsi_device_get(sdp->device);   /* XXX: retval ignored? */      
+-              sfp->closed = 1;        /* flag dirty state on this fd */
+-              SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
+-                                dirty));
+-      }
+-      return res;
++      execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew);
+ }
+ static int
+@@ -2197,19 +2156,38 @@ sg_last_dev(void)
+ }
+ #endif
+-static Sg_device *
+-sg_get_dev(int dev)
++/* must be called with sg_index_lock held */
++static Sg_device *sg_lookup_dev(int dev)
+ {
+-      Sg_device *sdp;
+-      unsigned long iflags;
++      return idr_find(&sg_index_idr, dev);
++}
+-      read_lock_irqsave(&sg_index_lock, iflags);
+-      sdp = idr_find(&sg_index_idr, dev);
+-      read_unlock_irqrestore(&sg_index_lock, iflags);
++static Sg_device *sg_get_dev(int dev)
++{
++      struct sg_device *sdp;
++      unsigned long flags;
++
++      read_lock_irqsave(&sg_index_lock, flags);
++      sdp = sg_lookup_dev(dev);
++      if (!sdp)
++              sdp = ERR_PTR(-ENXIO);
++      else if (sdp->detached) {
++              /* If sdp->detached, then the refcount may already be 0, in
++               * which case it would be a bug to do kref_get().
++               */
++              sdp = ERR_PTR(-ENODEV);
++      } else
++              kref_get(&sdp->d_ref);
++      read_unlock_irqrestore(&sg_index_lock, flags);
+       return sdp;
+ }
++static void sg_put_dev(struct sg_device *sdp)
++{
++      kref_put(&sdp->d_ref, sg_device_destroy);
++}
++
+ #ifdef CONFIG_SCSI_PROC_FS
+ static struct proc_dir_entry *sg_proc_sgp = NULL;
+@@ -2466,8 +2444,10 @@ static int sg_proc_seq_show_dev(struct s
+       struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
+       Sg_device *sdp;
+       struct scsi_device *scsidp;
++      unsigned long iflags;
+-      sdp = it ? sg_get_dev(it->index) : NULL;
++      read_lock_irqsave(&sg_index_lock, iflags);
++      sdp = it ? sg_lookup_dev(it->index) : NULL;
+       if (sdp && (scsidp = sdp->device) && (!sdp->detached))
+               seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+                             scsidp->host->host_no, scsidp->channel,
+@@ -2478,6 +2458,7 @@ static int sg_proc_seq_show_dev(struct s
+                             (int) scsi_device_online(scsidp));
+       else
+               seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
++      read_unlock_irqrestore(&sg_index_lock, iflags);
+       return 0;
+ }
+@@ -2491,16 +2472,20 @@ static int sg_proc_seq_show_devstrs(stru
+       struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
+       Sg_device *sdp;
+       struct scsi_device *scsidp;
++      unsigned long iflags;
+-      sdp = it ? sg_get_dev(it->index) : NULL;
++      read_lock_irqsave(&sg_index_lock, iflags);
++      sdp = it ? sg_lookup_dev(it->index) : NULL;
+       if (sdp && (scsidp = sdp->device) && (!sdp->detached))
+               seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n",
+                          scsidp->vendor, scsidp->model, scsidp->rev);
+       else
+               seq_printf(s, "<no active device>\n");
++      read_unlock_irqrestore(&sg_index_lock, iflags);
+       return 0;
+ }
++/* must be called while holding sg_index_lock */
+ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
+ {
+       int k, m, new_interface, blen, usg;
+@@ -2510,7 +2495,8 @@ static void sg_proc_debug_helper(struct 
+       const char * cp;
+       unsigned int ms;
+-      for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) {
++      for (k = 0, fp = sdp->headfp; fp != NULL; ++k, fp = fp->nextfp) {
++              read_lock(&fp->rq_list_lock); /* irqs already disabled */
+               seq_printf(s, "   FD(%d): timeout=%dms bufflen=%d "
+                          "(res)sgat=%d low_dma=%d\n", k + 1,
+                          jiffies_to_msecs(fp->timeout),
+@@ -2520,7 +2506,9 @@ static void sg_proc_debug_helper(struct 
+               seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n",
+                          (int) fp->cmd_q, (int) fp->force_packid,
+                          (int) fp->keep_orphan, (int) fp->closed);
+-              for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) {
++              for (m = 0, srp = fp->headrp;
++                              srp != NULL;
++                              ++m, srp = srp->nextrp) {
+                       hp = &srp->header;
+                       new_interface = (hp->interface_id == '\0') ? 0 : 1;
+                       if (srp->res_used) {
+@@ -2557,6 +2545,7 @@ static void sg_proc_debug_helper(struct 
+               }
+               if (0 == m)
+                       seq_printf(s, "     No requests active\n");
++              read_unlock(&fp->rq_list_lock);
+       }
+ }
+@@ -2569,39 +2558,34 @@ static int sg_proc_seq_show_debug(struct
+ {
+       struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
+       Sg_device *sdp;
++      unsigned long iflags;
+       if (it && (0 == it->index)) {
+               seq_printf(s, "max_active_device=%d(origin 1)\n",
+                          (int)it->max);
+               seq_printf(s, " def_reserved_size=%d\n", sg_big_buff);
+       }
+-      sdp = it ? sg_get_dev(it->index) : NULL;
+-      if (sdp) {
+-              struct scsi_device *scsidp = sdp->device;
+-              if (NULL == scsidp) {
+-                      seq_printf(s, "device %d detached ??\n", 
+-                                 (int)it->index);
+-                      return 0;
+-              }
++      read_lock_irqsave(&sg_index_lock, iflags);
++      sdp = it ? sg_lookup_dev(it->index) : NULL;
++      if (sdp && sdp->headfp) {
++              struct scsi_device *scsidp = sdp->device;
+-              if (sg_get_nth_sfp(sdp, 0)) {
+-                      seq_printf(s, " >>> device=%s ",
+-                              sdp->disk->disk_name);
+-                      if (sdp->detached)
+-                              seq_printf(s, "detached pending close ");
+-                      else
+-                              seq_printf
+-                                  (s, "scsi%d chan=%d id=%d lun=%d   em=%d",
+-                                   scsidp->host->host_no,
+-                                   scsidp->channel, scsidp->id,
+-                                   scsidp->lun,
+-                                   scsidp->host->hostt->emulated);
+-                      seq_printf(s, " sg_tablesize=%d excl=%d\n",
+-                                 sdp->sg_tablesize, sdp->exclude);
+-              }
++              seq_printf(s, " >>> device=%s ", sdp->disk->disk_name);
++              if (sdp->detached)
++                      seq_printf(s, "detached pending close ");
++              else
++                      seq_printf
++                          (s, "scsi%d chan=%d id=%d lun=%d   em=%d",
++                           scsidp->host->host_no,
++                           scsidp->channel, scsidp->id,
++                           scsidp->lun,
++                           scsidp->host->hostt->emulated);
++              seq_printf(s, " sg_tablesize=%d excl=%d\n",
++                         sdp->sg_tablesize, sdp->exclude);
+               sg_proc_debug_helper(s, sdp);
+       }
++      read_unlock_irqrestore(&sg_index_lock, iflags);
+       return 0;
+ }
diff --git a/queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch b/queue-2.6.28/0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch
new file mode 100644 (file)
index 0000000..cd9981c
--- /dev/null
@@ -0,0 +1,126 @@
+From d4845ceede8c4087233198d2847b788a4e6f65b5 Mon Sep 17 00:00:00 2001
+From: Tony Battersby <tonyb@cybernetics.com>
+Date: Tue, 20 Jan 2009 17:00:09 -0500
+Subject: SCSI: sg: fix races with ioctl(SG_IO)
+
+From: Tony Battersby <tonyb@cybernetics.com>
+
+upstream commit: a2dd3b4cea335713b58996bb07b3abcde1175f47
+
+sg_io_owned needs to be set before the command is sent to the midlevel;
+otherwise, a quickly-completing command may cause a different CPU
+to see "srp->done == 1 && !srp->sg_io_owned", which would lead to
+incorrect behavior.
+
+Check srp->done and set srp->orphan while holding rq_list_lock to
+prevent races with sg_rq_end_io().
+
+There is no need to check sfp->closed from read/write/ioctl/poll/etc.
+since the kernel guarantees that this won't happen.
+
+The usefulness of sg_srp_done() was questionable before; now it is
+definitely not needed.
+
+Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/scsi/sg.c |   39 ++++++++++++++-------------------------
+ 1 file changed, 14 insertions(+), 25 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -189,7 +189,7 @@ static ssize_t sg_new_read(Sg_fd * sfp, 
+                          Sg_request * srp);
+ static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
+                       const char __user *buf, size_t count, int blocking,
+-                      int read_only, Sg_request **o_srp);
++                      int read_only, int sg_io_owned, Sg_request **o_srp);
+ static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
+                          unsigned char *cmnd, int timeout, int blocking);
+ static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
+@@ -561,7 +561,8 @@ sg_write(struct file *filp, const char _
+               return -EFAULT;
+       blocking = !(filp->f_flags & O_NONBLOCK);
+       if (old_hdr.reply_len < 0)
+-              return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL);
++              return sg_new_write(sfp, filp, buf, count,
++                                  blocking, 0, 0, NULL);
+       if (count < (SZ_SG_HEADER + 6))
+               return -EIO;    /* The minimum scsi command length is 6 bytes. */
+@@ -642,7 +643,7 @@ sg_write(struct file *filp, const char _
+ static ssize_t
+ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
+-               size_t count, int blocking, int read_only,
++               size_t count, int blocking, int read_only, int sg_io_owned,
+                Sg_request **o_srp)
+ {
+       int k;
+@@ -662,6 +663,7 @@ sg_new_write(Sg_fd *sfp, struct file *fi
+               SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n"));
+               return -EDOM;
+       }
++      srp->sg_io_owned = sg_io_owned;
+       hp = &srp->header;
+       if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) {
+               sg_remove_request(sfp, srp);
+@@ -766,18 +768,6 @@ sg_common_write(Sg_fd * sfp, Sg_request 
+ }
+ static int
+-sg_srp_done(Sg_request *srp, Sg_fd *sfp)
+-{
+-      unsigned long iflags;
+-      int done;
+-
+-      read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      done = srp->done;
+-      read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-      return done;
+-}
+-
+-static int
+ sg_ioctl(struct inode *inode, struct file *filp,
+        unsigned int cmd_in, unsigned long arg)
+ {
+@@ -809,27 +799,26 @@ sg_ioctl(struct inode *inode, struct fil
+                               return -EFAULT;
+                       result =
+                           sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
+-                                       blocking, read_only, &srp);
++                                       blocking, read_only, 1, &srp);
+                       if (result < 0)
+                               return result;
+-                      srp->sg_io_owned = 1;
+                       while (1) {
+                               result = 0;     /* following macro to beat race condition */
+                               __wait_event_interruptible(sfp->read_wait,
+-                                      (sdp->detached || sfp->closed || sg_srp_done(srp, sfp)),
+-                                                         result);
++                                      (srp->done || sdp->detached),
++                                      result);
+                               if (sdp->detached)
+                                       return -ENODEV;
+-                              if (sfp->closed)
+-                                      return 0;       /* request packet dropped already */
+-                              if (0 == result)
++                              write_lock_irq(&sfp->rq_list_lock);
++                              if (srp->done) {
++                                      srp->done = 2;
++                                      write_unlock_irq(&sfp->rq_list_lock);
+                                       break;
++                              }
+                               srp->orphan = 1;
++                              write_unlock_irq(&sfp->rq_list_lock);
+                               return result;  /* -ERESTARTSYS because signal hit process */
+                       }
+-                      write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-                      srp->done = 2;
+-                      write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+                       result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
+                       return (result < 0) ? result : 0;
+               }
diff --git a/queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch b/queue-2.6.28/0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch
new file mode 100644 (file)
index 0000000..a824736
--- /dev/null
@@ -0,0 +1,81 @@
+From 74c646d9ca31798ec2bf862f5b7e1737b543d066 Mon Sep 17 00:00:00 2001
+From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+Date: Wed, 4 Feb 2009 11:36:27 +0900
+Subject: SCSI: sg: avoid blk_put_request/blk_rq_unmap_user in interrupt
+
+From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+
+upstream commit: c96952ed7031e7c576ecf90cf95b8ec099d5295a
+
+This fixes the following oops:
+
+http://marc.info/?l=linux-kernel&m=123316111415677&w=2
+
+You can reproduce this bug by interrupting a program before a sg
+response completes. This leads to the special sg state (the orphan
+state), then sg calls blk_put_request in interrupt (rq->end_io).
+
+The above bug report shows the recursive lock problem because sg calls
+blk_put_request in interrupt. We could call __blk_put_request here
+instead however we also need to handle blk_rq_unmap_user here, which
+can't be called in interrupt too.
+
+In the orphan state, we don't need to care about the data transfer
+(the program revoked the command) so adding 'just free the resource'
+mode to blk_rq_unmap_user is a possible option.
+
+I prefer to avoid complicating the blk mapping API when possible. I
+change the orphan state to call sg_finish_rem_req via
+execute_in_process_context. We hold sg_fd->kref so sg_fd doesn't go
+away until keventd_wq finishes our work. copy_from_user/to_user fails
+so blk_rq_unmap_user just frees the resource without the data
+transfer.
+
+Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/scsi/sg.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -138,6 +138,7 @@ typedef struct sg_request {        /* SG_MAX_QU
+       volatile char done;     /* 0->before bh, 1->before read, 2->read */
+       struct request *rq;
+       struct bio *bio;
++      struct execute_work ew;
+ } Sg_request;
+ typedef struct sg_fd {                /* holds the state of a file descriptor */
+@@ -1234,6 +1235,15 @@ sg_mmap(struct file *filp, struct vm_are
+       return 0;
+ }
++static void sg_rq_end_io_usercontext(struct work_struct *work)
++{
++      struct sg_request *srp = container_of(work, struct sg_request, ew.work);
++      struct sg_fd *sfp = srp->parentfp;
++
++      sg_finish_rem_req(srp);
++      kref_put(&sfp->f_ref, sg_remove_sfp);
++}
++
+ /*
+  * This function is a "bottom half" handler that is called by the mid
+  * level when a command is completed (or has failed).
+@@ -1312,10 +1322,9 @@ static void sg_rq_end_io(struct request 
+                */
+               wake_up_interruptible(&sfp->read_wait);
+               kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
++              kref_put(&sfp->f_ref, sg_remove_sfp);
+       } else
+-              sg_finish_rem_req(srp); /* call with srp->done == 0 */
+-
+-      kref_put(&sfp->f_ref, sg_remove_sfp);
++              execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew);
+ }
+ static struct file_operations sg_fops = {
diff --git a/queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch b/queue-2.6.28/0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch
new file mode 100644 (file)
index 0000000..6c56961
--- /dev/null
@@ -0,0 +1,48 @@
+From 5c435c37e2652e5d066dc81fcc108a0dffbdb33d Mon Sep 17 00:00:00 2001
+From: Jonathan McDowell <noodles@earth.li>
+Date: Fri, 17 Apr 2009 21:20:10 +0000
+Subject: usb gadget: fix ethernet link reports to ethtool
+
+From: Jonathan McDowell <noodles@earth.li>
+
+upstream commit: 237e75bf1e558f7330f8deb167fa3116405bef2c
+
+The g_ether USB gadget driver currently decides whether or not there's a
+link to report back for eth_get_link based on if the USB link speed is
+set. The USB gadget speed is however often set even before the device is
+enumerated. It seems more sensible to only report a "link" if we're
+actually connected to a host that wants to talk to us. The patch below
+does this for me - tested with the PXA27x UDC driver.
+
+Signed-off-by: Jonathan McDowell <noodles@earth.li>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/usb/gadget/u_ether.c |    8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_d
+       strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
+ }
+-static u32 eth_get_link(struct net_device *net)
+-{
+-      struct eth_dev  *dev = netdev_priv(net);
+-      return dev->gadget->speed != USB_SPEED_UNKNOWN;
+-}
+-
+ /* REVISIT can also support:
+  *   - WOL (by tracking suspends and issuing remote wakeup)
+  *   - msglevel (implies updated messaging)
+@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_devic
+ static struct ethtool_ops ops = {
+       .get_drvinfo = eth_get_drvinfo,
+-      .get_link = eth_get_link
++      .get_link = ethtool_op_get_link,
+ };
+ static void defer_kevent(struct eth_dev *dev, int flag)
diff --git a/queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch b/queue-2.6.28/0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch
new file mode 100644 (file)
index 0000000..f2bcbe9
--- /dev/null
@@ -0,0 +1,43 @@
+From 082240d79158decfc9918b96487da38a750b4d1d Mon Sep 17 00:00:00 2001
+From: Peter Korsgaard <jacmet@sunsite.dk>
+Date: Fri, 17 Apr 2009 21:20:07 +0000
+Subject: USB: ftdi_sio: add vendor/project id for JETI specbos 1201 spectrometer
+
+From: Peter Korsgaard <jacmet@sunsite.dk>
+
+upstream commit: ae27d84351f1f3568118318a8c40ff3a154bd629
+
+Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/usb/serial/ftdi_sio.c |    1 +
+ drivers/usb/serial/ftdi_sio.h |    7 +++++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -665,6 +665,7 @@ static struct usb_device_id id_table_com
+       { USB_DEVICE(DE_VID, WHT_PID) },
+       { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++      { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+       { },                                    /* Optional parameter entry */
+       { }                                     /* Terminating entry */
+ };
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -901,6 +901,13 @@
+ #define ADI_GNICE_PID                 0xF000
+ /*
++ * JETI SPECTROMETER SPECBOS 1201
++ * http://www.jeti.com/products/sys/scb/scb1201.php
++ */
++#define JETI_VID              0x0c6c
++#define JETI_SPC1201_PID      0x04b2
++
++/*
+  *   BmRequestType:  1100 0000b
+  *   bRequest:       FTDI_E2_READ
+  *   wValue:         0
diff --git a/queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch b/queue-2.6.28/0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch
new file mode 100644 (file)
index 0000000..a905a02
--- /dev/null
@@ -0,0 +1,29 @@
+From 4be149f9b684906505d49932fd18e1f17721b30f Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Fri, 17 Apr 2009 21:20:06 +0000
+Subject: USB: fix oops in cdc-wdm in case of malformed descriptors
+
+From: Oliver Neukum <oliver@neukum.org>
+
+upstream commit: e13c594f3a1fc2c78e7a20d1a07974f71e4b448f
+
+cdc-wdm needs to ignore extremely malformed descriptors.
+
+Signed-off-by: Oliver Neukum <oliver@neukum.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/usb/class/cdc-wdm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -652,7 +652,7 @@ next_desc:
+       iface = &intf->altsetting[0];
+       ep = &iface->endpoint[0].desc;
+-      if (!usb_endpoint_is_int_in(ep)) {
++      if (!ep || !usb_endpoint_is_int_in(ep)) {
+               rv = -EINVAL;
+               goto err;
+       }
diff --git a/queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch b/queue-2.6.28/0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch
new file mode 100644 (file)
index 0000000..903575d
--- /dev/null
@@ -0,0 +1,40 @@
+From 35fe207a082d775b0bbaac3f49a9dc2d7c02779c Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 17 Apr 2009 21:20:03 +0000
+Subject: USB: usb-storage: augment unusual_devs entry for Simple Tech/Datafab
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+upstream commit: e4813eec8d47c8299d968bd5349dc881fa481c26
+
+This patch (as1227) adds the MAX_SECTORS_64 flag to the unusual_devs
+entry for the Simple Tech/Datafab controller.  This fixes Bugzilla
+#12882.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: binbin <binbinsh@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/usb/storage/unusual_devs.h |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1164,12 +1164,14 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0x
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_INQUIRY ),
+-/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
++/* Reported by Rauch Wolke <rauchwolke@gmx.net>
++ * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882)
++ */
+ UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
+               "Simple Tech/Datafab",
+               "CF+SM Reader",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+-              US_FL_IGNORE_RESIDUE ),
++              US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ),
+ /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
+  * to the USB storage specification in two ways:
diff --git a/queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch b/queue-2.6.28/0090-Input-gameport-fix-attach-driver-code.patch
new file mode 100644 (file)
index 0000000..78c0735
--- /dev/null
@@ -0,0 +1,71 @@
+From fb1c95cd6b1b0522bf0f7bedc0e1abc3b05d0607 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 13 Apr 2009 15:27:49 -0700
+Subject: Input: gameport - fix attach driver code
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+upstream commit: 4ced8e7cb990a2c3bbf0ac7f27b35c890e7ce895
+
+The commit 6902c0bead4ce266226fc0c5b3828b850bdc884a that moved
+driver registration out of kgameportd thread was incomplete and
+did not add the code necessary to actually attach driver to
+already registered devices, rectify that.
+
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/input/gameport/gameport.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/input/gameport/gameport.c
++++ b/drivers/input/gameport/gameport.c
+@@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list);
+ static struct bus_type gameport_bus;
+-static void gameport_add_driver(struct gameport_driver *drv);
+ static void gameport_add_port(struct gameport *gameport);
+-static void gameport_destroy_port(struct gameport *gameport);
++static void gameport_attach_driver(struct gameport_driver *drv);
+ static void gameport_reconnect_port(struct gameport *gameport);
+ static void gameport_disconnect_port(struct gameport *gameport);
+@@ -230,7 +229,6 @@ static void gameport_find_driver(struct 
+ enum gameport_event_type {
+       GAMEPORT_REGISTER_PORT,
+-      GAMEPORT_REGISTER_DRIVER,
+       GAMEPORT_ATTACH_DRIVER,
+ };
+@@ -374,8 +372,8 @@ static void gameport_handle_event(void)
+                               gameport_add_port(event->object);
+                               break;
+-                      case GAMEPORT_REGISTER_DRIVER:
+-                              gameport_add_driver(event->object);
++                      case GAMEPORT_ATTACH_DRIVER:
++                              gameport_attach_driver(event->object);
+                               break;
+                       default:
+@@ -707,14 +705,14 @@ static int gameport_driver_remove(struct
+       return 0;
+ }
+-static void gameport_add_driver(struct gameport_driver *drv)
++static void gameport_attach_driver(struct gameport_driver *drv)
+ {
+       int error;
+-      error = driver_register(&drv->driver);
++      error = driver_attach(&drv->driver);
+       if (error)
+               printk(KERN_ERR
+-                      "gameport: driver_register() failed for %s, error: %d\n",
++                      "gameport: driver_attach() failed for %s, error: %d\n",
+                       drv->driver.name, error);
+ }
diff --git a/queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch b/queue-2.6.28/0093-agp-zero-pages-before-sending-to-userspace.patch
new file mode 100644 (file)
index 0000000..a9acf13
--- /dev/null
@@ -0,0 +1,43 @@
+From 0702b646e5bdc16af64ef6f663e5275a02bf40cd Mon Sep 17 00:00:00 2001
+From: Shaohua Li <shaohua.li@intel.com>
+Date: Mon, 20 Apr 2009 10:08:35 +1000
+Subject: agp: zero pages before sending to userspace
+
+From: Shaohua Li <shaohua.li@intel.com>
+
+upstream commit: 59de2bebabc5027f93df999d59cc65df591c3e6e
+
+CVE-2009-1192
+
+AGP pages might be mapped into userspace finally, so the pages should be
+set to zero before userspace can use it. Otherwise there is potential
+information leakage.
+
+Signed-off-by: Shaohua Li <shaohua.li@intel.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/char/agp/generic.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/agp/generic.c
++++ b/drivers/char/agp/generic.c
+@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_b
+       int i, ret = -ENOMEM;
+       for (i = 0; i < num_pages; i++) {
+-              page = alloc_page(GFP_KERNEL | GFP_DMA32);
++              page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+               /* agp_free_memory() needs gart address */
+               if (page == NULL)
+                       goto out;
+@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_
+ {
+       struct page * page;
+-      page = alloc_page(GFP_KERNEL | GFP_DMA32);
++      page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+       if (page == NULL)
+               return NULL;
diff --git a/queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch b/queue-2.6.28/0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch
new file mode 100644 (file)
index 0000000..98e11d2
--- /dev/null
@@ -0,0 +1,53 @@
+From 5a9b5af39e948919f272867516faa61c093124f6 Mon Sep 17 00:00:00 2001
+From: Akinobu Mita <akinobu.mita@gmail.com>
+Date: Tue, 21 Apr 2009 21:20:04 +0000
+Subject: hugetlbfs: return negative error code for bad mount option
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+upstream commit: c12ddba09394c60e1120e6997794fa6ed52da884
+
+This fixes the following BUG:
+
+  # mount -o size=MM -t hugetlbfs none /huge
+  hugetlbfs: Bad value 'MM' for mount option 'size=MM'
+  ------------[ cut here ]------------
+  kernel BUG at fs/super.c:996!
+
+Due to
+
+       BUG_ON(!mnt->mnt_sb);
+
+in vfs_kern_mount().
+
+Also, remove unused #include <linux/quotaops.h>
+
+Cc: William Irwin <wli@holomorphy.com>
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/hugetlbfs/inode.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -26,7 +26,6 @@
+ #include <linux/pagevec.h>
+ #include <linux/parser.h>
+ #include <linux/mman.h>
+-#include <linux/quotaops.h>
+ #include <linux/slab.h>
+ #include <linux/dnotify.h>
+ #include <linux/statfs.h>
+@@ -838,7 +837,7 @@ hugetlbfs_parse_options(char *options, s
+ bad_val:
+       printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n",
+              args[0].from, p);
+-      return 1;
++      return -EINVAL;
+ }
+ static int
index 46cffa95bc5e8e0b2fc6d1ffec100219b49afde9..8dc00f291afcf335512becd631ca658c2d46dfd3 100644 (file)
@@ -3,6 +3,7 @@ From: Tilman Schmidt <tilman@imap.cc>
 Date: Wed, 15 Apr 2009 03:25:43 -0700
 Subject: bas_gigaset: correctly allocate USB interrupt transfer buffer
 
+From: Tilman Schmidt <tilman@imap.cc>
 
 [ Upstream commit 170ebf85160dd128e1c4206cc197cce7d1424705 ]
 
index d538e245dd1417bb11cbf5747354b596f3ebfba2..d89f2ea3606412f155a554b3be3a6d23e702d351 100644 (file)
@@ -3,6 +3,7 @@ From: Jay Vosburgh <fubar@us.ibm.com>
 Date: Sat, 4 Apr 2009 17:23:15 -0700
 Subject: bonding: Fix updating of speed/duplex changes
 
+From: Jay Vosburgh <fubar@us.ibm.com>
 
 [ Upstream commit 17d04500e2528217de5fe967599f98ee84348a9c ]
 
index 631195a29422e2af8538046714ab03af0c518dd4..91cf5ee66422bafe456cb26bc03989c03220f34a 100644 (file)
@@ -3,6 +3,7 @@ From: Stephen Hemminger <shemminger@vyatta.com>
 Date: Wed, 25 Mar 2009 21:01:47 -0700
 Subject: bridge: bad error handling when adding invalid ether address
 
+From: Stephen Hemminger <shemminger@vyatta.com>
 
 [ Upstream commit cda6d377ec6b2ee2e58d563d0bd7eb313e0165df ]
 
index 364524250b7f0d1d90ca8dacb60638ff4b4c759e..9c3baafbb9a32a73638a3c459adaeffb0d8ac927 100644 (file)
@@ -3,6 +3,7 @@ From: Pavel Emelyanov <xemul@openvz.org>
 Date: Thu, 26 Feb 2009 03:35:13 -0800
 Subject: ipv6: don't use tw net when accounting for recycled tw
 
+From: Pavel Emelyanov <xemul@openvz.org>
 
 [ Upstream commit 3f53a38131a4e7a053c0aa060aba0411242fb6b9 ]
 
index 3123bc707d81c799bc9cb2656deaf472a786b106..62f5df48cd19a6e2916d8f50106dd7cd7531c79c 100644 (file)
@@ -3,6 +3,7 @@ From: Jesper Nilsson <jesper.nilsson@axis.com>
 Date: Fri, 27 Mar 2009 00:17:45 -0700
 Subject: ipv6: Plug sk_buff leak in ipv6_rcv (net/ipv6/ip6_input.c)
 
+From: Jesper Nilsson <jesper.nilsson@axis.com>
 
 [ Upstream commit 71f6f6dfdf7c7a67462386d9ea05c1095a89c555 ]
 
diff --git a/queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch b/queue-2.6.28/kprobes-fix-locking-imbalance-in-kretprobes.patch
new file mode 100644 (file)
index 0000000..3788a25
--- /dev/null
@@ -0,0 +1,87 @@
+From f02b8624fedca39886b0eef770dca70c2f0749b3 Mon Sep 17 00:00:00 2001
+From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+Date: Wed, 18 Mar 2009 17:06:21 +0530
+Subject: kprobes: Fix locking imbalance in kretprobes
+
+From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+
+commit f02b8624fedca39886b0eef770dca70c2f0749b3 upstream.
+
+Fix locking imbalance in kretprobes:
+
+=====================================
+[ BUG: bad unlock balance detected! ]
+-------------------------------------
+kthreadd/2 is trying to release lock (&rp->lock) at:
+[<c06b3080>] pre_handler_kretprobe+0xea/0xf4
+but there are no more locks to release!
+
+other info that might help us debug this:
+1 lock held by kthreadd/2:
+ #0:  (rcu_read_lock){..--}, at: [<c06b2b24>] __atomic_notifier_call_chain+0x0/0x5a
+
+stack backtrace:
+Pid: 2, comm: kthreadd Not tainted 2.6.29-rc8 #1
+Call Trace:
+ [<c06ae498>] ? printk+0xf/0x17
+ [<c06b3080>] ? pre_handler_kretprobe+0xea/0xf4
+ [<c044ce6c>] print_unlock_inbalance_bug+0xc3/0xce
+ [<c0444d4b>] ? clocksource_read+0x7/0xa
+ [<c04450a4>] ? getnstimeofday+0x5f/0xf6
+ [<c044a9ca>] ? register_lock_class+0x17/0x293
+ [<c044b72c>] ? mark_lock+0x1e/0x30b
+ [<c0448956>] ? tick_dev_program_event+0x4a/0xbc
+ [<c0498100>] ? __slab_alloc+0xa5/0x415
+ [<c06b2fbe>] ? pre_handler_kretprobe+0x28/0xf4
+ [<c06b3080>] ? pre_handler_kretprobe+0xea/0xf4
+ [<c044cf1b>] lock_release_non_nested+0xa4/0x1a5
+ [<c06b3080>] ? pre_handler_kretprobe+0xea/0xf4
+ [<c044d15d>] lock_release+0x141/0x166
+ [<c06b07dd>] _spin_unlock_irqrestore+0x19/0x50
+ [<c06b3080>] pre_handler_kretprobe+0xea/0xf4
+ [<c06b20b5>] kprobe_exceptions_notify+0x1c9/0x43e
+ [<c06b2b02>] notifier_call_chain+0x26/0x48
+ [<c06b2b5b>] __atomic_notifier_call_chain+0x37/0x5a
+ [<c06b2b24>] ? __atomic_notifier_call_chain+0x0/0x5a
+ [<c06b2b8a>] atomic_notifier_call_chain+0xc/0xe
+ [<c0442d0d>] notify_die+0x2d/0x2f
+ [<c06b0f9c>] do_int3+0x1f/0x71
+ [<c06b0e84>] int3+0x2c/0x34
+ [<c042d476>] ? do_fork+0x1/0x288
+ [<c040221b>] ? kernel_thread+0x71/0x79
+ [<c043ed1b>] ? kthread+0x0/0x60
+ [<c043ed1b>] ? kthread+0x0/0x60
+ [<c04040b8>] ? kernel_thread_helper+0x0/0x10
+ [<c043ec7f>] kthreadd+0xac/0x148
+ [<c043ebd3>] ? kthreadd+0x0/0x148
+ [<c04040bf>] kernel_thread_helper+0x7/0x10
+
+Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+Tested-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
+Cc: Masami Hiramatsu <mhiramat@redhat.com>
+Cc: Jim Keniston <jkenisto@us.ibm.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: <stable@kernel.org> [2.6.29.x, 2.6.28.x, 2.6.27.x]
+LKML-Reference: <20090318113621.GB4129@in.ibm.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/kprobes.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -901,10 +901,8 @@ static int __kprobes pre_handler_kretpro
+               ri->rp = rp;
+               ri->task = current;
+-              if (rp->entry_handler && rp->entry_handler(ri, regs)) {
+-                      spin_unlock_irqrestore(&rp->lock, flags);
++              if (rp->entry_handler && rp->entry_handler(ri, regs))
+                       return 0;
+-              }
+               arch_prepare_kretprobe(ri, regs);
index 382be622adee2e4c5e46b1e7f99d782d29642328..a4a6704dfea8cb4ed99717dc285877c0fe5a42b9 100644 (file)
@@ -3,6 +3,7 @@ From: Al Viro <viro@zeniv.linux.org.uk>
 Date: Wed, 18 Mar 2009 19:12:42 -0700
 Subject: net: fix sctp breakage
 
+From: Al Viro <viro@zeniv.linux.org.uk>
 
 [ Upstream commit cb0dc77de0d23615a845e45844a2e22fc224d7fe ]
 
index 24e25f03aaf94f217ebfd6538e062103c98a1932..35a1c824c98ddcbddaa248f7a859847feb4bf37e 100644 (file)
@@ -3,6 +3,7 @@ From: Mark H. Weaver <mhw@netris.org>
 Date: Mon, 23 Mar 2009 13:46:12 +0100
 Subject: netfilter: nf_conntrack_tcp: fix unaligned memory access in tcp_sack
 
+From: Mark H. Weaver <mhw@netris.org>
 
 [ Upstream commit 534f81a5068799799e264fd162e9488a129f98d4 ]
 
index 92513c380aa6197be1ca080c60b8d03a15784ef3..c44e43279311f5d8a8b50ffb0bc49bc433232120 100644 (file)
@@ -17,3 +17,36 @@ bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch
 0032-Add-a-missing-unlock_kernel-in-raw_open.patch
 0033-x86-PAT-PCI-Change-vma-prot-in-pci_mmap-to-reflec.patch
 0037-x86-mtrr-don-t-modify-RdDram-WrDram-bits-of-fixed.patch
+0001-security-smack-fix-oops-when-setting-a-size-0-SMACK.patch
+0011-x86-setup-mark-esi-as-clobbered-in-E820-BIOS-call.patch
+0013-dock-fix-dereference-after-kfree.patch
+0030-mm-define-a-UNIQUE-value-for-AS_UNEVICTABLE-flag.patch
+0031-mm-do_xip_mapping_read-fix-length-calculation.patch
+0034-vfs-skip-I_CLEAR-state-inodes.patch
+0043-af_rose-x25-Sanity-check-the-maximum-user-frame-siz.patch
+0044-net-netrom-Fix-socket-locking.patch
+kprobes-fix-locking-imbalance-in-kretprobes.patch
+0048-netfilter-ip-ip6-arp-_tables-fix-incorrect-loop.patch
+0049-splice-fix-deadlock-in-splicing-to-file.patch
+0050-ALSA-hda-add-missing-comma-in-ad1884_slave_vols.patch
+0052-SCSI-libiscsi-fix-iscsi-pool-error-path.patch
+0053-SCSI-libiscsi-fix-iscsi-pool-error-path.patch
+0055-posixtimers-sched-Fix-posix-clock-monotonicity.patch
+0060-sched-do-not-count-frozen-tasks-toward-load.patch
+0063-add-some-long-missing-capabilities-to-fs_mask.patch
+0064-spi-spi_write_then_read-bugfixes.patch
+0068-powerpc-Fix-data-corrupting-bug-in-__futex_atomic_o.patch
+0069-hpt366-fix-HPT370-DMA-timeouts.patch
+0070-pata_hpt37x-fix-HPT370-DMA-timeouts.patch
+0071-mm-pass-correct-mm-when-growing-stack.patch
+0072-SCSI-sg-fix-races-during-device-removal.patch
+0073-SCSI-sg-fix-races-with-ioctl-SG_IO.patch
+0074-SCSI-sg-avoid-blk_put_request-blk_rq_unmap_user-in.patch
+0077-usb-gadget-fix-ethernet-link-reports-to-ethtool.patch
+0078-USB-ftdi_sio-add-vendor-project-id-for-JETI-specbo.patch
+0079-USB-fix-oops-in-cdc-wdm-in-case-of-malformed-descri.patch
+0080-USB-usb-storage-augment-unusual_devs-entry-for-Sim.patch
+0090-Input-gameport-fix-attach-driver-code.patch
+0024-r8169-Reset-IntrStatus-after-chip-reset.patch
+0093-agp-zero-pages-before-sending-to-userspace.patch
+0096-hugetlbfs-return-negative-error-code-for-bad-mount.patch
index f221d5aa10735d57639943b413c5247741ed1b69..0e2616fdfc193e6db151a2bc0e64a4cd7f9bb74c 100644 (file)
@@ -3,6 +3,7 @@ From: Chuck Ebbert <cebbert@redhat.com>
 Date: Fri, 27 Mar 2009 00:22:01 -0700
 Subject: xfrm: spin_lock() should be spin_unlock() in xfrm_state.c
 
+From: Chuck Ebbert <cebbert@redhat.com>
 
 [ Upstream commit 7d0b591c655ca0d72ebcbd242cf659a20a8995c5 ]