+static int mdd_lfsck_namespace_lookup(const struct lu_env *env,
+ struct lfsck_component *com,
+ const struct lu_fid *fid,
+ __u8 *flags)
+{
+ struct lu_fid *key = &mdd_env_info(env)->mti_fid;
+ int rc;
+
+ fid_cpu_to_be(key, fid);
+ rc = dt_lookup(env, com->lc_obj, (struct dt_rec *)flags,
+ (const struct dt_key *)key, BYPASS_CAPA);
+ return rc;
+}
+
+static int mdd_lfsck_namespace_update(const struct lu_env *env,
+ struct lfsck_component *com,
+ const struct lu_fid *fid,
+ __u8 flags, bool force)
+{
+ struct mdd_device *mdd = mdd_lfsck2mdd(com->lc_lfsck);
+ struct lu_fid *key = &mdd_env_info(env)->mti_fid;
+ struct thandle *handle;
+ struct dt_object *obj = com->lc_obj;
+ int rc;
+ bool exist = false;
+ __u8 tf;
+ ENTRY;
+
+ rc = mdd_lfsck_namespace_lookup(env, com, fid, &tf);
+ if (rc != 0 && rc != -ENOENT)
+ RETURN(rc);
+
+ if (rc == 0) {
+ if (!force || flags == tf)
+ RETURN(0);
+
+ exist = true;
+ handle = dt_trans_create(env, mdd->mdd_bottom);
+ if (IS_ERR(handle))
+ RETURN(PTR_ERR(handle));
+
+ rc = dt_declare_delete(env, obj, (const struct dt_key *)fid,
+ handle);
+ if (rc != 0)
+ GOTO(out, rc);
+ } else {
+ handle = dt_trans_create(env, mdd->mdd_bottom);
+ if (IS_ERR(handle))
+ RETURN(PTR_ERR(handle));
+ }
+
+ rc = dt_declare_insert(env, obj, (const struct dt_rec *)&flags,
+ (const struct dt_key *)fid, handle);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ rc = dt_trans_start_local(env, mdd->mdd_bottom, handle);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ fid_cpu_to_be(key, fid);
+ if (exist) {
+ rc = dt_delete(env, obj, (const struct dt_key *)key, handle,
+ BYPASS_CAPA);
+ if (rc != 0) {
+ CERROR("%s: fail to insert "DFID", rc = %d\n",
+ mdd_lfsck2name(com->lc_lfsck), PFID(fid), rc);
+ GOTO(out, rc);
+ }
+ }
+
+ rc = dt_insert(env, obj, (const struct dt_rec *)&flags,
+ (const struct dt_key *)key, handle, BYPASS_CAPA, 1);
+
+ GOTO(out, rc);
+
+out:
+ dt_trans_stop(env, mdd->mdd_bottom, handle);
+ return rc;
+}
+