+ ll_ioepoch_close(inode, op_data, och, LLIF_DONE_WRITING);
+ /* If there is no @och, we do not do D_W yet. */
+ if (*och == NULL)
+ return;
+
+ ll_pack_inode2opdata(inode, op_data, &(*och)->och_fh);
+ ll_prep_md_op_data(op_data, inode, NULL, NULL,
+ 0, 0, LUSTRE_OPC_ANY, NULL);
+}
+
+/** Send a DONE_WRITING rpc. */
+static void ll_done_writing(struct inode *inode)
+{
+ struct obd_client_handle *och = NULL;
+ struct md_op_data *op_data;
+ int rc;
+ ENTRY;
+
+ LASSERT(exp_connect_som(ll_i2mdexp(inode)));
+
+ OBD_ALLOC_PTR(op_data);
+ if (op_data == NULL) {
+ CERROR("can't allocate op_data\n");
+ EXIT;
+ return;
+ }
+
+ ll_prepare_done_writing(inode, op_data, &och);
+ /* If there is no @och, we do not do D_W yet. */
+ if (och == NULL)
+ GOTO(out, 0);
+
+ rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, NULL);
+ if (rc == -EAGAIN) {
+ /* MDS has instructed us to obtain Size-on-MDS attribute from
+ * OSTs and send setattr to back to MDS. */
+ rc = ll_som_update(inode, op_data);
+ } else if (rc) {
+ CERROR("inode %lu mdc done_writing failed: rc = %d\n",
+ inode->i_ino, rc);
+ }
+out:
+ ll_finish_md_op_data(op_data);
+ if (och) {
+ md_clear_open_replay_data(ll_i2sbi(inode)->ll_md_exp, och);
+ OBD_FREE_PTR(och);
+ }
+ EXIT;