+static int lfsck_lmv_set(const struct lu_env *env,
+ struct lfsck_instance *lfsck,
+ struct dt_object *obj,
+ struct lmv_mds_md_v1 *lmv)
+{
+ struct dt_device *dev = lfsck->li_next;
+ struct thandle *th = NULL;
+ struct lu_buf buf = { lmv, sizeof(*lmv) };
+ int rc;
+
+ ENTRY;
+
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ rc = dt_declare_xattr_set(env, obj, &buf, XATTR_NAME_LMV".set", 0, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc != 0)
+ GOTO(stop, rc);
+
+ rc = dt_xattr_set(env, obj, &buf, XATTR_NAME_LMV".set", 0, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ EXIT;
+stop:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+static int lfsck_lmv_delete(const struct lu_env *env,
+ struct lfsck_instance *lfsck,
+ struct dt_object *obj)
+{
+ struct dt_device *dev = lfsck->li_next;
+ struct thandle *th = NULL;
+ int rc;
+
+ ENTRY;
+
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ rc = dt_declare_xattr_del(env, obj, XATTR_NAME_LMV, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc != 0)
+ GOTO(stop, rc);
+
+ rc = dt_xattr_del(env, obj, XATTR_NAME_LMV, th);
+ if (rc)
+ GOTO(stop, rc);
+
+ EXIT;
+stop:
+ dt_trans_stop(env, dev, th);
+
+ return rc;
+}
+
+static inline int lfsck_object_is_shard(const struct lu_env *env,
+ struct lfsck_instance *lfsck,
+ struct dt_object *obj,
+ const struct lu_name *lname)
+{
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lmv_mds_md_v1 *lmv = &info->lti_lmv;
+ int rc;
+
+ rc = lfsck_shard_name_to_index(env, lname->ln_name, lname->ln_namelen,
+ lfsck_object_type(obj),
+ lfsck_dto2fid(obj));
+ if (rc < 0)
+ return 0;
+
+ rc = lfsck_read_stripe_lmv(env, lfsck, obj, lmv);
+ if (rc == -ENODATA)
+ return 0;
+
+ if (!rc && lmv->lmv_magic == LMV_MAGIC_STRIPE)
+ return 1;
+
+ return rc;
+}
+