diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-08-05 11:59:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-16 12:16:41 -0500 |
commit | 7cbe66b6b53b6615f1033bd5b3dbad8162886373 (patch) | |
tree | d7e0a229155fec3e3841d9d3272d0ae1a3a393eb /net/socket.c | |
parent | 198de4d7ac3a0f1351c6377ff657950457ed0038 (diff) |
merge sock_alloc_fd/sock_attach_fd into a new helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 80 |
1 files changed, 23 insertions, 57 deletions
diff --git a/net/socket.c b/net/socket.c index bf538bea8fbf..dbb3802a7645 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -355,32 +355,30 @@ static const struct dentry_operations sockfs_dentry_operations = { | |||
355 | * but we take care of internal coherence yet. | 355 | * but we take care of internal coherence yet. |
356 | */ | 356 | */ |
357 | 357 | ||
358 | static int sock_alloc_fd(struct file **filep, int flags) | 358 | static int sock_alloc_file(struct socket *sock, struct file **f, int flags) |
359 | { | 359 | { |
360 | struct qstr name = { .name = "" }; | ||
361 | struct dentry *dentry; | ||
362 | struct file *file; | ||
360 | int fd; | 363 | int fd; |
361 | 364 | ||
362 | fd = get_unused_fd_flags(flags); | 365 | fd = get_unused_fd_flags(flags); |
363 | if (likely(fd >= 0)) { | 366 | if (unlikely(fd < 0)) |
364 | struct file *file = get_empty_filp(); | 367 | return fd; |
365 | 368 | ||
366 | *filep = file; | 369 | file = get_empty_filp(); |
367 | if (unlikely(!file)) { | ||
368 | put_unused_fd(fd); | ||
369 | return -ENFILE; | ||
370 | } | ||
371 | } else | ||
372 | *filep = NULL; | ||
373 | return fd; | ||
374 | } | ||
375 | 370 | ||
376 | static int sock_attach_fd(struct socket *sock, struct file *file, int flags) | 371 | if (unlikely(!file)) { |
377 | { | 372 | put_unused_fd(fd); |
378 | struct dentry *dentry; | 373 | return -ENFILE; |
379 | struct qstr name = { .name = "" }; | 374 | } |
380 | 375 | ||
381 | dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); | 376 | dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); |
382 | if (unlikely(!dentry)) | 377 | if (unlikely(!dentry)) { |
378 | put_filp(file); | ||
379 | put_unused_fd(fd); | ||
383 | return -ENOMEM; | 380 | return -ENOMEM; |
381 | } | ||
384 | 382 | ||
385 | dentry->d_op = &sockfs_dentry_operations; | 383 | dentry->d_op = &sockfs_dentry_operations; |
386 | /* | 384 | /* |
@@ -399,24 +397,18 @@ static int sock_attach_fd(struct socket *sock, struct file *file, int flags) | |||
399 | file->f_pos = 0; | 397 | file->f_pos = 0; |
400 | file->private_data = sock; | 398 | file->private_data = sock; |
401 | 399 | ||
402 | return 0; | 400 | *f = file; |
401 | return fd; | ||
403 | } | 402 | } |
404 | 403 | ||
405 | int sock_map_fd(struct socket *sock, int flags) | 404 | int sock_map_fd(struct socket *sock, int flags) |
406 | { | 405 | { |
407 | struct file *newfile; | 406 | struct file *newfile; |
408 | int fd = sock_alloc_fd(&newfile, flags); | 407 | int fd = sock_alloc_file(sock, &newfile, flags); |
409 | |||
410 | if (likely(fd >= 0)) { | ||
411 | int err = sock_attach_fd(sock, newfile, flags); | ||
412 | 408 | ||
413 | if (unlikely(err < 0)) { | 409 | if (likely(fd >= 0)) |
414 | put_filp(newfile); | ||
415 | put_unused_fd(fd); | ||
416 | return err; | ||
417 | } | ||
418 | fd_install(fd, newfile); | 410 | fd_install(fd, newfile); |
419 | } | 411 | |
420 | return fd; | 412 | return fd; |
421 | } | 413 | } |
422 | 414 | ||
@@ -1390,20 +1382,13 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, | |||
1390 | if (err < 0) | 1382 | if (err < 0) |
1391 | goto out_release_both; | 1383 | goto out_release_both; |
1392 | 1384 | ||
1393 | fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC); | 1385 | fd1 = sock_alloc_file(sock1, &newfile1, flags); |
1394 | if (unlikely(fd1 < 0)) { | 1386 | if (unlikely(fd1 < 0)) { |
1395 | err = fd1; | 1387 | err = fd1; |
1396 | goto out_release_both; | 1388 | goto out_release_both; |
1397 | } | 1389 | } |
1398 | 1390 | ||
1399 | err = sock_attach_fd(sock1, newfile1, flags & O_NONBLOCK); | 1391 | fd2 = sock_alloc_file(sock2, &newfile2, flags); |
1400 | if (unlikely(err < 0)) { | ||
1401 | put_filp(newfile1); | ||
1402 | put_unused_fd(fd1); | ||
1403 | goto out_release_both; | ||
1404 | } | ||
1405 | |||
1406 | fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC); | ||
1407 | if (unlikely(fd2 < 0)) { | 1392 | if (unlikely(fd2 < 0)) { |
1408 | err = fd2; | 1393 | err = fd2; |
1409 | fput(newfile1); | 1394 | fput(newfile1); |
@@ -1412,16 +1397,6 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, | |||
1412 | goto out; | 1397 | goto out; |
1413 | } | 1398 | } |
1414 | 1399 | ||
1415 | err = sock_attach_fd(sock2, newfile2, flags & O_NONBLOCK); | ||
1416 | if (unlikely(err < 0)) { | ||
1417 | put_filp(newfile2); | ||
1418 | put_unused_fd(fd2); | ||
1419 | fput(newfile1); | ||
1420 | put_unused_fd(fd1); | ||
1421 | sock_release(sock2); | ||
1422 | goto out; | ||
1423 | } | ||
1424 | |||
1425 | audit_fd_pair(fd1, fd2); | 1400 | audit_fd_pair(fd1, fd2); |
1426 | fd_install(fd1, newfile1); | 1401 | fd_install(fd1, newfile1); |
1427 | fd_install(fd2, newfile2); | 1402 | fd_install(fd2, newfile2); |
@@ -1548,17 +1523,13 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, | |||
1548 | */ | 1523 | */ |
1549 | __module_get(newsock->ops->owner); | 1524 | __module_get(newsock->ops->owner); |
1550 | 1525 | ||
1551 | newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC); | 1526 | newfd = sock_alloc_file(newsock, &newfile, flags); |
1552 | if (unlikely(newfd < 0)) { | 1527 | if (unlikely(newfd < 0)) { |
1553 | err = newfd; | 1528 | err = newfd; |
1554 | sock_release(newsock); | 1529 | sock_release(newsock); |
1555 | goto out_put; | 1530 | goto out_put; |
1556 | } | 1531 | } |
1557 | 1532 | ||
1558 | err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK); | ||
1559 | if (err < 0) | ||
1560 | goto out_fd_simple; | ||
1561 | |||
1562 | err = security_socket_accept(sock, newsock); | 1533 | err = security_socket_accept(sock, newsock); |
1563 | if (err) | 1534 | if (err) |
1564 | goto out_fd; | 1535 | goto out_fd; |
@@ -1588,11 +1559,6 @@ out_put: | |||
1588 | fput_light(sock->file, fput_needed); | 1559 | fput_light(sock->file, fput_needed); |
1589 | out: | 1560 | out: |
1590 | return err; | 1561 | return err; |
1591 | out_fd_simple: | ||
1592 | sock_release(newsock); | ||
1593 | put_filp(newfile); | ||
1594 | put_unused_fd(newfd); | ||
1595 | goto out_put; | ||
1596 | out_fd: | 1562 | out_fd: |
1597 | fput(newfile); | 1563 | fput(newfile); |
1598 | put_unused_fd(newfd); | 1564 | put_unused_fd(newfd); |