summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-01-14 00:48:54 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2019-01-14 00:49:02 -0500
commit8630059e6ac363bea39e54df3f8115da5a5c2c5d (patch)
treed503f1821d8bdabd9a4724de1b67e5ad48fe400c
parentd3b9fb6873d5e5d8620a7edd18a5a32904f7ea80 (diff)
Update bcachefs sources to bcca1c557b bcachefs: fixes for getting stuck flushing journal pins
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/fs-io.c15
-rw-r--r--libbcachefs/journal_reclaim.c43
-rw-r--r--linux/sched.c2
4 files changed, 29 insertions, 33 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index 3bcc585a..088f645c 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-ef60854e9912d24c0ba83e0760552c98257d2b07
+bcca1c557b1897ecc3aeb1f89ab91865487d91ab
diff --git a/libbcachefs/fs-io.c b/libbcachefs/fs-io.c
index fdc24be1..c1739f53 100644
--- a/libbcachefs/fs-io.c
+++ b/libbcachefs/fs-io.c
@@ -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) &&
diff --git a/libbcachefs/journal_reclaim.c b/libbcachefs/journal_reclaim.c
index d8d1b6b0..4a997366 100644
--- a/libbcachefs/journal_reclaim.c
+++ b/libbcachefs/journal_reclaim.c
@@ -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)
diff --git a/linux/sched.c b/linux/sched.c
index b3fc7739..353c11db 100644
--- a/linux/sched.c
+++ b/linux/sched.c
@@ -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);
}