From 01d107eb777c3e528de30dcfdeaf9374ef3417d9 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Aug 02 2010 23:40:13 +0000 Subject: * Mon Aug 02 2010 Chuck Ebbert 2.6.32.17-156 - Linux 2.6.32.17 - Drop the patches commented out for -rc1 except ssb_check_for_sprom.patch --- diff --git a/cifs-fix-malicious-redirect-problem-in-the-dns-lookup-code.patch b/cifs-fix-malicious-redirect-problem-in-the-dns-lookup-code.patch deleted file mode 100644 index 083605a..0000000 --- a/cifs-fix-malicious-redirect-problem-in-the-dns-lookup-code.patch +++ /dev/null @@ -1,203 +0,0 @@ -From: David Howells -Date: Thu, 22 Jul 2010 11:53:18 +0000 (+0100) -Subject: CIFS: Fix a malicious redirect problem in the DNS lookup code -X-Git-Tag: v2.6.35-rc6~6 -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4c0c03ca54f72fdd5912516ad0a23ec5cf01bda7 - -CIFS: Fix a malicious redirect problem in the DNS lookup code - -[ trivial backport to 2.6.32 : cebbert@redhat.com ] - -Fix the security problem in the CIFS filesystem DNS lookup code in which a -malicious redirect could be installed by a random user by simply adding a -result record into one of their keyrings with add_key() and then invoking a -CIFS CFS lookup [CVE-2010-2524]. - -This is done by creating an internal keyring specifically for the caching of -DNS lookups. To enforce the use of this keyring, the module init routine -creates a set of override credentials with the keyring installed as the thread -keyring and instructs request_key() to only install lookup result keys in that -keyring. - -The override is then applied around the call to request_key(). - -This has some additional benefits when a kernel service uses this module to -request a key: - - (1) The result keys are owned by root, not the user that caused the lookup. - - (2) The result keys don't pop up in the user's keyrings. - - (3) The result keys don't come out of the quota of the user that caused the - lookup. - -The keyring can be viewed as root by doing cat /proc/keys: - -2a0ca6c3 I----- 1 perm 1f030000 0 0 keyring .dns_resolver: 1/4 - -It can then be listed with 'keyctl list' by root. - - # keyctl list 0x2a0ca6c3 - 1 key in keyring: - 726766307: --alswrv 0 0 dns_resolver: foo.bar.com - -Signed-off-by: David Howells -Reviewed-and-Tested-by: Jeff Layton -Acked-by: Steve French -Signed-off-by: Linus Torvalds ---- - -diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c -index 484e52b..2cb1a70 100644 ---- a/fs/cifs/cifsfs.c -+++ b/fs/cifs/cifsfs.c -@@ -923,7 +923,7 @@ init_cifs(void) - goto out_unregister_filesystem; - #endif - #ifdef CONFIG_CIFS_DFS_UPCALL -- rc = register_key_type(&key_type_dns_resolver); -+ rc = cifs_init_dns_resolver(); - if (rc) - goto out_unregister_key_type; - #endif -@@ -935,7 +935,7 @@ init_cifs(void) - - out_unregister_resolver_key: - #ifdef CONFIG_CIFS_DFS_UPCALL -- unregister_key_type(&key_type_dns_resolver); -+ cifs_exit_dns_resolver(); - out_unregister_key_type: - #endif - #ifdef CONFIG_CIFS_UPCALL -@@ -961,7 +961,7 @@ exit_cifs(void) - cifs_proc_clean(); - #ifdef CONFIG_CIFS_DFS_UPCALL - cifs_dfs_release_automount_timer(); -- unregister_key_type(&key_type_dns_resolver); -+ cifs_exit_dns_resolver(); - #endif - #ifdef CONFIG_CIFS_UPCALL - unregister_key_type(&cifs_spnego_key_type); -diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c -index 4db2c5e..49315cb 100644 ---- a/fs/cifs/dns_resolve.c -+++ b/fs/cifs/dns_resolve.c -@@ -24,12 +24,17 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -+#include -+#include -+#include - #include - #include "dns_resolve.h" - #include "cifsglob.h" - #include "cifsproto.h" - #include "cifs_debug.h" - -+static const struct cred *dns_resolver_cache; -+ - /* Checks if supplied name is IP address - * returns: - * 1 - name is IP -@@ -94,6 +99,7 @@ struct key_type key_type_dns_resolver = { - int - dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) - { -+ const struct cred *saved_cred; - int rc = -EAGAIN; - struct key *rkey = ERR_PTR(-EAGAIN); - char *name; -@@ -133,8 +139,15 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) - goto skip_upcall; - } - -+ saved_cred = override_creds(dns_resolver_cache); - rkey = request_key(&key_type_dns_resolver, name, ""); -+ revert_creds(saved_cred); - if (!IS_ERR(rkey)) { -+ if (!(rkey->perm & KEY_USR_VIEW)) { -+ down_read(&rkey->sem); -+ rkey->perm |= KEY_USR_VIEW; -+ up_read(&rkey->sem); -+ } - len = rkey->type_data.x[0]; - data = rkey->payload.data; - } else { -@@ -165,4 +178,61 @@ out: - return rc; - } - -+int __init cifs_init_dns_resolver(void) -+{ -+ struct cred *cred; -+ struct key *keyring; -+ int ret; -+ -+ printk(KERN_NOTICE "Registering the %s key type\n", -+ key_type_dns_resolver.name); -+ -+ /* create an override credential set with a special thread keyring in -+ * which DNS requests are cached -+ * -+ * this is used to prevent malicious redirections from being installed -+ * with add_key(). -+ */ -+ cred = prepare_kernel_cred(NULL); -+ if (!cred) -+ return -ENOMEM; -+ -+ keyring = key_alloc(&key_type_keyring, ".dns_resolver", 0, 0, cred, -+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | -+ KEY_USR_VIEW | KEY_USR_READ, -+ KEY_ALLOC_NOT_IN_QUOTA); -+ if (IS_ERR(keyring)) { -+ ret = PTR_ERR(keyring); -+ goto failed_put_cred; -+ } -+ -+ ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); -+ if (ret < 0) -+ goto failed_put_key; -+ -+ ret = register_key_type(&key_type_dns_resolver); -+ if (ret < 0) -+ goto failed_put_key; -+ -+ /* instruct request_key() to use this special keyring as a cache for -+ * the results it looks up */ -+ cred->thread_keyring = keyring; -+ cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; -+ dns_resolver_cache = cred; -+ return 0; -+ -+failed_put_key: -+ key_put(keyring); -+failed_put_cred: -+ put_cred(cred); -+ return ret; -+} - -+void __exit cifs_exit_dns_resolver(void) -+{ -+ key_revoke(dns_resolver_cache->thread_keyring); -+ unregister_key_type(&key_type_dns_resolver); -+ put_cred(dns_resolver_cache); -+ printk(KERN_NOTICE "Unregistered %s key type\n", -+ key_type_dns_resolver.name); -+} -diff --git a/fs/cifs/dns_resolve.h b/fs/cifs/dns_resolve.h -index 966e928..26b9eaa 100644 ---- a/fs/cifs/dns_resolve.h -+++ b/fs/cifs/dns_resolve.h -@@ -24,8 +24,8 @@ - #define _DNS_RESOLVE_H - - #ifdef __KERNEL__ --#include --extern struct key_type key_type_dns_resolver; -+extern int __init cifs_init_dns_resolver(void); -+extern void __exit cifs_exit_dns_resolver(void); - extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr); - #endif /* KERNEL */ - diff --git a/ethtool-fix-buffer-overflow.patch b/ethtool-fix-buffer-overflow.patch deleted file mode 100644 index 01b1a41..0000000 --- a/ethtool-fix-buffer-overflow.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Ben Hutchings -Date: Mon, 28 Jun 2010 08:44:07 +0000 (+0000) -Subject: ethtool: Fix potential kernel buffer overflow in ETHTOOL_GRXCLSRLALL -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-2.6.git;a=commitdiff_plain;h=db048b69037e7fa6a7d9e95a1271a50dc08ae233 - -ethtool: Fix potential kernel buffer overflow in ETHTOOL_GRXCLSRLALL - -On a 32-bit machine, info.rule_cnt >= 0x40000000 leads to integer -overflow and the buffer may be smaller than needed. Since -ETHTOOL_GRXCLSRLALL is unprivileged, this can presumably be used for at -least denial of service. - -Signed-off-by: Ben Hutchings -Cc: stable@kernel.org -Signed-off-by: David S. Miller ---- - -diff --git a/net/core/ethtool.c b/net/core/ethtool.c -index a0f4964..a3a7e9a 100644 ---- a/net/core/ethtool.c -+++ b/net/core/ethtool.c -@@ -347,8 +347,9 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, - - if (info.cmd == ETHTOOL_GRXCLSRLALL) { - if (info.rule_cnt > 0) { -- rule_buf = kmalloc(info.rule_cnt * sizeof(u32), -- GFP_USER); -+ if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) -+ rule_buf = kmalloc(info.rule_cnt * sizeof(u32), -+ GFP_USER); - if (!rule_buf) - return -ENOMEM; - } diff --git a/ext4-issue-discard-operation-before-releasing-blocks.patch b/ext4-issue-discard-operation-before-releasing-blocks.patch deleted file mode 100644 index aa103bd..0000000 --- a/ext4-issue-discard-operation-before-releasing-blocks.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Theodore Ts'o -Date: Tue, 20 Apr 2010 20:51:59 +0000 (-0400) -Subject: ext4: Issue the discard operation *before* releasing the blocks to be reused -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=b90f687018e6d6c77d981b09203780f7001407e5 - -ext4: Issue the discard operation *before* releasing the blocks to be reused - -[ backported to 2.6.3[23] ] - -Otherwise, we can end up having data corruption because the blocks -could get reused and then discarded! - -https://bugzilla.kernel.org/show_bug.cgi?id=15579 - -Signed-off-by: "Theodore Ts'o" ---- - -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 54df209..e5ab41b 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -2534,6 +2534,20 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) - mb_debug(1, "gonna free %u blocks in group %u (0x%p):", - entry->count, entry->group, entry); - -+ if (test_opt(sb, DISCARD)) { -+ ext4_fsblk_t discard_block; -+ struct ext4_super_block *es = EXT4_SB(sb)->s_es; -+ -+ discard_block = (ext4_fsblk_t)entry->group * -+ EXT4_BLOCKS_PER_GROUP(sb) -+ + entry->start_blk -+ + le32_to_cpu(es->s_first_data_block); -+ trace_ext4_discard_blocks(sb, -+ (unsigned long long)discard_block, -+ entry->count); -+ sb_issue_discard(sb, discard_block, entry->count); -+ } -+ - err = ext4_mb_load_buddy(sb, entry->group, &e4b); - /* we expect to find existing buddy because it's pinned */ - BUG_ON(err != 0); -@@ -2555,19 +2566,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) - page_cache_release(e4b.bd_bitmap_page); - } - ext4_unlock_group(sb, entry->group); -- if (test_opt(sb, DISCARD)) { -- ext4_fsblk_t discard_block; -- struct ext4_super_block *es = EXT4_SB(sb)->s_es; -- -- discard_block = (ext4_fsblk_t)entry->group * -- EXT4_BLOCKS_PER_GROUP(sb) -- + entry->start_blk -- + le32_to_cpu(es->s_first_data_block); -- trace_ext4_discard_blocks(sb, -- (unsigned long long)discard_block, -- entry->count); -- sb_issue_discard(sb, discard_block, entry->count); -- } - kmem_cache_free(ext4_free_ext_cachep, entry); - ext4_mb_release_desc(&e4b); - } diff --git a/iwlwifi-cancel-scan-watchdog-in-iwl_bg_abort_scan.patch b/iwlwifi-cancel-scan-watchdog-in-iwl_bg_abort_scan.patch deleted file mode 100644 index 465d2ac..0000000 --- a/iwlwifi-cancel-scan-watchdog-in-iwl_bg_abort_scan.patch +++ /dev/null @@ -1,58 +0,0 @@ -commit a69b03e941abae00380fc6bc1877fb797a1b31e6 -Author: John W. Linville -Date: Mon Jun 14 14:30:25 2010 -0400 - - iwlwifi: cancel scan watchdog in iwl_bg_abort_scan - - Avoids this: - - WARNING: at net/mac80211/scan.c:312 ieee80211_scan_completed+0x5f/0x1f1 - [mac80211]() - Hardware name: Latitude E5400 - Modules linked in: aes_x86_64 aes_generic fuse ipt_MASQUERADE iptable_nat - nf_nat rfcomm sco bridge stp llc bnep l2cap sunrpc cpufreq_ondemand - acpi_cpufreq freq_table xt_physdev ip6t_REJECT nf_conntrack_ipv6 - ip6table_filter ip6_tables ipv6 kvm_intel kvm uinput arc4 ecb - snd_hda_codec_intelhdmi snd_hda_codec_idt snd_hda_intel iwlagn snd_hda_codec - snd_hwdep snd_seq snd_seq_device iwlcore snd_pcm dell_wmi sdhci_pci sdhci - iTCO_wdt tg3 dell_laptop mmc_core i2c_i801 wmi mac80211 snd_timer - iTCO_vendor_support btusb joydev dcdbas cfg80211 bluetooth snd soundcore - microcode rfkill snd_page_alloc firewire_ohci firewire_core crc_itu_t - yenta_socket rsrc_nonstatic i915 drm_kms_helper drm i2c_algo_bit i2c_core video - output [last unloaded: scsi_wait_scan] - Pid: 979, comm: iwlagn Tainted: G W 2.6.33.3-85.fc13.x86_64 #1 - Call Trace: - [] warn_slowpath_common+0x77/0x8f - [] warn_slowpath_null+0xf/0x11 - [] ieee80211_scan_completed+0x5f/0x1f1 [mac80211] - [] iwl_bg_scan_completed+0xbb/0x17a [iwlcore] - [] worker_thread+0x1a4/0x232 - [] ? iwl_bg_scan_completed+0x0/0x17a [iwlcore] - [] ? autoremove_wake_function+0x0/0x34 - [] ? worker_thread+0x0/0x232 - [] kthread+0x7a/0x82 - [] kernel_thread_helper+0x4/0x10 - [] ? kthread+0x0/0x82 - [] ? kernel_thread_helper+0x0/0x10 - - Reported here: - - https://bugzilla.redhat.com/show_bug.cgi?id=590436 - - Signed-off-by: John W. Linville - Reported-by: Mihai Harpau - Cc: stable@kernel.org - Acked-by: Reinette Chatre - -diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c -index 5d3f51f..386c5f9 100644 ---- a/drivers/net/wireless/iwlwifi/iwl-scan.c -+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c -@@ -491,6 +491,7 @@ void iwl_bg_abort_scan(struct work_struct *work) - - mutex_lock(&priv->mutex); - -+ cancel_delayed_work_sync(&priv->scan_check); - set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); - diff --git a/kernel.spec b/kernel.spec index 00e9acd..c9dd80f 100644 --- a/kernel.spec +++ b/kernel.spec @@ -47,7 +47,7 @@ Summary: The Linux kernel # reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec). # scripts/rebase.sh should be made to do that for you, actually. # -%global baserelease 155 +%global baserelease 156 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -61,7 +61,7 @@ Summary: The Linux kernel # Do we have a -stable update to apply? %define stable_update 17 # Is it a -stable RC? -%define stable_rc 1 +%define stable_rc 0 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev .%{stable_update} @@ -761,7 +761,6 @@ Patch2096: linux-2.6-v4l-dvb-add-kworld-a340-support.patch # fs fixes # ext4/quota -Patch3000: linux-2.6-ext4-quota-metadata-reservation.patch # NFSv4 Patch3050: linux-2.6-nfsd4-proots.patch @@ -819,9 +818,6 @@ Patch12414: iwlwifi_-Recover-TX-flow-failure.patch Patch12415: iwlwifi_-code-cleanup-for-connectivity-recovery.patch Patch12416: iwlwifi_-iwl_good_ack_health-only-apply-to-AGN-device.patch -# fix possible corruption with ssd -Patch12700: ext4-issue-discard-operation-before-releasing-blocks.patch - # iwlwifi: fix scan races Patch12910: iwlwifi-fix-scan-races.patch # iwlwifi: fix internal scan race @@ -830,31 +826,20 @@ Patch12911: iwlwifi-fix-internal-scan-race.patch Patch12912: iwlwifi-recover_from_tx_stall.patch Patch12921: iwlwifi-manage-QoS-by-mac-stack.patch -Patch12922: mac80211-do-not-wipe-out-old-supported-rates.patch Patch12923: mac80211-explicitly-disable-enable-QoS.patch -Patch12924: mac80211-fix-supported-rates-IE-if-AP-doesnt-give-us-its-rates.patch - -# iwlwifi: cancel scan watchdog in iwl_bg_abort_scan -Patch13020: iwlwifi-cancel-scan-watchdog-in-iwl_bg_abort_scan.patch # l2tp: fix oops in pppol2tp_xmit (#607054) Patch13030: l2tp-fix-oops-in-pppol2tp_xmit.patch -Patch14000: sched-fix-over-scheduling-bug.patch -Patch14010: ethtool-fix-buffer-overflow.patch - Patch14020: inotify-fix-inotify-oneshot-support.patch Patch14030: inotify-send-IN_UNMOUNT-events.patch Patch14040: crypto-testmgr-add-null-test-for-aesni.patch Patch14050: crypto-add-async-hash-testing.patch -Patch14100: cifs-fix-malicious-redirect-problem-in-the-dns-lookup-code.patch Patch14110: ext4-make-sure-the-move_ext-ioctl-can-t-overwrite-append-only-files.patch Patch14115: xfs-prevent-swapext-from-operating-on-write-only-files.patch -Patch14120: usb-obey-the-sysfs-power-wakeup-setting.patch - # Red Hat Bugzilla #610911 Patch14130: kvm-mmu-fix-conflict-access-permissions-in-direct-sp.patch @@ -1333,7 +1318,6 @@ ApplyPatch linux-2.6-execshield.patch # # ext4 -#ApplyPatch linux-2.6-ext4-quota-metadata-reservation.patch # xfs @@ -1544,9 +1528,6 @@ ApplyPatch iwlwifi_-Recover-TX-flow-failure.patch ApplyPatch iwlwifi_-code-cleanup-for-connectivity-recovery.patch ApplyPatch iwlwifi_-iwl_good_ack_health-only-apply-to-AGN-device.patch -# fix possible corruption with ssd -#ApplyPatch ext4-issue-discard-operation-before-releasing-blocks.patch - # iwlwifi: fix scan races ApplyPatch iwlwifi-fix-scan-races.patch # iwlwifi: fix internal scan race @@ -1557,21 +1538,10 @@ ApplyPatch iwlwifi-recover_from_tx_stall.patch # mac80211/iwlwifi fix connections to some APs (rhbz#558002) ApplyPatch mac80211-explicitly-disable-enable-QoS.patch ApplyPatch iwlwifi-manage-QoS-by-mac-stack.patch -#ApplyPatch mac80211-do-not-wipe-out-old-supported-rates.patch -#ApplyPatch mac80211-fix-supported-rates-IE-if-AP-doesnt-give-us-its-rates.patch - -# iwlwifi: cancel scan watchdog in iwl_bg_abort_scan -#ApplyPatch iwlwifi-cancel-scan-watchdog-in-iwl_bg_abort_scan.patch # l2tp: fix oops in pppol2tp_xmit (#607054) ApplyPatch l2tp-fix-oops-in-pppol2tp_xmit.patch -# fix performance problem with CGROUPS -#ApplyPatch sched-fix-over-scheduling-bug.patch - -# CVE-2010-2478 -#ApplyPatch ethtool-fix-buffer-overflow.patch - # fix broken oneshot support and missing umount events (F13#607327) ApplyPatch inotify-fix-inotify-oneshot-support.patch ApplyPatch inotify-send-IN_UNMOUNT-events.patch @@ -1581,16 +1551,11 @@ ApplyPatch crypto-testmgr-add-null-test-for-aesni.patch # add tests for crypto async hashing (#571577) ApplyPatch crypto-add-async-hash-testing.patch -# CVE-2010-2524 -#ApplyPatch cifs-fix-malicious-redirect-problem-in-the-dns-lookup-code.patch # CVE-2010-2066 ApplyPatch ext4-make-sure-the-move_ext-ioctl-can-t-overwrite-append-only-files.patch # CVE-2010-2266 ApplyPatch xfs-prevent-swapext-from-operating-on-write-only-files.patch -# fix broken USB device wakeups (#617559) -#ApplyPatch usb-obey-the-sysfs-power-wakeup-setting.patch - ApplyPatch kvm-mmu-fix-conflict-access-permissions-in-direct-sp.patch # END OF PATCH APPLICATIONS ==================================================== @@ -2243,6 +2208,10 @@ fi %kernel_variant_files -k vmlinux %{with_kdump} kdump %changelog +* Mon Aug 02 2010 Chuck Ebbert 2.6.32.17-156 +- Linux 2.6.32.17 +- Drop the patches commented out for -rc1 except ssb_check_for_sprom.patch + * Mon Aug 02 2010 Chuck Ebbert 2.6.32.17-155.rc1 - Linux 2.6.32.17-rc1 - Comment out patches merged upstream: diff --git a/linux-2.6-ext4-quota-metadata-reservation.patch b/linux-2.6-ext4-quota-metadata-reservation.patch deleted file mode 100644 index de000cb..0000000 --- a/linux-2.6-ext4-quota-metadata-reservation.patch +++ /dev/null @@ -1,723 +0,0 @@ -For bug #608770 - -Do not speculatively allocate metadata for quota; it's too complex, and we -usually get it wrong. - -Backport of these upstream patches, some of which just play a supporting role. - - -Eric - -515f41c33a9d44a964264c9511ad2c869af1fac3 ext4: Ensure zeroout blocks have no dirty metadata -d21cd8f163ac44b15c465aab7306db931c606908 ext4: Fix potential quota deadlock -0637c6f4135f592f094207c7c21e7c0fc5557834 ext4: Patch up how we claim metadata blocks for quota purposes -9d0be50230b333005635967f7ecd4897dbfd181b ext4: Calculate metadata requirements more accurately -1db913823c0f8360fccbd24ca67eb073966a5ffd ext4: Handle -EDQUOT error on write -5f634d064c709ea02c3cdaa850a08323a4a4bf28 ext4: Fix quota accounting error with fallocate -56246f9ae4cfa95b460f9dfbcfb1b772d85db046 quota: use flags interface for dquot alloc/free space -0e05842bc117ea70ceb979cca798fd026879951b quota: add the option to not fail with EDQUOT in block -72b8ab9dde211ea518ff27e631b2046ef90c29a2 ext4: don't use quota reservation for speculative metadata - - -Index: linux-2.6.32.noarch/fs/ext4/extents.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/extents.c -+++ linux-2.6.32.noarch/fs/ext4/extents.c -@@ -296,29 +296,44 @@ static inline int ext4_ext_space_root_id - * to allocate @blocks - * Worse case is one block per extent - */ --int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks) -+int ext4_ext_calc_metadata_amount(struct inode *inode, sector_t lblock) - { -- int lcap, icap, rcap, leafs, idxs, num; -- int newextents = blocks; -+ struct ext4_inode_info *ei = EXT4_I(inode); -+ int idxs, num = 0; - -- rcap = ext4_ext_space_root_idx(inode, 0); -- lcap = ext4_ext_space_block(inode, 0); -- icap = ext4_ext_space_block_idx(inode, 0); -+ idxs = ((inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) -+ / sizeof(struct ext4_extent_idx)); - -- /* number of new leaf blocks needed */ -- num = leafs = (newextents + lcap - 1) / lcap; -+ /* -+ * If the new delayed allocation block is contiguous with the -+ * previous da block, it can share index blocks with the -+ * previous block, so we only need to allocate a new index -+ * block every idxs leaf blocks. At ldxs**2 blocks, we need -+ * an additional index block, and at ldxs**3 blocks, yet -+ * another index blocks. -+ */ -+ if (ei->i_da_metadata_calc_len && -+ ei->i_da_metadata_calc_last_lblock+1 == lblock) { -+ if ((ei->i_da_metadata_calc_len % idxs) == 0) -+ num++; -+ if ((ei->i_da_metadata_calc_len % (idxs*idxs)) == 0) -+ num++; -+ if ((ei->i_da_metadata_calc_len % (idxs*idxs*idxs)) == 0) { -+ num++; -+ ei->i_da_metadata_calc_len = 0; -+ } else -+ ei->i_da_metadata_calc_len++; -+ ei->i_da_metadata_calc_last_lblock++; -+ return num; -+ } - - /* -- * Worse case, we need separate index block(s) -- * to link all new leaf blocks -+ * In the worst case we need a new set of index blocks at -+ * every level of the inode's extent tree. - */ -- idxs = (leafs + icap - 1) / icap; -- do { -- num += idxs; -- idxs = (idxs + icap - 1) / icap; -- } while (idxs > rcap); -- -- return num; -+ ei->i_da_metadata_calc_len = 1; -+ ei->i_da_metadata_calc_last_lblock = lblock; -+ return ext_depth(inode) + 1; - } - - static int -@@ -3029,6 +3044,14 @@ out: - return err; - } - -+static void unmap_underlying_metadata_blocks(struct block_device *bdev, -+ sector_t block, int count) -+{ -+ int i; -+ for (i = 0; i < count; i++) -+ unmap_underlying_metadata(bdev, block + i); -+} -+ - static int - ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, - ext4_lblk_t iblock, unsigned int max_blocks, -@@ -3104,6 +3127,30 @@ out: - } else - allocated = ret; - set_buffer_new(bh_result); -+ /* -+ * if we allocated more blocks than requested -+ * we need to make sure we unmap the extra block -+ * allocated. The actual needed block will get -+ * unmapped later when we find the buffer_head marked -+ * new. -+ */ -+ if (allocated > max_blocks) { -+ unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, -+ newblock + max_blocks, -+ allocated - max_blocks); -+ allocated = max_blocks; -+ } -+ -+ /* -+ * If we have done fallocate with the offset that is already -+ * delayed allocated, we would have block reservation -+ * and quota reservation done in the delayed write path. -+ * But fallocate would have already updated quota and block -+ * count for this offset. So cancel these reservation -+ */ -+ if (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE) -+ ext4_da_update_reserve_space(inode, allocated, 0); -+ - map_out: - set_buffer_mapped(bh_result); - out1: -@@ -3333,9 +3380,18 @@ int ext4_ext_get_blocks(handle_t *handle - /* previous routine could use block we allocated */ - newblock = ext_pblock(&newex); - allocated = ext4_ext_get_actual_len(&newex); -+ if (allocated > max_blocks) -+ allocated = max_blocks; - set_buffer_new(bh_result); - - /* -+ * Update reserved blocks/metadata blocks after successful -+ * block allocation which had been deferred till now. -+ */ -+ if (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE) -+ ext4_da_update_reserve_space(inode, allocated, 1); -+ -+ /* - * Cache the extent and update transaction to commit on fdatasync only - * when it is _not_ an uninitialized extent. - */ -Index: linux-2.6.32.noarch/fs/ext4/inode.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/inode.c -+++ linux-2.6.32.noarch/fs/ext4/inode.c -@@ -1051,81 +1051,105 @@ qsize_t *ext4_get_reserved_space(struct - return &EXT4_I(inode)->i_reserved_quota; - } - #endif -+ - /* - * Calculate the number of metadata blocks need to reserve -- * to allocate @blocks for non extent file based file -+ * to allocate a new block at @lblocks for non extent file based file - */ --static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) -+static int ext4_indirect_calc_metadata_amount(struct inode *inode, -+ sector_t lblock) - { -- int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); -- int ind_blks, dind_blks, tind_blks; -- -- /* number of new indirect blocks needed */ -- ind_blks = (blocks + icap - 1) / icap; -+ struct ext4_inode_info *ei = EXT4_I(inode); -+ int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1; -+ int blk_bits; - -- dind_blks = (ind_blks + icap - 1) / icap; -+ if (lblock < EXT4_NDIR_BLOCKS) -+ return 0; - -- tind_blks = 1; -+ lblock -= EXT4_NDIR_BLOCKS; - -- return ind_blks + dind_blks + tind_blks; -+ if (ei->i_da_metadata_calc_len && -+ (lblock & dind_mask) == ei->i_da_metadata_calc_last_lblock) { -+ ei->i_da_metadata_calc_len++; -+ return 0; -+ } -+ ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; -+ ei->i_da_metadata_calc_len = 1; -+ blk_bits = roundup_pow_of_two(lblock + 1); -+ return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1; - } - - /* - * Calculate the number of metadata blocks need to reserve -- * to allocate given number of blocks -+ * to allocate a block located at @lblock - */ --static int ext4_calc_metadata_amount(struct inode *inode, int blocks) -+static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock) - { -- if (!blocks) -- return 0; -- - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) -- return ext4_ext_calc_metadata_amount(inode, blocks); -+ return ext4_ext_calc_metadata_amount(inode, lblock); - -- return ext4_indirect_calc_metadata_amount(inode, blocks); -+ return ext4_indirect_calc_metadata_amount(inode, lblock); - } - --static void ext4_da_update_reserve_space(struct inode *inode, int used) -+/* -+ * Called with i_data_sem down, which is important since we can call -+ * ext4_discard_preallocations() from here. -+ */ -+void ext4_da_update_reserve_space(struct inode *inode, -+ int used, int quota_claim) - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -- int total, mdb, mdb_free; -+ struct ext4_inode_info *ei = EXT4_I(inode); - -- spin_lock(&EXT4_I(inode)->i_block_reservation_lock); -- /* recalculate the number of metablocks still need to be reserved */ -- total = EXT4_I(inode)->i_reserved_data_blocks - used; -- mdb = ext4_calc_metadata_amount(inode, total); -- -- /* figure out how many metablocks to release */ -- BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); -- mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; -- -- if (mdb_free) { -- /* Account for allocated meta_blocks */ -- mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; -- -- /* update fs dirty blocks counter */ -- percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); -- EXT4_I(inode)->i_allocated_meta_blocks = 0; -- EXT4_I(inode)->i_reserved_meta_blocks = mdb; -- } -- -- /* update per-inode reservations */ -- BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); -- EXT4_I(inode)->i_reserved_data_blocks -= used; -+ spin_lock(&ei->i_block_reservation_lock); -+ if (unlikely(used > ei->i_reserved_data_blocks)) { -+ ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d " -+ "with only %d reserved data blocks\n", -+ __func__, inode->i_ino, used, -+ ei->i_reserved_data_blocks); -+ WARN_ON(1); -+ used = ei->i_reserved_data_blocks; -+ } -+ -+ /* Update per-inode reservations */ -+ ei->i_reserved_data_blocks -= used; -+ ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; -+ percpu_counter_sub(&sbi->s_dirtyblocks_counter, -+ used + ei->i_allocated_meta_blocks); -+ ei->i_allocated_meta_blocks = 0; -+ -+ if (ei->i_reserved_data_blocks == 0) { -+ /* -+ * We can release all of the reserved metadata blocks -+ * only when we have written all of the delayed -+ * allocation blocks. -+ */ -+ percpu_counter_sub(&sbi->s_dirtyblocks_counter, -+ ei->i_reserved_meta_blocks); -+ ei->i_reserved_meta_blocks = 0; -+ ei->i_da_metadata_calc_len = 0; -+ } - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - -- /* -- * free those over-booking quota for metadata blocks -- */ -- if (mdb_free) -- vfs_dq_release_reservation_block(inode, mdb_free); -+ /* Update quota subsystem for data blocks */ -+ if (quota_claim) { -+ vfs_dq_claim_block(inode, used); -+ } else { -+ /* -+ * We did fallocate with an offset that is already delayed -+ * allocated. So on delayed allocated writeback we should -+ * not re-claim the quota for fallocated blocks. -+ */ -+ vfs_dq_release_reservation_block(inode, used); -+ } - - /* - * If we have done all the pending block allocations and if - * there aren't any writers on the inode, we can discard the - * inode's preallocations. - */ -- if (!total && (atomic_read(&inode->i_writecount) == 0)) -+ if ((ei->i_reserved_data_blocks == 0) && -+ (atomic_read(&inode->i_writecount) == 0)) - ext4_discard_preallocations(inode); - } - -@@ -1317,18 +1341,20 @@ int ext4_get_blocks(handle_t *handle, st - */ - EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE; - } -- } - -+ /* -+ * Update reserved blocks/metadata blocks after successful -+ * block allocation which had been deferred till now. We don't -+ * support fallocate for non extent files. So we can update -+ * reserve space here. -+ */ -+ if ((retval > 0) && -+ (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE)) -+ ext4_da_update_reserve_space(inode, retval, 1); -+ } - if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) - EXT4_I(inode)->i_delalloc_reserved_flag = 0; - -- /* -- * Update reserved blocks/metadata blocks after successful -- * block allocation which had been deferred till now. -- */ -- if ((retval > 0) && (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE)) -- ext4_da_update_reserve_space(inode, retval); -- - up_write((&EXT4_I(inode)->i_data_sem)); - if (retval > 0 && buffer_mapped(bh)) { - int ret = check_block_validity(inode, "file system " -@@ -1834,11 +1860,15 @@ static int ext4_journalled_write_end(str - return ret ? ret : copied; - } - --static int ext4_da_reserve_space(struct inode *inode, int nrblocks) -+/* -+ * Reserve a single block located at lblock -+ */ -+static int ext4_da_reserve_space(struct inode *inode, sector_t lblock) - { - int retries = 0; - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -- unsigned long md_needed, mdblocks, total = 0; -+ struct ext4_inode_info *ei = EXT4_I(inode); -+ unsigned long md_needed; - - /* - * recalculate the amount of metadata blocks to reserve -@@ -1846,35 +1876,34 @@ static int ext4_da_reserve_space(struct - * worse case is one extent per block - */ - repeat: -- spin_lock(&EXT4_I(inode)->i_block_reservation_lock); -- total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; -- mdblocks = ext4_calc_metadata_amount(inode, total); -- BUG_ON(mdblocks < EXT4_I(inode)->i_reserved_meta_blocks); -- -- md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; -- total = md_needed + nrblocks; -- spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); -+ spin_lock(&ei->i_block_reservation_lock); -+ md_needed = ext4_calc_metadata_amount(inode, lblock); -+ spin_unlock(&ei->i_block_reservation_lock); - - /* -- * Make quota reservation here to prevent quota overflow -- * later. Real quota accounting is done at pages writeout -- * time. -+ * We will charge metadata quota at writeout time; this saves -+ * us from metadata over-estimation, though we may go over by -+ * a small amount in the end. Here we just reserve for data. - */ -- if (vfs_dq_reserve_block(inode, total)) -+ if (vfs_dq_reserve_block(inode, 1)) - return -EDQUOT; - -- if (ext4_claim_free_blocks(sbi, total)) { -- vfs_dq_release_reservation_block(inode, total); -+ /* -+ * We do still charge estimated metadata to the sb though; -+ * we cannot afford to run out of free blocks. -+ */ -+ if (ext4_claim_free_blocks(sbi, md_needed + 1)) { -+ vfs_dq_release_reservation_block(inode, 1); - if (ext4_should_retry_alloc(inode->i_sb, &retries)) { - yield(); - goto repeat; - } - return -ENOSPC; - } -- spin_lock(&EXT4_I(inode)->i_block_reservation_lock); -- EXT4_I(inode)->i_reserved_data_blocks += nrblocks; -- EXT4_I(inode)->i_reserved_meta_blocks += md_needed; -- spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); -+ spin_lock(&ei->i_block_reservation_lock); -+ ei->i_reserved_data_blocks++; -+ ei->i_reserved_meta_blocks += md_needed; -+ spin_unlock(&ei->i_block_reservation_lock); - - return 0; /* success */ - } -@@ -1882,49 +1911,47 @@ repeat: - static void ext4_da_release_space(struct inode *inode, int to_free) - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -- int total, mdb, mdb_free, release; -+ struct ext4_inode_info *ei = EXT4_I(inode); - - if (!to_free) - return; /* Nothing to release, exit */ - - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - -- if (!EXT4_I(inode)->i_reserved_data_blocks) { -+ if (unlikely(to_free > ei->i_reserved_data_blocks)) { - /* -- * if there is no reserved blocks, but we try to free some -- * then the counter is messed up somewhere. -- * but since this function is called from invalidate -- * page, it's harmless to return without any action -- */ -- printk(KERN_INFO "ext4 delalloc try to release %d reserved " -- "blocks for inode %lu, but there is no reserved " -- "data blocks\n", to_free, inode->i_ino); -- spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); -- return; -+ * if there aren't enough reserved blocks, then the -+ * counter is messed up somewhere. Since this -+ * function is called from invalidate page, it's -+ * harmless to return without any action. -+ */ -+ ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: " -+ "ino %lu, to_free %d with only %d reserved " -+ "data blocks\n", inode->i_ino, to_free, -+ ei->i_reserved_data_blocks); -+ WARN_ON(1); -+ to_free = ei->i_reserved_data_blocks; - } -+ ei->i_reserved_data_blocks -= to_free; - -- /* recalculate the number of metablocks still need to be reserved */ -- total = EXT4_I(inode)->i_reserved_data_blocks - to_free; -- mdb = ext4_calc_metadata_amount(inode, total); -- -- /* figure out how many metablocks to release */ -- BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); -- mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; -- -- release = to_free + mdb_free; -- -- /* update fs dirty blocks counter for truncate case */ -- percpu_counter_sub(&sbi->s_dirtyblocks_counter, release); -+ if (ei->i_reserved_data_blocks == 0) { -+ /* -+ * We can release all of the reserved metadata blocks -+ * only when we have written all of the delayed -+ * allocation blocks. -+ */ -+ percpu_counter_sub(&sbi->s_dirtyblocks_counter, -+ ei->i_reserved_meta_blocks); -+ ei->i_reserved_meta_blocks = 0; -+ ei->i_da_metadata_calc_len = 0; -+ } - -- /* update per-inode reservations */ -- BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks); -- EXT4_I(inode)->i_reserved_data_blocks -= to_free; -+ /* update fs dirty data blocks counter */ -+ percpu_counter_sub(&sbi->s_dirtyblocks_counter, to_free); - -- BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); -- EXT4_I(inode)->i_reserved_meta_blocks = mdb; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); - -- vfs_dq_release_reservation_block(inode, release); -+ vfs_dq_release_reservation_block(inode, to_free); - } - - static void ext4_da_page_release_reservation(struct page *page, -@@ -2530,7 +2557,7 @@ static int ext4_da_get_block_prep(struct - * XXX: __block_prepare_write() unmaps passed block, - * is it OK? - */ -- ret = ext4_da_reserve_space(inode, 1); -+ ret = ext4_da_reserve_space(inode, iblock); - if (ret) - /* not enough space to reserve */ - return ret; -Index: linux-2.6.32.noarch/fs/ext4/mballoc.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/mballoc.c -+++ linux-2.6.32.noarch/fs/ext4/mballoc.c -@@ -2756,12 +2756,6 @@ ext4_mb_mark_diskspace_used(struct ext4_ - if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) - /* release all the reserved blocks if non delalloc */ - percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); -- else { -- percpu_counter_sub(&sbi->s_dirtyblocks_counter, -- ac->ac_b_ex.fe_len); -- /* convert reserved quota blocks to real quota blocks */ -- vfs_dq_claim_block(ac->ac_inode, ac->ac_b_ex.fe_len); -- } - - if (sbi->s_log_groups_per_flex) { - ext4_group_t flex_group = ext4_flex_group(sbi, -Index: linux-2.6.32.noarch/fs/ext4/ext4.h -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/ext4.h -+++ linux-2.6.32.noarch/fs/ext4/ext4.h -@@ -693,6 +693,8 @@ struct ext4_inode_info { - unsigned int i_reserved_meta_blocks; - unsigned int i_allocated_meta_blocks; - unsigned short i_delalloc_reserved_flag; -+ sector_t i_da_metadata_calc_last_lblock; -+ int i_da_metadata_calc_len; - - /* on-disk additional length */ - __u16 i_extra_isize; -@@ -1438,6 +1440,8 @@ extern int ext4_block_truncate_page(hand - extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); - extern qsize_t *ext4_get_reserved_space(struct inode *inode); - extern int flush_aio_dio_completed_IO(struct inode *inode); -+extern void ext4_da_update_reserve_space(struct inode *inode, -+ int used, int quota_claim); - /* ioctl.c */ - extern long ext4_ioctl(struct file *, unsigned int, unsigned long); - extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); -Index: linux-2.6.32.noarch/fs/ext4/ext4_extents.h -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/ext4_extents.h -+++ linux-2.6.32.noarch/fs/ext4/ext4_extents.h -@@ -225,7 +225,8 @@ static inline void ext4_ext_mark_initial - ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext)); - } - --extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks); -+extern int ext4_ext_calc_metadata_amount(struct inode *inode, -+ sector_t lblocks); - extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex); - extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); - extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); -Index: linux-2.6.32.noarch/fs/ext4/super.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/super.c -+++ linux-2.6.32.noarch/fs/ext4/super.c -@@ -702,6 +702,7 @@ static struct inode *ext4_alloc_inode(st - ei->i_reserved_data_blocks = 0; - ei->i_reserved_meta_blocks = 0; - ei->i_allocated_meta_blocks = 0; -+ ei->i_da_metadata_calc_len = 0; - ei->i_delalloc_reserved_flag = 0; - spin_lock_init(&(ei->i_block_reservation_lock)); - #ifdef CONFIG_QUOTA -Index: linux-2.6.32.noarch/fs/quota/dquot.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/quota/dquot.c -+++ linux-2.6.32.noarch/fs/quota/dquot.c -@@ -1492,11 +1492,13 @@ static void inode_decr_space(struct inod - /* - * This operation can block, but only after everything is updated - */ --int __dquot_alloc_space(struct inode *inode, qsize_t number, -- int warn, int reserve) -+int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) - { - int cnt, ret = QUOTA_OK; - char warntype[MAXQUOTAS]; -+ int warn = flags & DQUOT_SPACE_WARN; -+ int reserve = flags & DQUOT_SPACE_RESERVE; -+ int nofail = flags & DQUOT_SPACE_NOFAIL; - - /* - * First test before acquiring mutex - solves deadlocks when we -@@ -1521,7 +1523,7 @@ int __dquot_alloc_space(struct inode *in - if (!inode->i_dquot[cnt]) - continue; - if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) -- == NO_QUOTA) { -+ == NO_QUOTA && !nofail) { - ret = NO_QUOTA; - spin_unlock(&dq_data_lock); - goto out_flush_warn; -@@ -1552,15 +1554,19 @@ out: - return ret; - } - --int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) -+int dquot_alloc_space(struct inode *inode, qsize_t number, int flags) - { -- return __dquot_alloc_space(inode, number, warn, 0); -+ return __dquot_alloc_space(inode, number, flags); - } - EXPORT_SYMBOL(dquot_alloc_space); - - int dquot_reserve_space(struct inode *inode, qsize_t number, int warn) - { -- return __dquot_alloc_space(inode, number, warn, 1); -+ int flags = DQUOT_SPACE_RESERVE; -+ -+ if (warn) -+ flags |= DQUOT_SPACE_WARN; -+ return __dquot_alloc_space(inode, number, flags); - } - EXPORT_SYMBOL(dquot_reserve_space); - -@@ -1651,10 +1657,11 @@ EXPORT_SYMBOL(dquot_claim_space); - /* - * This operation can block, but only after everything is updated - */ --int __dquot_free_space(struct inode *inode, qsize_t number, int reserve) -+int __dquot_free_space(struct inode *inode, qsize_t number, int flags) - { - unsigned int cnt; - char warntype[MAXQUOTAS]; -+ int reserve = flags & DQUOT_SPACE_RESERVE; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1706,7 +1713,7 @@ EXPORT_SYMBOL(dquot_free_space); - */ - void dquot_release_reserved_space(struct inode *inode, qsize_t number) - { -- __dquot_free_space(inode, number, 1); -+ __dquot_free_space(inode, number, DQUOT_SPACE_RESERVE); - - } - EXPORT_SYMBOL(dquot_release_reserved_space); -Index: linux-2.6.32.noarch/include/linux/quotaops.h -=================================================================== ---- linux-2.6.32.noarch.orig/include/linux/quotaops.h -+++ linux-2.6.32.noarch/include/linux/quotaops.h -@@ -14,6 +14,10 @@ static inline struct quota_info *sb_dqop - return &sb->s_dquot; - } - -+#define DQUOT_SPACE_WARN 0x1 -+#define DQUOT_SPACE_RESERVE 0x2 -+#define DQUOT_SPACE_NOFAIL 0x4 -+ - #if defined(CONFIG_QUOTA) - - /* -@@ -159,7 +163,7 @@ static inline int vfs_dq_prealloc_space_ - { - if (sb_any_quota_active(inode->i_sb)) { - /* Used space is updated in alloc_space() */ -- if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) -+ if (inode->i_sb->dq_op->alloc_space(inode, nr, DQUOT_SPACE_WARN) == NO_QUOTA) - return 1; - } - else -@@ -187,6 +191,16 @@ static inline int vfs_dq_alloc_space_nod - return 0; - } - -+static inline void vfs_dq_alloc_space_nofail(struct inode *inode, qsize_t nr) -+{ -+ if (sb_any_quota_active(inode->i_sb)) { -+ /* Used space is updated in alloc_space() */ -+ inode->i_sb->dq_op->alloc_space(inode, nr, DQUOT_SPACE_NOFAIL); -+ } else -+ inode_add_bytes(inode, nr); -+ mark_inode_dirty(inode); -+} -+ - static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr) - { - int ret; -@@ -382,6 +396,12 @@ static inline int vfs_dq_alloc_space_nod - return 0; - } - -+static inline void vfs_dq_alloc_space_nofail(struct inode *inode, qsize_t nr) -+{ -+ inode_add_bytes(inode, nr); -+ mark_inode_dirty(inode); -+} -+ - static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr) - { - vfs_dq_alloc_space_nodirty(inode, nr); -@@ -433,6 +453,11 @@ static inline int vfs_dq_alloc_block_nod - return vfs_dq_alloc_space_nodirty(inode, nr << inode->i_blkbits); - } - -+static inline void vfs_dq_alloc_block_nofail(struct inode *inode, qsize_t nr) -+{ -+ vfs_dq_alloc_space_nofail(inode, nr << inode->i_blkbits); -+} -+ - static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr) - { - return vfs_dq_alloc_space(inode, nr << inode->i_blkbits); -Index: linux-2.6.32.noarch/fs/ext4/balloc.c -=================================================================== ---- linux-2.6.32.noarch.orig/fs/ext4/balloc.c -+++ linux-2.6.32.noarch/fs/ext4/balloc.c -@@ -642,14 +642,15 @@ ext4_fsblk_t ext4_new_meta_blocks(handle - ret = ext4_mb_new_blocks(handle, &ar, errp); - if (count) - *count = ar.len; -- - /* -- * Account for the allocated meta blocks -+ * Account for the allocated meta blocks. We will never -+ * fail EDQUOT for metdata, but we do account for it. - */ - if (!(*errp) && EXT4_I(inode)->i_delalloc_reserved_flag) { - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); - EXT4_I(inode)->i_allocated_meta_blocks += ar.len; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); -+ vfs_dq_alloc_block_nofail(inode, ar.len); - } - return ret; - } - diff --git a/mac80211-do-not-wipe-out-old-supported-rates.patch b/mac80211-do-not-wipe-out-old-supported-rates.patch deleted file mode 100644 index 0cdff31..0000000 --- a/mac80211-do-not-wipe-out-old-supported-rates.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Stanislaw Gruszka -To: kernel@lists.fedoraproject.org, "John W. Linville" -Subject: [PATCH 3/4 2.6.32.y] mac80211: do not wip out old supported rates -Date: Fri, 11 Jun 2010 17:03:15 +0200 - -Use old supported rates, if some buggy AP do not provide -supported rates information element in managment frame. - -Signed-off-by: Stanislaw Gruszka ---- - net/mac80211/scan.c | 21 +++++++++++---------- - 1 files changed, 11 insertions(+), 10 deletions(-) - -diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c -index fd6411d..169111a 100644 ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -62,7 +62,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, - bool beacon) - { - struct ieee80211_bss *bss; -- int clen; -+ int clen, srlen; - s32 signal = 0; - - if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) -@@ -94,23 +94,24 @@ ieee80211_bss_info_update(struct ieee80211_local *local, - if (bss->dtim_period == 0) - bss->dtim_period = 1; - -- bss->supp_rates_len = 0; -+ /* replace old supported rates if we get new values */ -+ srlen = 0; - if (elems->supp_rates) { -- clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; -+ clen = IEEE80211_MAX_SUPP_RATES; - if (clen > elems->supp_rates_len) - clen = elems->supp_rates_len; -- memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, -- clen); -- bss->supp_rates_len += clen; -+ memcpy(bss->supp_rates, elems->supp_rates, clen); -+ srlen += clen; - } - if (elems->ext_supp_rates) { -- clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; -+ clen = IEEE80211_MAX_SUPP_RATES - srlen; - if (clen > elems->ext_supp_rates_len) - clen = elems->ext_supp_rates_len; -- memcpy(&bss->supp_rates[bss->supp_rates_len], -- elems->ext_supp_rates, clen); -- bss->supp_rates_len += clen; -+ memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); -+ srlen += clen; - } -+ if (srlen) -+ bss->supp_rates_len = srlen; - - bss->wmm_used = elems->wmm_param || elems->wmm_info; - --- -1.6.2.5 - -_______________________________________________ -kernel mailing list -kernel@lists.fedoraproject.org -https://admin.fedoraproject.org/mailman/listinfo/kernel - diff --git a/mac80211-fix-supported-rates-IE-if-AP-doesnt-give-us-its-rates.patch b/mac80211-fix-supported-rates-IE-if-AP-doesnt-give-us-its-rates.patch deleted file mode 100644 index 947733f..0000000 --- a/mac80211-fix-supported-rates-IE-if-AP-doesnt-give-us-its-rates.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Stanislaw Gruszka -To: kernel@lists.fedoraproject.org, "John W. Linville" -Subject: [PATCH 4/4 2.6.32.y] mac80211: fix supported rates IE if AP doesn't - give us it's rates -Date: Fri, 11 Jun 2010 17:03:16 +0200 - -If AP do not provide us supported rates before assiociation, send -all rates we are supporting instead of empty information element. - -Signed-off-by: Stanislaw Gruszka ---- - net/mac80211/mlme.c | 17 +++++++++++------ - 1 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c -index d3950b7..abd62fc 100644 ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -269,12 +269,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, - if (wk->bss->wmm_used) - wmm = 1; - -- /* get all rates supported by the device and the AP as -- * some APs don't like getting a superset of their rates -- * in the association request (e.g. D-Link DAP 1353 in -- * b-only mode) */ -- rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates); -- - if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && - (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) - capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; -@@ -309,6 +303,17 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, - *pos++ = wk->ssid_len; - memcpy(pos, wk->ssid, wk->ssid_len); - -+ if (wk->bss->supp_rates_len) { -+ /* get all rates supported by the device and the AP as -+ * some APs don't like getting a superset of their rates -+ * in the association request (e.g. D-Link DAP 1353 in -+ * b-only mode) */ -+ rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates); -+ } else { -+ rates = ~0; -+ rates_len = sband->n_bitrates; -+ } -+ - /* add all rates which were marked to be used above */ - supp_rates_len = rates_len; - if (supp_rates_len > 8) --- -1.6.2.5 - -_______________________________________________ -kernel mailing list -kernel@lists.fedoraproject.org -https://admin.fedoraproject.org/mailman/listinfo/kernel - diff --git a/sched-fix-over-scheduling-bug.patch b/sched-fix-over-scheduling-bug.patch deleted file mode 100644 index b09c101..0000000 --- a/sched-fix-over-scheduling-bug.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Alex,Shi -Date: Thu, 17 Jun 2010 06:08:13 +0000 (+0800) -Subject: sched: Fix over-scheduling bug -X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3c93717cfa51316e4dbb471e7c0f9d243359d5f8 - -sched: Fix over-scheduling bug - -Commit e70971591 ("sched: Optimize unused cgroup configuration") introduced -an imbalanced scheduling bug. [[ in 2.6.32-rc1 ]] - -If we do not use CGROUP, function update_h_load won't update h_load. When the -system has a large number of tasks far more than logical CPU number, the -incorrect cfs_rq[cpu]->h_load value will cause load_balance() to pull too -many tasks to the local CPU from the busiest CPU. So the busiest CPU keeps -going in a round robin. That will hurt performance. - -The issue was found originally by a scientific calculation workload that -developed by Yanmin. With that commit, the workload performance drops -about 40%. - - CPU before after - - 00 : 2 : 7 - 01 : 1 : 7 - 02 : 11 : 6 - 03 : 12 : 7 - 04 : 6 : 6 - 05 : 11 : 7 - 06 : 10 : 6 - 07 : 12 : 7 - 08 : 11 : 6 - 09 : 12 : 6 - 10 : 1 : 6 - 11 : 1 : 6 - 12 : 6 : 6 - 13 : 2 : 6 - 14 : 2 : 6 - 15 : 1 : 6 - -Reviewed-by: Yanmin zhang -Signed-off-by: Alex Shi -Signed-off-by: Peter Zijlstra -LKML-Reference: <1276754893.9452.5442.camel@debian> -Signed-off-by: Ingo Molnar ---- - -diff --git a/kernel/sched.c b/kernel/sched.c -index 2aaceeb..6c9e7c8 100644 ---- a/kernel/sched.c -+++ b/kernel/sched.c -@@ -1657,9 +1657,6 @@ static void update_shares(struct sched_domain *sd) - - static void update_h_load(long cpu) - { -- if (root_task_group_empty()) -- return; -- - walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); - } - diff --git a/sources b/sources index f07f967..ab8874f 100644 --- a/sources +++ b/sources @@ -1,3 +1,2 @@ 260551284ac224c3a43c4adac7df4879 linux-2.6.32.tar.bz2 -744890f9651962ceae7663d44b19df65 patch-2.6.32.16.bz2 -d85be0216a7c8f0d4321eb9bb583fa5a patch-2.6.32.17-rc1.bz2 +ca9a0f5c28803e9231dc9ee5b0faa863 patch-2.6.32.17.bz2 diff --git a/usb-obey-the-sysfs-power-wakeup-setting.patch b/usb-obey-the-sysfs-power-wakeup-setting.patch deleted file mode 100644 index 8daccf0..0000000 --- a/usb-obey-the-sysfs-power-wakeup-setting.patch +++ /dev/null @@ -1,51 +0,0 @@ -This patch (as1403b) is a backport of commit -48826626263d4a61d06fd8c5805da31f925aefa0 (USB: obey the sysfs -power/wakeup setting) to 2.6.{32,33}.stable. It turns out that the -bug it fixes does affect quite a few people using USB infrared -remotes. The symptom is that the remote can no longer wake up the -system from suspend. - -This fixes Bugzilla #16043. - -Red Hat Bugzilla #617559 - -Signed-off-by: Alan Stern - ---- - -Index: 2.6.33.5/drivers/usb/core/driver.c -=================================================================== ---- 2.6.33.5.orig/drivers/usb/core/driver.c -+++ 2.6.33.5/drivers/usb/core/driver.c -@@ -1790,9 +1790,6 @@ int usb_external_resume_device(struct us - - static void choose_wakeup(struct usb_device *udev, pm_message_t msg) - { -- int w, i; -- struct usb_interface *intf; -- - /* Remote wakeup is needed only when we actually go to sleep. - * For things like FREEZE and QUIESCE, if the device is already - * autosuspended then its current wakeup setting is okay. -@@ -1802,18 +1799,10 @@ static void choose_wakeup(struct usb_dev - return; - } - -- /* If remote wakeup is permitted, see whether any interface drivers -+ /* Allow remote wakeup if it is enabled, even if no interface drivers - * actually want it. - */ -- w = 0; -- if (device_may_wakeup(&udev->dev) && udev->actconfig) { -- for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { -- intf = udev->actconfig->interface[i]; -- w |= intf->needs_remote_wakeup; -- } -- } -- -- udev->do_remote_wakeup = w; -+ udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - } - - int usb_suspend(struct device *dev, pm_message_t msg) -