nrsegs_copy = nr_segs;
}
+ down_read(&lli->lli_truncate_rwsem); /* Bug 18233 */
+
lock_style = ll_file_get_lock(file, (obd_off)(*ppos), end,
iov_copy, nrsegs_copy, &cookie, &tree,
OBD_BRW_READ);
+ if (lock_style < 0 || lock_style == LL_LOCK_STYLE_NOLOCK)
+ up_read(&lli->lli_truncate_rwsem);
if (lock_style < 0)
GOTO(out, retval = lock_style);
ll_inode_size_unlock(inode, 1);
retval = ll_glimpse_size(inode, LDLM_FL_BLOCK_GRANTED);
if (retval) {
- if (lock_style != LL_LOCK_STYLE_NOLOCK)
+ if (lock_style != LL_LOCK_STYLE_NOLOCK) {
ll_file_put_lock(inode, end, lock_style,
cookie, &tree, OBD_BRW_READ);
+ up_read(&lli->lli_truncate_rwsem);
+ }
goto out;
}
} else {
#endif
ll_file_put_lock(inode, end, lock_style, cookie,
&tree, OBD_BRW_READ);
+ up_read(&lli->lli_truncate_rwsem);
} else {
/* lockless read
*
* before child -- it is me should cleanup the dir readahead. */
void *lli_opendir_key;
struct ll_statahead_info *lli_sai;
+ struct rw_semaphore lli_truncate_rwsem;
/* the most recent attributes from mds, it is used for timestampts
* only so far */
struct ost_lvb lli_lvb;
#ifdef HAVE_CLOSE_THREAD
INIT_LIST_HEAD(&lli->lli_pending_write_llaps);
#endif
+ init_rwsem(&lli->lli_truncate_rwsem);
}
/* COMPAT_146 */
UNLOCK_INODE_MUTEX(inode);
UP_WRITE_I_ALLOC_SEM(inode);
+ down_write(&lli->lli_truncate_rwsem);
if (sbi->ll_lockless_truncate_enable &&
(sbi->ll_lco.lco_flags & OBD_CONNECT_TRUNCLOCK)) {
int n_matches = 0;
rc = err;
}
}
+ up_write(&lli->lli_truncate_rwsem);
RETURN(rc);
}
}
run_test 200i "Remove a pool ============================================"
+test_154() {
+ # do directio so as not to populate the page cache
+ log "creating a 10 Mb file"
+ multiop $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
+ log "starting reads"
+ dd if=$DIR/$tfile of=/dev/null bs=4096 &
+ log "truncating the file"
+ multiop $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
+ log "killing dd"
+ kill %+ || true # reads might have finished
+ echo "wait until dd is finished"
+ wait
+ log "removing the temporary file"
+ rm -rf $DIR/$tfile || error "tmp file removal failed"
+}
+run_test 154 "parallel read and truncate should not deadlock ======================="
+
#
# tests that do cleanup/setup should be run at the end
#