/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include "mdd_internal.h"
const char orph_index_name[] = "PENDING";
+const char *dotdot = "..";
enum {
ORPH_OP_UNLINK,
int rc;
LASSERT(key);
- rc = snprintf(key, NAME_MAX + 1, ORPHAN_FILE_NAME_FORMAT_18, fid_seq(lf),
- fid_oid(lf));
+ rc = snprintf(key, NAME_MAX + 1, ORPHAN_FILE_NAME_FORMAT_18,
+ (unsigned long long)fid_seq(lf), fid_oid(lf));
if (rc > 0)
return (struct dt_key*) key;
else
}
+int orph_declare_index_insert(const struct lu_env *env,
+ struct mdd_object *obj,
+ struct thandle *th)
+{
+ struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
+ int rc;
+
+ rc = dt_declare_insert(env, mdd->mdd_orphans, NULL, NULL, th);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_ref_add(env, obj, th);
+ if (rc)
+ return rc;
+
+ if (!S_ISDIR(mdd_object_type(obj)))
+ return 0;
+
+ rc = mdo_declare_ref_add(env, obj, th);
+ if (rc)
+ return rc;
+
+ rc = dt_declare_ref_add(env, mdd->mdd_orphans, th);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_index_delete(env, obj, dotdot, th);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_index_insert(env, obj, NULL, dotdot, th);
+
+ return rc;
+}
+
static int orph_index_insert(const struct lu_env *env,
struct mdd_object *obj,
__u32 op,
struct dt_object *dor = mdd->mdd_orphans;
const struct lu_fid *lf_dor = lu_object_fid(&dor->do_lu);
struct dt_object *next = mdd_object_child(obj);
- const struct dt_key *dotdot = (const struct dt_key *) "..";
int rc;
ENTRY;
if (!dt_try_as_dir(env, next))
goto out;
next->do_index_ops->dio_delete(env, next,
- dotdot, th, BYPASS_CAPA);
+ (const struct dt_key *)dotdot,
+ th, BYPASS_CAPA);
next->do_index_ops->dio_insert(env, next,
- (struct dt_rec *) lf_dor,
- dotdot, th, BYPASS_CAPA, 1);
+ (struct dt_rec *)lf_dor,
+ (const struct dt_key *)dotdot,
+ th, BYPASS_CAPA, 1);
out:
if (rc == 0)
if (rc == 0)
rc = mdd_lov_destroy(env, mdd, obj, la);
}
+ mdo_destroy(env, obj, th);
RETURN(rc);
}
+int orph_declare_index_delete(const struct lu_env *env,
+ struct mdd_object *obj,
+ struct thandle *th)
+{
+ struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
+ int rc;
+
+ rc = dt_declare_delete(env, mdd->mdd_orphans, NULL, th);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_ref_del(env, obj, th);
+ if (rc)
+ return rc;
+
+ if (S_ISDIR(mdd_object_type(obj))) {
+ rc = mdo_declare_ref_del(env, obj, th);
+ if (rc)
+ return rc;
+
+ rc = dt_declare_ref_del(env, mdd->mdd_orphans, th);
+ }
+
+ return rc;
+}
+
static int orph_index_delete(const struct lu_env *env,
struct mdd_object *obj,
__u32 op,
{
struct thandle *th = NULL;
struct mdd_device *mdd = mdo2mdd(&obj->mod_obj);
+ struct md_attr *ma = &mdd_env_info(env)->mti_ma;
int rc = 0;
ENTRY;
- mdd_txn_param_build(env, mdd, MDD_TXN_UNLINK_OP);
- th = mdd_trans_start(env, mdd);
+ /* init ma */
+ ma->ma_lmm_size = mdd_lov_mdsize(env, mdd);
+ ma->ma_lmm = mdd_max_lmm_get(env, mdd);
+ ma->ma_cookie_size = mdd_lov_cookiesize(env, mdd);
+ ma->ma_cookie = mdd_max_cookie_get(env, mdd);
+ ma->ma_need = MA_INODE | MA_LOV | MA_COOKIE;
+ ma->ma_valid = 0;
+
+ th = mdd_trans_create(env, mdd);
if (IS_ERR(th)) {
CERROR("Cannot get thandle\n");
RETURN(-ENOMEM);
}
+ rc = orph_declare_index_delete(env, obj, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = mdd_declare_object_kill(env, obj, ma, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = mdd_trans_start(env, mdd, th);
+ if (rc)
+ GOTO(stop, rc);
mdd_write_lock(env, obj, MOR_TGT_CHILD);
if (likely(obj->mod_count == 0)) {
mdd_orphan_write_unlock(env, mdd);
}
mdd_write_unlock(env, obj);
+
+stop:
mdd_trans_stop(env, mdd, 0, th);
RETURN(rc);
/* 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) {
+ it = iops->init(env, dor, LUDA_64BITHASH, BYPASS_CAPA);
+ if (!IS_ERR(it)) {
result = iops->load(env, it, 0);
if (result > 0) {
/* main cycle */
iops->put(env, it);
iops->fini(env, it);
} else {
- CERROR("not enough memory for clean pending.\n");
- result = -ENOMEM;
+ result = PTR_ERR(it);
+ CERROR("Cannot clean pending (%d).\n", result);
}
RETURN(result);