- UNLOCK_INODE_MUTEX(inode);
- UP_WRITE_I_ALLOC_SEM(inode);
-
- if (sbi->ll_lockless_truncate_enable &&
- (sbi->ll_lco.lco_flags & OBD_CONNECT_TRUNCLOCK)) {
- ast_flags = LDLM_FL_BLOCK_GRANTED;
- rc = obd_match(sbi->ll_dt_exp, lsm, LDLM_EXTENT,
- &policy, LCK_PW, &ast_flags, inode, &lockh);
- if (rc > 0) {
- local_lock = 2;
- rc = 0;
- } else if (rc == 0) {
- rc = ll_file_punch(inode, new_size, 1);
- }
- } else {
- /* XXX when we fix the AST intents to pass the discard-range
- * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA
- * XXX here. */
- ast_flags = (new_size == 0) ? LDLM_AST_DISCARD_DATA : 0;
- rc = ll_extent_lock(NULL, inode, lsm, LCK_PW, &policy,
- &lockh, ast_flags);
- if (likely(rc == 0))
- local_lock = 1;
- }
-
- LOCK_INODE_MUTEX(inode);
- DOWN_WRITE_I_ALLOC_SEM(inode);
-
- if (likely(rc == 0)) {
- /* Only ll_inode_size_lock is taken at this level.
- * lov_stripe_lock() is grabbed by ll_truncate() only over
- * call to obd_adjust_kms(). If vmtruncate returns 0, then
- * ll_truncate dropped ll_inode_size_lock() */
- ll_inode_size_lock(inode, 0);
- if (!local_lock) {
- spin_lock(&lli->lli_lock);
- lli->lli_flags |= LLIF_SRVLOCK;
- spin_unlock(&lli->lli_lock);
- }
- rc = vmtruncate(inode, new_size);
- if (!local_lock) {
- spin_lock(&lli->lli_lock);
- lli->lli_flags &= ~LLIF_SRVLOCK;
- spin_unlock(&lli->lli_lock);
- }
- if (rc != 0) {
- LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0);
- ll_inode_size_unlock(inode, 0);
- }
- }