mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-01-23 00:07:07 +03:00
Update bcachefs sources to bcca1c557b bcachefs: fixes for getting stuck flushing journal pins
This commit is contained in:
parent
d3b9fb6873
commit
8630059e6a
@ -1 +1 @@
|
||||
ef60854e9912d24c0ba83e0760552c98257d2b07
|
||||
bcca1c557b1897ecc3aeb1f89ab91865487d91ab
|
||||
|
@ -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) &&
|
||||
|
@ -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)
|
||||
|
@ -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(¤t->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG,
|
||||
v, NULL, NULL, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user