Commit 0ab6cba0 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: hold wiphy lock in netdev/link debugfs

It's no longer really needed to ensure that the debugfs
file isn't going away, debugfs handles that. So there's
no point in holding dev_base_lock or RTNL here, but we
should instead hold the wiphy lock since drivers will
be allowed to depend on that. Do that, which requires
splitting the sdata and link macros a bit.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 629ebb85
......@@ -22,18 +22,18 @@
#include "debugfs_netdev.h"
#include "driver-ops.h"
static ssize_t ieee80211_if_read(
void *data,
static ssize_t ieee80211_if_read_sdata(
struct ieee80211_sub_if_data *sdata,
char __user *userbuf,
size_t count, loff_t *ppos,
ssize_t (*format)(const void *, char *, int))
ssize_t (*format)(const struct ieee80211_sub_if_data *sdata, char *, int))
{
char buf[200];
ssize_t ret = -EINVAL;
read_lock(&dev_base_lock);
ret = (*format)(data, buf, sizeof(buf));
read_unlock(&dev_base_lock);
wiphy_lock(sdata->local->hw.wiphy);
ret = (*format)(sdata, buf, sizeof(buf));
wiphy_unlock(sdata->local->hw.wiphy);
if (ret >= 0)
ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
......@@ -41,11 +41,11 @@ static ssize_t ieee80211_if_read(
return ret;
}
static ssize_t ieee80211_if_write(
void *data,
static ssize_t ieee80211_if_write_sdata(
struct ieee80211_sub_if_data *sdata,
const char __user *userbuf,
size_t count, loff_t *ppos,
ssize_t (*write)(void *, const char *, int))
ssize_t (*write)(struct ieee80211_sub_if_data *sdata, const char *, int))
{
char buf[64];
ssize_t ret;
......@@ -57,9 +57,51 @@ static ssize_t ieee80211_if_write(
return -EFAULT;
buf[count] = '\0';
rtnl_lock();
ret = (*write)(data, buf, count);
rtnl_unlock();
wiphy_lock(sdata->local->hw.wiphy);
ret = (*write)(sdata, buf, count);
wiphy_unlock(sdata->local->hw.wiphy);
return ret;
}
static ssize_t ieee80211_if_read_link(
struct ieee80211_link_data *link,
char __user *userbuf,
size_t count, loff_t *ppos,
ssize_t (*format)(const struct ieee80211_link_data *link, char *, int))
{
char buf[200];
ssize_t ret = -EINVAL;
wiphy_lock(link->sdata->local->hw.wiphy);
ret = (*format)(link, buf, sizeof(buf));
wiphy_unlock(link->sdata->local->hw.wiphy);
if (ret >= 0)
ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
return ret;
}
static ssize_t ieee80211_if_write_link(
struct ieee80211_link_data *link,
const char __user *userbuf,
size_t count, loff_t *ppos,
ssize_t (*write)(struct ieee80211_link_data *link, const char *, int))
{
char buf[64];
ssize_t ret;
if (count >= sizeof(buf))
return -E2BIG;
if (copy_from_user(buf, userbuf, count))
return -EFAULT;
buf[count] = '\0';
wiphy_lock(link->sdata->local->hw.wiphy);
ret = (*write)(link, buf, count);
wiphy_unlock(link->sdata->local->hw.wiphy);
return ret;
}
......@@ -126,41 +168,37 @@ static const struct file_operations name##_ops = { \
.llseek = generic_file_llseek, \
}
#define _IEEE80211_IF_FILE_R_FN(name, type) \
#define _IEEE80211_IF_FILE_R_FN(name) \
static ssize_t ieee80211_if_read_##name(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
ssize_t (*fn)(const void *, char *, int) = (void *) \
((ssize_t (*)(const type, char *, int)) \
ieee80211_if_fmt_##name); \
return ieee80211_if_read(file->private_data, \
userbuf, count, ppos, fn); \
return ieee80211_if_read_sdata(file->private_data, \
userbuf, count, ppos, \
ieee80211_if_fmt_##name); \
}
#define _IEEE80211_IF_FILE_W_FN(name, type) \
#define _IEEE80211_IF_FILE_W_FN(name) \
static ssize_t ieee80211_if_write_##name(struct file *file, \
const char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
ssize_t (*fn)(void *, const char *, int) = (void *) \
((ssize_t (*)(type, const char *, int)) \
ieee80211_if_parse_##name); \
return ieee80211_if_write(file->private_data, userbuf, count, \
ppos, fn); \
return ieee80211_if_write_sdata(file->private_data, userbuf, \
count, ppos, \
ieee80211_if_parse_##name); \
}
#define IEEE80211_IF_FILE_R(name) \
_IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *) \
_IEEE80211_IF_FILE_R_FN(name) \
_IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, NULL)
#define IEEE80211_IF_FILE_W(name) \
_IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *) \
_IEEE80211_IF_FILE_W_FN(name) \
_IEEE80211_IF_FILE_OPS(name, NULL, ieee80211_if_write_##name)
#define IEEE80211_IF_FILE_RW(name) \
_IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *) \
_IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *) \
_IEEE80211_IF_FILE_R_FN(name) \
_IEEE80211_IF_FILE_W_FN(name) \
_IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, \
ieee80211_if_write_##name)
......@@ -168,18 +206,37 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \
IEEE80211_IF_FMT_##format(name, struct ieee80211_sub_if_data, field) \
IEEE80211_IF_FILE_R(name)
/* Same but with a link_ prefix in the ops variable name and different type */
#define _IEEE80211_IF_LINK_R_FN(name) \
static ssize_t ieee80211_if_read_##name(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
return ieee80211_if_read_link(file->private_data, \
userbuf, count, ppos, \
ieee80211_if_fmt_##name); \
}
#define _IEEE80211_IF_LINK_W_FN(name) \
static ssize_t ieee80211_if_write_##name(struct file *file, \
const char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
return ieee80211_if_write_link(file->private_data, userbuf, \
count, ppos, \
ieee80211_if_parse_##name); \
}
#define IEEE80211_IF_LINK_FILE_R(name) \
_IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *) \
_IEEE80211_IF_LINK_R_FN(name) \
_IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name, NULL)
#define IEEE80211_IF_LINK_FILE_W(name) \
_IEEE80211_IF_FILE_W_FN(name) \
_IEEE80211_IF_LINK_W_FN(name) \
_IEEE80211_IF_FILE_OPS(link_##name, NULL, ieee80211_if_write_##name)
#define IEEE80211_IF_LINK_FILE_RW(name) \
_IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *) \
_IEEE80211_IF_FILE_W_FN(name, struct ieee80211_link_data *) \
_IEEE80211_IF_LINK_R_FN(name) \
_IEEE80211_IF_LINK_W_FN(name) \
_IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name, \
ieee80211_if_write_##name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment