Whamcloud - gitweb
Branch b_new_cmd
authorvitaly <vitaly>
Thu, 5 Oct 2006 11:33:00 +0000 (11:33 +0000)
committervitaly <vitaly>
Thu, 5 Oct 2006 11:33:00 +0000 (11:33 +0000)
several size-on-mds related bug fixed

lustre/include/lustre_lib.h
lustre/liblustre/file.c
lustre/llite/file.c
lustre/llite/llite_close.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/rw.c

index 4233d36..5fb2ad3 100644 (file)
@@ -93,6 +93,7 @@ struct obd_client_handle {
         struct llog_cookie och_cookie;
         struct mdc_open_data *och_mod;
         __u32 och_magic;
+        int och_flags;
 };
 #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
 
index 81ba673..fea369a 100644 (file)
@@ -362,22 +362,24 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode)
         op_data.attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET |
                                 ATTR_MTIME_SET | ATTR_CTIME_SET;
         
-        if (!S_ISREG(llu_i2stat(inode)->st_mode)) {
-                op_data.attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
-        } else {
-                /* Inode cannot be dirty. Close the epoch. */
-                op_data.flags |= MF_EPOCH_CLOSE;
-                /* XXX: Send CHANGE flag only if Size-on-MDS inode attributes
-                 * are really changed.  */
-                op_data.flags |= MF_SOM_CHANGE;
-
-                /* Pack Size-on-MDS attrinodes if valid. */
-                if ((lli->lli_flags & LLIF_MDS_SIZE_LOCK) ||
-                    !llu_local_size(inode))
-                        op_data.attr.ia_valid |= 
-                                OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+        if (fd->fd_flags & FMODE_WRITE) {
+                if (!S_ISREG(llu_i2stat(inode)->st_mode)) {
+                        op_data.attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
+                } else {
+                        /* Inode cannot be dirty. Close the epoch. */
+                        op_data.flags |= MF_EPOCH_CLOSE;
+                        /* XXX: Send CHANGE flag only if Size-on-MDS inode attributes
+                         * are really changed.  */
+                        op_data.flags |= MF_SOM_CHANGE;
+
+                        /* Pack Size-on-MDS attributes if we are in IO epoch and 
+                         * attributes are valid. */
+                        LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK));
+                        if (!llu_local_size(inode))
+                                op_data.attr.ia_valid |= 
+                                        OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+                }
         }
-        
         op_data.fid1 = lli->lli_fid;
         op_data.attr.ia_atime = st->st_atime;
         op_data.attr.ia_mtime = st->st_mtime;
@@ -392,6 +394,7 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode)
         if (rc == -EAGAIN) {
                 /* We are the last writer, so the MDS has instructed us to get
                  * the file size and any write cookies, then close again. */
+                LASSERT(fd->fd_flags & FMODE_WRITE);
                 rc = llu_sizeonmds_update(inode, &och->och_fh);
                 if (rc) {
                         CERROR("inode %llu mdc Size-on-MDS update failed: "
index e042728..ed0e62e 100644 (file)
@@ -68,36 +68,19 @@ void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
 static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data,
                              struct obd_client_handle *och)
 {
-        struct ll_inode_info *lli = ll_i2info(inode);
-        int new_pending = 0;
         ENTRY;
         
         op_data->attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET |
                                  ATTR_MTIME_SET | ATTR_CTIME_SET;
 
-        if (!S_ISREG(inode->i_mode)) {
-                op_data->attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
+        if (!(och->och_flags & FMODE_WRITE))
                 goto out;
-        }
         
-        spin_lock(&lli->lli_lock);
-        if (!(list_empty(&lli->lli_pending_write_llaps)) && 
-            !(lli->lli_flags & LLIF_EPOCH_PENDING)) {
-                LASSERT(lli->lli_pending_och == NULL);
-                /* Inode is dirty and there is no pending write done request
-                 * yet, DONE_WRITE is to be sent later. */
-                lli->lli_flags |= LLIF_EPOCH_PENDING;
-                lli->lli_pending_och = och;
-                new_pending = 1;
-        } else {
-                ll_epoch_close(inode, op_data);
-        }
-        spin_unlock(&lli->lli_lock);
+        if (!S_ISREG(inode->i_mode))
+                op_data->attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
+        else
+                ll_epoch_close(inode, op_data, &och, 0);
 
-        if (new_pending) {
-                inode = igrab(inode);
-                LASSERT(inode);
-        }
 out:
         ll_pack_inode2opdata(inode, op_data, &och->och_fh);
         EXIT;
@@ -138,8 +121,9 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
                 GOTO(out, rc = -ENOMEM);
 
         ll_prepare_close(inode, op_data, och);
-        epoch_close = (op_data->flags & MF_EPOCH_CLOSE) || 
-                      !S_ISREG(inode->i_mode);
+        epoch_close = (och->och_flags & FMODE_WRITE) && 
+                      ((op_data->flags & MF_EPOCH_CLOSE) || 
+                       !S_ISREG(inode->i_mode));
         rc = md_close(md_exp, op_data, och, &req);
 
         ll_finish_md_op_data(op_data);
@@ -159,8 +143,8 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
                        inode->i_ino, rc);
         }
         
-        if (!epoch_close)
-                ll_init_done_writing(inode);
+        if (!epoch_close && (och->och_flags & FMODE_WRITE))
+                ll_queue_done_writing(inode, LLIF_DONE_WRITING);
 
         if (rc == 0) {
                 rc = ll_objects_destroy(req, inode);
@@ -395,6 +379,7 @@ static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
         memcpy(&och->och_fh, &body->handle, sizeof(body->handle));
         och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
         och->och_fid = &lli->lli_fid;
+        och->och_flags = it->it_flags;
         lli->lli_ioepoch = body->ioepoch;
 
         return md_set_open_replay_data(md_exp, och, req);
index f0bc9ec..9e2e680 100644 (file)
@@ -63,11 +63,13 @@ int llap_write_complete(struct inode *inode, struct ll_async_page *llap)
 /* Queue DONE_WRITING if 
  * - done writing is allowed;
  * - inode has no no dirty pages; */
-void ll_queue_done_writing(struct inode *inode)
+void ll_queue_done_writing(struct inode *inode, unsigned long flags)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
         
         spin_lock(&lli->lli_lock);
+        lli->lli_flags |= flags;
+        
         if ((lli->lli_flags & LLIF_DONE_WRITING) &&
             list_empty(&lli->lli_pending_write_llaps)) {
                 struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;
@@ -85,41 +87,61 @@ void ll_queue_done_writing(struct inode *inode)
         spin_unlock(&lli->lli_lock);
 }
 
-/* CLOSE has already occured but has not closed epoch;
- * Let let DONE_WRITING to happen. */
-void ll_init_done_writing(struct inode *inode) {
-        struct ll_inode_info *lli = ll_i2info(inode);
-        spin_lock(&lli->lli_lock);
-        if ((lli->lli_flags & LLIF_EPOCH_PENDING))
-                lli->lli_flags |= LLIF_DONE_WRITING;
-        spin_unlock(&lli->lli_lock);
-        ll_queue_done_writing(inode);
-}
-
 /* Close epoch and send Size-on-MDS attribute update if possible. 
  * Call this under @lli->lli_lock spinlock. */
-void ll_epoch_close(struct inode *inode, struct md_op_data *op_data)
+void ll_epoch_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);
         ENTRY;
 
+        spin_lock(&lli->lli_lock);
+        if (!(list_empty(&lli->lli_pending_write_llaps)) && 
+            !(lli->lli_flags & LLIF_EPOCH_PENDING)) {
+                LASSERT(*och != NULL);
+                LASSERT(lli->lli_pending_och == NULL);
+                /* Inode is dirty and there is no pending write done request
+                 * yet, DONE_WRITE is to be sent later. */
+                lli->lli_flags |= LLIF_EPOCH_PENDING;
+                lli->lli_pending_och = *och;
+                spin_unlock(&lli->lli_lock);
+                
+                inode = igrab(inode);
+                LASSERT(inode);
+                goto out;
+        }
+
         CDEBUG(D_INODE, "Epoch "LPU64" closed on "DFID"\n",
                op_data->ioepoch, PFID(&lli->lli_fid));
         op_data->flags |= MF_EPOCH_CLOSE;
 
-        /* Pack Size-on-MDS inode attributes only if they has changed */
-        if (!(lli->lli_flags & LLIF_SOM_DIRTY))
-                goto out;
-        
-        /* There is already 1 pending DONE_WRITE, do not create another one --
-         * close epoch with no attribute change. */
-        if (lli->lli_flags & LLIF_EPOCH_PENDING)
-                goto out;
+        if (flags & LLIF_DONE_WRITING) {
+                LASSERT(lli->lli_flags & LLIF_SOM_DIRTY);
+                *och = lli->lli_pending_och;
+                lli->lli_pending_och = NULL;
+                lli->lli_flags &= ~(LLIF_DONE_WRITING | LLIF_EPOCH_PENDING | 
+                                    LLIF_EPOCH_PENDING);
+        } else {
+                /* Pack Size-on-MDS inode attributes only if they has changed */
+                if (!(lli->lli_flags & LLIF_SOM_DIRTY)) {
+                        spin_unlock(&lli->lli_lock);
+                        goto out;
+                }
+
+                /* There is already 1 pending DONE_WRITE, do not create another
+                 * one -- close epoch with no attribute change. */
+                if (lli->lli_flags & LLIF_EPOCH_PENDING) {
+                        spin_unlock(&lli->lli_lock);
+                        goto out;
+                }
+        }
         
+        spin_unlock(&lli->lli_lock);
         op_data->flags |= MF_SOM_CHANGE;
 
         /* Check if Size-on-MDS attributes are valid. */
-        if ((lli->lli_flags & LLIF_MDS_SIZE_LOCK) || !ll_local_size(inode)) {
+        LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK));
+        if (!ll_local_size(inode)) {
                 /* Send Size-on-MDS Attributes if valid. */
                 op_data->attr.ia_valid |= ATTR_MTIME_SET | ATTR_CTIME_SET |
                                           ATTR_SIZE | ATTR_BLOCKS;
@@ -172,9 +194,8 @@ out:
 /* Send a DONE_WRITING rpc, pack Size-on-MDS attributes into it, if possible */
 static void ll_done_writing(struct inode *inode)
 {
-        struct ll_inode_info *lli = ll_i2info(inode);
+        struct obd_client_handle *och = NULL;
         struct md_op_data *op_data;
-        struct obd_client_handle *och;
         int rc;
         ENTRY;
 
@@ -185,16 +206,7 @@ static void ll_done_writing(struct inode *inode)
                 return;
         }
 
-        spin_lock(&lli->lli_lock);
-        LASSERT(lli->lli_flags & LLIF_SOM_DIRTY);
-        
-        och = lli->lli_pending_och;
-        lli->lli_pending_och = NULL;
-        lli->lli_flags &= ~(LLIF_DONE_WRITING | LLIF_EPOCH_PENDING);
-        ll_epoch_close(inode, op_data);
-        lli->lli_flags &= ~LLIF_SOM_DIRTY;
-        spin_unlock(&lli->lli_lock);
-        
+        ll_epoch_close(inode, op_data, &och, LLIF_DONE_WRITING);
         ll_pack_inode2opdata(inode, op_data, &och->och_fh);
 
         rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, och);
index 93103b5..2c19a92 100644 (file)
@@ -507,7 +507,8 @@ int ll_release_openhandle(struct dentry *, struct lookup_intent *);
 int ll_md_close(struct obd_export *md_exp, struct inode *inode,
                 struct file *file);
 int ll_md_real_close(struct inode *inode, int flags);
-void ll_epoch_close(struct inode *inode, struct md_op_data *op_data);
+void ll_epoch_close(struct inode *inode, struct md_op_data *op_data,
+                    struct obd_client_handle **och, unsigned long flags);
 int ll_sizeonmds_update(struct inode *inode, struct lustre_handle *fh);
 int ll_inode_getattr(struct inode *inode, struct obdo *obdo);
 int ll_md_setattr(struct inode *inode, struct md_op_data *op_data);
@@ -609,9 +610,8 @@ struct ll_close_queue {
 
 void llap_write_pending(struct inode *inode, struct ll_async_page *llap);
 int llap_write_complete(struct inode *inode, struct ll_async_page *llap);
-int ll_inode_dirty(struct inode *inode);
-void ll_queue_done_writing(struct inode *inode);
-void ll_init_done_writing(struct inode *inode);
+int ll_inode_dirty(struct inode *inode, unsigned long flags);
+void ll_queue_done_writing(struct inode *inode, unsigned long flags);
 void ll_close_thread_shutdown(struct ll_close_queue *lcq);
 int ll_close_thread_start(struct ll_close_queue **lcq_ret);
 
index a124445..7b2b8ff 100644 (file)
@@ -1312,11 +1312,11 @@ static int ll_setattr_done_writing(struct inode *inode,
         if (!S_ISREG(inode->i_mode))
                 RETURN(0);
 
-        /* XXX: pass och here for the recovery purpose. */
         CDEBUG(D_INODE, "Epoch "LPU64" closed on "DFID" for truncate\n",
                op_data->ioepoch, PFID(&lli->lli_fid));
 
         op_data->flags = MF_EPOCH_CLOSE | MF_SOM_CHANGE;
+        /* XXX: pass och here for the recovery purpose. */
         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
index 250e6a9..7e1de81 100644 (file)
@@ -892,7 +892,7 @@ int ll_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
 
         if (cmd & OBD_BRW_WRITE) {
                 if (llap_write_complete(page->mapping->host, llap))
-                        ll_queue_done_writing(page->mapping->host);
+                        ll_queue_done_writing(page->mapping->host, 0);
         }
 
         if (PageWriteback(page)) {
@@ -943,7 +943,7 @@ void ll_removepage(struct page *page)
         }
 
         if (llap_write_complete(inode, llap))
-                ll_queue_done_writing(inode);
+                ll_queue_done_writing(inode, 0);
 
         rc = obd_teardown_async_page(exp, ll_i2info(inode)->lli_smd, NULL,
                                      llap->llap_cookie);