diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/osd_client.c | 15 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 23 | ||||
-rw-r--r-- | net/core/net_namespace.c | 12 |
3 files changed, 29 insertions, 21 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 6ea2b892f44b..9cb627a4073a 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1144,6 +1144,13 @@ static void handle_osds_timeout(struct work_struct *work) | |||
1144 | round_jiffies_relative(delay)); | 1144 | round_jiffies_relative(delay)); |
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | static void complete_request(struct ceph_osd_request *req) | ||
1148 | { | ||
1149 | if (req->r_safe_callback) | ||
1150 | req->r_safe_callback(req, NULL); | ||
1151 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
1152 | } | ||
1153 | |||
1147 | /* | 1154 | /* |
1148 | * handle osd op reply. either call the callback if it is specified, | 1155 | * handle osd op reply. either call the callback if it is specified, |
1149 | * or do the completion to wake up the waiting thread. | 1156 | * or do the completion to wake up the waiting thread. |
@@ -1226,11 +1233,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
1226 | else | 1233 | else |
1227 | complete_all(&req->r_completion); | 1234 | complete_all(&req->r_completion); |
1228 | 1235 | ||
1229 | if (flags & CEPH_OSD_FLAG_ONDISK) { | 1236 | if (flags & CEPH_OSD_FLAG_ONDISK) |
1230 | if (req->r_safe_callback) | 1237 | complete_request(req); |
1231 | req->r_safe_callback(req, msg); | ||
1232 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
1233 | } | ||
1234 | 1238 | ||
1235 | done: | 1239 | done: |
1236 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); | 1240 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); |
@@ -1732,6 +1736,7 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc, | |||
1732 | __cancel_request(req); | 1736 | __cancel_request(req); |
1733 | __unregister_request(osdc, req); | 1737 | __unregister_request(osdc, req); |
1734 | mutex_unlock(&osdc->request_mutex); | 1738 | mutex_unlock(&osdc->request_mutex); |
1739 | complete_request(req); | ||
1735 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); | 1740 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); |
1736 | return rc; | 1741 | return rc; |
1737 | } | 1742 | } |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 11b98bc2aa8f..33d2a1fba131 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -1179,9 +1179,14 @@ static void remove_queue_kobjects(struct net_device *net) | |||
1179 | #endif | 1179 | #endif |
1180 | } | 1180 | } |
1181 | 1181 | ||
1182 | static const void *net_current_ns(void) | 1182 | static void *net_grab_current_ns(void) |
1183 | { | 1183 | { |
1184 | return current->nsproxy->net_ns; | 1184 | struct net *ns = current->nsproxy->net_ns; |
1185 | #ifdef CONFIG_NET_NS | ||
1186 | if (ns) | ||
1187 | atomic_inc(&ns->passive); | ||
1188 | #endif | ||
1189 | return ns; | ||
1185 | } | 1190 | } |
1186 | 1191 | ||
1187 | static const void *net_initial_ns(void) | 1192 | static const void *net_initial_ns(void) |
@@ -1196,22 +1201,13 @@ static const void *net_netlink_ns(struct sock *sk) | |||
1196 | 1201 | ||
1197 | struct kobj_ns_type_operations net_ns_type_operations = { | 1202 | struct kobj_ns_type_operations net_ns_type_operations = { |
1198 | .type = KOBJ_NS_TYPE_NET, | 1203 | .type = KOBJ_NS_TYPE_NET, |
1199 | .current_ns = net_current_ns, | 1204 | .grab_current_ns = net_grab_current_ns, |
1200 | .netlink_ns = net_netlink_ns, | 1205 | .netlink_ns = net_netlink_ns, |
1201 | .initial_ns = net_initial_ns, | 1206 | .initial_ns = net_initial_ns, |
1207 | .drop_ns = net_drop_ns, | ||
1202 | }; | 1208 | }; |
1203 | EXPORT_SYMBOL_GPL(net_ns_type_operations); | 1209 | EXPORT_SYMBOL_GPL(net_ns_type_operations); |
1204 | 1210 | ||
1205 | static void net_kobj_ns_exit(struct net *net) | ||
1206 | { | ||
1207 | kobj_ns_exit(KOBJ_NS_TYPE_NET, net); | ||
1208 | } | ||
1209 | |||
1210 | static struct pernet_operations kobj_net_ops = { | ||
1211 | .exit = net_kobj_ns_exit, | ||
1212 | }; | ||
1213 | |||
1214 | |||
1215 | #ifdef CONFIG_HOTPLUG | 1211 | #ifdef CONFIG_HOTPLUG |
1216 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) | 1212 | static int netdev_uevent(struct device *d, struct kobj_uevent_env *env) |
1217 | { | 1213 | { |
@@ -1339,6 +1335,5 @@ EXPORT_SYMBOL(netdev_class_remove_file); | |||
1339 | int netdev_kobject_init(void) | 1335 | int netdev_kobject_init(void) |
1340 | { | 1336 | { |
1341 | kobj_ns_type_register(&net_ns_type_operations); | 1337 | kobj_ns_type_register(&net_ns_type_operations); |
1342 | register_pernet_subsys(&kobj_net_ops); | ||
1343 | return class_register(&net_class); | 1338 | return class_register(&net_class); |
1344 | } | 1339 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e41e5110c65c..ea489db1bc23 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -128,6 +128,7 @@ static __net_init int setup_net(struct net *net) | |||
128 | LIST_HEAD(net_exit_list); | 128 | LIST_HEAD(net_exit_list); |
129 | 129 | ||
130 | atomic_set(&net->count, 1); | 130 | atomic_set(&net->count, 1); |
131 | atomic_set(&net->passive, 1); | ||
131 | 132 | ||
132 | #ifdef NETNS_REFCNT_DEBUG | 133 | #ifdef NETNS_REFCNT_DEBUG |
133 | atomic_set(&net->use_count, 0); | 134 | atomic_set(&net->use_count, 0); |
@@ -210,6 +211,13 @@ static void net_free(struct net *net) | |||
210 | kmem_cache_free(net_cachep, net); | 211 | kmem_cache_free(net_cachep, net); |
211 | } | 212 | } |
212 | 213 | ||
214 | void net_drop_ns(void *p) | ||
215 | { | ||
216 | struct net *ns = p; | ||
217 | if (ns && atomic_dec_and_test(&ns->passive)) | ||
218 | net_free(ns); | ||
219 | } | ||
220 | |||
213 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) | 221 | struct net *copy_net_ns(unsigned long flags, struct net *old_net) |
214 | { | 222 | { |
215 | struct net *net; | 223 | struct net *net; |
@@ -230,7 +238,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
230 | } | 238 | } |
231 | mutex_unlock(&net_mutex); | 239 | mutex_unlock(&net_mutex); |
232 | if (rv < 0) { | 240 | if (rv < 0) { |
233 | net_free(net); | 241 | net_drop_ns(net); |
234 | return ERR_PTR(rv); | 242 | return ERR_PTR(rv); |
235 | } | 243 | } |
236 | return net; | 244 | return net; |
@@ -286,7 +294,7 @@ static void cleanup_net(struct work_struct *work) | |||
286 | /* Finally it is safe to free my network namespace structure */ | 294 | /* Finally it is safe to free my network namespace structure */ |
287 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 295 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
288 | list_del_init(&net->exit_list); | 296 | list_del_init(&net->exit_list); |
289 | net_free(net); | 297 | net_drop_ns(net); |
290 | } | 298 | } |
291 | } | 299 | } |
292 | static DECLARE_WORK(net_cleanup_work, cleanup_net); | 300 | static DECLARE_WORK(net_cleanup_work, cleanup_net); |