From b562ef58080fb231740cf562c7ea19452f00df9f Mon Sep 17 00:00:00 2001 From: vitaly Date: Mon, 18 Sep 2006 19:56:14 +0000 Subject: [PATCH] Branch b_new_cmd b=22564 Size-on-MDS bugfixes for: - using in ll_done_writing not pinned inode; - queuing done_writing before close completes; - memleak in ll_setattr_raw --- lustre/llite/file.c | 14 +++++++++++--- lustre/llite/llite_close.c | 30 +++++++++++++++++------------- lustre/llite/llite_lib.c | 5 +++-- lustre/lmv/lmv_intent.c | 5 +++-- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 5b82144..4a1f8af 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -66,6 +66,7 @@ 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 | @@ -84,11 +85,16 @@ static void ll_prepare_close(struct inode *inode, struct md_op_data *op_data, * 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 (new_pending) { + inode = igrab(inode); + LASSERT(inode); + } out: ll_pack_inode2opdata(inode, op_data, &och->och_fh); EXIT; @@ -126,7 +132,7 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, OBD_ALLOC_PTR(op_data); if (op_data == NULL) - RETURN(-ENOMEM); + GOTO(out, rc = -ENOMEM); ll_prepare_close(inode, op_data, och); epoch_close = (op_data->flags & MF_EPOCH_CLOSE); @@ -145,9 +151,11 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, } else if (rc) { CERROR("inode %lu mdc close failed: rc = %d\n", inode->i_ino, rc); - } else if (!epoch_close) { - ll_queue_done_writing(inode); } + + if (!epoch_close) + ll_init_done_writing(inode); + OBD_FREE_PTR(op_data); if (rc == 0) { diff --git a/lustre/llite/llite_close.c b/lustre/llite/llite_close.c index eb0e714..80e6508 100644 --- a/lustre/llite/llite_close.c +++ b/lustre/llite/llite_close.c @@ -60,31 +60,24 @@ int llap_write_complete(struct inode *inode, struct ll_async_page *llap) RETURN(rc); } -/* DONE_WRITING should be queued only if: - * - CLOSE has been called already and that CLOSE has not closed epoch; - * - inode has no no dirty page; */ +/* Queue DONE_WRITING if + * - done writing is allowed; + * - inode has no no dirty pages; */ void ll_queue_done_writing(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); - struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq; - - spin_lock(&lli->lli_lock); - /* Close happened. If it has not closed epoch, let DONE_WRITING to - * happen. */ - if ((lli->lli_flags & LLIF_EPOCH_PENDING)) - lli->lli_flags |= LLIF_DONE_WRITING; - + spin_lock(&lli->lli_lock); if ((lli->lli_flags & LLIF_DONE_WRITING) && list_empty(&lli->lli_pending_write_llaps)) { + struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq; + /* DONE_WRITING is allowed and inode has no dirty page. */ spin_lock(&lcq->lcq_lock); - LASSERT(list_empty(&lli->lli_close_list)); CDEBUG(D_INODE, "adding inode %lu/%u to close list\n", inode->i_ino, inode->i_generation); - igrab(inode); list_add_tail(&lli->lli_close_list, &lcq->lcq_head); wake_up(&lcq->lcq_waitq); spin_unlock(&lcq->lcq_lock); @@ -92,6 +85,17 @@ 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) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 6fdfe13..53bf092 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1465,8 +1465,9 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) } EXIT; out: - if (op_data && op_data->ioepoch) { - rc = ll_setattr_done_writing(inode, op_data); + if (op_data) { + if (op_data->ioepoch) + rc = ll_setattr_done_writing(inode, op_data); OBD_FREE_PTR(op_data); } return rc; diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 9de3265..af16767 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -249,9 +249,10 @@ repeat: goto repeat; } } else if (rc == -ESTALE && it->d.lustre.it_lock_mode) { + struct lustre_handle *handle; /* cross-ref open can have lookup lock on child */ - ldlm_lock_decref((struct lustre_handle *)&it->d.lustre.it_lock_handle, - it->d.lustre.it_lock_mode); + handle = (struct lustre_handle *)&it->d.lustre.it_lock_handle; + ldlm_lock_decref(handle, it->d.lustre.it_lock_mode); } if (rc != 0) -- 1.8.3.1