return rc;
}
-static int lfsck_layout_lock(const struct lu_env *env,
- struct lfsck_component *com,
- struct dt_object *obj,
- struct lustre_handle *lh, __u64 bits)
-{
- struct lfsck_thread_info *info = lfsck_env_info(env);
- ldlm_policy_data_t *policy = &info->lti_policy;
- struct ldlm_res_id *resid = &info->lti_resid;
- struct lfsck_instance *lfsck = com->lc_lfsck;
- __u64 flags = LDLM_FL_ATOMIC_CB;
- int rc;
-
- LASSERT(lfsck->li_namespace != NULL);
-
- memset(policy, 0, sizeof(*policy));
- policy->l_inodebits.bits = bits;
- fid_build_reg_res_name(lfsck_dto2fid(obj), resid);
- rc = ldlm_cli_enqueue_local(lfsck->li_namespace, resid, LDLM_IBITS,
- policy, LCK_EX, &flags, ldlm_blocking_ast,
- ldlm_completion_ast, NULL, NULL, 0,
- LVB_T_NONE, NULL, lh);
- if (rc == ELDLM_OK) {
- rc = 0;
- } else {
- memset(lh, 0, sizeof(*lh));
- rc = -EIO;
- }
-
- return rc;
-}
-
-static void lfsck_layout_unlock(struct lustre_handle *lh)
-{
- if (lustre_handle_is_used(lh)) {
- ldlm_lock_decref(lh, LCK_EX);
- memset(lh, 0, sizeof(*lh));
- }
-}
-
static int lfsck_layout_trans_stop(const struct lu_env *env,
struct dt_device *dev,
struct thandle *handle, int result)
* because creating MDT-object for orphan OST-object is rare, we
* do not much care about the performance. It can be improved in
* the future when needed. */
- rc = lfsck_layout_lock(env, com, lfsck->li_lpf_obj, &lh,
- MDS_INODELOCK_UPDATE);
+ rc = lfsck_ibits_lock(env, lfsck, lfsck->li_lpf_obj, &lh,
+ MDS_INODELOCK_UPDATE, LCK_EX);
if (rc != 0)
GOTO(put, rc);
dt_trans_stop(env, next, th);
unlock:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
put:
if (cobj != NULL && !IS_ERR(cobj))
GOTO(out, rc);
/* Hold layout lock on the parent to prevent others to access. */
- rc = lfsck_layout_lock(env, com, parent, &lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
+ MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(out, rc);
* a new MDT-object for the orphan OST-object. */
if (rc == -ETXTBSY) {
/* No need the layout lock on the original parent. */
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
fid_zero(&rec->lor_fid);
snprintf(infix, LFSCK_TMPBUF_LEN, "-"DFID"-%x",
dt_trans_stop(env, dev, th);
unlock:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
out:
CDEBUG(D_LFSCK, "%s: layout LFSCK assistant replaced the conflict "
bool locked = false;
ENTRY;
- rc = lfsck_layout_lock(env, com, parent, &lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
+ MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0) {
CDEBUG(D_LFSCK, "%s: layout LFSCK assistant failed to recreate "
"LOV EA for "DFID": parent "DFID", OST-index %u, "
dt_write_unlock(env, parent);
if (handle != NULL)
dt_trans_stop(env, dt, handle);
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
rc = lfsck_layout_update_pfid(env, com, parent,
cfid, ltd->ltd_tgt, i);
dt_write_unlock(env, parent);
if (handle != NULL)
dt_trans_stop(env, dt, handle);
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V1)
objs = &lmm->lmm_objects[ea_off];
else
dt_trans_stop(env, dt, handle);
unlock_layout:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
return rc;
}
cla->la_valid = LA_TYPE | LA_MODE | LA_UID | LA_GID |
LA_ATIME | LA_MTIME | LA_CTIME;
- rc = lfsck_layout_lock(env, com, parent, &lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
+ MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(log, rc);
rc = lfsck_layout_trans_stop(env, dev, handle, rc);
unlock1:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
log:
CDEBUG(D_LFSCK, "%s: layout LFSCK assistant found dangling "
int rc;
ENTRY;
- rc = lfsck_layout_lock(env, com, parent, &lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
+ MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(log, rc);
rc = lfsck_layout_trans_stop(env, dev, handle, rc);
unlock1:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
log:
CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired unmatched "
int rc;
ENTRY;
- rc = lfsck_layout_lock(env, com, parent, &lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
+ MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
+ LCK_EX);
if (rc != 0)
GOTO(log, rc);
dt_trans_stop(env, pdev, handle);
unlock1:
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
log:
CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired multiple "
if (!lustre_handle_is_used(&lh)) {
dt_read_unlock(env, obj);
locked = false;
- rc = lfsck_layout_lock(env, com, obj, &lh,
- MDS_INODELOCK_LAYOUT |
- MDS_INODELOCK_XATTR);
+ rc = lfsck_ibits_lock(env, lfsck, obj, &lh,
+ MDS_INODELOCK_LAYOUT |
+ MDS_INODELOCK_XATTR, LCK_EX);
if (rc != 0)
GOTO(out, rc);
if (handle != NULL && !IS_ERR(handle))
dt_trans_stop(env, dev, handle);
- lfsck_layout_unlock(&lh);
+ lfsck_ibits_unlock(&lh, LCK_EX);
if (bad_oi)
CDEBUG(D_LFSCK, "%s: layout LFSCK master %s bad lmm_oi for "
RETURN(rc);
}
+/**
+ * Request the specified ibits lock for the given object.
+ *
+ * Before the LFSCK modifying on the namespace visible object,
+ * it needs to acquire related ibits ldlm lock.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] lfsck pointer to the lfsck instance
+ * \param[in] obj pointer to the dt_object to be locked
+ * \param[out] lh pointer to the lock handle
+ * \param[in] ibits the bits for the ldlm lock to be acquired
+ * \param[in] mode the mode for the ldlm lock to be acquired
+ *
+ * \retval 0 for success
+ * \retval negative error number on failure
+ */
+int lfsck_ibits_lock(const struct lu_env *env, struct lfsck_instance *lfsck,
+ struct dt_object *obj, struct lustre_handle *lh,
+ __u64 bits, ldlm_mode_t mode)
+{
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ ldlm_policy_data_t *policy = &info->lti_policy;
+ struct ldlm_res_id *resid = &info->lti_resid;
+ __u64 flags = LDLM_FL_ATOMIC_CB;
+ int rc;
+
+ LASSERT(lfsck->li_namespace != NULL);
+
+ memset(policy, 0, sizeof(*policy));
+ policy->l_inodebits.bits = bits;
+ fid_build_reg_res_name(lfsck_dto2fid(obj), resid);
+ rc = ldlm_cli_enqueue_local(lfsck->li_namespace, resid, LDLM_IBITS,
+ policy, mode, &flags, ldlm_blocking_ast,
+ ldlm_completion_ast, NULL, NULL, 0,
+ LVB_T_NONE, NULL, lh);
+ if (rc == ELDLM_OK) {
+ rc = 0;
+ } else {
+ memset(lh, 0, sizeof(*lh));
+ rc = -EIO;
+ }
+
+ return rc;
+}
+
+/**
+ * Release the the specified ibits lock.
+ *
+ * If the lock has been acquired before, release it
+ * and cleanup the handle. Otherwise, do nothing.
+ *
+ * \param[in] lh pointer to the lock handle
+ * \param[in] mode the mode for the ldlm lock to be released
+ */
+void lfsck_ibits_unlock(struct lustre_handle *lh, ldlm_mode_t mode)
+{
+ if (lustre_handle_is_used(lh)) {
+ ldlm_lock_decref(lh, mode);
+ memset(lh, 0, sizeof(*lh));
+ }
+}
+
static const char dot[] = ".";
static const char dotdot[] = "..";
static const char dotlustre[] = ".lustre";
struct dt_object_format *dof = &info->lti_dof;
struct dt_object *parent = NULL;
struct dt_object *child = NULL;
+ struct lustre_handle lh = { 0 };
char name[8];
int node = lfsck_dev_idx(lfsck->li_bottom);
int rc = 0;
if (IS_ERR(parent))
RETURN(PTR_ERR(parent));
+ if (lfsck->li_lpf_obj != NULL)
+ GOTO(out, rc = 0);
+
if (unlikely(!dt_try_as_dir(env, parent)))
GOTO(out, rc = -ENOTDIR);
+ rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
+ MDS_INODELOCK_UPDATE, LCK_EX);
+ if (rc != 0)
+ GOTO(out, rc);
+
mutex_lock(&lfsck->li_mutex);
if (lfsck->li_lpf_obj != NULL)
GOTO(unlock, rc = 0);
unlock:
mutex_unlock(&lfsck->li_mutex);
+ lfsck_ibits_unlock(&lh, LCK_EX);
if (rc != 0 && child != NULL && !IS_ERR(child))
lu_object_put(env, &child->do_lu);
out: