diff options
Diffstat (limited to 'net/ethtool/netlink.c')
| -rw-r--r-- | net/ethtool/netlink.c | 12 | 
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index 38b44c0291b1..5fe8f4ae2ceb 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -40,7 +40,8 @@ int ethnl_ops_begin(struct net_device *dev)  	if (dev->dev.parent)  		pm_runtime_get_sync(dev->dev.parent); -	if (!netif_device_present(dev)) { +	if (!netif_device_present(dev) || +	    dev->reg_state == NETREG_UNREGISTERING) {  		ret = -ENODEV;  		goto err;  	} @@ -141,6 +142,8 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,  	}  	req_info->dev = dev; +	if (dev) +		netdev_tracker_alloc(dev, &req_info->dev_tracker, GFP_KERNEL);  	req_info->flags = flags;  	return 0;  } @@ -399,7 +402,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)  		ops->cleanup_data(reply_data);  	genlmsg_end(rskb, reply_payload); -	dev_put(req_info->dev); +	dev_put_track(req_info->dev, &req_info->dev_tracker);  	kfree(reply_data);  	kfree(req_info);  	return genlmsg_reply(rskb, info); @@ -411,7 +414,7 @@ err_cleanup:  	if (ops->cleanup_data)  		ops->cleanup_data(reply_data);  err_dev: -	dev_put(req_info->dev); +	dev_put_track(req_info->dev, &req_info->dev_tracker);  	kfree(reply_data);  	kfree(req_info);  	return ret; @@ -547,7 +550,7 @@ static int ethnl_default_start(struct netlink_callback *cb)  		 * same parser as for non-dump (doit) requests is used, it  		 * would take reference to the device if it finds one  		 */ -		dev_put(req_info->dev); +		dev_put_track(req_info->dev, &req_info->dev_tracker);  		req_info->dev = NULL;  	}  	if (ret < 0) @@ -634,7 +637,6 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,  	if (ret < 0)  		goto err_cleanup;  	reply_len = ret + ethnl_reply_header_size(); -	ret = -ENOMEM;  	skb = genlmsg_new(reply_len, GFP_KERNEL);  	if (!skb)  		goto err_cleanup;  | 
