+int llu_md_setattr(struct inode *inode, struct md_op_data *op_data,
+ struct md_open_data **mod)
+{
+ struct lustre_md md;
+ struct llu_sb_info *sbi = llu_i2sbi(inode);
+ struct ptlrpc_request *request = NULL;
+ int rc;
+ ENTRY;
+
+ llu_prep_md_op_data(op_data, inode, NULL, NULL, 0, 0, LUSTRE_OPC_ANY);
+ rc = md_setattr(sbi->ll_md_exp, op_data, NULL, 0, NULL,
+ 0, &request, mod);
+
+ if (rc) {
+ ptlrpc_req_finished(request);
+ if (rc != -EPERM && rc != -EACCES)
+ CERROR("md_setattr fails: rc = %d\n", rc);
+ RETURN(rc);
+ }
+
+ rc = md_get_lustre_md(sbi->ll_md_exp, request,
+ sbi->ll_dt_exp, sbi->ll_md_exp, &md);
+ if (rc) {
+ ptlrpc_req_finished(request);
+ RETURN(rc);
+ }
+
+ /* We call inode_setattr to adjust timestamps.
+ * If there is at least some data in file, we cleared ATTR_SIZE
+ * above to avoid invoking vmtruncate, otherwise it is important
+ * to call vmtruncate in inode_setattr to update inode->i_size
+ * (bug 6196) */
+ inode_setattr(inode, &op_data->op_attr);
+ llu_update_inode(inode, &md);
+ ptlrpc_req_finished(request);
+
+ RETURN(rc);
+}
+
+/* Close IO epoch and send Size-on-MDS attribute update. */
+static int llu_setattr_done_writing(struct inode *inode,
+ struct md_op_data *op_data,
+ struct md_open_data *mod)
+{
+ struct llu_inode_info *lli = llu_i2info(inode);
+ struct intnl_stat *st = llu_i2stat(inode);
+ int rc = 0;
+ ENTRY;
+
+ LASSERT(op_data != NULL);
+ if (!S_ISREG(st->st_mode))
+ RETURN(0);
+
+ /* XXX: pass och here for the recovery purpose. */
+ CDEBUG(D_INODE, "Epoch "LPU64" closed on "DFID" for truncate\n",
+ op_data->op_ioepoch, PFID(&lli->lli_fid));
+
+ op_data->op_flags = MF_EPOCH_CLOSE;
+ llu_done_writing_attr(inode, op_data);
+ llu_pack_inode2opdata(inode, op_data, NULL);
+
+ rc = md_done_writing(llu_i2sbi(inode)->ll_md_exp, op_data, mod);
+ if (rc == -EAGAIN) {
+ /* MDS has instructed us to obtain Size-on-MDS attribute
+ * from OSTs and send setattr to back to MDS. */
+ rc = llu_som_update(inode, op_data);
+ } else if (rc) {
+ CERROR("inode %llu mdc truncate failed: rc = %d\n",
+ (unsigned long long)st->st_ino, rc);
+ }
+ RETURN(rc);
+}
+