aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_int.h
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-04-23 08:45:14 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:49:04 -0500
commited439848ca6029c748b537e510a1ed5a506ea123 (patch)
treea3f832db745f625616e7ea6a956173a86ca8be7b /drivers/block/drbd/drbd_int.h
parent71932efc1cfccfe1cc8e48b21f8cea5fbbc80e24 (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.h33
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. */
1489static inline int drbd_setsockopt(struct socket *sock, int level, int optname, 1489static 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
1501static inline void drbd_tcp_cork(struct socket *sock) 1508static 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
1508static inline void drbd_tcp_uncork(struct socket *sock) 1515static 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
1515static inline void drbd_tcp_nodelay(struct socket *sock) 1522static 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
1522static inline void drbd_tcp_quickack(struct socket *sock) 1529static 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
1529void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); 1536void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo);