diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 8286640d4d663fe51a207421f5a4190ee2d9bfb8..d249d7f45875265d85b3073b8abb69a85ae421ca 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "blk.h" #include "blk-mq.h" @@ -958,6 +959,48 @@ int blk_register_queue(struct gendisk *disk) } EXPORT_SYMBOL_GPL(blk_register_queue); +#ifdef CONFIG_DEBUG_FS +/* + * blk_prepare_release_queue - rename q->debugfs_dir and q->blk_trace->dir + * @q: request_queue of which the dir to be renamed belong to. + * + * Because the final release of request_queue is in a workqueue, the + * cleanup might not been finished yet while the same device start to + * create. It's not correct if q->debugfs_dir still exist while trying + * to create a new one. + */ +static void blk_prepare_release_queue(struct request_queue *q) +{ + struct dentry *new = NULL; + struct dentry **old = NULL; + char name[DNAME_INLINE_LEN]; + int i = 0; + +#ifdef CONFIG_BLK_DEBUG_FS + if (!IS_ERR_OR_NULL(q->debugfs_dir)) + old = &q->debugfs_dir; +#endif +#ifdef CONFIG_BLK_DEV_IO_TRACE + /* q->debugfs_dir and q->blk_trace->dir can't both exist */ + if (q->blk_trace && !IS_ERR_OR_NULL(q->blk_trace->dir)) + old = &q->blk_trace->dir; +#endif + if (old == NULL) + return; +#define MAX_ATTEMPT 1024 + while (new == NULL && i < MAX_ATTEMPT) { + sprintf(name, "ready_to_remove_%s_%d", + kobject_name(q->kobj.parent), i++); + new = debugfs_rename(blk_debugfs_root, *old, + blk_debugfs_root, name); + } + if (new) + *old = new; +} +#else +#define blk_prepare_release_queue(q) do { } while (0) +#endif + /** * blk_unregister_queue - counterpart of blk_register_queue() * @disk: Disk of which the request queue should be unregistered from sysfs. @@ -982,6 +1025,7 @@ void blk_unregister_queue(struct gendisk *disk) * concurrent elv_iosched_store() calls. */ mutex_lock(&q->sysfs_lock); + blk_prepare_release_queue(q); blk_queue_flag_clear(QUEUE_FLAG_REGISTERED, q); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5e56719f999c49fc1f90c462bad924897b6a65b5..1907085b12728608c301956594e2fe3ff5bc22d6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2078,6 +2078,16 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, return NULL; } +static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) +{ + return rx->key && + (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && + ieee80211_has_protected(fc); +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) { @@ -2122,12 +2132,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) /* This is the first fragment of a new frame. */ entry = ieee80211_reassemble_add(rx->sdata, frag, seq, rx->seqno_idx, &(rx->skb)); - if (rx->key && - (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && - ieee80211_has_protected(fc)) { + if (requires_sequential_pn(rx, fc)) { int queue = rx->security_idx; /* Store CCMP/GCMP PN so that we can verify that the @@ -2169,11 +2174,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; int queue; - if (!rx->key || - (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) + if (!requires_sequential_pn(rx, fc)) return RX_DROP_UNUSABLE; memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {