aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 13:18:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 13:18:43 -0500
commitd9894c228b11273e720bb63ba120d1d326fe9d94 (patch)
treec9b91b716f281f5accf8860dfadb1ac95abf0090 /net
parentdfa19426160046770b3a38985042df9c9760a25a (diff)
parented47b062ce9546fbe1eebf9da6937df4c5035372 (diff)
Merge branch 'for-3.14' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: - Handle some loose ends from the vfs read delegation support. (For example nfsd can stop breaking leases on its own in a fewer places where it can now depend on the vfs to.) - Make life a little easier for NFSv4-only configurations (thanks to Kinglong Mee). - Fix some gss-proxy problems (thanks Jeff Layton). - miscellaneous bug fixes and cleanup * 'for-3.14' of git://linux-nfs.org/~bfields/linux: (38 commits) nfsd: consider CLAIM_FH when handing out delegation nfsd4: fix delegation-unlink/rename race nfsd4: delay setting current_fh in open nfsd4: minor nfs4_setlease cleanup gss_krb5: use lcm from kernel lib nfsd4: decrease nfsd4_encode_fattr stack usage nfsd: fix encode_entryplus_baggage stack usage nfsd4: simplify xdr encoding of nfsv4 names nfsd4: encode_rdattr_error cleanup nfsd4: nfsd4_encode_fattr cleanup minor svcauth_gss.c cleanup nfsd4: better VERIFY comment nfsd4: break only delegations when appropriate NFSD: Fix a memory leak in nfsd4_create_session sunrpc: get rid of use_gssp_lock sunrpc: fix potential race between setting use_gss_proxy and the upcall rpc_clnt sunrpc: don't wait for write before allowing reads from use-gss-proxy file nfsd: get rid of unused function definition Define op_iattr for nfsd4_open instead using macro NFSD: fix compile warning without CONFIG_NFSD_V3 ...
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_keys.c17
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_upcall.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c82
-rw-r--r--net/sunrpc/cache.c4
-rw-r--r--net/sunrpc/netns.h1
-rw-r--r--net/sunrpc/svc.c25
-rw-r--r--net/sunrpc/xprtsock.c7
7 files changed, 47 insertions, 91 deletions
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 76e42e6be755..24589bd2a4b6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -59,6 +59,7 @@
59#include <linux/crypto.h> 59#include <linux/crypto.h>
60#include <linux/sunrpc/gss_krb5.h> 60#include <linux/sunrpc/gss_krb5.h>
61#include <linux/sunrpc/xdr.h> 61#include <linux/sunrpc/xdr.h>
62#include <linux/lcm.h>
62 63
63#ifdef RPC_DEBUG 64#ifdef RPC_DEBUG
64# define RPCDBG_FACILITY RPCDBG_AUTH 65# define RPCDBG_FACILITY RPCDBG_AUTH
@@ -72,7 +73,7 @@
72static void krb5_nfold(u32 inbits, const u8 *in, 73static void krb5_nfold(u32 inbits, const u8 *in,
73 u32 outbits, u8 *out) 74 u32 outbits, u8 *out)
74{ 75{
75 int a, b, c, lcm; 76 unsigned long ulcm;
76 int byte, i, msbit; 77 int byte, i, msbit;
77 78
78 /* the code below is more readable if I make these bytes 79 /* the code below is more readable if I make these bytes
@@ -82,17 +83,7 @@ static void krb5_nfold(u32 inbits, const u8 *in,
82 outbits >>= 3; 83 outbits >>= 3;
83 84
84 /* first compute lcm(n,k) */ 85 /* first compute lcm(n,k) */
85 86 ulcm = lcm(inbits, outbits);
86 a = outbits;
87 b = inbits;
88
89 while (b != 0) {
90 c = b;
91 b = a%b;
92 a = c;
93 }
94
95 lcm = outbits*inbits/a;
96 87
97 /* now do the real work */ 88 /* now do the real work */
98 89
@@ -101,7 +92,7 @@ static void krb5_nfold(u32 inbits, const u8 *in,
101 92
102 /* this will end up cycling through k lcm(k,n)/k times, which 93 /* this will end up cycling through k lcm(k,n)/k times, which
103 is correct */ 94 is correct */
104 for (i = lcm-1; i >= 0; i--) { 95 for (i = ulcm-1; i >= 0; i--) {
105 /* compute the msbit in k which gets added into this byte */ 96 /* compute the msbit in k which gets added into this byte */
106 msbit = ( 97 msbit = (
107 /* first, start with the msbit in the first, 98 /* first, start with the msbit in the first,
diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c
index 458f85e9b0ba..abbb7dcd1689 100644
--- a/net/sunrpc/auth_gss/gss_rpc_upcall.c
+++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c
@@ -137,7 +137,6 @@ void init_gssp_clnt(struct sunrpc_net *sn)
137{ 137{
138 mutex_init(&sn->gssp_lock); 138 mutex_init(&sn->gssp_lock);
139 sn->gssp_clnt = NULL; 139 sn->gssp_clnt = NULL;
140 init_waitqueue_head(&sn->gssp_wq);
141} 140}
142 141
143int set_gssp_clnt(struct net *net) 142int set_gssp_clnt(struct net *net)
@@ -154,7 +153,6 @@ int set_gssp_clnt(struct net *net)
154 sn->gssp_clnt = clnt; 153 sn->gssp_clnt = clnt;
155 } 154 }
156 mutex_unlock(&sn->gssp_lock); 155 mutex_unlock(&sn->gssp_lock);
157 wake_up(&sn->gssp_wq);
158 return ret; 156 return ret;
159} 157}
160 158
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 008cdade5aae..0f73f4507746 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1263,65 +1263,34 @@ out:
1263 return ret; 1263 return ret;
1264} 1264}
1265 1265
1266DEFINE_SPINLOCK(use_gssp_lock); 1266/*
1267 1267 * Try to set the sn->use_gss_proxy variable to a new value. We only allow
1268static bool use_gss_proxy(struct net *net) 1268 * it to be changed if it's currently undefined (-1). If it's any other value
1269{ 1269 * then return -EBUSY unless the type wouldn't have changed anyway.
1270 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1270 */
1271
1272 if (sn->use_gss_proxy != -1)
1273 return sn->use_gss_proxy;
1274 spin_lock(&use_gssp_lock);
1275 /*
1276 * If you wanted gss-proxy, you should have said so before
1277 * starting to accept requests:
1278 */
1279 sn->use_gss_proxy = 0;
1280 spin_unlock(&use_gssp_lock);
1281 return 0;
1282}
1283
1284#ifdef CONFIG_PROC_FS
1285
1286static int set_gss_proxy(struct net *net, int type) 1271static int set_gss_proxy(struct net *net, int type)
1287{ 1272{
1288 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1273 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1289 int ret = 0; 1274 int ret;
1290 1275
1291 WARN_ON_ONCE(type != 0 && type != 1); 1276 WARN_ON_ONCE(type != 0 && type != 1);
1292 spin_lock(&use_gssp_lock); 1277 ret = cmpxchg(&sn->use_gss_proxy, -1, type);
1293 if (sn->use_gss_proxy == -1 || sn->use_gss_proxy == type) 1278 if (ret != -1 && ret != type)
1294 sn->use_gss_proxy = type; 1279 return -EBUSY;
1295 else 1280 return 0;
1296 ret = -EBUSY;
1297 spin_unlock(&use_gssp_lock);
1298 wake_up(&sn->gssp_wq);
1299 return ret;
1300}
1301
1302static inline bool gssp_ready(struct sunrpc_net *sn)
1303{
1304 switch (sn->use_gss_proxy) {
1305 case -1:
1306 return false;
1307 case 0:
1308 return true;
1309 case 1:
1310 return sn->gssp_clnt;
1311 }
1312 WARN_ON_ONCE(1);
1313 return false;
1314} 1281}
1315 1282
1316static int wait_for_gss_proxy(struct net *net, struct file *file) 1283static bool use_gss_proxy(struct net *net)
1317{ 1284{
1318 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1285 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1319 1286
1320 if (file->f_flags & O_NONBLOCK && !gssp_ready(sn)) 1287 /* If use_gss_proxy is still undefined, then try to disable it */
1321 return -EAGAIN; 1288 if (sn->use_gss_proxy == -1)
1322 return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn)); 1289 set_gss_proxy(net, 0);
1290 return sn->use_gss_proxy;
1323} 1291}
1324 1292
1293#ifdef CONFIG_PROC_FS
1325 1294
1326static ssize_t write_gssp(struct file *file, const char __user *buf, 1295static ssize_t write_gssp(struct file *file, const char __user *buf,
1327 size_t count, loff_t *ppos) 1296 size_t count, loff_t *ppos)
@@ -1342,10 +1311,10 @@ static ssize_t write_gssp(struct file *file, const char __user *buf,
1342 return res; 1311 return res;
1343 if (i != 1) 1312 if (i != 1)
1344 return -EINVAL; 1313 return -EINVAL;
1345 res = set_gss_proxy(net, 1); 1314 res = set_gssp_clnt(net);
1346 if (res) 1315 if (res)
1347 return res; 1316 return res;
1348 res = set_gssp_clnt(net); 1317 res = set_gss_proxy(net, 1);
1349 if (res) 1318 if (res)
1350 return res; 1319 return res;
1351 return count; 1320 return count;
@@ -1355,16 +1324,12 @@ static ssize_t read_gssp(struct file *file, char __user *buf,
1355 size_t count, loff_t *ppos) 1324 size_t count, loff_t *ppos)
1356{ 1325{
1357 struct net *net = PDE_DATA(file_inode(file)); 1326 struct net *net = PDE_DATA(file_inode(file));
1327 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1358 unsigned long p = *ppos; 1328 unsigned long p = *ppos;
1359 char tbuf[10]; 1329 char tbuf[10];
1360 size_t len; 1330 size_t len;
1361 int ret;
1362 1331
1363 ret = wait_for_gss_proxy(net, file); 1332 snprintf(tbuf, sizeof(tbuf), "%d\n", sn->use_gss_proxy);
1364 if (ret)
1365 return ret;
1366
1367 snprintf(tbuf, sizeof(tbuf), "%d\n", use_gss_proxy(net));
1368 len = strlen(tbuf); 1333 len = strlen(tbuf);
1369 if (p >= len) 1334 if (p >= len)
1370 return 0; 1335 return 0;
@@ -1626,8 +1591,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
1626 BUG_ON(integ_len % 4); 1591 BUG_ON(integ_len % 4);
1627 *p++ = htonl(integ_len); 1592 *p++ = htonl(integ_len);
1628 *p++ = htonl(gc->gc_seq); 1593 *p++ = htonl(gc->gc_seq);
1629 if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, 1594 if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, integ_len))
1630 integ_len))
1631 BUG(); 1595 BUG();
1632 if (resbuf->tail[0].iov_base == NULL) { 1596 if (resbuf->tail[0].iov_base == NULL) {
1633 if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) 1597 if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE)
@@ -1635,10 +1599,8 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
1635 resbuf->tail[0].iov_base = resbuf->head[0].iov_base 1599 resbuf->tail[0].iov_base = resbuf->head[0].iov_base
1636 + resbuf->head[0].iov_len; 1600 + resbuf->head[0].iov_len;
1637 resbuf->tail[0].iov_len = 0; 1601 resbuf->tail[0].iov_len = 0;
1638 resv = &resbuf->tail[0];
1639 } else {
1640 resv = &resbuf->tail[0];
1641 } 1602 }
1603 resv = &resbuf->tail[0];
1642 mic.data = (u8 *)resv->iov_base + resv->iov_len + 4; 1604 mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
1643 if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic)) 1605 if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
1644 goto out_err; 1606 goto out_err;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index e521d20e1970..ae333c1845bb 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1111,9 +1111,7 @@ void qword_addhex(char **bpp, int *lp, char *buf, int blen)
1111 *bp++ = 'x'; 1111 *bp++ = 'x';
1112 len -= 2; 1112 len -= 2;
1113 while (blen && len >= 2) { 1113 while (blen && len >= 2) {
1114 unsigned char c = *buf++; 1114 bp = hex_byte_pack(bp, *buf++);
1115 *bp++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1);
1116 *bp++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1);
1117 len -= 2; 1115 len -= 2;
1118 blen--; 1116 blen--;
1119 } 1117 }
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 94e506f9d72b..df5826876535 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -27,7 +27,6 @@ struct sunrpc_net {
27 unsigned int rpcb_is_af_local : 1; 27 unsigned int rpcb_is_af_local : 1;
28 28
29 struct mutex gssp_lock; 29 struct mutex gssp_lock;
30 wait_queue_head_t gssp_wq;
31 struct rpc_clnt *gssp_clnt; 30 struct rpc_clnt *gssp_clnt;
32 int use_gss_proxy; 31 int use_gss_proxy;
33 int pipe_version; 32 int pipe_version;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e7fbe368b4a3..5de6801cd924 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -916,9 +916,6 @@ static int __svc_register(struct net *net, const char *progname,
916#endif 916#endif
917 } 917 }
918 918
919 if (error < 0)
920 printk(KERN_WARNING "svc: failed to register %sv%u RPC "
921 "service (errno %d).\n", progname, version, -error);
922 return error; 919 return error;
923} 920}
924 921
@@ -937,6 +934,7 @@ int svc_register(const struct svc_serv *serv, struct net *net,
937 const unsigned short port) 934 const unsigned short port)
938{ 935{
939 struct svc_program *progp; 936 struct svc_program *progp;
937 struct svc_version *vers;
940 unsigned int i; 938 unsigned int i;
941 int error = 0; 939 int error = 0;
942 940
@@ -946,7 +944,8 @@ int svc_register(const struct svc_serv *serv, struct net *net,
946 944
947 for (progp = serv->sv_program; progp; progp = progp->pg_next) { 945 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
948 for (i = 0; i < progp->pg_nvers; i++) { 946 for (i = 0; i < progp->pg_nvers; i++) {
949 if (progp->pg_vers[i] == NULL) 947 vers = progp->pg_vers[i];
948 if (vers == NULL)
950 continue; 949 continue;
951 950
952 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", 951 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
@@ -955,16 +954,26 @@ int svc_register(const struct svc_serv *serv, struct net *net,
955 proto == IPPROTO_UDP? "udp" : "tcp", 954 proto == IPPROTO_UDP? "udp" : "tcp",
956 port, 955 port,
957 family, 956 family,
958 progp->pg_vers[i]->vs_hidden? 957 vers->vs_hidden ?
959 " (but not telling portmap)" : ""); 958 " (but not telling portmap)" : "");
960 959
961 if (progp->pg_vers[i]->vs_hidden) 960 if (vers->vs_hidden)
962 continue; 961 continue;
963 962
964 error = __svc_register(net, progp->pg_name, progp->pg_prog, 963 error = __svc_register(net, progp->pg_name, progp->pg_prog,
965 i, family, proto, port); 964 i, family, proto, port);
966 if (error < 0) 965
966 if (vers->vs_rpcb_optnl) {
967 error = 0;
968 continue;
969 }
970
971 if (error < 0) {
972 printk(KERN_WARNING "svc: failed to register "
973 "%sv%u RPC service (errno %d).\n",
974 progp->pg_name, i, -error);
967 break; 975 break;
976 }
968 } 977 }
969 } 978 }
970 979
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 2a7ca8ffe83a..817a1e523969 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2964,10 +2964,9 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2964 2964
2965 /* 2965 /*
2966 * Once we've associated a backchannel xprt with a connection, 2966 * Once we've associated a backchannel xprt with a connection,
2967 * we want to keep it around as long as long as the connection 2967 * we want to keep it around as long as the connection lasts,
2968 * lasts, in case we need to start using it for a backchannel 2968 * in case we need to start using it for a backchannel again;
2969 * again; this reference won't be dropped until bc_xprt is 2969 * this reference won't be dropped until bc_xprt is destroyed.
2970 * destroyed.
2971 */ 2970 */
2972 xprt_get(xprt); 2971 xprt_get(xprt);
2973 args->bc_xprt->xpt_bc_xprt = xprt; 2972 args->bc_xprt->xpt_bc_xprt = xprt;