Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: cfq-iosched: do not leak ioc_data across iosched switches splice: fix infinite loop in generic_file_splice_read()
This commit is contained in:
commit
999646e3f9
|
@ -1214,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
|
||||||
static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
|
static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
|
||||||
struct cfq_io_context *cic)
|
struct cfq_io_context *cic)
|
||||||
{
|
{
|
||||||
|
struct io_context *ioc = cic->ioc;
|
||||||
|
|
||||||
list_del_init(&cic->queue_list);
|
list_del_init(&cic->queue_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1223,6 +1225,9 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
|
||||||
cic->dead_key = (unsigned long) cic->key;
|
cic->dead_key = (unsigned long) cic->key;
|
||||||
cic->key = NULL;
|
cic->key = NULL;
|
||||||
|
|
||||||
|
if (ioc->ioc_data == cic)
|
||||||
|
rcu_assign_pointer(ioc->ioc_data, NULL);
|
||||||
|
|
||||||
if (cic->cfqq[ASYNC]) {
|
if (cic->cfqq[ASYNC]) {
|
||||||
cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
|
cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
|
||||||
cic->cfqq[ASYNC] = NULL;
|
cic->cfqq[ASYNC] = NULL;
|
||||||
|
@ -1255,7 +1260,6 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
|
||||||
*/
|
*/
|
||||||
static void cfq_exit_io_context(struct io_context *ioc)
|
static void cfq_exit_io_context(struct io_context *ioc)
|
||||||
{
|
{
|
||||||
rcu_assign_pointer(ioc->ioc_data, NULL);
|
|
||||||
call_for_each_cic(ioc, cfq_exit_single_io_context);
|
call_for_each_cic(ioc, cfq_exit_single_io_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,8 +1482,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->lock, flags);
|
spin_lock_irqsave(&ioc->lock, flags);
|
||||||
|
|
||||||
if (ioc->ioc_data == cic)
|
BUG_ON(ioc->ioc_data == cic);
|
||||||
rcu_assign_pointer(ioc->ioc_data, NULL);
|
|
||||||
|
|
||||||
radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
|
radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
|
||||||
hlist_del_rcu(&cic->cic_list);
|
hlist_del_rcu(&cic->cic_list);
|
||||||
|
|
29
fs/splice.c
29
fs/splice.c
|
@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
* for an in-flight io page
|
* for an in-flight io page
|
||||||
*/
|
*/
|
||||||
if (flags & SPLICE_F_NONBLOCK) {
|
if (flags & SPLICE_F_NONBLOCK) {
|
||||||
if (TestSetPageLocked(page))
|
if (TestSetPageLocked(page)) {
|
||||||
|
error = -EAGAIN;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
lock_page(page);
|
lock_page(page);
|
||||||
|
|
||||||
|
@ -479,9 +481,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
struct pipe_inode_info *pipe, size_t len,
|
struct pipe_inode_info *pipe, size_t len,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
ssize_t spliced;
|
|
||||||
int ret;
|
|
||||||
loff_t isize, left;
|
loff_t isize, left;
|
||||||
|
int ret;
|
||||||
|
|
||||||
isize = i_size_read(in->f_mapping->host);
|
isize = i_size_read(in->f_mapping->host);
|
||||||
if (unlikely(*ppos >= isize))
|
if (unlikely(*ppos >= isize))
|
||||||
|
@ -491,29 +492,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
|
||||||
if (unlikely(left < len))
|
if (unlikely(left < len))
|
||||||
len = left;
|
len = left;
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
spliced = 0;
|
|
||||||
while (len && !spliced) {
|
|
||||||
ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
|
ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
|
||||||
|
if (ret > 0)
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
else if (!ret) {
|
|
||||||
if (spliced)
|
|
||||||
break;
|
|
||||||
if (flags & SPLICE_F_NONBLOCK) {
|
|
||||||
ret = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppos += ret;
|
*ppos += ret;
|
||||||
len -= ret;
|
|
||||||
spliced += ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spliced)
|
|
||||||
return spliced;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue