#ifndef _LUSTRE_SCRUB_H
# define _LUSTRE_SCRUB_H
+#include <linux/uuid.h>
#include <dt_object.h>
#include <lustre_net.h>
+#include <uapi/linux/lustre/lustre_disk.h>
-#define OSD_OI_FID_OID_BITS_MAX 10
-#define OSD_OI_FID_NR_MAX (1UL << OSD_OI_FID_OID_BITS_MAX)
-#define SCRUB_OI_BITMAP_SIZE (OSD_OI_FID_NR_MAX >> 3)
-#define PFID_STRIPE_IDX_BITS 16
-#define PFID_STRIPE_COUNT_MASK ((1 << PFID_STRIPE_IDX_BITS) - 1)
-
-#define SCRUB_MAGIC_V1 0x4C5FD252
#define SCRUB_CHECKPOINT_INTERVAL 60
#define SCRUB_WINDOW_SIZE 1024
-#define HALF_SEC msecs_to_jiffies(MSEC_PER_SEC >> 1)
-
enum scrub_next_status {
/* exit current loop and process next group */
SCRUB_NEXT_BREAK = 1,
SLFF_IDX_IN_FID = 0x0010,
};
-enum scrub_status {
- /* The scrub file is new created, for new MDT, upgrading from old disk,
- * or re-creating the scrub file manually. */
- SS_INIT = 0,
-
- /* The scrub is checking/repairing the OI files. */
- SS_SCANNING = 1,
-
- /* The scrub checked/repaired the OI files successfully. */
- SS_COMPLETED = 2,
-
- /* The scrub failed to check/repair the OI files. */
- SS_FAILED = 3,
-
- /* The scrub is stopped manually, the OI files may be inconsistent. */
- SS_STOPPED = 4,
-
- /* The scrub is paused automatically when umount. */
- SS_PAUSED = 5,
-
- /* The scrub crashed during the scanning, should be restarted. */
- SS_CRASHED = 6,
-};
-
-enum scrub_flags {
- /* OI files have been recreated, OI mappings should be re-inserted. */
- SF_RECREATED = 0x0000000000000001ULL,
-
- /* OI files are invalid, should be rebuild ASAP */
- SF_INCONSISTENT = 0x0000000000000002ULL,
-
- /* OI scrub is triggered automatically. */
- SF_AUTO = 0x0000000000000004ULL,
-
- /* The device is upgraded from 1.8 format. */
- SF_UPGRADE = 0x0000000000000008ULL,
-};
-
-enum scrub_param {
- /* Exit when fail. */
- SP_FAILOUT = 0x0001,
-
- /* Check only without repairing. */
- SP_DRYRUN = 0x0002,
-};
-
enum scrub_start {
/* Set failout flag. */
SS_SET_FAILOUT = 0x00000001,
* OI inconsistency especailly when OI scrub just done recently.
*
* The 'auto_scrub' defines the time (united as second) interval to
- * enable auto detect OI inconsistency since last OI scurb done. */
+ * enable auto detect OI inconsistency since last OI scurb done.
+ */
enum auto_scrub {
/* Disable auto scrub. */
AS_NEVER = 0,
/* 1 second is too short interval, it is almost equal to always auto
- * detect inconsistent OI, usually used for test. */
+ * detect inconsistent OI, usually used for test.
+ */
AS_ALWAYS = 1,
/* Enable auto detect OI inconsistency one month (60 * 60 * 24 * 30)
- * after last OI scrub. */
+ * after last OI scrub.
+ */
AS_DEFAULT = 2592000LL,
};
-struct scrub_file {
- /* 128-bit uuid for volume. */
- __u8 sf_uuid[16];
-
- /* See 'enum scrub_flags'. */
- __u64 sf_flags;
-
- /* The scrub magic. */
- __u32 sf_magic;
-
- /* See 'enum scrub_status'. */
- __u16 sf_status;
-
- /* See 'enum scrub_param'. */
- __u16 sf_param;
-
- /* The time for the last OI scrub completed. */
- __u64 sf_time_last_complete;
-
- /* The time for the latest OI scrub ran. */
- __u64 sf_time_latest_start;
-
- /* The time for the last OI scrub checkpoint. */
- __u64 sf_time_last_checkpoint;
-
- /* The position for the latest OI scrub started from. */
- __u64 sf_pos_latest_start;
-
- /* The position for the last OI scrub checkpoint. */
- __u64 sf_pos_last_checkpoint;
-
- /* The position for the first should be updated object. */
- __u64 sf_pos_first_inconsistent;
-
- /* How many objects have been checked. */
- __u64 sf_items_checked;
-
- /* How many objects have been updated. */
- __u64 sf_items_updated;
-
- /* How many objects failed to be processed. */
- __u64 sf_items_failed;
-
- /* How many prior objects have been updated during scanning. */
- __u64 sf_items_updated_prior;
-
- /* How many objects marked as LDISKFS_STATE_LUSTRE_NOSCRUB. */
- __u64 sf_items_noscrub;
-
- /* How many IGIF objects. */
- __u64 sf_items_igif;
-
- /* How long the OI scrub has run. */
- __u32 sf_run_time;
-
- /* How many completed OI scrub ran on the device. */
- __u32 sf_success_count;
-
- /* How many OI files. */
- __u16 sf_oi_count;
-
- /* Keep the flags after scrub reset. See 'enum scrub_internal_flags' */
- __u16 sf_internal_flags;
-
- __u32 sf_reserved_1;
- __u64 sf_reserved_2[16];
-
- /* Bitmap for OI files recreated case. */
- __u8 sf_oi_bitmap[SCRUB_OI_BITMAP_SIZE];
-};
-
struct lustre_scrub {
/* Object for the scrub file. */
struct dt_object *os_obj;
- struct ptlrpc_thread os_thread;
+ struct task_struct *os_task;
struct list_head os_inconsistent_items;
+ /* once inconsistent mapping can't be fixed, put into this list */
+ struct list_head os_stale_items;
/* write lock for scrub prep/update/post/checkpoint,
- * read lock for scrub dump. */
+ * read lock for scrub dump.
+ */
struct rw_semaphore os_rwsem;
spinlock_t os_lock;
const char *os_name;
- /* The time for last checkpoint, jiffies */
- cfs_time_t os_time_last_checkpoint;
+ /* The time for last checkpoint, seconds */
+ time64_t os_time_last_checkpoint;
+
+ /* The time for next checkpoint, seconds */
+ time64_t os_time_next_checkpoint;
- /* The time for next checkpoint, jiffies */
- cfs_time_t os_time_next_checkpoint;
+ /* How long to wait to start scrubbing */
+ time64_t os_auto_scrub_interval;
/* How many objects have been checked since last checkpoint. */
__u64 os_new_checked;
__u64 os_pos_current;
__u32 os_start_flags;
- unsigned int os_in_prior:1, /* process inconsistent item
- * found by RPC prior */
+ /* Some of these bits can be set by different threads so
+ * all updates must be protected by ->os_lock to avoid
+ * racing read-modify-write cycles causing corruption.
+ */
+ /* process inconsistent item found by RPC prior */
+ unsigned int os_in_prior:1,
os_waiting:1, /* Waiting for scan window. */
os_full_speed:1, /* run w/o speed limit */
os_paused:1, /* The scrub is paused. */
os_convert_igif:1,
os_partial_scan:1,
os_in_join:1,
- os_full_scrub:1;
+ os_running:1, /* scrub thread is running */
+ os_full_scrub:1,
+ os_has_ml_file:1;
};
#define INDEX_BACKUP_MAGIC_V1 0x1E41F208
char liru_name[0];
};
-void scrub_file_init(struct lustre_scrub *scrub, __u8 *uuid);
-void scrub_file_reset(struct lustre_scrub *scrub, __u8 *uuid, __u64 flags);
+void scrub_file_init(struct lustre_scrub *scrub, guid_t uuid);
+void scrub_file_reset(struct lustre_scrub *scrub, guid_t uuid, u64 flags);
int scrub_file_load(const struct lu_env *env, struct lustre_scrub *scrub);
int scrub_file_store(const struct lu_env *env, struct lustre_scrub *scrub);
+bool scrub_needs_check(struct lustre_scrub *scrub, const struct lu_fid *fid,
+ u64 index);
int scrub_checkpoint(const struct lu_env *env, struct lustre_scrub *scrub);
+int scrub_thread_prep(const struct lu_env *env, struct lustre_scrub *scrub,
+ guid_t uuid, u64 start);
+int scrub_thread_post(const struct lu_env *env, struct lustre_scrub *scrub,
+ int result);
int scrub_start(int (*threadfn)(void *data), struct lustre_scrub *scrub,
void *data, __u32 flags);
void scrub_stop(struct lustre_scrub *scrub);