Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
Pull nfsd bugfixes from Bruce Fields: "Just three minor bugfixes" * 'for-3.11' of git://linux-nfs.org/~bfields/linux: svcrdma: underflow issue in decode_write_list() nfsd4: fix minorversion support interface lockd: protect nlm_blocked access in nlmsvc_retry_blocked
This commit is contained in:
@@ -951,6 +951,7 @@ nlmsvc_retry_blocked(void)
|
|||||||
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
|
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
|
||||||
struct nlm_block *block;
|
struct nlm_block *block;
|
||||||
|
|
||||||
|
spin_lock(&nlm_blocked_lock);
|
||||||
while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
|
while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
|
||||||
block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
|
block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
|
||||||
|
|
||||||
@@ -960,6 +961,7 @@ nlmsvc_retry_blocked(void)
|
|||||||
timeout = block->b_when - jiffies;
|
timeout = block->b_when - jiffies;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
spin_unlock(&nlm_blocked_lock);
|
||||||
|
|
||||||
dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
|
dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
|
||||||
block, block->b_when);
|
block, block->b_when);
|
||||||
@@ -969,7 +971,9 @@ nlmsvc_retry_blocked(void)
|
|||||||
retry_deferred_block(block);
|
retry_deferred_block(block);
|
||||||
} else
|
} else
|
||||||
nlmsvc_grant_blocked(block);
|
nlmsvc_grant_blocked(block);
|
||||||
|
spin_lock(&nlm_blocked_lock);
|
||||||
}
|
}
|
||||||
|
spin_unlock(&nlm_blocked_lock);
|
||||||
|
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
@@ -1293,7 +1293,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
|
|||||||
* According to RFC3010, this takes precedence over all other errors.
|
* According to RFC3010, this takes precedence over all other errors.
|
||||||
*/
|
*/
|
||||||
status = nfserr_minor_vers_mismatch;
|
status = nfserr_minor_vers_mismatch;
|
||||||
if (args->minorversion > nfsd_supported_minorversion)
|
if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
status = nfs41_check_op_ordering(args);
|
status = nfs41_check_op_ordering(args);
|
||||||
|
@@ -53,7 +53,6 @@ struct readdir_cd {
|
|||||||
extern struct svc_program nfsd_program;
|
extern struct svc_program nfsd_program;
|
||||||
extern struct svc_version nfsd_version2, nfsd_version3,
|
extern struct svc_version nfsd_version2, nfsd_version3,
|
||||||
nfsd_version4;
|
nfsd_version4;
|
||||||
extern u32 nfsd_supported_minorversion;
|
|
||||||
extern struct mutex nfsd_mutex;
|
extern struct mutex nfsd_mutex;
|
||||||
extern spinlock_t nfsd_drc_lock;
|
extern spinlock_t nfsd_drc_lock;
|
||||||
extern unsigned long nfsd_drc_max_mem;
|
extern unsigned long nfsd_drc_max_mem;
|
||||||
|
@@ -116,7 +116,10 @@ struct svc_program nfsd_program = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 nfsd_supported_minorversion = 1;
|
static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
|
||||||
|
[0] = 1,
|
||||||
|
[1] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
int nfsd_vers(int vers, enum vers_op change)
|
int nfsd_vers(int vers, enum vers_op change)
|
||||||
{
|
{
|
||||||
@@ -151,15 +154,13 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
|
|||||||
return -1;
|
return -1;
|
||||||
switch(change) {
|
switch(change) {
|
||||||
case NFSD_SET:
|
case NFSD_SET:
|
||||||
nfsd_supported_minorversion = minorversion;
|
nfsd_supported_minorversions[minorversion] = true;
|
||||||
break;
|
break;
|
||||||
case NFSD_CLEAR:
|
case NFSD_CLEAR:
|
||||||
if (minorversion == 0)
|
nfsd_supported_minorversions[minorversion] = false;
|
||||||
return -1;
|
|
||||||
nfsd_supported_minorversion = minorversion - 1;
|
|
||||||
break;
|
break;
|
||||||
case NFSD_TEST:
|
case NFSD_TEST:
|
||||||
return minorversion <= nfsd_supported_minorversion;
|
return nfsd_supported_minorversions[minorversion];
|
||||||
case NFSD_AVAIL:
|
case NFSD_AVAIL:
|
||||||
return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
|
return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
|
||||||
}
|
}
|
||||||
|
@@ -98,6 +98,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
|
|||||||
*/
|
*/
|
||||||
static u32 *decode_write_list(u32 *va, u32 *vaend)
|
static u32 *decode_write_list(u32 *va, u32 *vaend)
|
||||||
{
|
{
|
||||||
|
unsigned long start, end;
|
||||||
int nchunks;
|
int nchunks;
|
||||||
|
|
||||||
struct rpcrdma_write_array *ary =
|
struct rpcrdma_write_array *ary =
|
||||||
@@ -113,9 +114,12 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
nchunks = ntohl(ary->wc_nchunks);
|
nchunks = ntohl(ary->wc_nchunks);
|
||||||
if (((unsigned long)&ary->wc_array[0] +
|
|
||||||
(sizeof(struct rpcrdma_write_chunk) * nchunks)) >
|
start = (unsigned long)&ary->wc_array[0];
|
||||||
(unsigned long)vaend) {
|
end = (unsigned long)vaend;
|
||||||
|
if (nchunks < 0 ||
|
||||||
|
nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
|
||||||
|
(start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
|
||||||
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
|
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
|
||||||
ary, nchunks, vaend);
|
ary, nchunks, vaend);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -129,6 +133,7 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
|
|||||||
|
|
||||||
static u32 *decode_reply_array(u32 *va, u32 *vaend)
|
static u32 *decode_reply_array(u32 *va, u32 *vaend)
|
||||||
{
|
{
|
||||||
|
unsigned long start, end;
|
||||||
int nchunks;
|
int nchunks;
|
||||||
struct rpcrdma_write_array *ary =
|
struct rpcrdma_write_array *ary =
|
||||||
(struct rpcrdma_write_array *)va;
|
(struct rpcrdma_write_array *)va;
|
||||||
@@ -143,9 +148,12 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
nchunks = ntohl(ary->wc_nchunks);
|
nchunks = ntohl(ary->wc_nchunks);
|
||||||
if (((unsigned long)&ary->wc_array[0] +
|
|
||||||
(sizeof(struct rpcrdma_write_chunk) * nchunks)) >
|
start = (unsigned long)&ary->wc_array[0];
|
||||||
(unsigned long)vaend) {
|
end = (unsigned long)vaend;
|
||||||
|
if (nchunks < 0 ||
|
||||||
|
nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
|
||||||
|
(start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
|
||||||
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
|
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
|
||||||
ary, nchunks, vaend);
|
ary, nchunks, vaend);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Reference in New Issue
Block a user