#ifndef _LUSTRE_SCRUB_H
# define _LUSTRE_SCRUB_H
+#include <libcfs/linux/linux-uuid.h>
#include <dt_object.h>
#include <lustre_net.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,
OLF_SHOW_NAME = 0x0004,
OLF_NO_OI = 0x0008,
OLF_IDX_IN_FID = 0x0010,
+ OLF_NOT_BACKUP = 0x0020,
};
/* There are some overhead to detect OI inconsistency automatically
struct scrub_file {
/* 128-bit uuid for volume. */
- __u8 sf_uuid[16];
+ uuid_t sf_uuid;
/* See 'enum scrub_flags'. */
__u64 sf_flags;
__u16 sf_param;
/* The time for the last OI scrub completed. */
- __u64 sf_time_last_complete;
+ time64_t sf_time_last_complete;
- /* The time for the latest OI scrub ran. */
- __u64 sf_time_latest_start;
+ /* The ttime for the latest OI scrub ran. */
+ time64_t sf_time_latest_start;
/* The time for the last OI scrub checkpoint. */
- __u64 sf_time_last_checkpoint;
+ time64_t sf_time_last_checkpoint;
/* The position for the latest OI scrub started from. */
__u64 sf_pos_latest_start;
/* How many IGIF objects. */
__u64 sf_items_igif;
- /* How long the OI scrub has run. */
- __u32 sf_run_time;
+ /* How long the OI scrub has run in seconds. Do NOT change
+ * to time64_t since this breaks backwards compatibility.
+ * It shouldn't take more than 136 years to complete :-)
+ */
+ s32 sf_run_time;
/* How many completed OI scrub ran on the device. */
__u32 sf_success_count;
};
struct lustre_scrub {
- struct lu_object_header os_obj_header;
/* Object for the scrub file. */
struct dt_object *os_obj;
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, jiffies */
- cfs_time_t os_time_next_checkpoint;
+ /* The time for next checkpoint, seconds */
+ time64_t os_time_next_checkpoint;
/* How many objects have been checked since last checkpoint. */
__u64 os_new_checked;
os_full_scrub:1;
};
-void scrub_file_init(struct lustre_scrub *scrub, __u8 *uuid);
-void scrub_file_reset(struct lustre_scrub *scrub, __u8 *uuid, __u64 flags);
+#define INDEX_BACKUP_MAGIC_V1 0x1E41F208
+#define INDEX_BACKUP_BUFSIZE (4096 * 4)
+
+enum lustre_index_backup_policy {
+ /* By default, do not backup the index */
+ LIBP_NONE = 0,
+
+ /* Backup the dirty index objects when umount */
+ LIBP_AUTO = 1,
+};
+
+struct lustre_index_backup_header {
+ __u32 libh_magic;
+ __u32 libh_count;
+ __u32 libh_keysize;
+ __u32 libh_recsize;
+ struct lu_fid libh_owner;
+ __u64 libh_pad[60]; /* keep header 512 bytes aligned */
+};
+
+struct lustre_index_backup_unit {
+ struct list_head libu_link;
+ struct lu_fid libu_fid;
+ __u32 libu_keysize;
+ __u32 libu_recsize;
+};
+
+struct lustre_index_restore_unit {
+ struct list_head liru_link;
+ struct lu_fid liru_pfid;
+ struct lu_fid liru_cfid;
+ __u64 liru_clid;
+ int liru_len;
+ char liru_name[0];
+};
+
+void scrub_file_init(struct lustre_scrub *scrub, uuid_t uuid);
+void scrub_file_reset(struct lustre_scrub *scrub, uuid_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);
int scrub_checkpoint(const struct lu_env *env, struct lustre_scrub *scrub);
void scrub_stop(struct lustre_scrub *scrub);
void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub);
+int lustre_liru_new(struct list_head *head, const struct lu_fid *pfid,
+ const struct lu_fid *cfid, __u64 child,
+ const char *name, int namelen);
+
+int lustre_index_register(struct dt_device *dev, const char *devname,
+ struct list_head *head, spinlock_t *lock, int *guard,
+ const struct lu_fid *fid,
+ __u32 keysize, __u32 recsize);
+
+void lustre_index_backup(const struct lu_env *env, struct dt_device *dev,
+ const char *devname, struct list_head *head,
+ spinlock_t *lock, int *guard, bool backup);
+int lustre_index_restore(const struct lu_env *env, struct dt_device *dev,
+ const struct lu_fid *parent_fid,
+ const struct lu_fid *tgt_fid,
+ const struct lu_fid *bak_fid, const char *name,
+ struct list_head *head, spinlock_t *lock,
+ char *buf, int bufsize);
+
+static inline void lustre_fid2lbx(char *buf, const struct lu_fid *fid, int len)
+{
+ snprintf(buf, len, DFID_NOBRACE".lbx", PFID(fid));
+}
+
static inline const char *osd_scrub2name(struct lustre_scrub *scrub)
{
return scrub->os_name;