aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-17 23:54:15 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:08:49 -0400
commit28407630513b1a86133db0ef8b39fabad6c494af (patch)
treee7b44dc7d4690eb9f66dab7042a66fe04af2e61b /net/socket.c
parent5905db5ca0ac9a6d5bfe87f86b87cd1bdec3755a (diff)
take descriptor handling from sock_alloc_file() to callers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/net/socket.c b/net/socket.c
index edc3c4af9085..a14ec19164b6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -346,22 +346,15 @@ static struct file_system_type sock_fs_type = {
346 * but we take care of internal coherence yet. 346 * but we take care of internal coherence yet.
347 */ 347 */
348 348
349static int sock_alloc_file(struct socket *sock, struct file **f, int flags) 349static struct file *sock_alloc_file(struct socket *sock, int flags)
350{ 350{
351 struct qstr name = { .name = "" }; 351 struct qstr name = { .name = "" };
352 struct path path; 352 struct path path;
353 struct file *file; 353 struct file *file;
354 int fd;
355
356 fd = get_unused_fd_flags(flags);
357 if (unlikely(fd < 0))
358 return fd;
359 354
360 path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); 355 path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
361 if (unlikely(!path.dentry)) { 356 if (unlikely(!path.dentry))
362 put_unused_fd(fd); 357 return ERR_PTR(-ENOMEM);
363 return -ENOMEM;
364 }
365 path.mnt = mntget(sock_mnt); 358 path.mnt = mntget(sock_mnt);
366 359
367 d_instantiate(path.dentry, SOCK_INODE(sock)); 360 d_instantiate(path.dentry, SOCK_INODE(sock));
@@ -373,28 +366,31 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
373 /* drop dentry, keep inode */ 366 /* drop dentry, keep inode */
374 ihold(path.dentry->d_inode); 367 ihold(path.dentry->d_inode);
375 path_put(&path); 368 path_put(&path);
376 put_unused_fd(fd); 369 return ERR_PTR(-ENFILE);
377 return -ENFILE;
378 } 370 }
379 371
380 sock->file = file; 372 sock->file = file;
381 file->f_flags = O_RDWR | (flags & O_NONBLOCK); 373 file->f_flags = O_RDWR | (flags & O_NONBLOCK);
382 file->f_pos = 0; 374 file->f_pos = 0;
383 file->private_data = sock; 375 file->private_data = sock;
384 376 return file;
385 *f = file;
386 return fd;
387} 377}
388 378
389int sock_map_fd(struct socket *sock, int flags) 379int sock_map_fd(struct socket *sock, int flags)
390{ 380{
391 struct file *newfile; 381 struct file *newfile;
392 int fd = sock_alloc_file(sock, &newfile, flags); 382 int fd = get_unused_fd_flags(flags);
383 if (unlikely(fd < 0))
384 return fd;
393 385
394 if (likely(fd >= 0)) 386 newfile = sock_alloc_file(sock, flags);
387 if (likely(!IS_ERR(newfile))) {
395 fd_install(fd, newfile); 388 fd_install(fd, newfile);
389 return fd;
390 }
396 391
397 return fd; 392 put_unused_fd(fd);
393 return PTR_ERR(newfile);
398} 394}
399EXPORT_SYMBOL(sock_map_fd); 395EXPORT_SYMBOL(sock_map_fd);
400 396
@@ -1394,17 +1390,32 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
1394 if (err < 0) 1390 if (err < 0)
1395 goto out_release_both; 1391 goto out_release_both;
1396 1392
1397 fd1 = sock_alloc_file(sock1, &newfile1, flags); 1393 fd1 = get_unused_fd_flags(flags);
1398 if (unlikely(fd1 < 0)) { 1394 if (unlikely(fd1 < 0)) {
1399 err = fd1; 1395 err = fd1;
1400 goto out_release_both; 1396 goto out_release_both;
1401 } 1397 }
1402 1398 fd2 = get_unused_fd_flags(flags);
1403 fd2 = sock_alloc_file(sock2, &newfile2, flags);
1404 if (unlikely(fd2 < 0)) { 1399 if (unlikely(fd2 < 0)) {
1405 err = fd2; 1400 err = fd2;
1401 put_unused_fd(fd1);
1402 goto out_release_both;
1403 }
1404
1405 newfile1 = sock_alloc_file(sock1, flags);
1406 if (unlikely(IS_ERR(newfile1))) {
1407 err = PTR_ERR(newfile1);
1408 put_unused_fd(fd1);
1409 put_unused_fd(fd2);
1410 goto out_release_both;
1411 }
1412
1413 newfile2 = sock_alloc_file(sock2, flags);
1414 if (IS_ERR(newfile2)) {
1415 err = PTR_ERR(newfile2);
1406 fput(newfile1); 1416 fput(newfile1);
1407 put_unused_fd(fd1); 1417 put_unused_fd(fd1);
1418 put_unused_fd(fd2);
1408 sock_release(sock2); 1419 sock_release(sock2);
1409 goto out; 1420 goto out;
1410 } 1421 }
@@ -1536,12 +1547,19 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1536 */ 1547 */
1537 __module_get(newsock->ops->owner); 1548 __module_get(newsock->ops->owner);
1538 1549
1539 newfd = sock_alloc_file(newsock, &newfile, flags); 1550 newfd = get_unused_fd_flags(flags);
1540 if (unlikely(newfd < 0)) { 1551 if (unlikely(newfd < 0)) {
1541 err = newfd; 1552 err = newfd;
1542 sock_release(newsock); 1553 sock_release(newsock);
1543 goto out_put; 1554 goto out_put;
1544 } 1555 }
1556 newfile = sock_alloc_file(newsock, flags);
1557 if (unlikely(IS_ERR(newfile))) {
1558 err = PTR_ERR(newfile);
1559 put_unused_fd(newfd);
1560 sock_release(newsock);
1561 goto out_put;
1562 }
1545 1563
1546 err = security_socket_accept(sock, newsock); 1564 err = security_socket_accept(sock, newsock);
1547 if (err) 1565 if (err)