Update bcachefs sources to bcca1c557b bcachefs: fixes for getting stuck flushing journal pins

This commit is contained in:
Kent Overstreet 2019-01-14 00:48:54 -05:00
parent d3b9fb6873
commit 8630059e6a
4 changed files with 29 additions and 33 deletions

View File

@ -1 +1 @@
ef60854e9912d24c0ba83e0760552c98257d2b07
bcca1c557b1897ecc3aeb1f89ab91865487d91ab

View File

@ -56,7 +56,7 @@ struct bch_writepage_io {
struct dio_write {
struct closure cl;
struct kiocb *req;
struct task_struct *task;
struct mm_struct *mm;
unsigned loop:1,
sync:1,
free_iov:1;
@ -1753,6 +1753,7 @@ static void bch2_dio_write_loop_async(struct closure *);
static long bch2_dio_write_loop(struct dio_write *dio)
{
bool kthread = (current->flags & PF_KTHREAD) != 0;
struct kiocb *req = dio->req;
struct address_space *mapping = req->ki_filp->f_mapping;
struct bch_inode_info *inode = dio->iop.inode;
@ -1777,13 +1778,13 @@ static long bch2_dio_write_loop(struct dio_write *dio)
while (1) {
BUG_ON(current->pagecache_lock);
current->pagecache_lock = &mapping->add_lock;
if (current != dio->task)
use_mm(dio->task->mm);
if (kthread)
use_mm(dio->mm);
ret = bio_iov_iter_get_pages(bio, &dio->iter);
if (current != dio->task)
unuse_mm(dio->task->mm);
if (kthread)
unuse_mm(dio->mm);
current->pagecache_lock = NULL;
if (unlikely(ret < 0))
@ -1894,7 +1895,7 @@ static int bch2_direct_IO_write(struct kiocb *req,
dio = container_of(bio, struct dio_write, iop.op.wbio.bio);
closure_init(&dio->cl, NULL);
dio->req = req;
dio->task = current;
dio->mm = current->mm;
dio->loop = false;
dio->sync = is_sync_kiocb(req) ||
offset + iter->count > inode->v.i_size;
@ -1902,7 +1903,7 @@ static int bch2_direct_IO_write(struct kiocb *req,
dio->quota_res.sectors = 0;
dio->iter = *iter;
bch2_fswrite_op_init(&dio->iop, c, inode, io_opts(c, inode), true);
dio->iop.op.write_point = writepoint_hashed((unsigned long) dio->task);
dio->iop.op.write_point = writepoint_hashed((unsigned long) current);
dio->iop.op.flags |= BCH_WRITE_NOPUT_RESERVATION;
if ((req->ki_flags & IOCB_DSYNC) &&

View File

@ -64,6 +64,9 @@ static inline void __journal_pin_drop(struct journal *j,
if (atomic_dec_and_test(&pin_list->count) &&
pin_list == &fifo_peek_front(&j->pin))
bch2_journal_reclaim_fast(j);
else if (fifo_used(&j->pin) == 1 &&
atomic_read(&pin_list->count) == 1)
journal_wake(j);
}
void bch2_journal_pin_drop(struct journal *j,
@ -336,56 +339,48 @@ void bch2_journal_reclaim_work(struct work_struct *work)
msecs_to_jiffies(j->reclaim_delay_ms));
}
static int journal_flush_done(struct journal *j, u64 seq_to_flush,
struct journal_entry_pin **pin,
u64 *pin_seq)
static int journal_flush_done(struct journal *j, u64 seq_to_flush)
{
struct journal_entry_pin *pin;
u64 pin_seq;
int ret;
*pin = NULL;
ret = bch2_journal_error(j);
if (ret)
return ret;
mutex_lock(&j->reclaim_lock);
spin_lock(&j->lock);
while ((pin = journal_get_next_pin(j, seq_to_flush, &pin_seq))) {
journal_pin_mark_flushing(j, pin, pin_seq);
spin_unlock(&j->lock);
journal_pin_flush(j, pin, pin_seq);
spin_lock(&j->lock);
}
/*
* If journal replay hasn't completed, the unreplayed journal entries
* hold refs on their corresponding sequence numbers
*/
ret = (*pin = journal_get_next_pin(j, seq_to_flush, pin_seq)) != NULL ||
!test_bit(JOURNAL_REPLAY_DONE, &j->flags) ||
ret = !test_bit(JOURNAL_REPLAY_DONE, &j->flags) ||
journal_last_seq(j) > seq_to_flush ||
(fifo_used(&j->pin) == 1 &&
atomic_read(&fifo_peek_front(&j->pin).count) == 1);
if (*pin)
journal_pin_mark_flushing(j, *pin, *pin_seq);
spin_unlock(&j->lock);
mutex_unlock(&j->reclaim_lock);
return ret;
}
void bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush)
{
struct journal_entry_pin *pin;
u64 pin_seq;
if (!test_bit(JOURNAL_STARTED, &j->flags))
return;
mutex_lock(&j->reclaim_lock);
while (1) {
wait_event(j->wait, journal_flush_done(j, seq_to_flush,
&pin, &pin_seq));
if (!pin)
break;
journal_pin_flush(j, pin, pin_seq);
}
mutex_unlock(&j->reclaim_lock);
closure_wait_event(&j->async_wait, journal_flush_done(j, seq_to_flush));
}
int bch2_journal_flush_device_pins(struct journal *j, int dev_idx)

View File

@ -37,7 +37,7 @@ void schedule(void)
rcu_quiescent_state();
while ((v = current->state) != TASK_RUNNING)
while ((v = READ_ONCE(current->state)) != TASK_RUNNING)
futex(&current->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG,
v, NULL, NULL, 0);
}