aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svclock.c4
-rw-r--r--fs/nfsd/nfs4proc.c2
-rw-r--r--fs/nfsd/nfsd.h1
-rw-r--r--fs/nfsd/nfssvc.c13
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_marshal.c20
5 files changed, 26 insertions, 14 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 067778b0ccc9..e066a3902973 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -951,6 +951,7 @@ nlmsvc_retry_blocked(void)
951 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 951 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
952 struct nlm_block *block; 952 struct nlm_block *block;
953 953
954 spin_lock(&nlm_blocked_lock);
954 while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { 955 while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
955 block = list_entry(nlm_blocked.next, struct nlm_block, b_list); 956 block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
956 957
@@ -960,6 +961,7 @@ nlmsvc_retry_blocked(void)
960 timeout = block->b_when - jiffies; 961 timeout = block->b_when - jiffies;
961 break; 962 break;
962 } 963 }
964 spin_unlock(&nlm_blocked_lock);
963 965
964 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", 966 dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
965 block, block->b_when); 967 block, block->b_when);
@@ -969,7 +971,9 @@ nlmsvc_retry_blocked(void)
969 retry_deferred_block(block); 971 retry_deferred_block(block);
970 } else 972 } else
971 nlmsvc_grant_blocked(block); 973 nlmsvc_grant_blocked(block);
974 spin_lock(&nlm_blocked_lock);
972 } 975 }
976 spin_unlock(&nlm_blocked_lock);
973 977
974 return timeout; 978 return timeout;
975} 979}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index a7cee864e7b2..0d4c410e4589 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1293,7 +1293,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1293 * According to RFC3010, this takes precedence over all other errors. 1293 * According to RFC3010, this takes precedence over all other errors.
1294 */ 1294 */
1295 status = nfserr_minor_vers_mismatch; 1295 status = nfserr_minor_vers_mismatch;
1296 if (args->minorversion > nfsd_supported_minorversion) 1296 if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1297 goto out; 1297 goto out;
1298 1298
1299 status = nfs41_check_op_ordering(args); 1299 status = nfs41_check_op_ordering(args);
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 2bbd94e51efc..30f34ab02137 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -53,7 +53,6 @@ struct readdir_cd {
53extern struct svc_program nfsd_program; 53extern struct svc_program nfsd_program;
54extern struct svc_version nfsd_version2, nfsd_version3, 54extern struct svc_version nfsd_version2, nfsd_version3,
55 nfsd_version4; 55 nfsd_version4;
56extern u32 nfsd_supported_minorversion;
57extern struct mutex nfsd_mutex; 56extern struct mutex nfsd_mutex;
58extern spinlock_t nfsd_drc_lock; 57extern spinlock_t nfsd_drc_lock;
59extern unsigned long nfsd_drc_max_mem; 58extern unsigned long nfsd_drc_max_mem;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 6b9f48ca4c25..760c85a6f534 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -116,7 +116,10 @@ struct svc_program nfsd_program = {
116 116
117}; 117};
118 118
119u32 nfsd_supported_minorversion = 1; 119static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
120 [0] = 1,
121 [1] = 1,
122};
120 123
121int nfsd_vers(int vers, enum vers_op change) 124int nfsd_vers(int vers, enum vers_op change)
122{ 125{
@@ -151,15 +154,13 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
151 return -1; 154 return -1;
152 switch(change) { 155 switch(change) {
153 case NFSD_SET: 156 case NFSD_SET:
154 nfsd_supported_minorversion = minorversion; 157 nfsd_supported_minorversions[minorversion] = true;
155 break; 158 break;
156 case NFSD_CLEAR: 159 case NFSD_CLEAR:
157 if (minorversion == 0) 160 nfsd_supported_minorversions[minorversion] = false;
158 return -1;
159 nfsd_supported_minorversion = minorversion - 1;
160 break; 161 break;
161 case NFSD_TEST: 162 case NFSD_TEST:
162 return minorversion <= nfsd_supported_minorversion; 163 return nfsd_supported_minorversions[minorversion];
163 case NFSD_AVAIL: 164 case NFSD_AVAIL:
164 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION; 165 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
165 } 166 }
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 8d2edddf48cf..65b146297f5a 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -98,6 +98,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
98 */ 98 */
99static u32 *decode_write_list(u32 *va, u32 *vaend) 99static u32 *decode_write_list(u32 *va, u32 *vaend)
100{ 100{
101 unsigned long start, end;
101 int nchunks; 102 int nchunks;
102 103
103 struct rpcrdma_write_array *ary = 104 struct rpcrdma_write_array *ary =
@@ -113,9 +114,12 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
113 return NULL; 114 return NULL;
114 } 115 }
115 nchunks = ntohl(ary->wc_nchunks); 116 nchunks = ntohl(ary->wc_nchunks);
116 if (((unsigned long)&ary->wc_array[0] + 117
117 (sizeof(struct rpcrdma_write_chunk) * nchunks)) > 118 start = (unsigned long)&ary->wc_array[0];
118 (unsigned long)vaend) { 119 end = (unsigned long)vaend;
120 if (nchunks < 0 ||
121 nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
122 (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
119 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n", 123 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
120 ary, nchunks, vaend); 124 ary, nchunks, vaend);
121 return NULL; 125 return NULL;
@@ -129,6 +133,7 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
129 133
130static u32 *decode_reply_array(u32 *va, u32 *vaend) 134static u32 *decode_reply_array(u32 *va, u32 *vaend)
131{ 135{
136 unsigned long start, end;
132 int nchunks; 137 int nchunks;
133 struct rpcrdma_write_array *ary = 138 struct rpcrdma_write_array *ary =
134 (struct rpcrdma_write_array *)va; 139 (struct rpcrdma_write_array *)va;
@@ -143,9 +148,12 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
143 return NULL; 148 return NULL;
144 } 149 }
145 nchunks = ntohl(ary->wc_nchunks); 150 nchunks = ntohl(ary->wc_nchunks);
146 if (((unsigned long)&ary->wc_array[0] + 151
147 (sizeof(struct rpcrdma_write_chunk) * nchunks)) > 152 start = (unsigned long)&ary->wc_array[0];
148 (unsigned long)vaend) { 153 end = (unsigned long)vaend;
154 if (nchunks < 0 ||
155 nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
156 (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
149 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n", 157 dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
150 ary, nchunks, vaend); 158 ary, nchunks, vaend);
151 return NULL; 159 return NULL;