- struct mds_obd *mds = &obd->u.mds;
- struct obd_export *dt_exp = mds->mds_dt_exp;
- struct inode *inode = dentry->d_inode;
- struct lov_mds_md *lmm= NULL;
- struct lov_stripe_md *lsm = NULL;
- struct obdo *oa = NULL;
- struct obd_trans_info oti = {0};
- struct iattr iattr = { 0 };
- obd_valid valid = 0;
- char idname[LL_ID_NAMELEN];
- int lmm_size = 0, lsm_size = 0, err, rc;
- void *handle;
- ENTRY;
-
- LASSERT(down_trylock(&inode->i_sem) != 0);
-
- ll_id2str(idname, inode->i_ino, inode->i_generation);
-
- /* XXX - add way to know if EA is already up to date & return
- * without doing anything. Easy to do since we get notified of
- * LOV updates. */
-
- lmm = lustre_msg_buf(msg, offset, 0);
- if (lmm == NULL) {
- CDEBUG(D_INFO, "no space reserved for inode %lu MD\n",
- inode->i_ino);
- RETURN(0);
- }
- lmm_size = msg->buflens[offset];
-
- rc = obd_unpackmd(dt_exp, &lsm, lmm, lmm_size);
- if (rc < 0)
- RETURN(0);
-
- lsm_size = rc;
-
- LASSERT(lsm->lsm_magic == LOV_MAGIC);
-
- oa = obdo_alloc();
- if (oa == NULL)
- GOTO(out_lsm, rc = -ENOMEM);
- oa->o_mode = S_IFREG | 0600;
- oa->o_id = inode->i_ino;
- oa->o_generation = inode->i_generation;
- oa->o_uid = 0; /* must have 0 uid / gid on OST */
- oa->o_gid = 0;
- oa->o_gr = FILTER_GROUP_FIRST_MDS + mds->mds_num;
-
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLGENER | OBD_MD_FLTYPE |
- OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID |
- OBD_MD_FLGROUP;
- valid = OBD_MD_FLTYPE | OBD_MD_FLATIME | OBD_MD_FLMTIME |
- OBD_MD_FLCTIME;
- obdo_from_inode(oa, inode, valid);
-
- rc = obd_revalidate_md(dt_exp, oa, lsm, &oti);
- if (rc == 0)
- GOTO(out_oa, rc);
- if (rc < 0) {
- CERROR("Error validating LOV EA on %lu/%u: %d\n",
- inode->i_ino, inode->i_generation, rc);
- GOTO(out_oa, rc);
- }
-
- rc = obd_packmd(dt_exp, &lmm, lsm);
- if (rc < 0)
- GOTO(out_oa, rc);
- lmm_size = rc;
-
- DOWN_WRITE_I_ALLOC_SEM(inode);
- mds_inode_set_attrs_old(inode);
- UP_WRITE_I_ALLOC_SEM(inode);
-
- handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
- if (IS_ERR(handle)) {
- rc = PTR_ERR(handle);
- GOTO(out_oa, rc);
- }
-
- rc = fsfilt_set_md(obd, inode, handle, lmm, lmm_size, EA_LOV);
- if (rc) {
- CERROR("error in fsfilt_set_md(%s): rc %d\n", idname, rc);
- GOTO(commit, rc);
- }
-
- /* the EA has changed - let's update i_size/i_blocks */
- /* NOTE: that we're calling mds_validate_size() with the i_sem held. */
- mds_validate_size(obd, inode, NULL, lsm, &iattr);
- if (iattr.ia_valid != 0) {
- rc = fsfilt_setattr(obd, dentry, handle, &iattr, 0);
- if (rc)
- CERROR("error in setattr(%s): rc %d\n", idname, rc);