NFS: Kill the obsolete NFS_PARANOIA
[powerpc.git] / net / netfilter / nf_sockopt.c
index 61a833a..8b8ece7 100644 (file)
@@ -1,9 +1,9 @@
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
+#include <linux/mutex.h>
 #include <net/sock.h>
 
 #include "nf_internals.h"
@@ -11,7 +11,7 @@
 /* Sockopts only registered and called from user context, so
    net locking would be overkill.  Also, [gs]etsockopt calls may
    sleep. */
-static DECLARE_MUTEX(nf_sockopt_mutex);
+static DEFINE_MUTEX(nf_sockopt_mutex);
 static LIST_HEAD(nf_sockopts);
 
 /* Do exclusive ranges overlap? */
@@ -26,19 +26,19 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg)
        struct list_head *i;
        int ret = 0;
 
-       if (down_interruptible(&nf_sockopt_mutex) != 0)
+       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
                return -EINTR;
 
        list_for_each(i, &nf_sockopts) {
                struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i;
                if (ops->pf == reg->pf
-                   && (overlap(ops->set_optmin, ops->set_optmax, 
+                   && (overlap(ops->set_optmin, ops->set_optmax,
                                reg->set_optmin, reg->set_optmax)
-                       || overlap(ops->get_optmin, ops->get_optmax, 
+                       || overlap(ops->get_optmin, ops->get_optmax,
                                   reg->get_optmin, reg->get_optmax))) {
                        NFDEBUG("nf_sock overlap: %u-%u/%u-%u v %u-%u/%u-%u\n",
-                               ops->set_optmin, ops->set_optmax, 
-                               ops->get_optmin, ops->get_optmax, 
+                               ops->set_optmin, ops->set_optmax,
+                               ops->get_optmin, ops->get_optmax,
                                reg->set_optmin, reg->set_optmax,
                                reg->get_optmin, reg->get_optmax);
                        ret = -EBUSY;
@@ -48,7 +48,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg)
 
        list_add(&reg->list, &nf_sockopts);
 out:
-       up(&nf_sockopt_mutex);
+       mutex_unlock(&nf_sockopt_mutex);
        return ret;
 }
 EXPORT_SYMBOL(nf_register_sockopt);
@@ -57,30 +57,30 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
 {
        /* No point being interruptible: we're probably in cleanup_module() */
  restart:
-       down(&nf_sockopt_mutex);
+       mutex_lock(&nf_sockopt_mutex);
        if (reg->use != 0) {
                /* To be woken by nf_sockopt call... */
                /* FIXME: Stuart Young's name appears gratuitously. */
                set_current_state(TASK_UNINTERRUPTIBLE);
                reg->cleanup_task = current;
-               up(&nf_sockopt_mutex);
+               mutex_unlock(&nf_sockopt_mutex);
                schedule();
                goto restart;
        }
        list_del(&reg->list);
-       up(&nf_sockopt_mutex);
+       mutex_unlock(&nf_sockopt_mutex);
 }
 EXPORT_SYMBOL(nf_unregister_sockopt);
 
 /* Call get/setsockopt() */
-static int nf_sockopt(struct sock *sk, int pf, int val, 
+static int nf_sockopt(struct sock *sk, int pf, int val,
                      char __user *opt, int *len, int get)
 {
        struct list_head *i;
        struct nf_sockopt_ops *ops;
        int ret;
 
-       if (down_interruptible(&nf_sockopt_mutex) != 0)
+       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
                return -EINTR;
 
        list_for_each(i, &nf_sockopts) {
@@ -90,7 +90,7 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
                                if (val >= ops->get_optmin
                                    && val < ops->get_optmax) {
                                        ops->use++;
-                                       up(&nf_sockopt_mutex);
+                                       mutex_unlock(&nf_sockopt_mutex);
                                        ret = ops->get(sk, val, opt, len);
                                        goto out;
                                }
@@ -98,22 +98,22 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
                                if (val >= ops->set_optmin
                                    && val < ops->set_optmax) {
                                        ops->use++;
-                                       up(&nf_sockopt_mutex);
+                                       mutex_unlock(&nf_sockopt_mutex);
                                        ret = ops->set(sk, val, opt, *len);
                                        goto out;
                                }
                        }
                }
        }
-       up(&nf_sockopt_mutex);
+       mutex_unlock(&nf_sockopt_mutex);
        return -ENOPROTOOPT;
-       
+
  out:
-       down(&nf_sockopt_mutex);
+       mutex_lock(&nf_sockopt_mutex);
        ops->use--;
        if (ops->cleanup_task)
                wake_up_process(ops->cleanup_task);
-       up(&nf_sockopt_mutex);
+       mutex_unlock(&nf_sockopt_mutex);
        return ret;
 }
 
@@ -130,3 +130,72 @@ int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len)
 }
 EXPORT_SYMBOL(nf_getsockopt);
 
+#ifdef CONFIG_COMPAT
+static int compat_nf_sockopt(struct sock *sk, int pf, int val,
+                            char __user *opt, int *len, int get)
+{
+       struct list_head *i;
+       struct nf_sockopt_ops *ops;
+       int ret;
+
+       if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
+               return -EINTR;
+
+       list_for_each(i, &nf_sockopts) {
+               ops = (struct nf_sockopt_ops *)i;
+               if (ops->pf == pf) {
+                       if (get) {
+                               if (val >= ops->get_optmin
+                                   && val < ops->get_optmax) {
+                                       ops->use++;
+                                       mutex_unlock(&nf_sockopt_mutex);
+                                       if (ops->compat_get)
+                                               ret = ops->compat_get(sk,
+                                                       val, opt, len);
+                                       else
+                                               ret = ops->get(sk,
+                                                       val, opt, len);
+                                       goto out;
+                               }
+                       } else {
+                               if (val >= ops->set_optmin
+                                   && val < ops->set_optmax) {
+                                       ops->use++;
+                                       mutex_unlock(&nf_sockopt_mutex);
+                                       if (ops->compat_set)
+                                               ret = ops->compat_set(sk,
+                                                       val, opt, *len);
+                                       else
+                                               ret = ops->set(sk,
+                                                       val, opt, *len);
+                                       goto out;
+                               }
+                       }
+               }
+       }
+       mutex_unlock(&nf_sockopt_mutex);
+       return -ENOPROTOOPT;
+
+ out:
+       mutex_lock(&nf_sockopt_mutex);
+       ops->use--;
+       if (ops->cleanup_task)
+               wake_up_process(ops->cleanup_task);
+       mutex_unlock(&nf_sockopt_mutex);
+       return ret;
+}
+
+int compat_nf_setsockopt(struct sock *sk, int pf,
+               int val, char __user *opt, int len)
+{
+       return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
+}
+EXPORT_SYMBOL(compat_nf_setsockopt);
+
+int compat_nf_getsockopt(struct sock *sk, int pf,
+               int val, char __user *opt, int *len)
+{
+       return compat_nf_sockopt(sk, pf, val, opt, len, 1);
+}
+EXPORT_SYMBOL(compat_nf_getsockopt);
+#endif