X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_scrub.c;h=dfdd87c40ec6336f68624d49d682b2cfe728352f;hp=2ede42c39373200a2f2997d565b9e319cdf2516f;hb=f843facff59226d3788d855d1d6948523ab8d944;hpb=a48853cf3dc51b24cc276fcf5f2e3e25a32c0d25 diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 2ede42c..dfdd87c 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -163,13 +163,13 @@ static int osd_scrub_convert_ff(struct osd_thread_info *info, struct osd_device *dev, struct inode *inode, const struct lu_fid *fid) { - struct filter_fid_old *ff = &info->oti_ff; - struct dentry *dentry = &info->oti_obj_dentry; - struct lu_fid *tfid = &info->oti_fid; - handle_t *jh; - int size = 0; - int rc; - bool reset = false; + struct filter_fid_18_23 *ff = &info->oti_ff_old; + struct dentry *dentry = &info->oti_obj_dentry; + struct lu_fid *tfid = &info->oti_fid; + bool fid_18_23 = false; + handle_t *jh; + int size = 0; + int rc; ENTRY; if (dev->od_scrub.os_scrub.os_file.sf_param & SP_DRYRUN) @@ -207,19 +207,19 @@ osd_scrub_convert_ff(struct osd_thread_info *info, struct osd_device *dev, rc = __osd_xattr_get(inode, dentry, XATTR_NAME_FID, ff, sizeof(*ff)); if (rc == sizeof(*ff)) { /* 2) delete the old XATTR_NAME_FID */ - ll_vfs_dq_init(inode); - rc = inode->i_op->removexattr(dentry, XATTR_NAME_FID); + dquot_initialize(inode); + rc = osd_removexattr(dentry, inode, XATTR_NAME_FID); if (rc) GOTO(stop, rc); - reset = true; - } else if (rc != -ENODATA && rc != sizeof(struct filter_fid)) { + fid_18_23 = true; + } else if (rc != -ENODATA && rc < (int)sizeof(struct filter_fid_24_29)) { GOTO(stop, rc = -EINVAL); } /* 3) make new LMA and add it */ rc = osd_ea_fid_set(info, inode, tfid, LMAC_FID_ON_OST, 0); - if (reset) { + if (fid_18_23) { if (rc) /* If failed, we should try to add the old back. */ size = sizeof(*ff); @@ -472,8 +472,7 @@ static int osd_scrub_prep(const struct lu_env *env, struct osd_device *dev) } if (flags & SS_RESET) - scrub_file_reset(scrub, - LDISKFS_SB(osd_sb(dev))->s_es->s_uuid, 0); + scrub_file_reset(scrub, dev->od_uuid, 0); if (flags & SS_AUTO_FULL) { scrub->os_full_speed = 1; @@ -564,8 +563,9 @@ static int osd_scrub_post(const struct lu_env *env, struct osd_device *dev, } 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); @@ -626,8 +626,8 @@ static int osd_scrub_check_local_fldb(struct osd_thread_info *info, * quite possible for FID-on-MDT. */ if (dev->od_is_ost) return SCRUB_NEXT_OSTOBJ_OLD; - else - return 0; + + return 0; } static int osd_scrub_get_fid(struct osd_thread_info *info, @@ -635,8 +635,8 @@ static int osd_scrub_get_fid(struct osd_thread_info *info, struct lu_fid *fid, bool scrub) { struct lustre_mdt_attrs *lma = &info->oti_ost_attrs.loa_lma; - int rc; bool has_lma = false; + int rc; rc = osd_get_lma(info, inode, &info->oti_obj_dentry, &info->oti_ost_attrs); @@ -673,7 +673,7 @@ static int osd_scrub_get_fid(struct osd_thread_info *info, rc = osd_get_idif(info, inode, &info->oti_obj_dentry, fid); if (rc == 0) { if (scrub) - /* It is old 2.x (x <= 3) or 1.8 OST-object. */ + /* It is 2.3 or older OST-object. */ rc = SCRUB_NEXT_OSTOBJ_OLD; return rc; } @@ -684,7 +684,7 @@ static int osd_scrub_get_fid(struct osd_thread_info *info, * to generate its FID, ignore it directly. */ rc = SCRUB_NEXT_CONTINUE; else - /* It is 2.4 OST-object. */ + /* It is 2.4 or newer OST-object. */ rc = SCRUB_NEXT_OSTOBJ_OLD; return rc; } @@ -729,9 +729,16 @@ static int osd_iit_iget(struct osd_thread_info *info, struct osd_device *dev, /* Not handle the backend root object and agent parent object. * They are neither visible to namespace nor have OI mappings. */ if (unlikely(pos == osd_sb(dev)->s_root->d_inode->i_ino || - pos == osd_remote_parent_ino(dev))) + is_remote_parent_ino(dev, pos))) RETURN(SCRUB_NEXT_CONTINUE); + /* Skip project quota inode since it is greater than s_first_ino. */ +#ifdef HAVE_PROJECT_QUOTA + if (ldiskfs_has_feature_project(sb) && + pos == le32_to_cpu(LDISKFS_SB(sb)->s_es->s_prj_quota_inum)) + RETURN(SCRUB_NEXT_CONTINUE); +#endif + osd_id_gen(lid, pos, OSD_OII_NOGEN); inode = osd_iget(info, dev, lid); if (IS_ERR(inode)) { @@ -981,8 +988,8 @@ static void osd_scrub_join(const struct lu_env *env, struct osd_device *dev, sf->sf_param &= ~SP_DRYRUN; if (flags & SS_RESET) { - scrub_file_reset(scrub, LDISKFS_SB(osd_sb(dev))->s_es->s_uuid, - inconsistent ? SF_INCONSISTENT : 0); + scrub_file_reset(scrub, dev->od_uuid, + inconsistent ? SF_INCONSISTENT : 0); sf->sf_status = SS_SCANNING; } @@ -1418,8 +1425,8 @@ static const struct osd_lf_map osd_lf_maps[] = { /* PENDING */ { - .olm_name = "PENDING", - .olm_namelen = sizeof("PENDING") - 1, + .olm_name = MDT_ORPHAN_DIR, + .olm_namelen = sizeof(MDT_ORPHAN_DIR) - 1, }, /* ROOT */ @@ -1734,32 +1741,6 @@ struct osd_ios_filldir_buf { int oifb_items; }; -static inline struct dentry * -osd_ios_lookup_one_len(const char *name, struct dentry *parent, int namelen) -{ - struct dentry *dentry; - - dentry = ll_lookup_one_len(name, parent, namelen); - if (IS_ERR(dentry)) { - int rc = PTR_ERR(dentry); - - if (rc != -ENOENT) - CERROR("Fail to find %.*s in %.*s (%lu/%u): rc = %d\n", - namelen, name, parent->d_name.len, - parent->d_name.name, parent->d_inode->i_ino, - parent->d_inode->i_generation, rc); - - return dentry; - } - - if (dentry->d_inode == NULL) { - dput(dentry); - return ERR_PTR(-ENOENT); - } - - return dentry; -} - static int osd_ios_new_item(struct osd_device *dev, struct dentry *dentry, scandir_t scandir, filldir_t filldir) @@ -1915,6 +1896,12 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, int rc; ENTRY; + if (!inode) { + CDEBUG(D_INODE, "%s: child '%.*s' lacks inode: rc = -2\n", + osd_name(dev), namelen, name); + RETURN(-ENOENT); + } + rc = osd_get_lma(info, inode, &info->oti_obj_dentry, &info->oti_ost_attrs); if (rc != 0 && rc != -ENODATA) { @@ -1989,8 +1976,7 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, RETURN(0); if (!(sf->sf_flags & SF_INCONSISTENT)) { - scrub_file_reset(scrub, LDISKFS_SB(osd_sb(dev))->s_es->s_uuid, - SF_INCONSISTENT); + scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT); rc = scrub_file_store(info->oti_env, scrub); if (rc != 0) RETURN(rc); @@ -2006,7 +1992,7 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, /** * It scans the /lost+found, and for the OST-object (with filter_fid - * or filter_fid_old), move them back to its proper /O//d. + * or filter_fid_18_23), move them back to its proper /O//d. */ #ifdef HAVE_FILLDIR_USE_CTX static int osd_ios_lf_fill(struct dir_context *buf, @@ -2041,6 +2027,11 @@ static int osd_ios_lf_fill(void *buf, CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n", osd_name(dev), namelen, name, (int)PTR_ERR(child)); RETURN(0); + } else if (!child->d_inode) { + dput(child); + CDEBUG(D_INODE, "%s: child '%.*s' lacks inode\n", + osd_name(dev), namelen, name); + RETURN(0); } inode = child->d_inode; @@ -2239,6 +2230,8 @@ static int osd_ios_root_fill(void *buf, child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen); if (IS_ERR(child)) RETURN(PTR_ERR(child)); + else if (!child->d_inode) + GOTO(out_put, rc = -ENOENT); if (!(map->olm_flags & OLF_NO_OI)) rc = osd_ios_scan_one(fill_buf->oifb_info, dev, @@ -2247,6 +2240,7 @@ static int osd_ios_root_fill(void *buf, if (rc == 0 && map->olm_flags & OLF_SCAN_SUBITEMS) rc = osd_ios_new_item(dev, child, map->olm_scandir, map->olm_filldir); +out_put: dput(child); RETURN(rc); @@ -2283,7 +2277,11 @@ osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev, buf.oifb_items = 0; #ifdef HAVE_DIR_CONTEXT buf.ctx.pos = filp->f_pos; +#ifdef HAVE_ITERATE_SHARED + rc = fops->iterate_shared(filp, &buf.ctx); +#else rc = fops->iterate(filp, &buf.ctx); +#endif filp->f_pos = buf.ctx.pos; #else rc = fops->readdir(filp, &buf, filldir); @@ -2321,20 +2319,20 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev, scrub->os_convert_igif = 1; child = osd_ios_lookup_one_len(dot_lustre_name, dentry, strlen(dot_lustre_name)); - if (IS_ERR(child)) { + if (IS_ERR(child) && PTR_ERR(child) != -ENOENT) { rc = PTR_ERR(child); - if (rc == -ENOENT) { - /* It is 1.8 MDT device. */ - if (!(sf->sf_flags & SF_UPGRADE)) { - scrub_file_reset(scrub, - LDISKFS_SB(osd_sb(dev))->s_es->s_uuid, - SF_UPGRADE); - sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID; - rc = scrub_file_store(info->oti_env, scrub); - } else { - rc = 0; - } + } else if (IS_ERR(child) || !child->d_inode) { + /* It is 1.8 MDT device. */ + if (!(sf->sf_flags & SF_UPGRADE)) { + scrub_file_reset(scrub, dev->od_uuid, + SF_UPGRADE); + sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID; + rc = scrub_file_store(info->oti_env, scrub); + } else { + rc = 0; } + if (!IS_ERR(child)) + dput(child); } else { /* For lustre-2.x (x <= 3), the ".lustre" has NO FID-in-LMA, * so the client will get IGIF for the ".lustre" object when @@ -2390,32 +2388,28 @@ osd_ios_OBJECTS_scan(struct osd_thread_info *info, struct osd_device *dev, } child = osd_ios_lookup_one_len(ADMIN_USR, dentry, strlen(ADMIN_USR)); - if (!IS_ERR(child)) { + if (IS_ERR(child)) { + rc = PTR_ERR(child); + } else { rc = osd_ios_scan_one(info, dev, dentry->d_inode, child->d_inode, NULL, ADMIN_USR, strlen(ADMIN_USR), 0); dput(child); - } else { - rc = PTR_ERR(child); } if (rc != 0 && rc != -ENOENT) - RETURN(rc); + GOTO(out, rc); child = osd_ios_lookup_one_len(ADMIN_GRP, dentry, strlen(ADMIN_GRP)); - if (!IS_ERR(child)) { - rc = osd_ios_scan_one(info, dev, dentry->d_inode, - child->d_inode, NULL, ADMIN_GRP, - strlen(ADMIN_GRP), 0); - dput(child); - } else { - rc = PTR_ERR(child); - } - - if (rc == -ENOENT) - rc = 0; + if (IS_ERR(child)) + GOTO(out, rc = PTR_ERR(child)); - RETURN(rc); + rc = osd_ios_scan_one(info, dev, dentry->d_inode, + child->d_inode, NULL, ADMIN_GRP, + strlen(ADMIN_GRP), 0); + dput(child); +out: + RETURN(rc == -ENOENT ? 0 : rc); } static void osd_initial_OI_scrub(struct osd_thread_info *info, @@ -2465,12 +2459,13 @@ static void osd_initial_OI_scrub(struct osd_thread_info *info, child = osd_ios_lookup_one_len(map->olm_name, osd_sb(dev)->s_root, map->olm_namelen); - if (!IS_ERR(child)) - dput(child); - else if (PTR_ERR(child) == -ENOENT) + if (PTR_ERR(child) == -ENOENT || + (!IS_ERR(child) && !child->d_inode)) osd_scrub_refresh_mapping(info, dev, &map->olm_fid, NULL, DTO_INDEX_DELETE, true, 0, NULL); + if (!IS_ERR(child)) + dput(child); map++; } @@ -2548,7 +2543,7 @@ int osd_scrub_start(const struct lu_env *env, struct osd_device *dev, RETURN(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.os_scrub; @@ -2570,7 +2565,6 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) struct lvfs_run_ctxt *ctxt = &dev->od_scrub.os_ctxt; struct scrub_file *sf = &scrub->os_file; struct super_block *sb = osd_sb(dev); - struct ldiskfs_super_block *es = LDISKFS_SB(sb)->s_es; struct lvfs_run_ctxt saved; struct file *filp; struct inode *inode; @@ -2586,7 +2580,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) OBD_SET_CTXT_MAGIC(ctxt); ctxt->pwdmnt = dev->od_mnt; ctxt->pwd = dev->od_mnt->mnt_root; - ctxt->fs = get_ds(); + ctxt->fs = KERNEL_DS; init_waitqueue_head(&scrub->os_thread.t_ctl_waitq); init_rwsem(&scrub->os_rwsem); @@ -2624,10 +2618,15 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) if (IS_ERR_OR_NULL(obj)) RETURN(obj ? PTR_ERR(obj) : -ENOENT); +#ifndef HAVE_S_UUID_AS_UUID_T + memcpy(dev->od_uuid.b, sb->s_uuid, UUID_SIZE); +#else + uuid_copy(&dev->od_uuid, &sb->s_uuid); +#endif scrub->os_obj = obj; rc = scrub_file_load(env, scrub); if (rc == -ENOENT || rc == -EFAULT) { - scrub_file_init(scrub, es->s_uuid); + scrub_file_init(scrub, dev->od_uuid); /* If the "/O" dir does not exist when mount (indicated by * osd_device::od_maybe_new), neither for the "/OI_scrub", * then it is quite probably that the device is a new one, @@ -2637,7 +2636,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) * an old device, it can be found and cleared later. * * For the system with "SIF_NO_HANDLE_OLD_FID", we do not - * need to check "filter_fid_old" and to convert it to + * need to check "filter_fid_18_23" and to convert it to * "filter_fid" for each object, and all the IGIF should * have their FID mapping in OI files already. */ if (dev->od_maybe_new && rc == -ENOENT) @@ -2646,30 +2645,13 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) } else if (rc < 0) { GOTO(cleanup_obj, rc); } else { - if (memcmp(sf->sf_uuid, es->s_uuid, 16) != 0) { - struct obd_uuid *old_uuid; - struct obd_uuid *new_uuid; - - OBD_ALLOC_PTR(old_uuid); - OBD_ALLOC_PTR(new_uuid); - if (old_uuid == NULL || new_uuid == NULL) { - CERROR("%s: UUID has been changed, but" - "failed to allocate RAM for report\n", - osd_dev2name(dev)); - } else { - class_uuid_unparse(sf->sf_uuid, old_uuid); - class_uuid_unparse(es->s_uuid, new_uuid); - CDEBUG(D_LFSCK, "%s: UUID has been changed " - "from %s to %s\n", osd_dev2name(dev), - old_uuid->uuid, new_uuid->uuid); - } - scrub_file_reset(scrub, es->s_uuid, SF_INCONSISTENT); + if (!uuid_equal(&sf->sf_uuid, &dev->od_uuid)) { + CDEBUG(D_LFSCK, + "%s: UUID has been changed from %pU to %pU\n", + osd_dev2name(dev), &sf->sf_uuid, &dev->od_uuid); + scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT); dirty = true; restored = true; - if (old_uuid != NULL) - OBD_FREE_PTR(old_uuid); - if (new_uuid != NULL) - OBD_FREE_PTR(new_uuid); } else if (sf->sf_status == SS_SCANNING) { sf->sf_status = SS_CRASHED; dirty = true;