diff options
| -rw-r--r-- | fs/nfs/callback_xdr.c | 2 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc.h | 2 | ||||
| -rw-r--r-- | net/sunrpc/svc.c | 27 |
3 files changed, 25 insertions, 6 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 06233bfa6d73..73a5a5ea2976 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
| @@ -983,7 +983,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) | |||
| 983 | 983 | ||
| 984 | out_invalidcred: | 984 | out_invalidcred: |
| 985 | pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n"); | 985 | pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n"); |
| 986 | return rpc_autherr_badcred; | 986 | return svc_return_autherr(rqstp, rpc_autherr_badcred); |
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | /* | 989 | /* |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index e52385340b3b..7ff12c9dbeaf 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
| @@ -271,6 +271,7 @@ struct svc_rqst { | |||
| 271 | #define RQ_VICTIM (5) /* about to be shut down */ | 271 | #define RQ_VICTIM (5) /* about to be shut down */ |
| 272 | #define RQ_BUSY (6) /* request is busy */ | 272 | #define RQ_BUSY (6) /* request is busy */ |
| 273 | #define RQ_DATA (7) /* request has data */ | 273 | #define RQ_DATA (7) /* request has data */ |
| 274 | #define RQ_AUTHERR (8) /* Request status is auth error */ | ||
| 274 | unsigned long rq_flags; /* flags field */ | 275 | unsigned long rq_flags; /* flags field */ |
| 275 | ktime_t rq_qtime; /* enqueue time */ | 276 | ktime_t rq_qtime; /* enqueue time */ |
| 276 | 277 | ||
| @@ -504,6 +505,7 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, | |||
| 504 | char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, | 505 | char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, |
| 505 | struct kvec *first, void *p, | 506 | struct kvec *first, void *p, |
| 506 | size_t total); | 507 | size_t total); |
| 508 | __be32 svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err); | ||
| 507 | 509 | ||
| 508 | #define RPC_MAX_ADDRBUFLEN (63U) | 510 | #define RPC_MAX_ADDRBUFLEN (63U) |
| 509 | 511 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index dbd19697ee38..3d5dd6b86652 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -1144,6 +1144,22 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) | |||
| 1144 | static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {} | 1144 | static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {} |
| 1145 | #endif | 1145 | #endif |
| 1146 | 1146 | ||
| 1147 | __be32 | ||
| 1148 | svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err) | ||
| 1149 | { | ||
| 1150 | set_bit(RQ_AUTHERR, &rqstp->rq_flags); | ||
| 1151 | return auth_err; | ||
| 1152 | } | ||
| 1153 | EXPORT_SYMBOL_GPL(svc_return_autherr); | ||
| 1154 | |||
| 1155 | static __be32 | ||
| 1156 | svc_get_autherr(struct svc_rqst *rqstp, __be32 *statp) | ||
| 1157 | { | ||
| 1158 | if (test_and_clear_bit(RQ_AUTHERR, &rqstp->rq_flags)) | ||
| 1159 | return *statp; | ||
| 1160 | return rpc_auth_ok; | ||
| 1161 | } | ||
| 1162 | |||
| 1147 | /* | 1163 | /* |
| 1148 | * Common routine for processing the RPC request. | 1164 | * Common routine for processing the RPC request. |
| 1149 | */ | 1165 | */ |
| @@ -1290,11 +1306,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
| 1290 | procp->pc_release(rqstp); | 1306 | procp->pc_release(rqstp); |
| 1291 | goto dropit; | 1307 | goto dropit; |
| 1292 | } | 1308 | } |
| 1293 | if (*statp == rpc_autherr_badcred) { | 1309 | auth_stat = svc_get_autherr(rqstp, statp); |
| 1294 | if (procp->pc_release) | 1310 | if (auth_stat != rpc_auth_ok) |
| 1295 | procp->pc_release(rqstp); | 1311 | goto err_release_bad_auth; |
| 1296 | goto err_bad_auth; | ||
| 1297 | } | ||
| 1298 | if (*statp == rpc_success && procp->pc_encode && | 1312 | if (*statp == rpc_success && procp->pc_encode && |
| 1299 | !procp->pc_encode(rqstp, resv->iov_base + resv->iov_len)) { | 1313 | !procp->pc_encode(rqstp, resv->iov_base + resv->iov_len)) { |
| 1300 | dprintk("svc: failed to encode reply\n"); | 1314 | dprintk("svc: failed to encode reply\n"); |
| @@ -1351,6 +1365,9 @@ err_bad_rpc: | |||
| 1351 | svc_putnl(resv, 2); | 1365 | svc_putnl(resv, 2); |
| 1352 | goto sendit; | 1366 | goto sendit; |
| 1353 | 1367 | ||
| 1368 | err_release_bad_auth: | ||
| 1369 | if (procp->pc_release) | ||
| 1370 | procp->pc_release(rqstp); | ||
| 1354 | err_bad_auth: | 1371 | err_bad_auth: |
| 1355 | dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat)); | 1372 | dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat)); |
| 1356 | serv->sv_stats->rpcbadauth++; | 1373 | serv->sv_stats->rpcbadauth++; |
