Lines Matching +full:non +full:- +full:live
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
28 * Live File Scan
31 * Live file scans walk every inode in a live filesystem. This is more or
41 * live updates, which means there must be a provision to update the new index
43 * can be used in live update hook code to stop the scan and protect this data
47 * the live filesystem, it is assumed that the caller will add hooks as needed
55 * If the inobt record @rec covers @iscan->skip_ino, mark the inode free so
65 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_mask_skipino()
66 struct xfs_mount *mp = sc->mp; in xchk_iscan_mask_skipino()
67 xfs_agnumber_t skip_agno = XFS_INO_TO_AGNO(mp, iscan->skip_ino); in xchk_iscan_mask_skipino()
68 xfs_agnumber_t skip_agino = XFS_INO_TO_AGINO(mp, iscan->skip_ino); in xchk_iscan_mask_skipino()
72 if (skip_agino < rec->ir_startino) in xchk_iscan_mask_skipino()
77 rec->ir_free |= xfs_inobt_maskn(skip_agino - rec->ir_startino, 1); in xchk_iscan_mask_skipino()
93 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_find_next()
96 struct xfs_mount *mp = sc->mp; in xchk_iscan_find_next()
97 struct xfs_trans *tp = sc->tp; in xchk_iscan_find_next()
137 error = -EFSCORRUPTED; in xchk_iscan_find_next()
144 error = -EFSCORRUPTED; in xchk_iscan_find_next()
147 lastino = rec.ir_startino + XFS_INODES_PER_CHUNK - 1; in xchk_iscan_find_next()
156 if (iscan->skip_ino) in xchk_iscan_find_next()
167 agino + 1 - rec.ir_startino); in xchk_iscan_find_next()
180 *nr_inodesp = XFS_INODES_PER_CHUNK - next; in xchk_iscan_find_next()
195 * the same time so that the scan user can receive live updates for inodes that
204 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_move_cursor()
205 struct xfs_mount *mp = sc->mp; in xchk_iscan_move_cursor()
211 * Special-case ino == 0 here so that we never set visited_ino to in xchk_iscan_move_cursor()
213 * live updates. in xchk_iscan_move_cursor()
219 visited = cursor - 1; in xchk_iscan_move_cursor()
221 mutex_lock(&iscan->lock); in xchk_iscan_move_cursor()
222 iscan->cursor_ino = cursor; in xchk_iscan_move_cursor()
223 iscan->__visited_ino = visited; in xchk_iscan_move_cursor()
225 mutex_unlock(&iscan->lock); in xchk_iscan_move_cursor()
237 mutex_lock(&iscan->lock); in xchk_iscan_finish()
238 iscan->cursor_ino = NULLFSINO; in xchk_iscan_finish()
240 /* All live updates will be applied from now on */ in xchk_iscan_finish()
241 iscan->__visited_ino = NULLFSINO; in xchk_iscan_finish()
243 mutex_unlock(&iscan->lock); in xchk_iscan_finish()
251 ASSERT(iscan->cursor_ino == iscan->scan_start_ino); in xchk_iscan_finish_early()
252 ASSERT(iscan->__visited_ino == iscan->scan_start_ino); in xchk_iscan_finish_early()
259 * -ECANCELED if the live scan aborted, -EBUSY if the AGI could not be grabbed,
268 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_read_agi()
273 return xfs_ialloc_read_agi(pag, sc->tp, 0, agi_bpp); in xchk_iscan_read_agi()
275 relax = msecs_to_jiffies(iscan->iget_retry_delay); in xchk_iscan_read_agi()
277 ret = xfs_ialloc_read_agi(pag, sc->tp, XFS_IALLOC_FLAG_TRYLOCK, in xchk_iscan_read_agi()
279 if (ret != -EAGAIN) in xchk_iscan_read_agi()
281 if (!iscan->iget_timeout || in xchk_iscan_read_agi()
282 time_is_before_jiffies(iscan->__iget_deadline)) in xchk_iscan_read_agi()
283 return -EBUSY; in xchk_iscan_read_agi()
288 return -ECANCELED; in xchk_iscan_read_agi()
295 * scan forward, so set the iscan cursor to (ino - 1) so that our live update
300 * -ECANCELED if the live scan aborted, or the usual negative errno.
310 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_advance()
311 struct xfs_mount *mp = sc->mp; in xchk_iscan_advance()
318 ASSERT(iscan->cursor_ino >= iscan->__visited_ino); in xchk_iscan_advance()
322 return -ECANCELED; in xchk_iscan_advance()
324 agno = XFS_INO_TO_AGNO(mp, iscan->cursor_ino); in xchk_iscan_advance()
327 return -ECANCELED; in xchk_iscan_advance()
333 agino = XFS_INO_TO_AGINO(mp, iscan->cursor_ino); in xchk_iscan_advance()
355 agno = (agno + 1) % mp->m_sb.sb_agcount; in xchk_iscan_advance()
357 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_advance()
361 } while (iscan->cursor_ino != iscan->scan_start_ino); in xchk_iscan_advance()
367 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_advance()
375 * to try to _advance the scan again. Returns -EBUSY if we've run out of retry
376 * opportunities, -ECANCELED if the process has a fatal signal pending, or
377 * -EAGAIN if we should try again.
384 ASSERT(iscan->cursor_ino == iscan->__visited_ino + 1); in xchk_iscan_iget_retry()
386 if (!iscan->iget_timeout || in xchk_iscan_iget_retry()
387 time_is_before_jiffies(iscan->__iget_deadline)) in xchk_iscan_iget_retry()
388 return -EBUSY; in xchk_iscan_iget_retry()
398 relax = msecs_to_jiffies(iscan->iget_retry_delay); in xchk_iscan_iget_retry()
403 return -ECANCELED; in xchk_iscan_iget_retry()
406 iscan->cursor_ino--; in xchk_iscan_iget_retry()
407 return -EAGAIN; in xchk_iscan_iget_retry()
424 * Returns the number of incore inodes grabbed; -EAGAIN if the caller should
425 * call again xchk_iscan_advance; -EBUSY if we couldn't grab an inode;
426 * -ECANCELED if there's a fatal signal pending; or some other negative errno.
436 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_iget()
437 struct xfs_mount *mp = sc->mp; in xchk_iscan_iget()
438 xfs_ino_t ino = iscan->cursor_ino; in xchk_iscan_iget()
443 ASSERT(iscan->__inodes[0] == NULL); in xchk_iscan_iget()
446 error = xfs_iget(sc->mp, sc->tp, ino, ISCAN_IGET_FLAGS, 0, in xchk_iscan_iget()
447 &iscan->__inodes[idx]); in xchk_iscan_iget()
451 if (error == -ENOENT || error == -EAGAIN) { in xchk_iscan_iget()
452 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_iget()
459 * If we have a non-empty transaction, we must not block on in xchk_iscan_iget()
462 if (sc->tp && !(sc->tp->t_flags & XFS_TRANS_NO_WRITECOUNT)) in xchk_iscan_iget()
469 if (error == -EINVAL) { in xchk_iscan_iget()
470 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_iget()
484 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_iget()
497 * the _want_live_update predicate will pass through all live updates. in xchk_iscan_iget()
501 mutex_lock(&iscan->lock); in xchk_iscan_iget()
502 iscan->__batch_ino = ino - 1; in xchk_iscan_iget()
503 iscan->__skipped_inomask = 0; in xchk_iscan_iget()
504 mutex_unlock(&iscan->lock); in xchk_iscan_iget()
508 ASSERT(!(iscan->__skipped_inomask & (1ULL << i))); in xchk_iscan_iget()
510 mutex_lock(&iscan->lock); in xchk_iscan_iget()
511 iscan->cursor_ino = ino; in xchk_iscan_iget()
512 iscan->__skipped_inomask |= (1ULL << i); in xchk_iscan_iget()
513 mutex_unlock(&iscan->lock); in xchk_iscan_iget()
517 ASSERT(iscan->__inodes[idx] == NULL); in xchk_iscan_iget()
519 error = xfs_iget(sc->mp, sc->tp, ino, ISCAN_IGET_FLAGS, 0, in xchk_iscan_iget()
520 &iscan->__inodes[idx]); in xchk_iscan_iget()
524 mutex_lock(&iscan->lock); in xchk_iscan_iget()
525 iscan->cursor_ino = ino; in xchk_iscan_iget()
526 mutex_unlock(&iscan->lock); in xchk_iscan_iget()
530 trace_xchk_iscan_iget_batch(sc->mp, iscan, nr_inodes, idx); in xchk_iscan_iget()
531 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_iget()
546 mutex_lock(&iscan->lock); in xchk_iscan_finish_batch()
548 if (iscan->__batch_ino != NULLFSINO) { in xchk_iscan_finish_batch()
549 highest_skipped = iscan->__batch_ino + in xchk_iscan_finish_batch()
550 xfs_highbit64(iscan->__skipped_inomask); in xchk_iscan_finish_batch()
551 iscan->__visited_ino = max(iscan->__visited_ino, in xchk_iscan_finish_batch()
557 iscan->__batch_ino = NULLFSINO; in xchk_iscan_finish_batch()
558 iscan->__skipped_inomask = 0; in xchk_iscan_finish_batch()
560 mutex_unlock(&iscan->lock); in xchk_iscan_finish_batch()
571 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_iter_batch()
576 if (iscan->iget_timeout) in xchk_iscan_iter_batch()
577 iscan->__iget_deadline = jiffies + in xchk_iscan_iter_batch()
578 msecs_to_jiffies(iscan->iget_timeout); in xchk_iscan_iter_batch()
592 xfs_trans_brelse(sc->tp, agi_bp); in xchk_iscan_iter_batch()
594 ret = -ECANCELED; in xchk_iscan_iter_batch()
599 } while (ret == -EAGAIN); in xchk_iscan_iter_batch()
609 * -ECANCELED if the live scan aborted, -EBUSY if the incore inode could not be
612 * If the function returns -EBUSY and the caller can handle skipping an inode,
626 if (iscan->__inodes[i]) in xchk_iscan_iter()
634 ASSERT(iscan->__inodes[0] != NULL); in xchk_iscan_iter()
639 *ipp = iscan->__inodes[i]; in xchk_iscan_iter()
640 iscan->__inodes[i] = NULL; in xchk_iscan_iter()
649 struct xfs_scrub *sc = iscan->sc; in xchk_iscan_iter_finish()
653 if (iscan->__inodes[i]) { in xchk_iscan_iter_finish()
654 xchk_irele(sc, iscan->__inodes[i]); in xchk_iscan_iter_finish()
655 iscan->__inodes[i] = NULL; in xchk_iscan_iter_finish()
667 mutex_destroy(&iscan->lock); in xchk_iscan_teardown()
676 unsigned int r = atomic_inc_return(&agi_rotor) - 1; in xchk_iscan_rotor()
682 r = (r % mp->m_sb.sb_agcount) + 1; in xchk_iscan_rotor()
684 return XFS_AGINO_TO_INO(mp, mp->m_sb.sb_agcount - r, 0); in xchk_iscan_rotor()
703 start_ino = xchk_iscan_rotor(sc->mp); in xchk_iscan_start()
705 iscan->__batch_ino = NULLFSINO; in xchk_iscan_start()
706 iscan->__skipped_inomask = 0; in xchk_iscan_start()
708 iscan->sc = sc; in xchk_iscan_start()
709 clear_bit(XCHK_ISCAN_OPSTATE_ABORTED, &iscan->__opstate); in xchk_iscan_start()
710 iscan->iget_timeout = iget_timeout; in xchk_iscan_start()
711 iscan->iget_retry_delay = iget_retry_delay; in xchk_iscan_start()
712 iscan->__visited_ino = start_ino; in xchk_iscan_start()
713 iscan->cursor_ino = start_ino; in xchk_iscan_start()
714 iscan->scan_start_ino = start_ino; in xchk_iscan_start()
715 mutex_init(&iscan->lock); in xchk_iscan_start()
716 memset(iscan->__inodes, 0, sizeof(iscan->__inodes)); in xchk_iscan_start()
730 mutex_lock(&iscan->lock); in xchk_iscan_mark_visited()
731 iscan->__visited_ino = ip->i_ino; in xchk_iscan_mark_visited()
733 mutex_unlock(&iscan->lock); in xchk_iscan_mark_visited()
738 * If so, it is newly allocated and will not be scanned. All live updates to
746 if (iscan->__batch_ino == NULLFSINO) in xchk_iscan_skipped()
748 if (ino < iscan->__batch_ino) in xchk_iscan_skipped()
750 if (ino >= iscan->__batch_ino + XFS_INODES_PER_CHUNK) in xchk_iscan_skipped()
753 return iscan->__skipped_inomask & (1ULL << (ino - iscan->__batch_ino)); in xchk_iscan_skipped()
757 * Do we need a live update for this inode? This is true if the scanner thread
772 mutex_lock(&iscan->lock); in xchk_iscan_want_live_update()
777 if (iscan->__visited_ino == NULLFSINO) { in xchk_iscan_want_live_update()
786 if (iscan->scan_start_ino == iscan->__visited_ino) { in xchk_iscan_want_live_update()
804 * 0 ------------ S ************ V ------------ EOFS in xchk_iscan_want_live_update()
806 if (iscan->scan_start_ino <= iscan->__visited_ino) { in xchk_iscan_want_live_update()
807 if (ino >= iscan->scan_start_ino && in xchk_iscan_want_live_update()
808 ino <= iscan->__visited_ino) in xchk_iscan_want_live_update()
818 * 0 ************ V ------------ S ************ EOFS in xchk_iscan_want_live_update()
820 if (ino >= iscan->scan_start_ino || ino <= iscan->__visited_ino) in xchk_iscan_want_live_update()
824 mutex_unlock(&iscan->lock); in xchk_iscan_want_live_update()