/** * delete unreferenced files and directories in the PENDING directory * * Files that remain in PENDING after client->MDS recovery has completed * have to be referenced (opened) by some client during recovery, or they * will be deleted here (for clients that did not complete recovery). * * \param mdd MDD device finishing recovery * * \retval 0 success * \retval -ve error */ static int orph_index_iterate(const struct lu_env *env, struct mdd_device *mdd) { struct dt_object *dor = mdd->mdd_orphans; struct lu_dirent *ent = &mdd_env_info(env)->mti_ent; const struct dt_it_ops *iops; struct dt_it *it; struct lu_fid fid; int key_sz = 0; int rc; __u64 cookie; ENTRY; /* In recovery phase, do not need for any lock here */ iops = &dor->do_index_ops->dio_it; it = iops->init(env, dor, LUDA_64BITHASH, BYPASS_CAPA); if (IS_ERR(it)) { rc = PTR_ERR(it); CERROR("%s: cannot clean PENDING: rc = %d\n", mdd2obd_dev(mdd)->obd_name, rc); GOTO(out, rc); } rc = iops->load(env, it, 0); if (rc < 0) GOTO(out_put, rc); if (rc == 0) { CERROR("%s: error loading iterator to clean PENDING\n", mdd2obd_dev(mdd)->obd_name); /* Index contains no zero key? */ GOTO(out_put, rc = -EIO); } do { key_sz = iops->key_size(env, it); /* filter out "." and ".." entries from PENDING dir. */ if (key_sz < 8) goto next; rc = iops->rec(env, it, (struct dt_rec *)ent, LUDA_64BITHASH); if (rc != 0) { CERROR("%s: fail to get FID for orphan it: rc = %d\n", mdd2obd_dev(mdd)->obd_name, rc); goto next; } fid_le_to_cpu(&fid, &ent->lde_fid); if (!fid_is_sane(&fid)) { CERROR("%s: bad FID "DFID" cleaning PENDING\n", mdd2obd_dev(mdd)->obd_name, PFID(&fid)); goto next; } /* kill orphan object */ cookie = iops->store(env, it); iops->put(env, it); rc = orph_key_test_and_del(env, mdd, &fid, (struct dt_key *)ent->lde_name); /* after index delete reset iterator */ if (rc == 0) rc = iops->get(env, it, (const void *)""); else rc = iops->load(env, it, cookie); next: rc = iops->next(env, it); } while (rc == 0); GOTO(out_put, rc = 0); out_put: iops->put(env, it); iops->fini(env, it); out: return rc; }
static int orph_index_iterate(const struct lu_env *env, struct mdd_device *mdd) { struct dt_object *dor = mdd->mdd_orphans; char *mti_key = mdd_env_info(env)->mti_orph_key; const struct dt_it_ops *iops; struct dt_it *it; char *key; struct lu_fid fid; int result = 0; int key_sz = 0; int rc; __u64 cookie; ENTRY; /* In recovery phase, do not need for any lock here */ iops = &dor->do_index_ops->dio_it; it = iops->init(env, dor, BYPASS_CAPA); if (it != NULL) { result = iops->load(env, it, 0); if (result > 0) { /* main cycle */ do { key = (void *)iops->key(env, it); if (IS_ERR(key)) { CERROR("key failed when clean pending.\n"); goto next; } key_sz = iops->key_size(env, it); /* filter out "." and ".." entries from * PENDING dir. */ if (key_sz < 8) goto next; memcpy(mti_key, key, key_sz); mti_key[key_sz] = 0; if (orphan_key_to_fid(mti_key, &fid)) goto next; if (!fid_is_sane(&fid)) { CERROR("fid is not sane when clean pending.\n"); goto next; } /* kill orphan object */ cookie = iops->store(env, it); iops->put(env, it); rc = orph_key_test_and_del(env, mdd, &fid, (struct dt_key *)mti_key); /* after index delete reset iterator */ if (!rc) result = iops->get(env, it, (const void *)""); else result = iops->load(env, it, cookie); next: result = iops->next(env, it); } while (result == 0); result = 0; } else if (result == 0) { CERROR("Input/Output for clean pending.\n"); /* Index contains no zero key? */ result = -EIO; } iops->put(env, it); iops->fini(env, it); } else { CERROR("not enough memory for clean pending.\n"); result = -ENOMEM; } RETURN(result); }