X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_oi.c;h=5dceea711309b501d63a188703936d441e8aa864;hp=0a0d4e1a88c8bd9affa7cbad32dc17738ed259f9;hb=61743b88672687f789f9c609c85a351e1595118b;hpb=d8612e307f28cc81df5d93e45130b9f04837ee27;ds=sidebyside diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index 0a0d4e1..5dceea7 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2014, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -44,8 +40,6 @@ #include -/* LUSTRE_VERSION_CODE */ -#include /* * struct OBD_{ALLOC,FREE}*() * OBD_FAIL_CHECK @@ -56,19 +50,15 @@ /* fid_cpu_to_be() */ #include #include +#include #include "osd_oi.h" /* osd_lookup(), struct osd_thread_info */ #include "osd_internal.h" -#include "osd_scrub.h" - -static unsigned int osd_oi_count = OSD_OI_FID_NR; -CFS_MODULE_PARM(osd_oi_count, "i", int, 0444, - "Number of Object Index containers to be created, " - "it's only valid for new filesystem."); -/** to serialize concurrent OI index initialization */ -static struct mutex oi_init_lock; +unsigned int osd_oi_count = OSD_OI_FID_NR; +module_param(osd_oi_count, int, 0444); +MODULE_PARM_DESC(osd_oi_count, "Number of Object Index containers to be created, it's only valid for new filesystem."); static struct dt_index_features oi_feat = { .dif_flags = DT_IND_UPDATE, @@ -118,7 +108,7 @@ static int osd_oi_index_create_one(struct osd_thread_info *info, dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name)); bh = osd_ldiskfs_find_entry(dir, &dentry->d_name, &de, NULL, NULL); - if (bh) { + if (!IS_ERR(bh)) { osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN); brelse(bh); inode = osd_iget(info, osd, id); @@ -129,6 +119,9 @@ static int osd_oi_index_create_one(struct osd_thread_info *info, return PTR_ERR(inode); } + if (osd->od_dt_dev.dd_rdonly) + RETURN(-EROFS); + jh = osd_journal_start_sb(sb, LDISKFS_HT_MISC, 100); if (IS_ERR(jh)) return PTR_ERR(jh); @@ -151,7 +144,7 @@ static int osd_oi_index_create_one(struct osd_thread_info *info, feat->dif_ptrsize, feat->dif_recsize_max, jh); dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name)); - rc = osd_ldiskfs_add_entry(jh, dentry, inode, NULL); + rc = osd_ldiskfs_add_entry(info, osd, jh, dentry, inode, NULL); ldiskfs_journal_stop(jh); iput(inode); return rc; @@ -231,12 +224,16 @@ static int osd_oi_open(struct osd_thread_info *info, struct osd_device *osd, if (IS_ERR(inode)) RETURN(PTR_ERR(inode)); - /* 'What the @fid is' is not imporatant, because these objects - * have no OI mappings, and only are visible inside the OSD.*/ - lu_igif_build(&info->oti_fid, inode->i_ino, inode->i_generation); - rc = osd_ea_fid_set(info, inode, &info->oti_fid, LMAC_NOT_IN_OI, 0); - if (rc != 0) - GOTO(out_inode, rc); + if (!osd->od_dt_dev.dd_rdonly) { + /* 'What the @fid is' is not imporatant, because these objects + * have no OI mappings, and only are visible inside the OSD.*/ + lu_igif_build(&info->oti_fid, inode->i_ino, + inode->i_generation); + rc = osd_ea_fid_set(info, inode, &info->oti_fid, + LMAC_NOT_IN_OI, 0); + if (rc) + GOTO(out_inode, rc); + } OBD_ALLOC_PTR(oi); if (oi == NULL) @@ -287,10 +284,10 @@ static int osd_oi_table_open(struct osd_thread_info *info, struct osd_device *osd, struct osd_oi **oi_table, unsigned oi_count, bool create) { - struct scrub_file *sf = &osd->od_scrub.os_file; - int count = 0; - int rc = 0; - int i; + struct scrub_file *sf = &osd->od_scrub.os_scrub.os_file; + int count = 0; + int rc = 0; + int i; ENTRY; /* NB: oi_count != 0 means that we have already created/known all OIs @@ -298,14 +295,14 @@ osd_oi_table_open(struct osd_thread_info *info, struct osd_device *osd, LASSERT(oi_count <= OSD_OI_FID_NR_MAX); for (i = 0; i < (oi_count != 0 ? oi_count : OSD_OI_FID_NR_MAX); i++) { - char name[12]; + char name[sizeof(OSD_OI_NAME_BASE) + 3 * sizeof(i) + 1]; if (oi_table[i] != NULL) { count++; continue; } - sprintf(name, "%s.%d", OSD_OI_NAME_BASE, i); + snprintf(name, sizeof(name), "%s.%d", OSD_OI_NAME_BASE, i); rc = osd_oi_open(info, osd, name, &oi_table[i], create); if (rc == 0) { count++; @@ -321,12 +318,11 @@ osd_oi_table_open(struct osd_thread_info *info, struct osd_device *osd, continue; } - CERROR("%.16s: can't open %s: rc = %d\n", - LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name, name, rc); + CERROR("%s: can't open %s: rc = %d\n", + osd_dev2name(osd), name, rc); if (oi_count > 0) - CERROR("%.16s: expect to open total %d OI files.\n", - LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name, - oi_count); + CERROR("%s: expect to open total %d OI files.\n", + osd_dev2name(osd), oi_count); break; } @@ -338,38 +334,113 @@ osd_oi_table_open(struct osd_thread_info *info, struct osd_device *osd, RETURN(count); } -int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd) +static int osd_remove_oi_one(struct dentry *parent, const char *name, + int namelen) { - struct osd_scrub *scrub = &osd->od_scrub; + struct dentry *child; + int rc; + + child = ll_lookup_one_len(name, parent, namelen); + if (IS_ERR(child)) { + rc = PTR_ERR(child); + } else { + rc = ll_vfs_unlink(parent->d_inode, child); + dput(child); + } + + return rc == -ENOENT ? 0 : rc; +} + +static int osd_remove_ois(struct osd_thread_info *info, struct osd_device *osd) +{ + char name[16]; + int namelen; + int rc; + int i; + + if (osd->od_dt_dev.dd_rdonly) + RETURN(-EROFS); + + for (i = 0; i < OSD_OI_FID_NR_MAX; i++) { + namelen = snprintf(name, sizeof(name), "%s.%d", + OSD_OI_NAME_BASE, i); + rc = osd_remove_oi_one(osd_sb(osd)->s_root, name, namelen); + if (rc != 0) { + CERROR("%s: fail to remove the stale OI file %s: " + "rc = %d\n", osd_dev2name(osd), name, rc); + return rc; + } + } + + namelen = snprintf(name, sizeof(name), "%s", OSD_OI_NAME_BASE); + rc = osd_remove_oi_one(osd_sb(osd)->s_root, name, namelen); + if (rc != 0) + CERROR("%s: fail to remove the stale OI file %s: rc = %d\n", + osd_dev2name(osd), name, rc); + + return rc; +} + +int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd, + bool restored) +{ + struct lustre_scrub *scrub = &osd->od_scrub.os_scrub; struct scrub_file *sf = &scrub->os_file; - struct osd_oi **oi; - int rc; + struct osd_oi **oi; + int count; + int rc; ENTRY; + if (unlikely(sf->sf_oi_count & (sf->sf_oi_count - 1)) != 0) { + LCONSOLE_WARN("%s: Invalid OI count in scrub file %d\n", + osd_dev2name(osd), sf->sf_oi_count); + sf->sf_oi_count = 0; + } + + if (restored) { + rc = osd_remove_ois(info, osd); + if (rc) + RETURN(rc); + } + OBD_ALLOC(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX); if (oi == NULL) RETURN(-ENOMEM); - mutex_lock(&oi_init_lock); /* try to open existing multiple OIs first */ - rc = osd_oi_table_open(info, osd, oi, sf->sf_oi_count, false); - if (rc < 0) - GOTO(out, rc); - - if (rc > 0) { - if (rc == sf->sf_oi_count || sf->sf_oi_count == 0) - GOTO(out, rc); + count = osd_oi_table_open(info, osd, oi, sf->sf_oi_count, false); + if (count < 0) + GOTO(out, rc = count); + + if (count > 0) { + if (count == sf->sf_oi_count) + GOTO(out, rc = count); + + if (sf->sf_oi_count == 0) { + if (likely((count & (count - 1)) == 0)) + GOTO(out, rc = count); + + LCONSOLE_WARN("%s: invalid oi count %d, remove them, " + "then set it to %d\n", osd_dev2name(osd), + count, osd_oi_count); + osd_oi_table_put(info, oi, count); + rc = osd_remove_ois(info, osd); + if (rc) + GOTO(out, rc); + + sf->sf_oi_count = osd_oi_count; + } - osd_scrub_file_reset(scrub, - LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, - SF_RECREATED); - osd_oi_count = sf->sf_oi_count; + scrub_file_reset(scrub, LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, + SF_RECREATED); + count = sf->sf_oi_count; goto create; } /* if previous failed then try found single OI from old filesystem */ rc = osd_oi_open(info, osd, OSD_OI_NAME_BASE, &oi[0], false); if (rc == 0) { /* found single OI from old filesystem */ + count = 1; ldiskfs_clear_bit(0, sf->sf_oi_bitmap); if (sf->sf_success_count == 0) /* XXX: There is one corner case that if the OI_scrub @@ -382,39 +453,39 @@ int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd) * and restored after former upgrading from 1.8 * to 2.x. Fortunately, the osd_fid_lookup()can * verify the inode to decrease the risk. */ - osd_scrub_file_reset(scrub, - LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, - SF_UPGRADE); + scrub_file_reset(scrub, + LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, + SF_UPGRADE); GOTO(out, rc = 1); } else if (rc != -ENOENT) { - CERROR("%.16s: can't open %s: rc = %d\n", - LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name, - OSD_OI_NAME_BASE, rc); + CERROR("%s: can't open %s: rc = %d\n", + osd_dev2name(osd), OSD_OI_NAME_BASE, rc); GOTO(out, rc); } if (sf->sf_oi_count > 0) { int i; + count = sf->sf_oi_count; memset(sf->sf_oi_bitmap, 0, SCRUB_OI_BITMAP_SIZE); - for (i = 0; i < osd_oi_count; i++) + for (i = 0; i < count; i++) ldiskfs_set_bit(i, sf->sf_oi_bitmap); - osd_scrub_file_reset(scrub, - LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, - SF_RECREATED); + scrub_file_reset(scrub, LDISKFS_SB(osd_sb(osd))->s_es->s_uuid, + SF_RECREATED); + } else { + count = sf->sf_oi_count = osd_oi_count; } - sf->sf_oi_count = osd_oi_count; create: - rc = osd_scrub_file_store(scrub); + rc = scrub_file_store(info->oti_env, scrub); if (rc < 0) { - osd_oi_table_put(info, oi, sf->sf_oi_count); + osd_oi_table_put(info, oi, count); GOTO(out, rc); } /* No OIs exist, new filesystem, create OI objects */ - rc = osd_oi_table_open(info, osd, oi, osd_oi_count, true); - LASSERT(ergo(rc >= 0, rc == osd_oi_count)); + rc = osd_oi_table_open(info, osd, oi, count, true); + LASSERT(ergo(rc >= 0, rc == count)); GOTO(out, rc); @@ -422,14 +493,15 @@ out: if (rc < 0) { OBD_FREE(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX); } else { - LASSERT((rc & (rc - 1)) == 0); + LASSERTF((rc & (rc - 1)) == 0, "Invalid OI count %d\n", rc); + osd->od_oi_table = oi; osd->od_oi_count = rc; if (sf->sf_oi_count != rc) { sf->sf_oi_count = rc; - rc = osd_scrub_file_store(scrub); + rc = scrub_file_store(info->oti_env, scrub); if (rc < 0) { - osd_oi_table_put(info, oi, sf->sf_oi_count); + osd_oi_table_put(info, oi, count); OBD_FREE(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX); } } else { @@ -437,20 +509,19 @@ out: } } - mutex_unlock(&oi_init_lock); return rc; } void osd_oi_fini(struct osd_thread_info *info, struct osd_device *osd) { - if (unlikely(osd->od_oi_table == NULL)) + if (unlikely(!osd->od_oi_table)) return; - osd_oi_table_put(info, osd->od_oi_table, osd->od_oi_count); + osd_oi_table_put(info, osd->od_oi_table, osd->od_oi_count); - OBD_FREE(osd->od_oi_table, - sizeof(*(osd->od_oi_table)) * OSD_OI_FID_NR_MAX); - osd->od_oi_table = NULL; + OBD_FREE(osd->od_oi_table, + sizeof(*(osd->od_oi_table)) * OSD_OI_FID_NR_MAX); + osd->od_oi_table = NULL; } static inline int fid_is_fs_root(const struct lu_fid *fid) @@ -519,6 +590,14 @@ int fid_is_on_ost(struct osd_thread_info *info, struct osd_device *osd, rc = osd_fld_lookup(info->oti_env, osd, fid_seq(fid), range); if (rc != 0) { + /* During upgrade, OST FLDB might not be loaded because + * OST FLDB is not created until 2.6, so if some DNE + * filesystem upgrade from 2.5 to 2.7/2.8, they will + * not be able to find the sequence from local FLDB + * cache see fld_index_init(). */ + if (rc == -ENOENT && osd->od_is_ost) + RETURN(1); + if (rc != -ENOENT) CERROR("%s: lookup FLD "DFID": rc = %d\n", osd_name(osd), PFID(fid), rc); @@ -618,7 +697,7 @@ static int osd_oi_iam_refresh(struct osd_thread_info *oti, struct osd_oi *oi, int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, const struct osd_inode_id *id, - handle_t *th, enum oi_check_flags flags) + handle_t *th, enum oi_check_flags flags, bool *exist) { struct lu_fid *oi_fid = &info->oti_fid2; struct osd_inode_id *oi_id = &info->oti_id2; @@ -637,7 +716,7 @@ int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, (const struct dt_key *)oi_fid, th, true); if (rc != 0) { struct inode *inode; - struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs; + struct lustre_mdt_attrs *lma = &info->oti_ost_attrs.loa_lma; if (rc != -EEXIST) return rc; @@ -658,7 +737,15 @@ int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, return rc; } - rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma); + /* The EA inode should NOT be in OI, old OI scrub may added + * such OI mapping by wrong, replace it. */ + if (unlikely(osd_is_ea_inode(inode))) { + iput(inode); + goto update; + } + + rc = osd_get_lma(info, inode, &info->oti_obj_dentry, + &info->oti_ost_attrs); iput(inode); if (rc == -ENODATA) goto update; @@ -668,9 +755,8 @@ int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, if (!(lma->lma_compat & LMAC_NOT_IN_OI) && lu_fid_eq(fid, &lma->lma_self_fid)) { - CERROR("%.16s: the FID "DFID" is used by two objects: " - "%u/%u %u/%u\n", - LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name, + CERROR("%s: the FID "DFID" is used by two objects: " + "%u/%u %u/%u\n", osd_dev2name(osd), PFID(fid), oi_id->oii_ino, oi_id->oii_gen, id->oii_ino, id->oii_gen); return -EEXIST; @@ -683,6 +769,9 @@ update: (const struct dt_key *)oi_fid, th, false); if (rc != 0) return rc; + + if (exist != NULL) + *exist = true; } if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) @@ -766,15 +855,14 @@ int osd_oi_update(struct osd_thread_info *info, struct osd_device *osd, int osd_oi_mod_init(void) { - if (osd_oi_count == 0 || osd_oi_count > OSD_OI_FID_NR_MAX) - osd_oi_count = OSD_OI_FID_NR; + if (osd_oi_count == 0 || osd_oi_count > OSD_OI_FID_NR_MAX) + osd_oi_count = OSD_OI_FID_NR; - if ((osd_oi_count & (osd_oi_count - 1)) != 0) { - LCONSOLE_WARN("Round up oi_count %d to power2 %d\n", - osd_oi_count, size_roundup_power2(osd_oi_count)); - osd_oi_count = size_roundup_power2(osd_oi_count); - } + if ((osd_oi_count & (osd_oi_count - 1)) != 0) { + LCONSOLE_WARN("Round up oi_count %d to power2 %d\n", + osd_oi_count, size_roundup_power2(osd_oi_count)); + osd_oi_count = size_roundup_power2(osd_oi_count); + } - mutex_init(&oi_init_lock); - return 0; + return 0; }