#include <obd_class.h>
#include <lustre_nodemap.h>
#include <sys/dsl_dataset.h>
+#include <sys/zap_impl.h>
+#include <sys/zap.h>
+#include <sys/zap_leaf.h>
#include "osd_internal.h"
scrub->os_pos_current = sf->sf_pos_latest_start;
sf->sf_status = SS_SCANNING;
- sf->sf_time_latest_start = cfs_time_current_sec();
+ sf->sf_time_latest_start = ktime_get_real_seconds();
sf->sf_time_last_checkpoint = sf->sf_time_latest_start;
sf->sf_pos_last_checkpoint = sf->sf_pos_latest_start - 1;
rc = scrub_file_store(env, scrub);
scrub->os_new_checked = 0;
sf->sf_pos_last_checkpoint = scrub->os_pos_current;
}
- sf->sf_time_last_checkpoint = cfs_time_current_sec();
+ sf->sf_time_last_checkpoint = ktime_get_real_seconds();
if (result > 0) {
sf->sf_status = SS_COMPLETED;
if (!(sf->sf_param & SP_DRYRUN)) {
} else {
sf->sf_status = SS_FAILED;
}
- sf->sf_run_time += cfs_duration_sec(cfs_time_current() + HALF_SEC -
- scrub->os_time_last_checkpoint);
+ sf->sf_run_time += ktime_get_seconds() -
+ scrub->os_time_last_checkpoint;
+
rc = scrub_file_store(env, scrub);
up_write(&scrub->os_rwsem);
/* PENDING */
{
- .olm_name = "PENDING",
+ .olm_name = MDT_ORPHAN_DIR,
},
/* ROOT */
/* LFSCK */
{
.olm_name = LFSCK_DIR,
- .olm_flags = OLF_SCAN_SUBITEMS,
+ .olm_flags = OLF_SCAN_SUBITEMS | OLF_NOT_BACKUP,
.olm_scan_dir = osd_ios_general_sd,
.olm_handle_dirent = osd_ios_varfid_hd,
},
.olm_name = LUSTRE_NODEMAP_NAME,
},
+ /* index_backup */
+ {
+ .olm_name = INDEX_BACKUP_DIR,
+ .olm_fid = {
+ .f_seq = FID_SEQ_LOCAL_FILE,
+ .f_oid = INDEX_BACKUP_OID,
+ },
+ .olm_flags = OLF_SCAN_SUBITEMS | OLF_NOT_BACKUP,
+ .olm_scan_dir = osd_ios_general_sd,
+ .olm_handle_dirent = osd_ios_varfid_hd,
+ },
+
{
.olm_name = NULL
}
return 0;
}
+static bool osd_index_need_recreate(const struct lu_env *env,
+ struct osd_device *dev, uint64_t oid)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ zap_attribute_t *za = &info->oti_za2;
+ zap_cursor_t *zc = &info->oti_zc2;
+ int rc;
+ ENTRY;
+
+ zap_cursor_init_serialized(zc, dev->od_os, oid, 0);
+ rc = -zap_cursor_retrieve(zc, za);
+ zap_cursor_fini(zc);
+ if (rc && rc != -ENOENT)
+ RETURN(true);
+
+ RETURN(false);
+}
+
+static void osd_ios_index_register(const struct lu_env *env,
+ struct osd_device *osd,
+ const struct lu_fid *fid, uint64_t oid)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ zap_attribute_t *za = &info->oti_za2;
+ zap_cursor_t *zc = &info->oti_zc2;
+ struct zap_leaf_entry *le;
+ dnode_t *dn = NULL;
+ sa_handle_t *hdl;
+ __u64 mode = 0;
+ __u32 keysize = 0;
+ __u32 recsize = 0;
+ int rc;
+ ENTRY;
+
+ rc = __osd_obj2dnode(osd->od_os, oid, &dn);
+ if (rc == -EEXIST || rc == -ENOENT)
+ RETURN_EXIT;
+
+ if (rc < 0)
+ GOTO(log, rc);
+
+ if (!osd_object_is_zap(dn))
+ GOTO(log, rc = 1);
+
+ rc = -sa_handle_get(osd->od_os, oid, NULL, SA_HDL_PRIVATE, &hdl);
+ if (rc)
+ GOTO(log, rc);
+
+ rc = -sa_lookup(hdl, SA_ZPL_MODE(osd), &mode, sizeof(mode));
+ sa_handle_destroy(hdl);
+ if (rc)
+ GOTO(log, rc);
+
+ if (!S_ISREG(mode))
+ GOTO(log, rc = 1);
+
+ zap_cursor_init_serialized(zc, osd->od_os, oid, 0);
+ rc = -zap_cursor_retrieve(zc, za);
+ if (rc)
+ /* Skip empty index object */
+ GOTO(fini, rc = (rc == -ENOENT ? 1 : rc));
+
+ if (zc->zc_zap->zap_ismicro ||
+ !(zap_f_phys(zc->zc_zap)->zap_flags & ZAP_FLAG_UINT64_KEY))
+ GOTO(fini, rc = 1);
+
+ le = ZAP_LEAF_ENTRY(zc->zc_leaf, 0);
+ keysize = le->le_name_numints * 8;
+ recsize = za->za_integer_length * za->za_num_integers;
+ if (likely(keysize && recsize))
+ rc = osd_index_register(osd, fid, keysize, recsize);
+
+ GOTO(fini, rc);
+
+fini:
+ zap_cursor_fini(zc);
+
+log:
+ if (dn)
+ osd_dnode_rele(dn);
+ if (rc < 0)
+ CWARN("%s: failed to register index "DFID" (%u/%u): rc = %d\n",
+ osd_name(osd), PFID(fid), keysize, recsize, rc);
+ else if (!rc)
+ CDEBUG(D_LFSCK, "%s: registered index "DFID" (%u/%u)\n",
+ osd_name(osd), PFID(fid), keysize, recsize);
+}
+
+static void osd_index_restore(const struct lu_env *env, struct osd_device *dev,
+ struct lustre_index_restore_unit *liru, void *buf,
+ int bufsize)
+{
+ struct luz_direntry *zde = &osd_oti_get(env)->oti_zde;
+ struct lu_fid *tgt_fid = &liru->liru_cfid;
+ struct lu_fid bak_fid;
+ int rc;
+ ENTRY;
+
+ lustre_fid2lbx(buf, tgt_fid, bufsize);
+ rc = -zap_lookup(dev->od_os, dev->od_index_backup_id, buf, 8,
+ sizeof(*zde) / 8, (void *)zde);
+ if (rc)
+ GOTO(log, rc);
+
+ rc = osd_get_fid_by_oid(env, dev, zde->lzd_reg.zde_dnode, &bak_fid);
+ if (rc)
+ GOTO(log, rc);
+
+ /* The OI mapping for index may be invalid, since it will be
+ * re-created, not update the OI mapping, just cache it in RAM. */
+ rc = osd_idc_find_and_init_with_oid(env, dev, tgt_fid,
+ liru->liru_clid);
+ if (!rc)
+ rc = lustre_index_restore(env, &dev->od_dt_dev,
+ &liru->liru_pfid, tgt_fid, &bak_fid,
+ liru->liru_name, &dev->od_index_backup_list,
+ &dev->od_lock, buf, bufsize);
+ GOTO(log, rc);
+
+log:
+ CDEBUG(D_WARNING, "%s: restore index '%s' with "DFID": rc = %d\n",
+ osd_name(dev), liru->liru_name, PFID(tgt_fid), rc);
+}
+
/**
* verify FID-in-LMA and OI entry for one object
*
RETURN(0);
}
+ if (lma->lma_compat & LMAC_IDX_BACKUP &&
+ osd_index_need_recreate(env, dev, oid)) {
+ if (parent == dev->od_root) {
+ lu_local_obj_fid(&tfid,
+ OSD_FS_ROOT_OID);
+ } else {
+ rc = osd_get_fid_by_oid(env, dev,
+ parent, &tfid);
+ if (rc) {
+ nvlist_free(nvbuf);
+ RETURN(rc);
+ }
+ }
+
+ rc = lustre_liru_new(
+ &dev->od_index_restore_list,
+ &tfid, &lma->lma_self_fid, oid,
+ name, strlen(name));
+ nvlist_free(nvbuf);
+ RETURN(rc);
+ }
+
tfid = lma->lma_self_fid;
+ if (!(flags & OLF_NOT_BACKUP))
+ osd_ios_index_register(env, dev, &tfid, oid);
}
nvlist_free(nvbuf);
}
OBD_FREE_PTR(item);
}
+ if (!list_empty(&dev->od_index_restore_list)) {
+ char *buf;
+
+ OBD_ALLOC_LARGE(buf, INDEX_BACKUP_BUFSIZE);
+ if (!buf)
+ CERROR("%s: not enough RAM for rebuild index\n",
+ osd_name(dev));
+
+ while (!list_empty(&dev->od_index_restore_list)) {
+ struct lustre_index_restore_unit *liru;
+
+ liru = list_entry(dev->od_index_restore_list.next,
+ struct lustre_index_restore_unit,
+ liru_link);
+ list_del(&liru->liru_link);
+ if (buf)
+ osd_index_restore(env, dev, liru, buf,
+ INDEX_BACKUP_BUFSIZE);
+ OBD_FREE(liru, liru->liru_len);
+ }
+
+ if (buf)
+ OBD_FREE_LARGE(buf, INDEX_BACKUP_BUFSIZE);
+ }
+
EXIT;
}
RETURN(rc == -EALREADY ? 0 : rc);
}
-static void osd_scrub_stop(struct osd_device *dev)
+void osd_scrub_stop(struct osd_device *dev)
{
struct lustre_scrub *scrub = &dev->od_scrub;
ENTRY;
if (IS_ERR_OR_NULL(obj))
RETURN(obj ? PTR_ERR(obj) : -ENOENT);
+ obj->do_body_ops = &osd_body_scrub_ops;
scrub->os_obj = obj;
rc = scrub_file_load(env, scrub);
if (rc == -ENOENT || rc == -EFAULT) {
"failed to allocate RAM for report\n",
osd_name(dev));
} else {
- class_uuid_unparse(sf->sf_uuid, old_uuid);
- class_uuid_unparse(dev->od_uuid, new_uuid);
- CDEBUG(D_LFSCK, "%s: UUID has been changed "
- "from %s to %s\n", osd_name(dev),
+ snprintf(old_uuid->uuid, UUID_SIZE, "%pU", sf->sf_uuid);
+ snprintf(new_uuid->uuid, UUID_SIZE, "%pU", dev->od_uuid);
+ CDEBUG(D_LFSCK,
+ "%s: UUID has been changed from %s to %s\n",
+ osd_name(dev),
old_uuid->uuid, new_uuid->uuid);
}
scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT);