/* Swabbed by mdc_readpage() */
LASSERT(lustre_rep_swabbed(request, REPLY_REC_OFF));
- if (body->valid & OBD_MD_FLSIZE)
+ if (body->valid & OBD_MD_FLSIZE) {
+ ll_inode_size_lock(inode, 0);
i_size_write(inode, body->size);
+ ll_inode_size_unlock(inode, 0);
+ }
SetPageUptodate(page);
}
ptlrpc_req_finished(request);
"the size got from MDS\n",
inode->i_ino, lli->lli_flags);
} else {
- i_size_write(inode, body->size);
+ /* Use old size assignment to avoid
+ * deadlock bz14138 & bz14326 */
+ inode->i_size = body->size;
lli->lli_flags |= LLIF_MDS_SIZE_LOCK;
}
ldlm_lock_decref(&lockh, mode);
}
} else {
- i_size_write(inode, body->size);
+ /* Use old size assignment to avoid
+ * deadlock bz14138 & bz14326 */
+ inode->i_size = body->size;
}
if (body->valid & OBD_MD_FLBLOCKS)
/* XXX change inode size without ll_inode_size_lock() held!
* there is a race condition with truncate path. (see
* ll_extent_lock) */
- /* region is within kms and, hence, within real file size (A).
+ /* XXX i_size_write() is not used because it is not safe to
+ * take the ll_inode_size_lock() due to a potential lock
+ * inversion (bug 6077). And since it's not safe to use
+ * i_size_write() without a covering mutex we do the
+ * assignment directly. It is not critical that the
+ * size be correct. */
+ /* region is within kms and, hence, within real file size (A).
* We need to increase i_size to cover the read region so that
* generic_file_read() will do its job, but that doesn't mean
* the kms size is _correct_, it is only the _minimum_ size.
* If someone does a stat they will get the correct size which
* will always be >= the kms value here. b=11081 */
if (i_size_read(inode) < kms) {
- i_size_write(inode, kms);
+ inode->i_size = kms;
CDEBUG(D_INODE, "ino=%lu, updating i_size %llu\n",
inode->i_ino, i_size_read(inode));
}