diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2011-04-23 08:45:14 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:49:04 -0500 |
commit | ed439848ca6029c748b537e510a1ed5a506ea123 (patch) | |
tree | a3f832db745f625616e7ea6a956173a86ca8be7b /drivers/block/drbd/drbd_int.h | |
parent | 71932efc1cfccfe1cc8e48b21f8cea5fbbc80e24 (diff) |
drbd: fix setsockopt for user mode linux
We use our own copy of kernel_setsockopt, and did not mess around with
get_fs/set_fs, since we thought we knew we would always be KERNEL_DS
anyways. Apparently not so for at least user mode linux, so put the
set_fs(KERNEL_DS) in there.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 3833d56b8de8..30801922a971 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1484,46 +1484,53 @@ static inline void drbd_flush_workqueue(struct drbd_conf *mdev) | |||
1484 | conn_flush_workqueue(mdev->tconn); | 1484 | conn_flush_workqueue(mdev->tconn); |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to | 1487 | /* Yes, there is kernel_setsockopt, but only since 2.6.18. |
1488 | * mess with get_fs/set_fs, we know we are KERNEL_DS always. */ | 1488 | * So we have our own copy of it here. */ |
1489 | static inline int drbd_setsockopt(struct socket *sock, int level, int optname, | 1489 | static inline int drbd_setsockopt(struct socket *sock, int level, int optname, |
1490 | char __user *optval, int optlen) | 1490 | char *optval, int optlen) |
1491 | { | 1491 | { |
1492 | mm_segment_t oldfs = get_fs(); | ||
1493 | char __user *uoptval; | ||
1492 | int err; | 1494 | int err; |
1495 | |||
1496 | uoptval = (char __user __force *)optval; | ||
1497 | |||
1498 | set_fs(KERNEL_DS); | ||
1493 | if (level == SOL_SOCKET) | 1499 | if (level == SOL_SOCKET) |
1494 | err = sock_setsockopt(sock, level, optname, optval, optlen); | 1500 | err = sock_setsockopt(sock, level, optname, uoptval, optlen); |
1495 | else | 1501 | else |
1496 | err = sock->ops->setsockopt(sock, level, optname, optval, | 1502 | err = sock->ops->setsockopt(sock, level, optname, uoptval, |
1497 | optlen); | 1503 | optlen); |
1504 | set_fs(oldfs); | ||
1498 | return err; | 1505 | return err; |
1499 | } | 1506 | } |
1500 | 1507 | ||
1501 | static inline void drbd_tcp_cork(struct socket *sock) | 1508 | static inline void drbd_tcp_cork(struct socket *sock) |
1502 | { | 1509 | { |
1503 | int __user val = 1; | 1510 | int val = 1; |
1504 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, | 1511 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, |
1505 | (char __user *)&val, sizeof(val)); | 1512 | (char*)&val, sizeof(val)); |
1506 | } | 1513 | } |
1507 | 1514 | ||
1508 | static inline void drbd_tcp_uncork(struct socket *sock) | 1515 | static inline void drbd_tcp_uncork(struct socket *sock) |
1509 | { | 1516 | { |
1510 | int __user val = 0; | 1517 | int val = 0; |
1511 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, | 1518 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, |
1512 | (char __user *)&val, sizeof(val)); | 1519 | (char*)&val, sizeof(val)); |
1513 | } | 1520 | } |
1514 | 1521 | ||
1515 | static inline void drbd_tcp_nodelay(struct socket *sock) | 1522 | static inline void drbd_tcp_nodelay(struct socket *sock) |
1516 | { | 1523 | { |
1517 | int __user val = 1; | 1524 | int val = 1; |
1518 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY, | 1525 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY, |
1519 | (char __user *)&val, sizeof(val)); | 1526 | (char*)&val, sizeof(val)); |
1520 | } | 1527 | } |
1521 | 1528 | ||
1522 | static inline void drbd_tcp_quickack(struct socket *sock) | 1529 | static inline void drbd_tcp_quickack(struct socket *sock) |
1523 | { | 1530 | { |
1524 | int __user val = 2; | 1531 | int val = 2; |
1525 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, | 1532 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, |
1526 | (char __user *)&val, sizeof(val)); | 1533 | (char*)&val, sizeof(val)); |
1527 | } | 1534 | } |
1528 | 1535 | ||
1529 | void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); | 1536 | void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); |