From f04fe09574947998888fedd1999a194f21b4efd4 Mon Sep 17 00:00:00 2001 From: vitaly Date: Thu, 5 Oct 2006 11:33:00 +0000 Subject: [PATCH] Branch b_new_cmd several size-on-mds related bug fixed --- lustre/include/lustre_lib.h | 1 + lustre/liblustre/file.c | 33 ++++++++++-------- lustre/llite/file.c | 37 ++++++-------------- lustre/llite/llite_close.c | 80 +++++++++++++++++++++++++------------------ lustre/llite/llite_internal.h | 8 ++--- lustre/llite/llite_lib.c | 2 +- lustre/llite/rw.c | 4 +-- 7 files changed, 83 insertions(+), 82 deletions(-) diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index 4233d36..5fb2ad3 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -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 diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c index 81ba673..fea369a 100644 --- a/lustre/liblustre/file.c +++ b/lustre/liblustre/file.c @@ -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: " diff --git a/lustre/llite/file.c b/lustre/llite/file.c index e042728..ed0e62e 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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); diff --git a/lustre/llite/llite_close.c b/lustre/llite/llite_close.c index f0bc9ec..9e2e680 100644 --- a/lustre/llite/llite_close.c +++ b/lustre/llite/llite_close.c @@ -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); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 93103b5..2c19a92 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index a124445..7b2b8ff 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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 diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 250e6a9..7e1de81 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -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); -- 1.8.3.1