From 44f0b1f2ee9a07787d0be403762d0973ed3cfa80 Mon Sep 17 00:00:00 2001 From: yury Date: Wed, 2 Mar 2005 17:30:19 +0000 Subject: [PATCH] - fixes from b1_4: - in filter_setattr() for test_17 from sanityN.sh. - in ll_truncate() do not call truncate on server if new inode size the same as previous one. Note: using lov_merge_size() in llite is clear layering violation. - fixes in ll_setattr_raw() --- lustre/llite/llite_lib.c | 14 ++++++++++ lustre/llite/rw.c | 65 ++++++++++++++++++++++++++--------------------- lustre/obdfilter/filter.c | 25 ++++++++---------- 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 7968f4f..f0443a1 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1035,9 +1035,16 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) /* bug 1639: avoid write/truncate i_sem/DLM deadlock */ LASSERT(atomic_read(&inode->i_sem.count) <= 0); up(&inode->i_sem); + UP_WRITE_I_ALLOC_SEM(inode); rc = ll_extent_lock(NULL, inode, lsm, LCK_PW, &policy, &lockh, ast_flags, &ll_i2sbi(inode)->ll_seek_stime); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + DOWN_WRITE_I_ALLOC_SEM(inode); + down(&inode->i_sem); +#else down(&inode->i_sem); + DOWN_WRITE_I_ALLOC_SEM(inode); +#endif if (rc != 0) RETURN(rc); @@ -1046,10 +1053,17 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) /* We need to drop the semaphore here, because this unlock may * result in a cancellation, which will need the i_sem */ up(&inode->i_sem); + UP_WRITE_I_ALLOC_SEM(inode); /* unlock now as we don't mind others file lockers racing with * the mds updates below? */ err = ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + DOWN_WRITE_I_ALLOC_SEM(inode); + down(&inode->i_sem); +#else down(&inode->i_sem); + DOWN_WRITE_I_ALLOC_SEM(inode); +#endif if (err) { CERROR("ll_extent_unlock failed: %d\n", err); if (!rc) diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 8a7f6eb..4ac38e4 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -104,6 +104,8 @@ static int ll_brw(int cmd, struct inode *inode, struct obdo *oa, RETURN(rc); } +__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms); + /* this isn't where truncate starts. roughly: * sys_truncate->ll_setattr_raw->vmtruncate->ll_truncate * we grab the lock back in setattr_raw to avoid races. */ @@ -124,39 +126,44 @@ void ll_truncate(struct inode *inode) return; } - oa = obdo_alloc(); - if (oa == NULL) { - CERROR("cannot alloc oa, error %d\n", - -ENOMEM); - EXIT; - return; - } - - oa->o_id = lsm->lsm_object_id; - oa->o_gr = lsm->lsm_object_gr; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP; - obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME); - - CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after %Lu)\n", - oa->o_id, inode->i_size); - - /* truncate == punch from new size to absolute end of file */ - /* NB: obd_punch must be called with i_sem held! It updates the kms! */ - rc = obd_punch(ll_i2dtexp(inode), oa, lsm, inode->i_size, - OBD_OBJECT_EOF, NULL); - if (rc) - CERROR("obd_truncate fails (%d) ino %lu\n", rc, inode->i_ino); - else - obdo_to_inode(inode, oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | - OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME); - - obdo_free(oa); + if (lov_merge_size(lsm, 0) == inode->i_size) { + CDEBUG(D_VFSTRACE, "skipping punch for "LPX64" (size = %llu)\n", + lsm->lsm_object_id, inode->i_size); + } else { + CDEBUG(D_INFO, "calling punch for "LPX64" (new size %llu)\n", + lsm->lsm_object_id, inode->i_size); + + oa = obdo_alloc(); + if (oa == NULL) { + CERROR("cannot alloc oa, error %d\n", + -ENOMEM); + EXIT; + return; + } + + oa->o_id = lsm->lsm_object_id; + oa->o_gr = lsm->lsm_object_gr; + oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP; + obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLMODE | + OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME); + + /* truncate == punch from new size to absolute end of file */ + /* NB: obd_punch must be called with i_sem held! It updates the kms! */ + rc = obd_punch(ll_i2dtexp(inode), oa, lsm, inode->i_size, + OBD_OBJECT_EOF, NULL); + if (rc) + CERROR("obd_truncate fails (%d) ino %lu\n", rc, inode->i_ino); + else + obdo_to_inode(inode, oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | + OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME); + + obdo_free(oa); + } + EXIT; return; } /* ll_truncate */ -__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms); int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index b441bdb..e7495de 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2079,20 +2079,17 @@ static int filter_setattr(struct obd_export *exp, struct obdo *oa, rc = rc2; } - if (iattr.ia_valid & ATTR_SIZE) { - res = ldlm_resource_get(exp->exp_obd->obd_namespace, NULL, - res_id, LDLM_EXTENT, 0); - if (res == NULL) { - CERROR("!!! resource_get failed for object "LPU64" -- " - "filter_setattr with no lock?\n", oa->o_id); - } else { - if (res->lr_namespace->ns_lvbo && - res->lr_namespace->ns_lvbo->lvbo_update) { - rc = res->lr_namespace->ns_lvbo->lvbo_update - (res, NULL, 0, 0); - } - ldlm_resource_putref(res); - } + res = ldlm_resource_get(exp->exp_obd->obd_namespace, NULL, + res_id, LDLM_EXTENT, 0); + if (res != NULL) { + if (res->lr_namespace->ns_lvbo && + res->lr_namespace->ns_lvbo->lvbo_update) + rc = res->lr_namespace->ns_lvbo->lvbo_update(res, NULL, + 0, 0); + ldlm_resource_putref(res); + } else if (iattr.ia_valid & ATTR_SIZE) { + CERROR("!!! resource_get failed for object "LPU64" -- " + "filter_setattr with no lock?\n", oa->o_id); } oa->o_valid = OBD_MD_FLID; -- 1.8.3.1