#include <lustre/lustre_lfsck_user.h>
#include <lustre/lustre_user.h>
#include <lustre/lustre_idl.h>
+#include <lustre_lfsck.h>
#include <obd.h>
#include <lu_object.h>
#include <dt_object.h>
#include <lustre_net.h>
#include <lustre_dlm.h>
#include <lustre_fid.h>
+#include <md_object.h>
#define HALF_SEC (HZ >> 1)
#define LFSCK_CHECKPOINT_INTERVAL 60
#define LFSCK_NAMEENTRY_REMOVED 2 /* The entry has been removed. */
#define LFSCK_NAMEENTRY_RECREATED 3 /* The entry has been recreated. */
-enum lfsck_status {
- /* The lfsck file is new created, for new MDT, upgrading from old disk,
- * or re-creating the lfsck file manually. */
- LS_INIT = 0,
-
- /* The first-step system scanning. */
- LS_SCANNING_PHASE1 = 1,
-
- /* The second-step system scanning. */
- LS_SCANNING_PHASE2 = 2,
-
- /* The LFSCK processing has completed for all objects. */
- LS_COMPLETED = 3,
-
- /* The LFSCK exited automatically for failure, will not auto restart. */
- LS_FAILED = 4,
-
- /* The LFSCK is stopped manually, will not auto restart. */
- LS_STOPPED = 5,
-
- /* LFSCK is paused automatically when umount,
- * will be restarted automatically when remount. */
- LS_PAUSED = 6,
-
- /* System crashed during the LFSCK,
- * will be restarted automatically after recovery. */
- LS_CRASHED = 7,
-};
-
enum lfsck_flags {
/* Finish the first cycle scanning. */
- LF_SCANNED_ONCE = 0x00000001ULL,
+ LF_SCANNED_ONCE = 0x00000001ULL,
/* There is some namespace inconsistency. */
- LF_INCONSISTENT = 0x00000002ULL,
+ LF_INCONSISTENT = 0x00000002ULL,
/* The device is upgraded from 1.8 format. */
- LF_UPGRADE = 0x00000004ULL,
+ LF_UPGRADE = 0x00000004ULL,
+
+ /* The server ever restarted during the LFSCK, and may miss to process
+ * some objects check/repair. */
+ LF_INCOMPLETE = 0x00000008ULL,
};
struct lfsck_position {
__u64 ln_reserved[2];
};
+enum lfsck_layout_inconsistency_type {
+ LLIT_NONE = 0,
+ LLIT_DANGLING = 1,
+ LLIT_UNMATCHED_PAIR = 2,
+ LLIT_MULTIPLE_REFERENCED = 3,
+ LLIT_ORPHAN = 4,
+ LLIT_INCONSISTENT_OWNER = 5,
+ LLIT_OTHERS = 6,
+ LLIT_MAX = LLIT_OTHERS
+};
+
+struct lfsck_layout {
+ /* Magic number to detect that this struct contains valid data. */
+ __u32 ll_magic;
+
+ /* See 'enum lfsck_status'. */
+ __u32 ll_status;
+
+ /* See 'enum lfsck_flags'. */
+ __u32 ll_flags;
+
+ /* How many completed LFSCK runs on the device. */
+ __u32 ll_success_count;
+
+ /* How long the LFSCK phase1 has run in seconds. */
+ __u32 ll_run_time_phase1;
+
+ /* How long the LFSCK phase2 has run in seconds. */
+ __u32 ll_run_time_phase2;
+
+ /* Time for the last LFSCK completed in seconds since epoch. */
+ __u64 ll_time_last_complete;
+
+ /* Time for the latest LFSCK ran in seconds since epoch. */
+ __u64 ll_time_latest_start;
+
+ /* Time for the last LFSCK checkpoint in seconds since epoch. */
+ __u64 ll_time_last_checkpoint;
+
+ /* Position for the latest LFSCK started from. */
+ __u64 ll_pos_latest_start;
+
+ /* Position for the last LFSCK checkpoint. */
+ __u64 ll_pos_last_checkpoint;
+
+ /* Position for the first should be updated object. */
+ __u64 ll_pos_first_inconsistent;
+
+ /* How many objects have been checked. */
+ __u64 ll_objs_checked_phase1;
+
+ /* How many objects failed to be processed. */
+ __u64 ll_objs_failed_phase1;
+
+ /* How many objects have been double scanned. */
+ __u64 ll_objs_checked_phase2;
+
+ /* How many objects failed to be processed during double scan. */
+ __u64 ll_objs_failed_phase2;
+
+ /* kinds of inconsistency have been repaired.
+ * ll_objs_repaired[type - 1] is the count for the given @type. */
+ __u64 ll_objs_repaired[LLIT_MAX];
+
+ /* How many objects have been skipped because of related
+ * MDT(s)/OST(s) do not participate in the LFSCK */
+ __u64 ll_objs_skipped;
+
+ /* For further using. 256-bytes aligned now. */
+ __u64 ll_reserved[12];
+};
+
struct lfsck_component;
struct lfsck_operations {
/* into lfsck_instance::li_list_dir */
cfs_list_t lc_link_dir;
struct rw_semaphore lc_sem;
- cfs_atomic_t lc_ref;
+ atomic_t lc_ref;
struct lfsck_position lc_pos_start;
struct lfsck_instance *lc_lfsck;
struct lfsck_operations *lc_ops;
void *lc_file_ram;
void *lc_file_disk;
+
+ /* The time for last checkpoint, jiffies */
+ cfs_time_t lc_time_last_checkpoint;
+
+ /* The time for next checkpoint, jiffies */
+ cfs_time_t lc_time_next_checkpoint;
+
__u32 lc_file_size;
/* How many objects have been checked since last checkpoint. */
__u32 lc_new_checked;
+
+ /* How many objects have been scanned since last sleep. */
+ __u32 lc_new_scanned;
+
unsigned int lc_journal:1;
__u16 lc_type;
};
/* For the components those are not scanning now. */
cfs_list_t li_list_idle;
- cfs_atomic_t li_ref;
+ atomic_t li_ref;
struct ptlrpc_thread li_thread;
/* The time for last checkpoint, jiffies */
struct dt_device *li_bottom;
struct ldlm_namespace *li_namespace;
struct local_oid_storage *li_los;
- struct dt_object *li_local_root; /* backend root "/" */
+ struct lu_fid li_local_root_fid; /* backend root "/" */
struct lu_fid li_global_root_fid; /* /ROOT */
struct dt_object *li_bookmark_obj;
struct lfsck_bookmark li_bookmark_ram;
LLF_REPAIR_FAILED = 0x02,
};
+struct lfsck_thread_args {
+ struct lu_env lta_env;
+ struct lfsck_instance *lta_lfsck;
+ struct lfsck_component *lta_com;
+};
+
struct lfsck_thread_info {
struct lu_name lti_name;
struct lu_buf lti_buf;
struct lu_fid lti_fid;
struct lu_fid lti_fid2;
struct lu_attr lti_la;
+ struct ost_id lti_oi;
+ union {
+ struct lustre_mdt_attrs lti_lma;
+ /* old LMA for compatibility */
+ char lti_lma_old[LMA_OLD_SIZE];
+ };
/* lti_ent and lti_key must be conjoint,
* then lti_ent::lde_name will be lti_key. */
struct lu_dirent lti_ent;
};
/* lfsck_lib.c */
+const char *lfsck_status2names(enum lfsck_status status);
void lfsck_component_cleanup(const struct lu_env *env,
struct lfsck_component *com);
+void lfsck_instance_cleanup(const struct lu_env *env,
+ struct lfsck_instance *lfsck);
int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[],
const char *prefix);
int lfsck_time_dump(char **buf, int *len, __u64 time, const char *prefix);
void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck,
struct lfsck_position *pos, bool init);
void lfsck_control_speed(struct lfsck_instance *lfsck);
+void lfsck_control_speed_by_self(struct lfsck_component *com);
int lfsck_reset(const struct lu_env *env, struct lfsck_instance *lfsck,
bool init);
+struct lfsck_thread_args *lfsck_thread_args_init(struct lfsck_instance *lfsck,
+ struct lfsck_component *com);
+void lfsck_thread_args_fini(struct lfsck_thread_args *lta);
void lfsck_fail(const struct lu_env *env, struct lfsck_instance *lfsck,
bool new_checked);
int lfsck_checkpoint(const struct lu_env *env, struct lfsck_instance *lfsck);
int lfsck_namespace_setup(const struct lu_env *env,
struct lfsck_instance *lfsck);
-extern const char *lfsck_status_names[];
+/* lfsck_layout.c */
+int lfsck_layout_setup(const struct lu_env *env, struct lfsck_instance *lfsck);
+
extern const char *lfsck_flags_names[];
extern const char *lfsck_param_names[];
extern struct lu_context_key lfsck_thread_key;
lu_object_put(env, &obj->do_lu);
}
+static inline struct lfsck_component *
+lfsck_component_get(struct lfsck_component *com)
+{
+ atomic_inc(&com->lc_ref);
+
+ return com;
+}
+
+static inline void lfsck_component_put(const struct lu_env *env,
+ struct lfsck_component *com)
+{
+ if (atomic_dec_and_test(&com->lc_ref)) {
+ if (com->lc_obj != NULL)
+ lu_object_put_nocache(env, &com->lc_obj->do_lu);
+ if (com->lc_file_ram != NULL)
+ OBD_FREE(com->lc_file_ram, com->lc_file_size);
+ if (com->lc_file_disk != NULL)
+ OBD_FREE(com->lc_file_disk, com->lc_file_size);
+ OBD_FREE_PTR(com);
+ }
+}
+
+static inline struct lfsck_instance *
+lfsck_instance_get(struct lfsck_instance *lfsck)
+{
+ atomic_inc(&lfsck->li_ref);
+
+ return lfsck;
+}
+
+static inline void lfsck_instance_put(const struct lu_env *env,
+ struct lfsck_instance *lfsck)
+{
+ if (atomic_dec_and_test(&lfsck->li_ref))
+ lfsck_instance_cleanup(env, lfsck);
+}
+
+static inline mdsno_t lfsck_dev_idx(struct dt_device *dev)
+{
+ return dev->dd_lu_dev.ld_site->ld_seq_site->ss_node_id;
+}
+
#endif /* _LFSCK_INTERNAL_H */