aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/net/socket.c b/net/socket.c
index 088fb3fd45e0..ac2219f90d5d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = {
156 */ 156 */
157 157
158static DEFINE_SPINLOCK(net_family_lock); 158static DEFINE_SPINLOCK(net_family_lock);
159static const struct net_proto_family *net_families[NPROTO] __read_mostly; 159static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
160 160
161/* 161/*
162 * Statistics counters of the socket lists 162 * Statistics counters of the socket lists
@@ -262,6 +262,7 @@ static struct inode *sock_alloc_inode(struct super_block *sb)
262} 262}
263 263
264 264
265
265static void wq_free_rcu(struct rcu_head *head) 266static void wq_free_rcu(struct rcu_head *head)
266{ 267{
267 struct socket_wq *wq = container_of(head, struct socket_wq, rcu); 268 struct socket_wq *wq = container_of(head, struct socket_wq, rcu);
@@ -305,20 +306,6 @@ static const struct super_operations sockfs_ops = {
305 .statfs = simple_statfs, 306 .statfs = simple_statfs,
306}; 307};
307 308
308static struct dentry *sockfs_mount(struct file_system_type *fs_type,
309 int flags, const char *dev_name, void *data)
310{
311 return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
312}
313
314static struct vfsmount *sock_mnt __read_mostly;
315
316static struct file_system_type sock_fs_type = {
317 .name = "sockfs",
318 .mount = sockfs_mount,
319 .kill_sb = kill_anon_super,
320};
321
322/* 309/*
323 * sockfs_dname() is called from d_path(). 310 * sockfs_dname() is called from d_path().
324 */ 311 */
@@ -332,6 +319,21 @@ static const struct dentry_operations sockfs_dentry_operations = {
332 .d_dname = sockfs_dname, 319 .d_dname = sockfs_dname,
333}; 320};
334 321
322static struct dentry *sockfs_mount(struct file_system_type *fs_type,
323 int flags, const char *dev_name, void *data)
324{
325 return mount_pseudo(fs_type, "socket:", &sockfs_ops,
326 &sockfs_dentry_operations, SOCKFS_MAGIC);
327}
328
329static struct vfsmount *sock_mnt __read_mostly;
330
331static struct file_system_type sock_fs_type = {
332 .name = "sockfs",
333 .mount = sockfs_mount,
334 .kill_sb = kill_anon_super,
335};
336
335/* 337/*
336 * Obtains the first available file descriptor and sets it up for use. 338 * Obtains the first available file descriptor and sets it up for use.
337 * 339 *
@@ -360,14 +362,13 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
360 if (unlikely(fd < 0)) 362 if (unlikely(fd < 0))
361 return fd; 363 return fd;
362 364
363 path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 365 path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
364 if (unlikely(!path.dentry)) { 366 if (unlikely(!path.dentry)) {
365 put_unused_fd(fd); 367 put_unused_fd(fd);
366 return -ENOMEM; 368 return -ENOMEM;
367 } 369 }
368 path.mnt = mntget(sock_mnt); 370 path.mnt = mntget(sock_mnt);
369 371
370 path.dentry->d_op = &sockfs_dentry_operations;
371 d_instantiate(path.dentry, SOCK_INODE(sock)); 372 d_instantiate(path.dentry, SOCK_INODE(sock));
372 SOCK_INODE(sock)->i_fop = &socket_file_ops; 373 SOCK_INODE(sock)->i_fop = &socket_file_ops;
373 374
@@ -1215,7 +1216,7 @@ int __sock_create(struct net *net, int family, int type, int protocol,
1215 * requested real, full-featured networking support upon configuration. 1216 * requested real, full-featured networking support upon configuration.
1216 * Otherwise module support will break! 1217 * Otherwise module support will break!
1217 */ 1218 */
1218 if (net_families[family] == NULL) 1219 if (rcu_access_pointer(net_families[family]) == NULL)
1219 request_module("net-pf-%d", family); 1220 request_module("net-pf-%d", family);
1220#endif 1221#endif
1221 1222
@@ -2347,10 +2348,11 @@ int sock_register(const struct net_proto_family *ops)
2347 } 2348 }
2348 2349
2349 spin_lock(&net_family_lock); 2350 spin_lock(&net_family_lock);
2350 if (net_families[ops->family]) 2351 if (rcu_dereference_protected(net_families[ops->family],
2352 lockdep_is_held(&net_family_lock)))
2351 err = -EEXIST; 2353 err = -EEXIST;
2352 else { 2354 else {
2353 net_families[ops->family] = ops; 2355 rcu_assign_pointer(net_families[ops->family], ops);
2354 err = 0; 2356 err = 0;
2355 } 2357 }
2356 spin_unlock(&net_family_lock); 2358 spin_unlock(&net_family_lock);
@@ -2378,7 +2380,7 @@ void sock_unregister(int family)
2378 BUG_ON(family < 0 || family >= NPROTO); 2380 BUG_ON(family < 0 || family >= NPROTO);
2379 2381
2380 spin_lock(&net_family_lock); 2382 spin_lock(&net_family_lock);
2381 net_families[family] = NULL; 2383 rcu_assign_pointer(net_families[family], NULL);
2382 spin_unlock(&net_family_lock); 2384 spin_unlock(&net_family_lock);
2383 2385
2384 synchronize_rcu(); 2386 synchronize_rcu();
@@ -2389,6 +2391,8 @@ EXPORT_SYMBOL(sock_unregister);
2389 2391
2390static int __init sock_init(void) 2392static int __init sock_init(void)
2391{ 2393{
2394 int err;
2395
2392 /* 2396 /*
2393 * Initialize sock SLAB cache. 2397 * Initialize sock SLAB cache.
2394 */ 2398 */
@@ -2405,8 +2409,15 @@ static int __init sock_init(void)
2405 */ 2409 */
2406 2410
2407 init_inodecache(); 2411 init_inodecache();
2408 register_filesystem(&sock_fs_type); 2412
2413 err = register_filesystem(&sock_fs_type);
2414 if (err)
2415 goto out_fs;
2409 sock_mnt = kern_mount(&sock_fs_type); 2416 sock_mnt = kern_mount(&sock_fs_type);
2417 if (IS_ERR(sock_mnt)) {
2418 err = PTR_ERR(sock_mnt);
2419 goto out_mount;
2420 }
2410 2421
2411 /* The real protocol initialization is performed in later initcalls. 2422 /* The real protocol initialization is performed in later initcalls.
2412 */ 2423 */
@@ -2419,7 +2430,13 @@ static int __init sock_init(void)
2419 skb_timestamping_init(); 2430 skb_timestamping_init();
2420#endif 2431#endif
2421 2432
2422 return 0; 2433out:
2434 return err;
2435
2436out_mount:
2437 unregister_filesystem(&sock_fs_type);
2438out_fs:
2439 goto out;
2423} 2440}
2424 2441
2425core_initcall(sock_init); /* early initcall */ 2442core_initcall(sock_init); /* early initcall */