- rc = 0;
- if (!eviction && !mdt_epoch_opened(o)) {
- /* Epoch ends. Is an Size-on-MDS update needed? */
- if (o->mot_flags & MF_SOM_CHANGE) {
- /* Some previous writer changed the attribute.
- * Do not believe to the current Size-on-MDS
- * update, re-ask client. */
- rc = -EAGAIN;
- } else if (!(la->la_valid & LA_SIZE) && achange) {
- /* Attributes were changed by the last writer
- * only but no Size-on-MDS update is received.*/
- rc = -EAGAIN;
- }
+ la = &info->mti_attr.ma_attr;
+ achange = (info->mti_ioepoch->flags & MF_SOM_CHANGE);
+
+ cfs_down(&o->mot_ioepoch_sem);
+ o->mot_ioepoch_count--;
+
+ tmp_ma = &info->mti_u.som.attr;
+ tmp_ma->ma_lmm = info->mti_attr.ma_lmm;
+ tmp_ma->ma_lmm_size = info->mti_attr.ma_lmm_size;
+ tmp_ma->ma_som = &info->mti_u.som.data;
+ tmp_ma->ma_need = MA_INODE | MA_LOV | MA_SOM;
+ tmp_ma->ma_valid = 0;
+ rc = mo_attr_get(info->mti_env, mdt_object_child(o), tmp_ma);
+ if (rc)
+ GOTO(error_up, rc);
+
+ /* Check the on-disk SOM state. */
+ if (o->mot_flags & MOF_SOM_RECOV)
+ recovery = 1;
+ else if (!(o->mot_flags & MOF_SOM_CREATED) &&
+ !(tmp_ma->ma_valid & MA_SOM))
+ recovery = 1;
+
+ CDEBUG(D_INODE, "Closing epoch "LPU64" on "DFID". Count %d\n",
+ o->mot_ioepoch, PFID(mdt_object_fid(o)), o->mot_ioepoch_count);
+
+ opened = mdt_ioepoch_opened(o);
+ /**
+ * If IOEpoch is not opened, check if a Size-on-MDS update is needed.
+ * Skip the check for file with no LOV or for unlink files.
+ */
+ if (!opened && tmp_ma->ma_valid & MA_LOV &&
+ !(tmp_ma->ma_valid & MA_INODE && tmp_ma->ma_attr.la_nlink == 0)) {
+ if (recovery)
+ /* If some previous writer was evicted, re-ask the
+ * client for attributes. Even if attributes are
+ * provided, we cannot believe in them.
+ * Another use case is that there is no SOM cache on
+ * disk -- first access with SOM or there was an MDS
+ * failure. */
+ ret = MDT_IOEPOCH_GETATTR;
+ else if (o->mot_flags & MOF_SOM_CHANGE)
+ /* Some previous writer changed the attribute.
+ * Do not believe to the current Size-on-MDS
+ * update, re-ask client. */
+ ret = MDT_IOEPOCH_GETATTR;
+ else if (!(la->la_valid & LA_SIZE) && achange)
+ /* Attributes were changed by the last writer
+ * only but no Size-on-MDS update is received.*/
+ ret = MDT_IOEPOCH_GETATTR;
+ }
+
+ if (achange || ret == MDT_IOEPOCH_GETATTR)
+ o->mot_flags |= MOF_SOM_CHANGE;
+
+ /* If epoch ends and relable SOM attributes are obtained, update them.
+ * Create SOM ea for new files even if there is no attributes obtained
+ * (0-length file). */
+ if (ret == MDT_IOEPOCH_CLOSED && !opened) {
+ if (achange || o->mot_flags & MOF_SOM_CREATED) {
+ LASSERT(achange || !(la->la_valid & LA_SIZE));
+ rc = mdt_som_attr_set(info, o, o->mot_ioepoch,
+ MDT_SOM_ENABLE);
+ /* Avoid the following setattrs of these attributes,
+ * e.g. for atime update. */
+ info->mti_attr.ma_valid = 0;