/* 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);
/* 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)
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. */
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)
{
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;