|
@@ -1263,41 +1263,35 @@ out:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-DEFINE_SPINLOCK(use_gssp_lock);
|
|
|
|
-
|
|
|
|
-static bool use_gss_proxy(struct net *net)
|
|
|
|
|
|
+/*
|
|
|
|
+ * Try to set the sn->use_gss_proxy variable to a new value. We only allow
|
|
|
|
+ * it to be changed if it's currently undefined (-1). If it's any other value
|
|
|
|
+ * then return -EBUSY unless the type wouldn't have changed anyway.
|
|
|
|
+ */
|
|
|
|
+static int set_gss_proxy(struct net *net, int type)
|
|
{
|
|
{
|
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
|
|
|
+ int ret;
|
|
|
|
|
|
- if (sn->use_gss_proxy != -1)
|
|
|
|
- return sn->use_gss_proxy;
|
|
|
|
- spin_lock(&use_gssp_lock);
|
|
|
|
- /*
|
|
|
|
- * If you wanted gss-proxy, you should have said so before
|
|
|
|
- * starting to accept requests:
|
|
|
|
- */
|
|
|
|
- sn->use_gss_proxy = 0;
|
|
|
|
- spin_unlock(&use_gssp_lock);
|
|
|
|
|
|
+ WARN_ON_ONCE(type != 0 && type != 1);
|
|
|
|
+ ret = cmpxchg(&sn->use_gss_proxy, -1, type);
|
|
|
|
+ if (ret != -1 && ret != type)
|
|
|
|
+ return -EBUSY;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_PROC_FS
|
|
|
|
-
|
|
|
|
-static int set_gss_proxy(struct net *net, int type)
|
|
|
|
|
|
+static bool use_gss_proxy(struct net *net)
|
|
{
|
|
{
|
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
|
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
|
- int ret = 0;
|
|
|
|
|
|
|
|
- WARN_ON_ONCE(type != 0 && type != 1);
|
|
|
|
- spin_lock(&use_gssp_lock);
|
|
|
|
- if (sn->use_gss_proxy == -1 || sn->use_gss_proxy == type)
|
|
|
|
- sn->use_gss_proxy = type;
|
|
|
|
- else
|
|
|
|
- ret = -EBUSY;
|
|
|
|
- spin_unlock(&use_gssp_lock);
|
|
|
|
- return ret;
|
|
|
|
|
|
+ /* If use_gss_proxy is still undefined, then try to disable it */
|
|
|
|
+ if (sn->use_gss_proxy == -1)
|
|
|
|
+ set_gss_proxy(net, 0);
|
|
|
|
+ return sn->use_gss_proxy;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
|
+
|
|
static ssize_t write_gssp(struct file *file, const char __user *buf,
|
|
static ssize_t write_gssp(struct file *file, const char __user *buf,
|
|
size_t count, loff_t *ppos)
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
{
|