示例#1
0
/**
 * 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;
}
示例#2
0
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);
}