|
|
@@ -188,6 +188,8 @@ static struct napi_struct *napi_by_id(unsigned int napi_id);
|
|
|
DEFINE_RWLOCK(dev_base_lock);
|
|
|
EXPORT_SYMBOL(dev_base_lock);
|
|
|
|
|
|
+static DEFINE_MUTEX(ifalias_mutex);
|
|
|
+
|
|
|
/* protects napi_hash addition/deletion and napi_gen_id */
|
|
|
static DEFINE_SPINLOCK(napi_hash_lock);
|
|
|
|
|
|
@@ -1265,29 +1267,53 @@ rollback:
|
|
|
*/
|
|
|
int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
|
|
|
{
|
|
|
- char *new_ifalias;
|
|
|
-
|
|
|
- ASSERT_RTNL();
|
|
|
+ struct dev_ifalias *new_alias = NULL;
|
|
|
|
|
|
if (len >= IFALIASZ)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (!len) {
|
|
|
- kfree(dev->ifalias);
|
|
|
- dev->ifalias = NULL;
|
|
|
- return 0;
|
|
|
+ if (len) {
|
|
|
+ new_alias = kmalloc(sizeof(*new_alias) + len + 1, GFP_KERNEL);
|
|
|
+ if (!new_alias)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ memcpy(new_alias->ifalias, alias, len);
|
|
|
+ new_alias->ifalias[len] = 0;
|
|
|
}
|
|
|
|
|
|
- new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
|
|
|
- if (!new_ifalias)
|
|
|
- return -ENOMEM;
|
|
|
- dev->ifalias = new_ifalias;
|
|
|
- memcpy(dev->ifalias, alias, len);
|
|
|
- dev->ifalias[len] = 0;
|
|
|
+ mutex_lock(&ifalias_mutex);
|
|
|
+ rcu_swap_protected(dev->ifalias, new_alias,
|
|
|
+ mutex_is_locked(&ifalias_mutex));
|
|
|
+ mutex_unlock(&ifalias_mutex);
|
|
|
+
|
|
|
+ if (new_alias)
|
|
|
+ kfree_rcu(new_alias, rcuhead);
|
|
|
|
|
|
return len;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * dev_get_alias - get ifalias of a device
|
|
|
+ * @dev: device
|
|
|
+ * @alias: buffer to store name of ifalias
|
|
|
+ * @len: size of buffer
|
|
|
+ *
|
|
|
+ * get ifalias for a device. Caller must make sure dev cannot go
|
|
|
+ * away, e.g. rcu read lock or own a reference count to device.
|
|
|
+ */
|
|
|
+int dev_get_alias(const struct net_device *dev, char *name, size_t len)
|
|
|
+{
|
|
|
+ const struct dev_ifalias *alias;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ alias = rcu_dereference(dev->ifalias);
|
|
|
+ if (alias)
|
|
|
+ ret = snprintf(name, len, "%s", alias->ifalias);
|
|
|
+ rcu_read_unlock();
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* netdev_features_change - device changes features
|