diff --git a/[refs] b/[refs] index 4f3de8f8eaab..56a13dfc71a8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3172f8fe1ca1d432b196efad453c0ceb89302075 +refs/heads/master: dc87cd5c264cb587f16459285565830689ecf7a7 diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 589f2da5d545..f049a1ca186f 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -282,11 +282,11 @@ tcp_max_ssthresh - INTEGER Default: 0 (off) tcp_max_syn_backlog - INTEGER - Maximal number of remembered connection requests, which have not - received an acknowledgment from connecting client. - The minimal value is 128 for low memory machines, and it will - increase in proportion to the memory of machine. - If server suffers from overload, try increasing this number. + Maximal number of remembered connection requests, which are + still did not receive an acknowledgment from connecting client. + Default value is 1024 for systems with more than 128Mb of memory, + and 128 for low memory machines. If server suffers of overload, + try to increase this number. tcp_max_tw_buckets - INTEGER Maximal number of timewait sockets held by system simultaneously. diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index 06e413e6a920..4b27efa4405b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -233,13 +233,12 @@ u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_TRAVIS: case ENCODER_OBJECT_ID_NUTMEG: - return true; + return radeon_encoder->encoder_id; default: - return false; + return ENCODER_OBJECT_ID_NONE; } } - - return false; + return ENCODER_OBJECT_ID_NONE; } void radeon_panel_mode_fixup(struct drm_encoder *encoder, diff --git a/trunk/drivers/net/ethernet/pasemi/Makefile b/trunk/drivers/net/ethernet/pasemi/Makefile index 90497ffb1ac3..05db5434bafc 100644 --- a/trunk/drivers/net/ethernet/pasemi/Makefile +++ b/trunk/drivers/net/ethernet/pasemi/Makefile @@ -2,5 +2,4 @@ # Makefile for the A Semi network device drivers. # -obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o -pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o +obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 67bf07819992..6f06aa10f0d7 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -1183,13 +1183,11 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } -static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) +static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) { - void __iomem *ioaddr = tp->mmio_addr; - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, tp->intr_event); - RTL_R8(ChipCmd); + + RTL_W16(IntrStatus, 0xffff); } static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) @@ -3935,6 +3933,8 @@ static void rtl_hw_reset(struct rtl8169_private *tp) break; udelay(100); } + + rtl8169_init_ring_indexes(tp); } static int __devinit @@ -4339,7 +4339,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; /* Disable interrupts */ - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); rtl_rx_close(tp); @@ -4885,7 +4885,8 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W16(IntrMitigate, 0x5151); /* Work around for RxFIFO overflow. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + if (tp->mac_version == RTL_GIGA_MAC_VER_11 || + tp->mac_version == RTL_GIGA_MAC_VER_22) { tp->intr_event |= RxFIFOOver | PCSTimeout; tp->intr_event &= ~RxOverflow; } @@ -5075,11 +5076,6 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { - tp->intr_event &= ~RxFIFOOver; - tp->napi_event &= ~RxFIFOOver; - } - if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { int cap = pci_pcie_cap(pdev); @@ -5346,7 +5342,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) /* Wait for any pending NAPI task to complete */ napi_disable(&tp->napi); - rtl8169_irq_mask_and_ack(tp); + rtl8169_irq_mask_and_ack(ioaddr); tp->intr_mask = 0xffff; RTL_W16(IntrMask, tp->intr_event); @@ -5393,16 +5389,14 @@ static void rtl8169_reset_task(struct work_struct *work) if (!netif_running(dev)) goto out_unlock; - rtl8169_hw_reset(tp); - rtl8169_wait_for_quiescence(dev); for (i = 0; i < NUM_RX_DESC; i++) rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); rtl8169_tx_clear(tp); - rtl8169_init_ring_indexes(tp); + rtl8169_hw_reset(tp); rtl_hw_start(dev); netif_wake_queue(dev); rtl8169_check_link_status(dev, tp, tp->mmio_addr); @@ -5413,6 +5407,11 @@ static void rtl8169_reset_task(struct work_struct *work) static void rtl8169_tx_timeout(struct net_device *dev) { + struct rtl8169_private *tp = netdev_priv(dev); + + rtl8169_hw_reset(tp); + + /* Let's wait a bit while any (async) irq lands on */ rtl8169_schedule_work(dev, rtl8169_reset_task); } @@ -5805,10 +5804,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) */ status = RTL_R16(IntrStatus); while (status && status != 0xffff) { - status &= tp->intr_event; - if (!status) - break; - handled = 1; /* Handle all of the error cases first. These will reset @@ -5823,9 +5818,27 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) switch (tp->mac_version) { /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_22: + case RTL_GIGA_MAC_VER_26: netif_stop_queue(dev); rtl8169_tx_timeout(dev); goto done; + /* Testers needed. */ + case RTL_GIGA_MAC_VER_17: + case RTL_GIGA_MAC_VER_19: + case RTL_GIGA_MAC_VER_20: + case RTL_GIGA_MAC_VER_21: + case RTL_GIGA_MAC_VER_23: + case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + /* Experimental science. Pktgen proof. */ + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_25: + if (status == RxFIFOOver) + goto done; + break; default: break; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index dd008b0e6417..e12b48c2cff6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -191,7 +191,6 @@ static struct iwl_base_params iwl1000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, - .wd_disable = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index f55fb2d1af52..c511c98a89a8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -364,7 +364,6 @@ static struct iwl_base_params iwl5000_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .no_idle_support = true, - .wd_disable = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a7a6def40d05..58a381c01c89 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -528,24 +528,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx) -{ - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } -} - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; @@ -604,11 +586,19 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ctx->ht.enabled = conf_is_ht(conf); if (ctx->ht.enabled) { - /* if HT40 is used, it should not change - * after associated except channel switch */ - if (iwl_is_associated_ctx(ctx) && - !ctx->ht.is_40mhz) - iwlagn_config_ht40(conf, ctx); + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } } else ctx->ht.is_40mhz = false; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 4b2aa1da0953..ed6283623932 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1268,6 +1268,9 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_TKIP: + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (sta) addr = sta->addr; else /* station mode case only */ @@ -1280,6 +1283,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, seq.tkip.iv32, p1k, CMD_SYNC); break; case WLAN_CIPHER_SUITE_CCMP: + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + /* fall through */ case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: ret = iwlagn_send_sta_key(priv, keyconf, sta_id, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index bacc06c95e7a..ccba69b7f8a7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2316,17 +2316,6 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - switch (key->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - /* fall through */ - case WLAN_CIPHER_SUITE_CCMP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - break; - default: - break; - } - /* * We could program these keys into the hardware as well, but we * don't expect much multicast traffic in IBSS and having keys @@ -2610,9 +2599,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, /* Configure HT40 channels */ ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) - iwlagn_config_ht40(conf, ctx); - else + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else ctx->ht.is_40mhz = false; if ((le16_to_cpu(ctx->staging.channel) != ch)) @@ -3498,10 +3499,9 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); -module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); +module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); MODULE_PARM_DESC(wd_disable, - "Disable stuck queue watchdog timer 0=system default, " - "1=disable, 2=enable (default: 0)"); + "Disable stuck queue watchdog timer (default: 0 [enabled])"); /* * set bt_coex_active to true, uCode will do kill/defer diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h index 3856abaea507..5b936ec1a541 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -86,8 +86,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx); /* uCode */ int iwlagn_rx_calib_result(struct iwl_priv *priv, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index fcf54160e4ed..001fdf140abb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1810,23 +1810,11 @@ void iwl_setup_watchdog(struct iwl_priv *priv) { unsigned int timeout = priv->cfg->base_params->wd_timeout; - if (!iwlagn_mod_params.wd_disable) { - /* use system default */ - if (timeout && !priv->cfg->base_params->wd_disable) - mod_timer(&priv->watchdog, - jiffies + - msecs_to_jiffies(IWL_WD_TICK(timeout))); - else - del_timer(&priv->watchdog); - } else { - /* module parameter overwrite default configuration */ - if (timeout && iwlagn_mod_params.wd_disable == 2) - mod_timer(&priv->watchdog, - jiffies + - msecs_to_jiffies(IWL_WD_TICK(timeout))); - else - del_timer(&priv->watchdog); - } + if (timeout && !iwlagn_mod_params.wd_disable) + mod_timer(&priv->watchdog, + jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); + else + del_timer(&priv->watchdog); } /** diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index f2fc288f3dd3..137da3380704 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -113,7 +113,6 @@ struct iwl_lib_ops { * @shadow_reg_enable: HW shadhow register bit * @no_idle_support: do not support idle mode * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up - * wd_disable: disable watchdog timer */ struct iwl_base_params { int eeprom_size; @@ -135,7 +134,6 @@ struct iwl_base_params { const bool shadow_reg_enable; const bool no_idle_support; const bool hd_v2; - const bool wd_disable; }; /* * @advanced_bt_coexist: support advanced bt coexist diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h index 14eaf37ce3b1..1f7a93c67c45 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; * @restart_fw: restart firmware, default = 1 * @plcp_check: enable plcp health check, default = true * @ack_check: disable ack health check, default = false - * @wd_disable: enable stuck queue check, default = 0 + * @wd_disable: enable stuck queue check, default = false * @bt_coex_active: enable bt coex, default = true * @led_mode: system default, default = 0 * @no_sleep_autoadjust: disable autoadjust, default = true @@ -141,7 +141,7 @@ struct iwl_mod_params { int restart_fw; bool plcp_check; bool ack_check; - int wd_disable; + bool wd_disable; bool bt_coex_active; int led_mode; bool no_sleep_autoadjust; diff --git a/trunk/drivers/net/xen-netback/netback.c b/trunk/drivers/net/xen-netback/netback.c index 15e332d08c8d..1ae270eed51a 100644 --- a/trunk/drivers/net/xen-netback/netback.c +++ b/trunk/drivers/net/xen-netback/netback.c @@ -1668,7 +1668,7 @@ static int __init netback_init(void) "netback/%u", group); if (IS_ERR(netbk->task)) { - printk(KERN_ALERT "kthread_create() fails at netback\n"); + printk(KERN_ALERT "kthread_run() fails at netback\n"); del_timer(&netbk->net_timer); rc = PTR_ERR(netbk->task); goto failed_init; diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index dcdc1f4a4624..13ef8c37471d 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -121,7 +121,6 @@ struct toshiba_acpi_dev { int illumination_supported:1; int video_supported:1; int fan_supported:1; - int system_event_supported:1; struct mutex mutex; }; @@ -725,7 +724,7 @@ static int keys_proc_show(struct seq_file *m, void *v) u32 hci_result; u32 value; - if (!dev->key_event_valid && dev->system_event_supported) { + if (!dev->key_event_valid) { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); if (hci_result == HCI_SUCCESS) { dev->key_event_valid = 1; @@ -965,8 +964,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) /* enable event fifo */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); - if (hci_result == HCI_SUCCESS) - dev->system_event_supported = 1; props.type = BACKLIGHT_PLATFORM; props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; @@ -1035,15 +1032,12 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); u32 hci_result, value; - int retries = 3; - if (!dev->system_event_supported || event != 0x80) + if (event != 0x80) return; - do { hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); - switch (hci_result) { - case HCI_SUCCESS: + if (hci_result == HCI_SUCCESS) { if (value == 0x100) continue; /* act on key press; ignore key release */ @@ -1055,19 +1049,14 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) pr_info("Unknown key %x\n", value); } - break; - case HCI_NOT_SUPPORTED: + } else if (hci_result == HCI_NOT_SUPPORTED) { /* This is a workaround for an unresolved issue on * some machines where system events sporadically * become disabled. */ hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); pr_notice("Re-enabled hotkeys\n"); - /* fall through */ - default: - retries--; - break; } - } while (retries && hci_result != HCI_EMPTY); + } while (hci_result != HCI_EMPTY); } diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 89509b5a090e..10ba92def3f6 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -2439,14 +2439,16 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) /** * prepend_path - Prepend path string to a buffer * @path: the dentry/vfsmount to report - * @root: root vfsmnt/dentry + * @root: root vfsmnt/dentry (may be modified by this function) * @buffer: pointer to the end of the buffer * @buflen: pointer to buffer length * * Caller holds the rename_lock. + * + * If path is not reachable from the supplied root, then the value of + * root is changed (without modifying refcounts). */ -static int prepend_path(const struct path *path, - const struct path *root, +static int prepend_path(const struct path *path, struct path *root, char **buffer, int *buflen) { struct dentry *dentry = path->dentry; @@ -2481,10 +2483,10 @@ static int prepend_path(const struct path *path, dentry = parent; } +out: if (!error && !slash) error = prepend(buffer, buflen, "/", 1); -out: br_read_unlock(vfsmount_lock); return error; @@ -2498,17 +2500,15 @@ static int prepend_path(const struct path *path, WARN(1, "Root dentry has weird name <%.*s>\n", (int) dentry->d_name.len, dentry->d_name.name); } - if (!slash) - error = prepend(buffer, buflen, "/", 1); - if (!error) - error = vfsmnt->mnt_ns ? 1 : 2; + root->mnt = vfsmnt; + root->dentry = dentry; goto out; } /** * __d_path - return the path of a dentry * @path: the dentry/vfsmount to report - * @root: root vfsmnt/dentry + * @root: root vfsmnt/dentry (may be modified by this function) * @buf: buffer to return value in * @buflen: buffer length * @@ -2519,10 +2519,10 @@ static int prepend_path(const struct path *path, * * "buflen" should be positive. * - * If the path is not reachable from the supplied root, return %NULL. + * If path is not reachable from the supplied root, then the value of + * root is changed (without modifying refcounts). */ -char *__d_path(const struct path *path, - const struct path *root, +char *__d_path(const struct path *path, struct path *root, char *buf, int buflen) { char *res = buf + buflen; @@ -2533,28 +2533,7 @@ char *__d_path(const struct path *path, error = prepend_path(path, root, &res, &buflen); write_sequnlock(&rename_lock); - if (error < 0) - return ERR_PTR(error); - if (error > 0) - return NULL; - return res; -} - -char *d_absolute_path(const struct path *path, - char *buf, int buflen) -{ - struct path root = {}; - char *res = buf + buflen; - int error; - - prepend(&res, &buflen, "\0", 1); - write_seqlock(&rename_lock); - error = prepend_path(path, &root, &res, &buflen); - write_sequnlock(&rename_lock); - - if (error > 1) - error = -EINVAL; - if (error < 0) + if (error) return ERR_PTR(error); return res; } @@ -2562,9 +2541,8 @@ char *d_absolute_path(const struct path *path, /* * same as __d_path but appends "(deleted)" for unlinked files. */ -static int path_with_deleted(const struct path *path, - const struct path *root, - char **buf, int *buflen) +static int path_with_deleted(const struct path *path, struct path *root, + char **buf, int *buflen) { prepend(buf, buflen, "\0", 1); if (d_unlinked(path->dentry)) { @@ -2601,6 +2579,7 @@ char *d_path(const struct path *path, char *buf, int buflen) { char *res = buf + buflen; struct path root; + struct path tmp; int error; /* @@ -2615,8 +2594,9 @@ char *d_path(const struct path *path, char *buf, int buflen) get_fs_root(current->fs, &root); write_seqlock(&rename_lock); - error = path_with_deleted(path, &root, &res, &buflen); - if (error < 0) + tmp = root; + error = path_with_deleted(path, &tmp, &res, &buflen); + if (error) res = ERR_PTR(error); write_sequnlock(&rename_lock); path_put(&root); @@ -2637,6 +2617,7 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) { char *res = buf + buflen; struct path root; + struct path tmp; int error; if (path->dentry->d_op && path->dentry->d_op->d_dname) @@ -2644,8 +2625,9 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) get_fs_root(current->fs, &root); write_seqlock(&rename_lock); - error = path_with_deleted(path, &root, &res, &buflen); - if (error > 0) + tmp = root; + error = path_with_deleted(path, &tmp, &res, &buflen); + if (!error && !path_equal(&tmp, &root)) error = prepend_unreachable(&res, &buflen); write_sequnlock(&rename_lock); path_put(&root); @@ -2776,18 +2758,19 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) write_seqlock(&rename_lock); if (!d_unlinked(pwd.dentry)) { unsigned long len; + struct path tmp = root; char *cwd = page + PAGE_SIZE; int buflen = PAGE_SIZE; prepend(&cwd, &buflen, "\0", 1); - error = prepend_path(&pwd, &root, &cwd, &buflen); + error = prepend_path(&pwd, &tmp, &cwd, &buflen); write_sequnlock(&rename_lock); - if (error < 0) + if (error) goto out; /* Unreachable from current root */ - if (error > 0) { + if (!path_equal(&tmp, &root)) { error = prepend_unreachable(&cwd, &buflen); if (error) goto out; diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index cfc6d4448aa5..6d3a1963879b 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -1048,12 +1048,15 @@ static int show_mountinfo(struct seq_file *m, void *v) if (err) goto out; seq_putc(m, ' '); - - /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ - err = seq_path_root(m, &mnt_path, &root, " \t\n\\"); - if (err) - goto out; - + seq_path_root(m, &mnt_path, &root, " \t\n\\"); + if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { + /* + * Mountpoint is outside root, discard that one. Ugly, + * but less so than trying to do that in iterator in a + * race-free way (due to renames). + */ + return SEQ_SKIP; + } seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); show_mnt_opts(m, mnt); @@ -2773,8 +2776,3 @@ void kern_unmount(struct vfsmount *mnt) } } EXPORT_SYMBOL(kern_unmount); - -bool our_mnt(struct vfsmount *mnt) -{ - return check_mnt(mnt); -} diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index dba43c3ea3af..05d6b0e78c95 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -449,6 +449,8 @@ EXPORT_SYMBOL(seq_path); /* * Same as seq_path, but relative to supplied root. + * + * root may be changed, see __d_path(). */ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, char *esc) @@ -461,8 +463,6 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, char *p; p = __d_path(path, root, buf, size); - if (!p) - return SEQ_SKIP; res = PTR_ERR(p); if (!IS_ERR(p)) { char *end = mangle_path(buf, p, esc); @@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, } seq_commit(m, res); - return res < 0 && res != -ENAMETOOLONG ? res : 0; + return res < 0 ? res : 0; } /* diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index ed9f74f6c519..4df926199369 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -339,8 +339,7 @@ extern int d_validate(struct dentry *, struct dentry *); */ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *__d_path(const struct path *, const struct path *, char *, int); -extern char *d_absolute_path(const struct path *, char *, int); +extern char *__d_path(const struct path *path, struct path *root, char *, int); extern char *d_path(const struct path *, char *, int); extern char *d_path_with_unreachable(const struct path *, char *, int); extern char *dentry_path_raw(struct dentry *, char *, int); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 019dc558df1a..e3130220ce3e 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1942,7 +1942,6 @@ extern int fd_statfs(int, struct kstatfs *); extern int statfs_by_dentry(struct dentry *, struct kstatfs *); extern int freeze_super(struct super_block *super); extern int thaw_super(struct super_block *super); -extern bool our_mnt(struct vfsmount *mnt); extern int current_umask(void); diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index c3da42dd22ba..96efa6794ea5 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -172,7 +172,6 @@ enum { TRACE_EVENT_FL_FILTERED_BIT, TRACE_EVENT_FL_RECORDED_CMD_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, - TRACE_EVENT_FL_NO_SET_FILTER_BIT, }; enum { @@ -180,7 +179,6 @@ enum { TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), - TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), }; struct ftrace_event_call { diff --git a/trunk/kernel/jump_label.c b/trunk/kernel/jump_label.c index 66ff7109f697..bbdfe2a462a0 100644 --- a/trunk/kernel/jump_label.c +++ b/trunk/kernel/jump_label.c @@ -66,9 +66,8 @@ void jump_label_inc(struct jump_label_key *key) return; jump_label_lock(); - if (atomic_read(&key->enabled) == 0) + if (atomic_add_return(1, &key->enabled) == 1) jump_label_update(key, JUMP_LABEL_ENABLE); - atomic_inc(&key->enabled); jump_label_unlock(); } diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index b1e8943fed1d..900b409543db 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -152,6 +152,7 @@ void clear_ftrace_function(void) ftrace_pid_function = ftrace_stub; } +#undef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST /* * For those archs that do not test ftrace_trace_stop in their @@ -1211,9 +1212,7 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, if (!src->count) { free_ftrace_hash_rcu(*dst); rcu_assign_pointer(*dst, EMPTY_HASH); - /* still need to update the function records */ - ret = 0; - goto out; + return 0; } /* diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c index c212a7f934ec..581876f9f387 100644 --- a/trunk/kernel/trace/trace_events.c +++ b/trunk/kernel/trace/trace_events.c @@ -1078,6 +1078,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) /* First see if we did not already create this dir */ list_for_each_entry(system, &event_subsystems, list) { if (strcmp(system->name, name) == 0) { + __get_system(system); system->nr_events++; return system->entry; } diff --git a/trunk/kernel/trace/trace_events_filter.c b/trunk/kernel/trace/trace_events_filter.c index 95dc31efd6dd..d6e7926dcd26 100644 --- a/trunk/kernel/trace/trace_events_filter.c +++ b/trunk/kernel/trace/trace_events_filter.c @@ -1649,9 +1649,7 @@ static int replace_system_preds(struct event_subsystem *system, */ err = replace_preds(call, NULL, ps, filter_string, true); if (err) - call->flags |= TRACE_EVENT_FL_NO_SET_FILTER; - else - call->flags &= ~TRACE_EVENT_FL_NO_SET_FILTER; + goto fail; } list_for_each_entry(call, &ftrace_events, list) { @@ -1660,9 +1658,6 @@ static int replace_system_preds(struct event_subsystem *system, if (strcmp(call->class->system, system->name) != 0) continue; - if (call->flags & TRACE_EVENT_FL_NO_SET_FILTER) - continue; - filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); if (!filter_item) goto fail_mem; diff --git a/trunk/net/core/request_sock.c b/trunk/net/core/request_sock.c index 9b570a6a33c5..182236b2510a 100644 --- a/trunk/net/core/request_sock.c +++ b/trunk/net/core/request_sock.c @@ -26,11 +26,10 @@ * but then some measure against one socket starving all other sockets * would be needed. * - * The minimum value of it is 128. Experiments with real servers show that + * It was 128 by default. Experiments with real servers show, that * it is absolutely not enough even at 100conn/sec. 256 cures most - * of problems. - * This value is adjusted to 128 for low memory machines, - * and it will increase in proportion to the memory of machine. + * of problems. This value is adjusted to 128 for very small machines + * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). * Note : Dont forget somaxconn that may limit backlog too. */ int sysctl_max_syn_backlog = 256; diff --git a/trunk/net/core/secure_seq.c b/trunk/net/core/secure_seq.c index 925991ae6f52..025233de25f9 100644 --- a/trunk/net/core/secure_seq.c +++ b/trunk/net/core/secure_seq.c @@ -19,7 +19,6 @@ static int __init net_secret_init(void) } late_initcall(net_secret_init); -#ifdef CONFIG_INET static u32 seq_scale(u32 seq) { /* @@ -34,7 +33,6 @@ static u32 seq_scale(u32 seq) */ return seq + (ktime_to_ns(ktime_get_real()) >> 6); } -#endif #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 46af62363b8c..ca5e237df029 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -112,7 +112,7 @@ #include #define RT_FL_TOS(oldflp4) \ - ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)) + ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) #define IP_MAX_MTU 0xFFF0 @@ -1310,7 +1310,7 @@ static void rt_del(unsigned hash, struct rtable *rt) spin_unlock_bh(rt_hash_lock_addr(hash)); } -static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) +static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; @@ -1321,19 +1321,21 @@ static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) rt->rt_gateway = peer->redirect_learned.a4; n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); - if (IS_ERR(n)) { - rt->rt_gateway = orig_gw; - return; - } + if (IS_ERR(n)) + return PTR_ERR(n); old_n = xchg(&rt->dst._neighbour, n); if (old_n) neigh_release(old_n); - if (!(n->nud_state & NUD_VALID)) { - neigh_event_send(n, NULL); + if (!n || !(n->nud_state & NUD_VALID)) { + if (n) + neigh_event_send(n, NULL); + rt->rt_gateway = orig_gw; + return -EAGAIN; } else { rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } + return 0; } /* called in rcu_read_lock() section */ @@ -1691,7 +1693,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } -static void ipv4_validate_peer(struct rtable *rt) +static struct rtable *ipv4_validate_peer(struct rtable *rt) { if (rt->rt_peer_genid != rt_peer_genid()) { struct inet_peer *peer; @@ -1706,12 +1708,15 @@ static void ipv4_validate_peer(struct rtable *rt) if (peer->redirect_genid != redirect_genid) peer->redirect_learned.a4 = 0; if (peer->redirect_learned.a4 && - peer->redirect_learned.a4 != rt->rt_gateway) - check_peer_redir(&rt->dst, peer); + peer->redirect_learned.a4 != rt->rt_gateway) { + if (check_peer_redir(&rt->dst, peer)) + return NULL; + } } rt->rt_peer_genid = rt_peer_genid(); } + return rt; } static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) @@ -1720,7 +1725,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) if (rt_is_expired(rt)) return NULL; - ipv4_validate_peer(rt); + dst = (struct dst_entry *) ipv4_validate_peer(rt); return dst; } @@ -2375,7 +2380,9 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_mark == skb->mark && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { - ipv4_validate_peer(rth); + rth = ipv4_validate_peer(rth); + if (!rth) + continue; if (noref) { dst_use_noref(&rth->dst, jiffies); skb_dst_set_noref(skb, &rth->dst); @@ -2434,11 +2441,11 @@ EXPORT_SYMBOL(ip_route_input_common); static struct rtable *__mkroute_output(const struct fib_result *res, const struct flowi4 *fl4, __be32 orig_daddr, __be32 orig_saddr, - int orig_oif, __u8 orig_rtos, - struct net_device *dev_out, + int orig_oif, struct net_device *dev_out, unsigned int flags) { struct fib_info *fi = res->fi; + u32 tos = RT_FL_TOS(fl4); struct in_device *in_dev; u16 type = res->type; struct rtable *rth; @@ -2489,7 +2496,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_genid = rt_genid(dev_net(dev_out)); rth->rt_flags = flags; rth->rt_type = type; - rth->rt_key_tos = orig_rtos; + rth->rt_key_tos = tos; rth->rt_dst = fl4->daddr; rth->rt_src = fl4->saddr; rth->rt_route_iif = 0; @@ -2539,7 +2546,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) { struct net_device *dev_out = NULL; - __u8 tos = RT_FL_TOS(fl4); + u32 tos = RT_FL_TOS(fl4); unsigned int flags = 0; struct fib_result res; struct rtable *rth; @@ -2715,7 +2722,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) make_route: rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, - tos, dev_out, flags); + dev_out, flags); if (!IS_ERR(rth)) { unsigned int hash; @@ -2751,7 +2758,9 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { - ipv4_validate_peer(rth); + rth = ipv4_validate_peer(rth); + if (!rth) + continue; dst_use(&rth->dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index cae443563ec9..d999bf3b84e1 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -757,12 +757,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (!local->int_scan_req) return -ENOMEM; - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!local->hw.wiphy->bands[band]) - continue; - local->int_scan_req->rates[band] = (u32) -1; - } - /* if low-level driver supports AP, we also support VLAN */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index d5230ecc784d..eca0fad09709 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -1039,6 +1039,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) struct ieee80211_sub_if_data, u.ap); + memset(&sta->sta.drv_priv, 0, hw->sta_data_size); WARN_ON(drv_sta_add(local, sdata, &sta->sta)); } } diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 3302c56f60d1..77e926738014 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -57,17 +57,8 @@ #define REG_DBG_PRINT(args...) #endif -static struct regulatory_request core_request_world = { - .initiator = NL80211_REGDOM_SET_BY_CORE, - .alpha2[0] = '0', - .alpha2[1] = '0', - .intersect = false, - .processed = true, - .country_ie_env = ENVIRON_ANY, -}; - /* Receipt of information from last regulatory request */ -static struct regulatory_request *last_request = &core_request_world; +static struct regulatory_request *last_request; /* To trigger userspace events */ static struct platform_device *reg_pdev; @@ -159,7 +150,7 @@ static char user_alpha2[2]; module_param(ieee80211_regdom, charp, 0444); MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); -static void reset_regdomains(bool full_reset) +static void reset_regdomains(void) { /* avoid freeing static information or freeing something twice */ if (cfg80211_regdomain == cfg80211_world_regdom) @@ -174,13 +165,6 @@ static void reset_regdomains(bool full_reset) cfg80211_world_regdom = &world_regdom; cfg80211_regdomain = NULL; - - if (!full_reset) - return; - - if (last_request != &core_request_world) - kfree(last_request); - last_request = &core_request_world; } /* @@ -191,7 +175,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) { BUG_ON(!last_request); - reset_regdomains(false); + reset_regdomains(); cfg80211_world_regdom = rd; cfg80211_regdomain = rd; @@ -1423,8 +1407,7 @@ static int __regulatory_hint(struct wiphy *wiphy, } new_request: - if (last_request != &core_request_world) - kfree(last_request); + kfree(last_request); last_request = pending_request; last_request->intersect = intersect; @@ -1594,6 +1577,9 @@ static int regulatory_hint_core(const char *alpha2) { struct regulatory_request *request; + kfree(last_request); + last_request = NULL; + request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); if (!request) @@ -1791,7 +1777,7 @@ static void restore_regulatory_settings(bool reset_user) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); - reset_regdomains(true); + reset_regdomains(); restore_alpha2(alpha2, reset_user); /* @@ -2051,10 +2037,8 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) } request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); - if (!request_wiphy && - (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER || - last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) { - schedule_delayed_work(®_timeout, 0); + if (!request_wiphy) { + reg_set_request_processed(); return -ENODEV; } @@ -2062,7 +2046,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) int r; if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = rd; return 0; } @@ -2083,7 +2067,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) if (r) return r; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = rd; return 0; } @@ -2108,7 +2092,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) rd = NULL; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = intersected_rd; return 0; @@ -2128,7 +2112,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) kfree(rd); rd = NULL; - reset_regdomains(false); + reset_regdomains(); cfg80211_regdomain = intersected_rd; return 0; @@ -2281,8 +2265,11 @@ void /* __init_or_exit */ regulatory_exit(void) mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); - reset_regdomains(true); + reset_regdomains(); + + kfree(last_request); + last_request = NULL; dev_set_uevent_suppress(®_pdev->dev, true); platform_device_unregister(reg_pdev); diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c index b566eba4a65c..36cc0cc39e78 100644 --- a/trunk/security/apparmor/path.c +++ b/trunk/security/apparmor/path.c @@ -57,44 +57,23 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen) static int d_namespace_path(struct path *path, char *buf, int buflen, char **name, int flags) { + struct path root, tmp; char *res; - int error = 0; - int connected = 1; - - if (path->mnt->mnt_flags & MNT_INTERNAL) { - /* it's not mounted anywhere */ - res = dentry_path(path->dentry, buf, buflen); - *name = res; - if (IS_ERR(res)) { - *name = buf; - return PTR_ERR(res); - } - if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC && - strncmp(*name, "/sys/", 5) == 0) { - /* TODO: convert over to using a per namespace - * control instead of hard coded /proc - */ - return prepend(name, *name - buf, "/proc", 5); - } - return 0; - } + int connected, error = 0; - /* resolve paths relative to chroot?*/ + /* Get the root we want to resolve too, released below */ if (flags & PATH_CHROOT_REL) { - struct path root; + /* resolve paths relative to chroot */ get_fs_root(current->fs, &root); - res = __d_path(path, &root, buf, buflen); - if (res && !IS_ERR(res)) { - /* everything's fine */ - *name = res; - path_put(&root); - goto ok; - } - path_put(&root); - connected = 0; + } else { + /* resolve paths relative to namespace */ + root.mnt = current->nsproxy->mnt_ns->root; + root.dentry = root.mnt->mnt_root; + path_get(&root); } - res = d_absolute_path(path, buf, buflen); + tmp = root; + res = __d_path(path, &tmp, buf, buflen); *name = res; /* handle error conditions - and still allow a partial path to @@ -105,10 +84,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, *name = buf; goto out; } - if (!our_mnt(path->mnt)) - connected = 0; -ok: /* Handle two cases: * 1. A deleted dentry && profile is not allowing mediation of deleted * 2. On some filesystems, newly allocated dentries appear to the @@ -121,7 +97,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, goto out; } - /* If the path is not connected to the expected root, + /* Determine if the path is connected to the expected root */ + connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt; + + /* If the path is not connected, * check if it is a sysctl and handle specially else remove any * leading / that __d_path may have returned. * Unless @@ -133,9 +112,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, * namespace root. */ if (!connected) { - if (!(flags & PATH_CONNECT_PATH) && + /* is the disconnect path a sysctl? */ + if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC && + strncmp(*name, "/sys/", 5) == 0) { + /* TODO: convert over to using a per namespace + * control instead of hard coded /proc + */ + error = prepend(name, *name - buf, "/proc", 5); + } else if (!(flags & PATH_CONNECT_PATH) && !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && - our_mnt(path->mnt))) { + (tmp.mnt == current->nsproxy->mnt_ns->root && + tmp.dentry == tmp.mnt->mnt_root))) { /* disconnected path, don't return pathname starting * with '/' */ @@ -146,6 +133,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, } out: + path_put(&root); + return error; } diff --git a/trunk/security/tomoyo/realpath.c b/trunk/security/tomoyo/realpath.c index 36fa7c9bedc4..738bbdf8d4c7 100644 --- a/trunk/security/tomoyo/realpath.c +++ b/trunk/security/tomoyo/realpath.c @@ -101,8 +101,9 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, { char *pos = ERR_PTR(-ENOMEM); if (buflen >= 256) { + struct path ns_root = { }; /* go to whatever namespace root we are under */ - pos = d_absolute_path(path, buffer, buflen - 1); + pos = __d_path(path, &ns_root, buffer, buflen - 1); if (!IS_ERR(pos) && *pos == '/' && pos[1]) { struct inode *inode = path->dentry->d_inode; if (inode && S_ISDIR(inode->i_mode)) { diff --git a/trunk/tools/perf/util/trace-event-parse.c b/trunk/tools/perf/util/trace-event-parse.c index 6c164dc9ee95..0a7ed5b5e281 100644 --- a/trunk/tools/perf/util/trace-event-parse.c +++ b/trunk/tools/perf/util/trace-event-parse.c @@ -1537,8 +1537,6 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) field = malloc_or_die(sizeof(*field)); type = process_arg(event, field, &token); - while (type == EVENT_OP) - type = process_op(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free;