aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-mips/socket.h7
-rw-r--r--include/linux/net.h9
-rw-r--r--net/9p/trans_fd.c2
-rw-r--r--net/sctp/socket.c2
-rw-r--r--net/socket.c28
5 files changed, 37 insertions, 11 deletions
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h
index 63f60254d308..facc2d7a87ca 100644
--- a/include/asm-mips/socket.h
+++ b/include/asm-mips/socket.h
@@ -102,6 +102,13 @@ enum sock_type {
102}; 102};
103 103
104#define SOCK_MAX (SOCK_PACKET + 1) 104#define SOCK_MAX (SOCK_PACKET + 1)
105/* Mask which covers at least up to SOCK_MASK-1. The
106 * * remaining bits are used as flags. */
107#define SOCK_TYPE_MASK 0xf
108
109/* Flags for socket, socketpair, paccept */
110#define SOCK_CLOEXEC O_CLOEXEC
111#define SOCK_NONBLOCK O_NONBLOCK
105 112
106#define ARCH_HAS_SOCKET_TYPES 1 113#define ARCH_HAS_SOCKET_TYPES 1
107 114
diff --git a/include/linux/net.h b/include/linux/net.h
index 150a48c68d52..8b5383c45b45 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -20,6 +20,7 @@
20 20
21#include <linux/wait.h> 21#include <linux/wait.h>
22#include <linux/socket.h> 22#include <linux/socket.h>
23#include <linux/fcntl.h> /* For O_CLOEXEC */
23#include <asm/socket.h> 24#include <asm/socket.h>
24 25
25struct poll_table_struct; 26struct poll_table_struct;
@@ -94,6 +95,12 @@ enum sock_type {
94}; 95};
95 96
96#define SOCK_MAX (SOCK_PACKET + 1) 97#define SOCK_MAX (SOCK_PACKET + 1)
98/* Mask which covers at least up to SOCK_MASK-1. The
99 * remaining bits are used as flags. */
100#define SOCK_TYPE_MASK 0xf
101
102/* Flags for socket, socketpair, paccept */
103#define SOCK_CLOEXEC O_CLOEXEC
97 104
98#endif /* ARCH_HAS_SOCKET_TYPES */ 105#endif /* ARCH_HAS_SOCKET_TYPES */
99 106
@@ -208,7 +215,7 @@ extern int sock_sendmsg(struct socket *sock, struct msghdr *msg,
208 size_t len); 215 size_t len);
209extern int sock_recvmsg(struct socket *sock, struct msghdr *msg, 216extern int sock_recvmsg(struct socket *sock, struct msghdr *msg,
210 size_t size, int flags); 217 size_t size, int flags);
211extern int sock_map_fd(struct socket *sock); 218extern int sock_map_fd(struct socket *sock, int flags);
212extern struct socket *sockfd_lookup(int fd, int *err); 219extern struct socket *sockfd_lookup(int fd, int *err);
213#define sockfd_put(sock) fput(sock->file) 220#define sockfd_put(sock) fput(sock->file)
214extern int net_ratelimit(void); 221extern int net_ratelimit(void);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 4507f744f44e..cdf137af7adc 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -1285,7 +1285,7 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
1285 int fd, ret; 1285 int fd, ret;
1286 1286
1287 csocket->sk->sk_allocation = GFP_NOIO; 1287 csocket->sk->sk_allocation = GFP_NOIO;
1288 fd = sock_map_fd(csocket); 1288 fd = sock_map_fd(csocket, 0);
1289 if (fd < 0) { 1289 if (fd < 0) {
1290 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); 1290 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
1291 return fd; 1291 return fd;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 79bece16aede..dbb79adf8f3c 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3910,7 +3910,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
3910 goto out; 3910 goto out;
3911 3911
3912 /* Map the socket to an unused fd that can be returned to the user. */ 3912 /* Map the socket to an unused fd that can be returned to the user. */
3913 retval = sock_map_fd(newsock); 3913 retval = sock_map_fd(newsock, 0);
3914 if (retval < 0) { 3914 if (retval < 0) {
3915 sock_release(newsock); 3915 sock_release(newsock);
3916 goto out; 3916 goto out;
diff --git a/net/socket.c b/net/socket.c
index 1ba57d888981..64601f900352 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -349,11 +349,11 @@ static struct dentry_operations sockfs_dentry_operations = {
349 * but we take care of internal coherence yet. 349 * but we take care of internal coherence yet.
350 */ 350 */
351 351
352static int sock_alloc_fd(struct file **filep) 352static int sock_alloc_fd(struct file **filep, int flags)
353{ 353{
354 int fd; 354 int fd;
355 355
356 fd = get_unused_fd(); 356 fd = get_unused_fd_flags(flags);
357 if (likely(fd >= 0)) { 357 if (likely(fd >= 0)) {
358 struct file *file = get_empty_filp(); 358 struct file *file = get_empty_filp();
359 359
@@ -396,10 +396,10 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
396 return 0; 396 return 0;
397} 397}
398 398
399int sock_map_fd(struct socket *sock) 399int sock_map_fd(struct socket *sock, int flags)
400{ 400{
401 struct file *newfile; 401 struct file *newfile;
402 int fd = sock_alloc_fd(&newfile); 402 int fd = sock_alloc_fd(&newfile, flags);
403 403
404 if (likely(fd >= 0)) { 404 if (likely(fd >= 0)) {
405 int err = sock_attach_fd(sock, newfile); 405 int err = sock_attach_fd(sock, newfile);
@@ -1218,12 +1218,18 @@ asmlinkage long sys_socket(int family, int type, int protocol)
1218{ 1218{
1219 int retval; 1219 int retval;
1220 struct socket *sock; 1220 struct socket *sock;
1221 int flags;
1222
1223 flags = type & ~SOCK_TYPE_MASK;
1224 if (flags & ~SOCK_CLOEXEC)
1225 return -EINVAL;
1226 type &= SOCK_TYPE_MASK;
1221 1227
1222 retval = sock_create(family, type, protocol, &sock); 1228 retval = sock_create(family, type, protocol, &sock);
1223 if (retval < 0) 1229 if (retval < 0)
1224 goto out; 1230 goto out;
1225 1231
1226 retval = sock_map_fd(sock); 1232 retval = sock_map_fd(sock, flags & O_CLOEXEC);
1227 if (retval < 0) 1233 if (retval < 0)
1228 goto out_release; 1234 goto out_release;
1229 1235
@@ -1246,6 +1252,12 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1246 struct socket *sock1, *sock2; 1252 struct socket *sock1, *sock2;
1247 int fd1, fd2, err; 1253 int fd1, fd2, err;
1248 struct file *newfile1, *newfile2; 1254 struct file *newfile1, *newfile2;
1255 int flags;
1256
1257 flags = type & ~SOCK_TYPE_MASK;
1258 if (flags & ~SOCK_CLOEXEC)
1259 return -EINVAL;
1260 type &= SOCK_TYPE_MASK;
1249 1261
1250 /* 1262 /*
1251 * Obtain the first socket and check if the underlying protocol 1263 * Obtain the first socket and check if the underlying protocol
@@ -1264,13 +1276,13 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1264 if (err < 0) 1276 if (err < 0)
1265 goto out_release_both; 1277 goto out_release_both;
1266 1278
1267 fd1 = sock_alloc_fd(&newfile1); 1279 fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC);
1268 if (unlikely(fd1 < 0)) { 1280 if (unlikely(fd1 < 0)) {
1269 err = fd1; 1281 err = fd1;
1270 goto out_release_both; 1282 goto out_release_both;
1271 } 1283 }
1272 1284
1273 fd2 = sock_alloc_fd(&newfile2); 1285 fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC);
1274 if (unlikely(fd2 < 0)) { 1286 if (unlikely(fd2 < 0)) {
1275 err = fd2; 1287 err = fd2;
1276 put_filp(newfile1); 1288 put_filp(newfile1);
@@ -1426,7 +1438,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
1426 */ 1438 */
1427 __module_get(newsock->ops->owner); 1439 __module_get(newsock->ops->owner);
1428 1440
1429 newfd = sock_alloc_fd(&newfile); 1441 newfd = sock_alloc_fd(&newfile, 0);
1430 if (unlikely(newfd < 0)) { 1442 if (unlikely(newfd < 0)) {
1431 err = newfd; 1443 err = newfd;
1432 sock_release(newsock); 1444 sock_release(newsock);