Lines Matching full:j
37 unsigned bch2_journal_dev_buckets_available(struct journal *j, in bch2_journal_dev_buckets_available() argument
54 void bch2_journal_set_watermark(struct journal *j) in bch2_journal_set_watermark() argument
56 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_set_watermark()
57 bool low_on_space = j->space[journal_space_clean].total * 4 <= in bch2_journal_set_watermark()
58 j->space[journal_space_total].total; in bch2_journal_set_watermark()
59 bool low_on_pin = fifo_free(&j->pin) < j->pin.size / 4; in bch2_journal_set_watermark()
66 &j->low_on_space_start, low_on_space) || in bch2_journal_set_watermark()
68 &j->low_on_pin_start, low_on_pin) || in bch2_journal_set_watermark()
70 &j->write_buffer_full_start, low_on_wb)) in bch2_journal_set_watermark()
73 swap(watermark, j->watermark); in bch2_journal_set_watermark()
74 if (watermark > j->watermark) in bch2_journal_set_watermark()
75 journal_wake(j); in bch2_journal_set_watermark()
79 journal_dev_space_available(struct journal *j, struct bch_dev *ca, in journal_dev_space_available() argument
92 buckets = bch2_journal_dev_buckets_available(j, ja, from); in journal_dev_space_available()
99 for (seq = journal_last_unwritten_seq(j); in journal_dev_space_available()
100 seq <= journal_cur_seq(j); in journal_dev_space_available()
102 unwritten = j->buf[seq & JOURNAL_BUF_MASK].sectors; in journal_dev_space_available()
135 static struct journal_space __journal_space_available(struct journal *j, unsigned nr_devs_want, in __journal_space_available() argument
138 struct bch_fs *c = container_of(j, struct bch_fs, journal); in __journal_space_available()
149 space = journal_dev_space_available(j, ca, from); in __journal_space_available()
171 void bch2_journal_space_available(struct journal *j) in bch2_journal_space_available() argument
173 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_space_available()
175 unsigned max_entry_size = min(j->buf[0].buf_size >> 9, in bch2_journal_space_available()
176 j->buf[1].buf_size >> 9); in bch2_journal_space_available()
181 lockdep_assert_held(&j->lock); in bch2_journal_space_available()
191 ja->bucket_seq[ja->dirty_idx] < journal_last_seq(j)) in bch2_journal_space_available()
195 ja->bucket_seq[ja->dirty_idx_ondisk] < j->last_seq_ondisk) in bch2_journal_space_available()
206 j->can_discard = can_discard; in bch2_journal_space_available()
216 j->space[i] = __journal_space_available(j, nr_devs_want, i); in bch2_journal_space_available()
218 clean_ondisk = j->space[journal_space_clean_ondisk].total; in bch2_journal_space_available()
219 clean = j->space[journal_space_clean].total; in bch2_journal_space_available()
220 total = j->space[journal_space_total].total; in bch2_journal_space_available()
222 if (!j->space[journal_space_discarded].next_entry) in bch2_journal_space_available()
225 if ((j->space[journal_space_clean_ondisk].next_entry < in bch2_journal_space_available()
226 j->space[journal_space_clean_ondisk].total) && in bch2_journal_space_available()
229 set_bit(JOURNAL_MAY_SKIP_FLUSH, &j->flags); in bch2_journal_space_available()
231 clear_bit(JOURNAL_MAY_SKIP_FLUSH, &j->flags); in bch2_journal_space_available()
233 bch2_journal_set_watermark(j); in bch2_journal_space_available()
235 j->cur_entry_sectors = !ret ? j->space[journal_space_discarded].next_entry : 0; in bch2_journal_space_available()
236 j->cur_entry_error = ret; in bch2_journal_space_available()
239 journal_wake(j); in bch2_journal_space_available()
244 static bool should_discard_bucket(struct journal *j, struct journal_device *ja) in should_discard_bucket() argument
248 spin_lock(&j->lock); in should_discard_bucket()
250 spin_unlock(&j->lock); in should_discard_bucket()
259 void bch2_journal_do_discards(struct journal *j) in bch2_journal_do_discards() argument
261 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_do_discards()
263 mutex_lock(&j->discard_lock); in bch2_journal_do_discards()
268 while (should_discard_bucket(j, ja)) { in bch2_journal_do_discards()
277 spin_lock(&j->lock); in bch2_journal_do_discards()
280 bch2_journal_space_available(j); in bch2_journal_do_discards()
281 spin_unlock(&j->lock); in bch2_journal_do_discards()
285 mutex_unlock(&j->discard_lock); in bch2_journal_do_discards()
293 void bch2_journal_reclaim_fast(struct journal *j) in bch2_journal_reclaim_fast() argument
297 lockdep_assert_held(&j->lock); in bch2_journal_reclaim_fast()
303 while (!fifo_empty(&j->pin) && in bch2_journal_reclaim_fast()
304 j->pin.front <= j->seq_ondisk && in bch2_journal_reclaim_fast()
305 !atomic_read(&fifo_peek_front(&j->pin).count)) { in bch2_journal_reclaim_fast()
306 j->pin.front++; in bch2_journal_reclaim_fast()
311 bch2_journal_space_available(j); in bch2_journal_reclaim_fast()
314 bool __bch2_journal_pin_put(struct journal *j, u64 seq) in __bch2_journal_pin_put() argument
316 struct journal_entry_pin_list *pin_list = journal_seq_pin(j, seq); in __bch2_journal_pin_put()
321 void bch2_journal_pin_put(struct journal *j, u64 seq) in bch2_journal_pin_put() argument
323 if (__bch2_journal_pin_put(j, seq)) { in bch2_journal_pin_put()
324 spin_lock(&j->lock); in bch2_journal_pin_put()
325 bch2_journal_reclaim_fast(j); in bch2_journal_pin_put()
326 spin_unlock(&j->lock); in bch2_journal_pin_put()
330 static inline bool __journal_pin_drop(struct journal *j, in __journal_pin_drop() argument
338 if (j->flush_in_progress == pin) in __journal_pin_drop()
339 j->flush_in_progress_dropped = true; in __journal_pin_drop()
341 pin_list = journal_seq_pin(j, pin->seq); in __journal_pin_drop()
350 pin_list == &fifo_peek_front(&j->pin); in __journal_pin_drop()
353 void bch2_journal_pin_drop(struct journal *j, in bch2_journal_pin_drop() argument
356 spin_lock(&j->lock); in bch2_journal_pin_drop()
357 if (__journal_pin_drop(j, pin)) in bch2_journal_pin_drop()
358 bch2_journal_reclaim_fast(j); in bch2_journal_pin_drop()
359 spin_unlock(&j->lock); in bch2_journal_pin_drop()
373 static inline void bch2_journal_pin_set_locked(struct journal *j, u64 seq, in bch2_journal_pin_set_locked() argument
378 struct journal_entry_pin_list *pin_list = journal_seq_pin(j, seq); in bch2_journal_pin_set_locked()
392 void bch2_journal_pin_copy(struct journal *j, in bch2_journal_pin_copy() argument
399 spin_lock(&j->lock); in bch2_journal_pin_copy()
403 if (seq < journal_last_seq(j)) { in bch2_journal_pin_copy()
410 spin_unlock(&j->lock); in bch2_journal_pin_copy()
414 reclaim = __journal_pin_drop(j, dst); in bch2_journal_pin_copy()
416 bch2_journal_pin_set_locked(j, seq, dst, flush_fn, journal_pin_type(flush_fn)); in bch2_journal_pin_copy()
419 bch2_journal_reclaim_fast(j); in bch2_journal_pin_copy()
420 spin_unlock(&j->lock); in bch2_journal_pin_copy()
426 journal_wake(j); in bch2_journal_pin_copy()
429 void bch2_journal_pin_set(struct journal *j, u64 seq, in bch2_journal_pin_set() argument
435 spin_lock(&j->lock); in bch2_journal_pin_set()
437 BUG_ON(seq < journal_last_seq(j)); in bch2_journal_pin_set()
439 reclaim = __journal_pin_drop(j, pin); in bch2_journal_pin_set()
441 bch2_journal_pin_set_locked(j, seq, pin, flush_fn, journal_pin_type(flush_fn)); in bch2_journal_pin_set()
444 bch2_journal_reclaim_fast(j); in bch2_journal_pin_set()
445 spin_unlock(&j->lock); in bch2_journal_pin_set()
451 journal_wake(j); in bch2_journal_pin_set()
456 * @j: journal object
459 void bch2_journal_pin_flush(struct journal *j, struct journal_entry_pin *pin) in bch2_journal_pin_flush() argument
463 wait_event(j->pin_flush_wait, j->flush_in_progress != pin); in bch2_journal_pin_flush()
476 journal_get_next_pin(struct journal *j, in journal_get_next_pin() argument
486 fifo_for_each_entry_ptr(pin_list, &j->pin, *seq) { in journal_get_next_pin()
504 static size_t journal_flush_pins(struct journal *j, in journal_flush_pins() argument
517 lockdep_assert_held(&j->reclaim_lock); in journal_flush_pins()
535 j->last_flushed = jiffies; in journal_flush_pins()
537 spin_lock(&j->lock); in journal_flush_pins()
538 pin = journal_get_next_pin(j, seq_to_flush, allowed_below, allowed_above, &seq); in journal_flush_pins()
540 BUG_ON(j->flush_in_progress); in journal_flush_pins()
541 j->flush_in_progress = pin; in journal_flush_pins()
542 j->flush_in_progress_dropped = false; in journal_flush_pins()
545 spin_unlock(&j->lock); in journal_flush_pins()
556 err = flush_fn(j, pin, seq); in journal_flush_pins()
558 spin_lock(&j->lock); in journal_flush_pins()
560 if (likely(!err && !j->flush_in_progress_dropped)) in journal_flush_pins()
561 list_move(&pin->list, &journal_seq_pin(j, seq)->flushed); in journal_flush_pins()
562 j->flush_in_progress = NULL; in journal_flush_pins()
563 j->flush_in_progress_dropped = false; in journal_flush_pins()
564 spin_unlock(&j->lock); in journal_flush_pins()
566 wake_up(&j->pin_flush_wait); in journal_flush_pins()
577 static u64 journal_seq_to_flush(struct journal *j) in journal_seq_to_flush() argument
579 struct bch_fs *c = container_of(j, struct bch_fs, journal); in journal_seq_to_flush()
582 spin_lock(&j->lock); in journal_seq_to_flush()
603 (s64) journal_cur_seq(j) - in journal_seq_to_flush()
604 (j->pin.size >> 1)); in journal_seq_to_flush()
605 spin_unlock(&j->lock); in journal_seq_to_flush()
612 * @j: journal object
632 static int __bch2_journal_reclaim(struct journal *j, bool direct, bool kicked) in __bch2_journal_reclaim() argument
634 struct bch_fs *c = container_of(j, struct bch_fs, journal); in __bch2_journal_reclaim()
647 lockdep_assert_held(&j->reclaim_lock); in __bch2_journal_reclaim()
654 if (bch2_journal_error(j)) { in __bch2_journal_reclaim()
659 bch2_journal_do_discards(j); in __bch2_journal_reclaim()
661 seq_to_flush = journal_seq_to_flush(j); in __bch2_journal_reclaim()
665 * If it's been longer than j->reclaim_delay_ms since we last flushed, in __bch2_journal_reclaim()
668 if (time_after(jiffies, j->last_flushed + in __bch2_journal_reclaim()
672 if (j->watermark != BCH_WATERMARK_stripe) in __bch2_journal_reclaim()
688 nr_flushed = journal_flush_pins(j, seq_to_flush, in __bch2_journal_reclaim()
693 j->nr_direct_reclaim += nr_flushed; in __bch2_journal_reclaim()
695 j->nr_background_reclaim += nr_flushed; in __bch2_journal_reclaim()
699 wake_up(&j->reclaim_wait); in __bch2_journal_reclaim()
707 int bch2_journal_reclaim(struct journal *j) in bch2_journal_reclaim() argument
709 return __bch2_journal_reclaim(j, true, true); in bch2_journal_reclaim()
714 struct journal *j = arg; in bch2_journal_reclaim_thread() local
715 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_reclaim_thread()
722 j->last_flushed = jiffies; in bch2_journal_reclaim_thread()
725 bool kicked = j->reclaim_kicked; in bch2_journal_reclaim_thread()
727 j->reclaim_kicked = false; in bch2_journal_reclaim_thread()
729 mutex_lock(&j->reclaim_lock); in bch2_journal_reclaim_thread()
730 ret = __bch2_journal_reclaim(j, false, kicked); in bch2_journal_reclaim_thread()
731 mutex_unlock(&j->reclaim_lock); in bch2_journal_reclaim_thread()
735 j->next_reclaim = j->last_flushed + delay; in bch2_journal_reclaim_thread()
737 if (!time_in_range(j->next_reclaim, now, now + delay)) in bch2_journal_reclaim_thread()
738 j->next_reclaim = now + delay; in bch2_journal_reclaim_thread()
744 if (j->reclaim_kicked) in bch2_journal_reclaim_thread()
747 spin_lock(&j->lock); in bch2_journal_reclaim_thread()
748 journal_empty = fifo_empty(&j->pin); in bch2_journal_reclaim_thread()
749 spin_unlock(&j->lock); in bch2_journal_reclaim_thread()
753 else if (time_after(j->next_reclaim, jiffies)) in bch2_journal_reclaim_thread()
754 schedule_timeout(j->next_reclaim - jiffies); in bch2_journal_reclaim_thread()
764 void bch2_journal_reclaim_stop(struct journal *j) in bch2_journal_reclaim_stop() argument
766 struct task_struct *p = j->reclaim_thread; in bch2_journal_reclaim_stop()
768 j->reclaim_thread = NULL; in bch2_journal_reclaim_stop()
776 int bch2_journal_reclaim_start(struct journal *j) in bch2_journal_reclaim_start() argument
778 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_reclaim_start()
782 if (j->reclaim_thread) in bch2_journal_reclaim_start()
785 p = kthread_create(bch2_journal_reclaim_thread, j, in bch2_journal_reclaim_start()
793 j->reclaim_thread = p; in bch2_journal_reclaim_start()
798 static int journal_flush_done(struct journal *j, u64 seq_to_flush, in journal_flush_done() argument
803 ret = bch2_journal_error(j); in journal_flush_done()
807 mutex_lock(&j->reclaim_lock); in journal_flush_done()
809 if (journal_flush_pins(j, seq_to_flush, in journal_flush_done()
812 journal_flush_pins(j, seq_to_flush, in journal_flush_done()
816 if (seq_to_flush > journal_cur_seq(j)) in journal_flush_done()
817 bch2_journal_entry_close(j); in journal_flush_done()
819 spin_lock(&j->lock); in journal_flush_done()
824 ret = !test_bit(JOURNAL_REPLAY_DONE, &j->flags) || in journal_flush_done()
825 journal_last_seq(j) > seq_to_flush || in journal_flush_done()
826 !fifo_used(&j->pin); in journal_flush_done()
828 spin_unlock(&j->lock); in journal_flush_done()
829 mutex_unlock(&j->reclaim_lock); in journal_flush_done()
834 bool bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush) in bch2_journal_flush_pins() argument
839 if (!test_bit(JOURNAL_STARTED, &j->flags)) in bch2_journal_flush_pins()
842 closure_wait_event(&j->async_wait, in bch2_journal_flush_pins()
843 journal_flush_done(j, seq_to_flush, &did_work)); in bch2_journal_flush_pins()
848 int bch2_journal_flush_device_pins(struct journal *j, int dev_idx) in bch2_journal_flush_device_pins() argument
850 struct bch_fs *c = container_of(j, struct bch_fs, journal); in bch2_journal_flush_device_pins()
855 spin_lock(&j->lock); in bch2_journal_flush_device_pins()
856 fifo_for_each_entry_ptr(p, &j->pin, iter) in bch2_journal_flush_device_pins()
861 spin_unlock(&j->lock); in bch2_journal_flush_device_pins()
863 bch2_journal_flush_pins(j, seq); in bch2_journal_flush_device_pins()
865 ret = bch2_journal_error(j); in bch2_journal_flush_device_pins()
884 spin_lock(&j->lock); in bch2_journal_flush_device_pins()
888 seq = max(seq, journal_last_seq(j)); in bch2_journal_flush_device_pins()
889 if (seq >= j->pin.back) in bch2_journal_flush_device_pins()
892 journal_seq_pin(j, seq)->devs); in bch2_journal_flush_device_pins()
896 spin_unlock(&j->lock); in bch2_journal_flush_device_pins()
898 spin_lock(&j->lock); in bch2_journal_flush_device_pins()
901 spin_unlock(&j->lock); in bch2_journal_flush_device_pins()