diff options
-rw-r--r-- | fs/lockd/svclock.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsd.h | 1 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 13 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_marshal.c | 20 |
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 { | |||
53 | extern struct svc_program nfsd_program; | 53 | extern struct svc_program nfsd_program; |
54 | extern struct svc_version nfsd_version2, nfsd_version3, | 54 | extern struct svc_version nfsd_version2, nfsd_version3, |
55 | nfsd_version4; | 55 | nfsd_version4; |
56 | extern u32 nfsd_supported_minorversion; | ||
57 | extern struct mutex nfsd_mutex; | 56 | extern struct mutex nfsd_mutex; |
58 | extern spinlock_t nfsd_drc_lock; | 57 | extern spinlock_t nfsd_drc_lock; |
59 | extern unsigned long nfsd_drc_max_mem; | 58 | extern 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 | ||
119 | u32 nfsd_supported_minorversion = 1; | 119 | static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = { |
120 | [0] = 1, | ||
121 | [1] = 1, | ||
122 | }; | ||
120 | 123 | ||
121 | int nfsd_vers(int vers, enum vers_op change) | 124 | int 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 | */ |
99 | static u32 *decode_write_list(u32 *va, u32 *vaend) | 99 | static 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 | ||
130 | static u32 *decode_reply_array(u32 *va, u32 *vaend) | 134 | static 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; |