提交 999646e3 编写于 作者: L Linus Torvalds

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()
...@@ -1214,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
...@@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, ...@@ -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, ...@@ -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, ...@@ -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; ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
spliced = 0; if (ret > 0)
while (len && !spliced) {
ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
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;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册