From 2a7e1688e2c9bff8f18f5596c112c445d0039e94 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Mon, 29 Apr 2013 12:15:27 +0800 Subject: [PATCH] LU-2742 oi: handle IGIF lookup For the MDT upgraded from 1.8 device, OI scrub will immobilize the IGIF and insert the mapping for "IGIF <=> ino#" into the OI file. There are three cases to be processed: 1) After the upgrading, all IGIFs have been processed and inserted into OI files. Then any IGIF object lookup should be processed as normal FID does, means via OI. If no entry in the OI file, then the IGIF object does not exist. 2) During the upgrading, some IGIFs may be already in OI files, others may be not yet. Under such case, lookup an IGIF in OI files may return -ENOENT, but it does not means the IGIF obj does not exist. Since the new immobilize IGIF is the same as the original one before backup/restore, OSD will generate local identifier from IGIF directly as old 2.x did. 3) The upgrading is paused, and backup/restore. Means upgrading from 1.8 may be partly processed, but some clients may hold some immobilized IGIFs, and use them to access related objects. Under such case, OSD does not know whether an given IGIF has been processed or to be processed, and it also cannot generate local ino#/gen# directly from the immobilized IGIF because of the backup/restore. Then force OSD to lookup the given IGIF in OI files, and if no entry, then ask the client to retry after upgrading completed. No better choice. Test-Parameters: testlist=sanity-scrub Signed-off-by: Fan Yong Change-Id: I7fff7898e2fcdf6b075bb04817f3b825c9a911b0 Reviewed-on: http://review.whamcloud.com/6254 Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Tested-by: Hudson Tested-by: Maloo --- lustre/osd-ldiskfs/osd_internal.h | 11 ++++--- lustre/osd-ldiskfs/osd_oi.c | 5 +++ lustre/osd-ldiskfs/osd_scrub.c | 66 ++++++++++++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index 14fef88..9c98789 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -244,7 +244,12 @@ struct osd_device { * Fid Capability */ unsigned int od_fl_capa:1, - od_is_md:1; /* set in ->ldo_prepare */ + od_is_md:1, /* set in ->ldo_prepare */ + od_noscrub:1, + od_dirent_journal:1, + od_handle_nolma:1, + od_igif_inoi:1; + unsigned long od_capa_timeout; __u32 od_capa_alg; struct lustre_capa_key *od_capa_keys; @@ -259,10 +264,6 @@ struct osd_device { struct obd_statfs od_statfs; spinlock_t od_osfs_lock; - unsigned int od_noscrub:1, - od_dirent_journal:1, - od_handle_nolma:1; - struct fsfilt_operations *od_fsops; int od_connects; struct lu_site od_site; diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index d8cc266..f90e518 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -527,6 +527,11 @@ int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, if (unlikely(fid_is_acct(fid))) return osd_acct_obj_lookup(info, osd, fid, id); + if (!osd->od_igif_inoi && fid_is_igif(fid)) { + osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid)); + return 0; + } + return __osd_oi_lookup(info, osd, fid, id); } diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 4bab583..6e9c37b 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -124,7 +124,7 @@ static int osd_scrub_refresh_mapping(struct osd_thread_info *info, rc = iam_update(jh, bag, (const struct iam_key *)oi_fid, (struct iam_rec *)oi_id, ipd); if (unlikely(rc == -ENOENT)) { - /* Some unlink thread mat removed the OI mapping. */ + /* Some unlink thread may removed the OI mapping. */ rc = 1; } break; @@ -483,8 +483,11 @@ iget: rc = osd_ea_fid_set(info, inode, fid, 0); if (rc != 0) GOTO(out, rc); + + if (!(sf->sf_flags & SF_INCONSISTENT)) + dev->od_igif_inoi = 0; } else { - sf->sf_flags |= SF_RECREATED | SF_INCONSISTENT; + sf->sf_flags |= SF_RECREATED; scrub->os_full_speed = 1; if (unlikely(!ldiskfs_test_bit(idx, sf->sf_oi_bitmap))) ldiskfs_set_bit(idx, sf->sf_oi_bitmap); @@ -494,6 +497,20 @@ iget: } else { sf->sf_flags |= SF_INCONSISTENT; scrub->os_full_speed = 1; + + /* XXX: If the device is restored from file-level backup, then + * some IGIFs may have been already in OI files, and some + * may be not yet. Means upgrading from 1.8 may be partly + * processed, but some clients may hold some immobilized + * IGIFs, and use them to access related objects. Under + * such case, OSD does not know whether an given IGIF has + * been processed or to be processed, and it also cannot + * generate local ino#/gen# directly from the immobilized + * IGIF because of the backup/restore. Then force OSD to + * lookup the given IGIF in OI files, and if no entry, + * then ask the client to retry after upgrading completed. + * No better choice. */ + dev->od_igif_inoi = 1; } rc = osd_scrub_refresh_mapping(info, dev, fid, lid, ops); @@ -576,6 +593,10 @@ static void osd_scrub_post(struct osd_scrub *scrub, int result) } sf->sf_time_last_checkpoint = cfs_time_current_sec(); if (result > 0) { + struct osd_device *dev = + container_of0(scrub, struct osd_device, od_scrub); + + dev->od_igif_inoi = 1; sf->sf_status = SS_COMPLETED; memset(sf->sf_oi_bitmap, 0, SCRUB_OI_BITMAP_SIZE); sf->sf_flags &= ~(SF_RECREATED | SF_INCONSISTENT | @@ -1710,14 +1731,33 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) RETURN(rc); rc = osd_initial_OI_scrub(info, dev); - if (rc == 0 && !dev->od_noscrub && - ((sf->sf_status == SS_PAUSED) || - (sf->sf_status == SS_CRASHED && - sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | SF_UPGRADE | - SF_AUTO)) || - (sf->sf_status == SS_INIT && - sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | SF_UPGRADE)))) - rc = osd_scrub_start(dev); + if (rc == 0) { + if ((sf->sf_flags & SF_UPGRADE) && + !(sf->sf_flags & SF_INCONSISTENT)) + /* The 'od_igif_inoi' will be set after the + * upgrading completed, needs NOT remount. */ + dev->od_igif_inoi = 0; + else + /* The 'od_igif_inoi' will be set under the + * following cases: + * 1) new created system, or + * 2) restored from file-level backup, or + * 3) the upgrading completed. + * + * The 'od_igif_inoi' may be cleared by OI scrub + * later if found that the system is upgrading. */ + dev->od_igif_inoi = 1; + + if (!dev->od_noscrub && + ((sf->sf_status == SS_PAUSED) || + (sf->sf_status == SS_CRASHED && + sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | + SF_UPGRADE | SF_AUTO)) || + (sf->sf_status == SS_INIT && + sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | + SF_UPGRADE)))) + rc = osd_scrub_start(dev); + } RETURN(rc); } @@ -1948,12 +1988,10 @@ static __u64 osd_otable_it_store(const struct lu_env *env, struct osd_otable_cache *ooc = &it->ooi_cache; __u64 hash; - if (!it->ooi_user_ready) - hash = ooc->ooc_pos_preload; - else if (likely(ooc->ooc_consumer_idx != -1)) + if (it->ooi_user_ready && ooc->ooc_consumer_idx != -1) hash = ooc->ooc_cache[ooc->ooc_consumer_idx].oic_lid.oii_ino; else - hash = 0; + hash = ooc->ooc_pos_preload; return hash; } -- 1.8.3.1