blob: c5e0a7c08be05650ca31774ae838faec38bb6e8e [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2021-2024 Oracle. All Rights Reserved.
* Author: Darrick J. Wong <djwong@kernel.org>
*/
#ifndef XFS_SCRUB_SCRUB_PRIVATE_H_
#define XFS_SCRUB_SCRUB_PRIVATE_H_
/* Shared code between scrub.c and repair.c. */
void xfrog_scrubv_from_item(struct xfrog_scrubv *scrubv,
const struct scrub_item *sri);
void xfrog_scrubv_add_item(struct xfrog_scrubv *scrubv,
const struct scrub_item *sri, unsigned int scrub_type,
bool want_repair);
void xfrog_scrubv_add_barrier(struct xfrog_scrubv *scrubv);
struct scrubv_descr {
struct xfrog_scrubv *scrubv;
int idx;
};
#define SCRUBV_DESCR(sv) { .scrubv = (sv), .idx = -1 }
int format_scrubv_descr(struct scrub_ctx *ctx, char *buf, size_t buflen,
void *where);
/* Predicates for scrub flag state. */
static inline bool is_corrupt(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_CORRUPT;
}
static inline bool is_unoptimized(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_PREEN;
}
static inline bool xref_failed(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_XFAIL;
}
static inline bool xref_disagrees(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_XCORRUPT;
}
static inline bool is_incomplete(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_INCOMPLETE;
}
static inline bool is_suspicious(const struct xfs_scrub_vec *sv)
{
return sv->sv_flags & XFS_SCRUB_OFLAG_WARNING;
}
/* Should we fix it? */
static inline bool needs_repair(const struct xfs_scrub_vec *sv)
{
return is_corrupt(sv) || xref_disagrees(sv);
}
/*
* We want to retry an operation if the kernel says it couldn't complete the
* scan/repair; or if there were cross-referencing problems but the object was
* not obviously corrupt.
*/
static inline bool want_retry(const struct xfs_scrub_vec *sv)
{
return is_incomplete(sv) || (xref_disagrees(sv) && !is_corrupt(sv));
}
void scrub_warn_incomplete_scrub(struct scrub_ctx *ctx, struct descr *dsc,
const struct xfs_scrub_vec *meta);
/* Scrub item functions */
static inline void
scrub_item_save_state(
struct scrub_item *sri,
unsigned int scrub_type,
unsigned int scrub_flags)
{
sri->sri_state[scrub_type] = scrub_flags & SCRUB_ITEM_REPAIR_ANY;
if (scrub_flags & SCRUB_ITEM_NEEDSREPAIR)
sri->sri_inconsistent = true;
}
static inline void
scrub_item_clean_state(
struct scrub_item *sri,
unsigned int scrub_type)
{
sri->sri_state[scrub_type] = 0;
}
static inline bool
scrub_item_type_boosted(
struct scrub_item *sri,
unsigned int scrub_type)
{
return sri->sri_state[scrub_type] & SCRUB_ITEM_BOOST_REPAIR;
}
/* Decide if we want to retry this operation and update bookkeeping if yes. */
static inline bool
scrub_item_schedule_retry(struct scrub_item *sri, unsigned int scrub_type)
{
if (sri->sri_tries[scrub_type] == 0)
return false;
sri->sri_tries[scrub_type]--;
return true;
}
bool scrub_item_call_kernel_again(struct scrub_item *sri, uint8_t work_mask,
const struct scrub_item *old);
bool scrub_item_schedule_work(struct scrub_item *sri, uint8_t state_flags,
const unsigned int *schedule_deps);
#endif /* XFS_SCRUB_SCRUB_PRIVATE_H_ */