+static inline int lli_lsm_md_eq(const struct lmv_stripe_md *lsm_md1,
+ const struct lmv_stripe_md *lsm_md2)
+{
+ return lsm_md1->lsm_md_magic == lsm_md2->lsm_md_magic &&
+ lsm_md1->lsm_md_stripe_count == lsm_md2->lsm_md_stripe_count &&
+ lsm_md1->lsm_md_master_mdt_index ==
+ lsm_md2->lsm_md_master_mdt_index &&
+ lsm_md1->lsm_md_hash_type == lsm_md2->lsm_md_hash_type &&
+ lsm_md1->lsm_md_layout_version ==
+ lsm_md2->lsm_md_layout_version &&
+ strcmp(lsm_md1->lsm_md_pool_name,
+ lsm_md2->lsm_md_pool_name) == 0;
+}
+
+static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lmv_stripe_md *lsm = md->lmv;
+ int idx;
+ ENTRY;
+
+ LASSERT(S_ISDIR(inode->i_mode));
+ CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md,
+ PFID(ll_inode2fid(inode)));
+
+ /* no striped information from request. */
+ if (lsm == NULL) {
+ if (lli->lli_lsm_md == NULL) {
+ RETURN_EXIT;
+ } else if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_MIGRATE) {
+ /* migration is done, the temporay MIGRATE layout has
+ * been removed */
+ CDEBUG(D_INODE, DFID" finish migration.\n",
+ PFID(ll_inode2fid(inode)));
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
+ RETURN_EXIT;
+ } else {
+ /* The lustre_md from req does not include stripeEA,
+ * see ll_md_setattr */
+ RETURN_EXIT;
+ }
+ }
+
+ /* set the directory layout */
+ if (lli->lli_lsm_md == NULL) {
+ int rc;
+
+ rc = ll_init_lsm_md(inode, md);
+ if (rc != 0) {
+ CERROR("%s: init "DFID" failed: rc = %d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0),
+ PFID(&lli->lli_fid), rc);
+ return;
+ }
+ lli->lli_lsm_md = lsm;
+ /* set lsm_md to NULL, so the following free lustre_md
+ * will not free this lsm */
+ md->lmv = NULL;
+ CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
+ lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
+ RETURN_EXIT;
+ }
+
+ /* Compare the old and new stripe information */
+ if (!lli_lsm_md_eq(lli->lli_lsm_md, lsm)) {
+ CERROR("inode %p %lu mismatch\n"
+ " new(%p) vs lli_lsm_md(%p):\n"
+ " magic: %x %x\n"
+ " count: %x %x\n"
+ " master: %x %x\n"
+ " hash_type: %x %x\n"
+ " layout: %x %x\n"
+ " pool: %s %s\n",
+ inode, inode->i_ino, lsm, lli->lli_lsm_md,
+ lsm->lsm_md_magic, lli->lli_lsm_md->lsm_md_magic,
+ lsm->lsm_md_stripe_count,
+ lli->lli_lsm_md->lsm_md_stripe_count,
+ lsm->lsm_md_master_mdt_index,
+ lli->lli_lsm_md->lsm_md_master_mdt_index,
+ lsm->lsm_md_hash_type, lli->lli_lsm_md->lsm_md_hash_type,
+ lsm->lsm_md_layout_version,
+ lli->lli_lsm_md->lsm_md_layout_version,
+ lsm->lsm_md_pool_name,
+ lli->lli_lsm_md->lsm_md_pool_name);
+ return;
+ }
+
+ for (idx = 0; idx < lli->lli_lsm_md->lsm_md_stripe_count; idx++) {
+ if (!lu_fid_eq(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid,
+ &lsm->lsm_md_oinfo[idx].lmo_fid)) {
+ CERROR("%s: FID in lsm mismatch idx %d, old: "DFID
+ "new:"DFID"\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), idx,
+ PFID(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid),
+ PFID(&lsm->lsm_md_oinfo[idx].lmo_fid));
+ return;
+ }
+ }
+
+ md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
+ md->body, ll_md_blocking_ast);
+
+ RETURN_EXIT;