Whamcloud - gitweb
b=19964 SOM cleanups, part2
[fs/lustre-release.git] / lustre / llite / llite_close.c
index 53b8514..803f478 100644 (file)
@@ -84,12 +84,14 @@ void vvp_write_complete(struct ccc_object *club, struct ccc_page *page)
 void ll_queue_done_writing(struct inode *inode, unsigned long flags)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
+        struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob);
+        ENTRY;
 
         spin_lock(&lli->lli_lock);
         lli->lli_flags |= flags;
 
         if ((lli->lli_flags & LLIF_DONE_WRITING) &&
-            list_empty(&lli->lli_pending_write_llaps)) {
+            list_empty(&club->cob_pending_list)) {
                 struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;
 
                 if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
@@ -117,18 +119,40 @@ void ll_queue_done_writing(struct inode *inode, unsigned long flags)
                 spin_unlock(&lcq->lcq_lock);
         }
         spin_unlock(&lli->lli_lock);
+        EXIT;
 }
 
-/** Closes epoch and sends Size-on-MDS attribute update if possible.  Call
- * this under ll_inode_info::lli_lock spinlock. */
-void ll_epoch_close(struct inode *inode, struct md_op_data *op_data,
-                    struct obd_client_handle **och, unsigned long flags)
+/** Pack SOM attributes info @opdata for CLOSE, DONE_WRITING rpc. */
+void ll_done_writing_attr(struct inode *inode, struct md_op_data *op_data)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
         ENTRY;
 
+        op_data->op_flags |= MF_SOM_CHANGE;
+        /* Check if Size-on-MDS attributes are valid. */
+        if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
+                CERROR("ino %lu/%u(flags %lu) som valid it just after "
+                       "recovery\n", inode->i_ino, inode->i_generation,
+                       lli->lli_flags);
+
+        if (!cl_local_size(inode)) {
+                /* Send Size-on-MDS Attributes if valid. */
+                op_data->op_attr.ia_valid |= ATTR_MTIME_SET | ATTR_CTIME_SET |
+                                ATTR_ATIME_SET | ATTR_SIZE | ATTR_BLOCKS;
+        }
+        EXIT;
+}
+
+/** Closes ioepoch and packs Size-on-MDS attribute if needed into @op_data. */
+void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
+                      struct obd_client_handle **och, unsigned long flags)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob);
+        ENTRY;
+
         spin_lock(&lli->lli_lock);
-        if (!(list_empty(&lli->lli_pending_write_llaps))) {
+        if (!(list_empty(&club->cob_pending_list))) {
                 if (!(lli->lli_flags & LLIF_EPOCH_PENDING)) {
                         LASSERT(*och != NULL);
                         LASSERT(lli->lli_pending_och == NULL);
@@ -180,81 +204,89 @@ void ll_epoch_close(struct inode *inode, struct md_op_data *op_data,
                 }
         }
 
-        LASSERT(list_empty(&lli->lli_pending_write_llaps));
+        LASSERT(list_empty(&club->cob_pending_list));
         lli->lli_flags &= ~LLIF_SOM_DIRTY;
         spin_unlock(&lli->lli_lock);
-        op_data->op_flags |= MF_SOM_CHANGE;
-
-        /* Check if Size-on-MDS attributes are valid. */
-        if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
-                CWARN("ino %lu/%u(flags %lu) som valid it just after "
-                      "recovery\n",
-                      inode->i_ino, inode->i_generation, lli->lli_flags);
+        ll_done_writing_attr(inode, op_data);
 
-        if (!cl_local_size(inode)) {
-                /* Send Size-on-MDS Attributes if valid. Atime is sent along
-                 * with all the attributes. */
-                op_data->op_attr.ia_valid |= ATTR_MTIME_SET | ATTR_CTIME_SET |
-                                ATTR_ATIME_SET | ATTR_SIZE | ATTR_BLOCKS;
-        }
         EXIT;
 out:
         return;
 }
 
-int ll_sizeonmds_update(struct inode *inode, struct md_open_data *mod,
-                        struct lustre_handle *fh, __u64 ioepoch)
+/**
+ * Cliens updates SOM attributes on MDS (including llog cookies):
+ * obd_getattr with no lock and md_setattr.
+ */
+int ll_som_update(struct inode *inode, struct md_op_data *op_data)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
-        struct md_op_data *op_data;
+        struct ptlrpc_request *request = NULL;
         struct obdo *oa;
         int rc;
         ENTRY;
 
-        /* LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)); */
-        /* After recovery that can be valid. */
         if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
-                CWARN("ino %lu/%u(flags %lu) som valid it just after "
-                      "recovery\n", inode->i_ino, inode->i_generation,
-                      lli->lli_flags);
+                CERROR("ino %lu/%u(flags %lu) som valid it just after "
+                       "recovery\n", inode->i_ino, inode->i_generation,
+                       lli->lli_flags);
 
         OBDO_ALLOC(oa);
-        OBD_ALLOC_PTR(op_data);
-        if (!oa || !op_data) {
+        if (!oa) {
                 CERROR("can't allocate memory for Size-on-MDS update.\n");
                 RETURN(-ENOMEM);
         }
-        rc = ll_inode_getattr(inode, oa);
-        if (rc == -ENOENT) {
-                oa->o_valid = 0;
-                CDEBUG(D_INODE, "objid "LPX64" is already destroyed\n",
-                       lli->lli_smd->lsm_object_id);
-        } else if (rc) {
-                CERROR("inode_getattr failed (%d): unable to send a "
-                       "Size-on-MDS attribute update for inode %lu/%u\n",
-                       rc, inode->i_ino, inode->i_generation);
-                GOTO(out, rc);
+
+        op_data->op_flags = MF_SOM_CHANGE;
+
+        /* If inode is already in another epoch, skip getattr from OSTs. */
+        if (lli->lli_ioepoch == op_data->op_ioepoch) {
+                rc = ll_inode_getattr(inode, oa, op_data->op_ioepoch);
+                if (rc) {
+                        oa->o_valid = 0;
+                        if (rc == -ENOENT)
+                                CDEBUG(D_INODE, "objid "LPX64" is destroyed\n",
+                                       lli->lli_smd->lsm_object_id);
+                        else
+                                CERROR("inode_getattr failed (%d): unable to "
+                                       "send a Size-on-MDS attribute update "
+                                       "for inode %lu/%u\n", rc, inode->i_ino,
+                                       inode->i_generation);
+                } else {
+                        CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n",
+                               PFID(&lli->lli_fid));
+                }
+                /* Install attributes into op_data. */
+                md_from_obdo(op_data, oa, oa->o_valid);
         }
-        CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n", PFID(&lli->lli_fid));
 
-        md_from_obdo(op_data, oa, oa->o_valid);
-        memcpy(&op_data->op_handle, fh, sizeof(*fh));
+        rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data,
+                        NULL, 0, NULL, 0, &request, NULL);
+        ptlrpc_req_finished(request);
 
-        op_data->op_ioepoch = ioepoch;
-        op_data->op_flags |= MF_SOM_CHANGE;
+        OBDO_FREE(oa);
+        RETURN(rc);
+}
 
-        rc = ll_md_setattr(inode, op_data, &mod);
-        EXIT;
-out:
-        if (oa)
-                OBDO_FREE(oa);
-        if (op_data)
-                ll_finish_md_op_data(op_data);
-        return rc;
+/**
+ * Closes the ioepoch and packs all the attributes into @op_data for
+ * DONE_WRITING rpc.
+ */
+static void ll_prepare_done_writing(struct inode *inode,
+                                    struct md_op_data *op_data,
+                                    struct obd_client_handle **och)
+{
+        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);
 }
 
-/** Sends a DONE_WRITING rpc, packs Size-on-MDS attributes into it, if
- * possible */
+/** Send a DONE_WRITING rpc. */
 static void ll_done_writing(struct inode *inode)
 {
         struct obd_client_handle *och = NULL;
@@ -262,7 +294,7 @@ static void ll_done_writing(struct inode *inode)
         int rc;
         ENTRY;
 
-        LASSERT(ll_i2mdexp(inode)->exp_connect_flags & OBD_CONNECT_SOM);
+        LASSERT(exp_connect_som(ll_i2mdexp(inode)));
 
         OBD_ALLOC_PTR(op_data);
         if (op_data == NULL) {
@@ -271,19 +303,16 @@ static void ll_done_writing(struct inode *inode)
                 return;
         }
 
-        ll_epoch_close(inode, op_data, &och, LLIF_DONE_WRITING);
+        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);
 
-        ll_pack_inode2opdata(inode, op_data, &och->och_fh);
-
-        rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, och->och_mod);
+        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_sizeonmds_update(inode, och->och_mod,
-                                         &och->och_fh, op_data->op_ioepoch);
+                rc = ll_som_update(inode, op_data);
         } else if (rc) {
                 CERROR("inode %lu mdc done_writing failed: rc = %d\n",
                        inode->i_ino, rc);