/*
* if dir layout mismatch, check whether version is increased, which
* means layout is changed, this happens in dir migration and lfsck.
+ *
+ * foreign LMV should not change.
*/
- if (lli->lli_lsm_md && !lsm_md_eq(lli->lli_lsm_md, lsm)) {
+ if (lli->lli_lsm_md &&
+ lli->lli_lsm_md->lsm_md_magic != LMV_MAGIC_FOREIGN &&
+ !lsm_md_eq(lli->lli_lsm_md, lsm)) {
if (lsm->lsm_md_layout_version <=
lli->lli_lsm_md->lsm_md_layout_version) {
CERROR("%s: "DFID" dir layout mismatch:\n",
if (!lli->lli_lsm_md) {
struct cl_attr *attr;
+ if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN) {
+ /* set md->lmv to NULL, so the following free lustre_md
+ * will not free this lsm */
+ md->lmv = NULL;
+ lli->lli_lsm_md = lsm;
+ up_write(&lli->lli_lsm_sem);
+ RETURN(0);
+ }
+
rc = ll_init_lsm_md(inode, md);
up_write(&lli->lli_lsm_sem);
if (rc != 0)
rc = md_get_lustre_md(sbi->ll_md_exp, req, sbi->ll_dt_exp,
sbi->ll_md_exp, &md);
if (rc != 0)
- GOTO(cleanup, rc);
+ GOTO(out, rc);
if (*inode) {
rc = ll_update_inode(*inode, &md);
GOTO(out, rc = 0);
out:
+ /* cleanup will be done if necessary */
md_free_lustre_md(sbi->ll_md_exp, &md);
-cleanup:
if (rc != 0 && it != NULL && it->it_op & IT_OPEN)
ll_open_cleanup(sb != NULL ? sb : (*inode)->i_sb, req);