+/* get default LMV from client cache */
+static int ll_dir_get_default_lmv(struct inode *inode, struct lmv_user_md *lum)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ const struct lmv_stripe_md *lsm;
+ bool fs_dmv_got = false;
+ int rc = -ENODATA;
+
+ ENTRY;
+retry:
+ if (lli->lli_default_lsm_md) {
+ down_read(&lli->lli_lsm_sem);
+ lsm = lli->lli_default_lsm_md;
+ if (lsm) {
+ lum->lum_magic = lsm->lsm_md_magic;
+ lum->lum_stripe_count = lsm->lsm_md_stripe_count;
+ lum->lum_stripe_offset = lsm->lsm_md_master_mdt_index;
+ lum->lum_hash_type = lsm->lsm_md_hash_type;
+ lum->lum_max_inherit = lsm->lsm_md_max_inherit;
+ lum->lum_max_inherit_rr = lsm->lsm_md_max_inherit_rr;
+ rc = 0;
+ }
+ up_read(&lli->lli_lsm_sem);
+ }
+
+ if (rc == -ENODATA && !is_root_inode(inode) && !fs_dmv_got) {
+ lli = ll_i2info(inode->i_sb->s_root->d_inode);
+ fs_dmv_got = true;
+ goto retry;
+ }
+
+ if (!rc && fs_dmv_got) {
+ lli = ll_i2info(inode);
+ if (lum->lum_max_inherit != LMV_INHERIT_UNLIMITED) {
+ if (lum->lum_max_inherit == LMV_INHERIT_NONE ||
+ lum->lum_max_inherit < LMV_INHERIT_END ||
+ lum->lum_max_inherit > LMV_INHERIT_MAX ||
+ lum->lum_max_inherit <= lli->lli_dir_depth)
+ GOTO(out, rc = -ENODATA);
+
+ lum->lum_max_inherit -= lli->lli_dir_depth;
+ }
+
+ if (lum->lum_max_inherit_rr != LMV_INHERIT_RR_UNLIMITED) {
+ if (lum->lum_max_inherit_rr == LMV_INHERIT_NONE ||
+ lum->lum_max_inherit_rr < LMV_INHERIT_RR_END ||
+ lum->lum_max_inherit_rr > LMV_INHERIT_RR_MAX ||
+ lum->lum_max_inherit_rr <= lli->lli_dir_depth)
+ lum->lum_max_inherit_rr = LMV_INHERIT_RR_NONE;
+
+ if (lum->lum_max_inherit_rr > lli->lli_dir_depth)
+ lum->lum_max_inherit_rr -= lli->lli_dir_depth;
+ }
+ }
+out:
+ RETURN(rc);
+}
+