diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 13:18:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 13:18:43 -0500 |
commit | d9894c228b11273e720bb63ba120d1d326fe9d94 (patch) | |
tree | c9b91b716f281f5accf8860dfadb1ac95abf0090 /net | |
parent | dfa19426160046770b3a38985042df9c9760a25a (diff) | |
parent | ed47b062ce9546fbe1eebf9da6937df4c5035372 (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.c | 17 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_upcall.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 82 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 4 | ||||
-rw-r--r-- | net/sunrpc/netns.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 25 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 7 |
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 @@ | |||
72 | static void krb5_nfold(u32 inbits, const u8 *in, | 73 | static 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 | ||
143 | int set_gssp_clnt(struct net *net) | 142 | int 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 | ||
1266 | DEFINE_SPINLOCK(use_gssp_lock); | 1266 | /* |
1267 | 1267 | * Try to set the sn->use_gss_proxy variable to a new value. We only allow | |
1268 | static 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 | |||
1286 | static int set_gss_proxy(struct net *net, int type) | 1271 | static 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 | |||
1302 | static 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 | ||
1316 | static int wait_for_gss_proxy(struct net *net, struct file *file) | 1283 | static 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 | ||
1326 | static ssize_t write_gssp(struct file *file, const char __user *buf, | 1295 | static 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; |