if(cfs_down_interruptible(&lli->lli_write_sem))
GOTO(out, result = -ERESTARTSYS);
write_sem_locked = 1;
+ } else if (iot == CIT_READ) {
+ cfs_down_read(&lli->lli_trunc_sem);
}
break;
case IO_SENDFILE:
result = cl_io_loop(env, io);
if (write_sem_locked)
cfs_up(&lli->lli_write_sem);
+ else if (args->via_io_subtype == IO_NORMAL && iot == CIT_READ)
+ cfs_up_read(&lli->lli_trunc_sem);
} else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
cfs_semaphore_t lli_size_sem; /* protect open and change size */
void *lli_size_sem_owner;
cfs_semaphore_t lli_write_sem;
- cfs_semaphore_t lli_trunc_sem;
+ cfs_rw_semaphore_t lli_trunc_sem;
char *lli_symlink_name;
__u64 lli_maxbytes;
__u64 lli_ioepoch;
lli->lli_inode_magic = LLI_INODE_MAGIC;
cfs_sema_init(&lli->lli_size_sem, 1);
cfs_sema_init(&lli->lli_write_sem, 1);
- cfs_sema_init(&lli->lli_trunc_sem, 1);
+ cfs_init_rwsem(&lli->lli_trunc_sem);
lli->lli_flags = 0;
lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
cfs_spin_lock_init(&lli->lli_lock);
UNLOCK_INODE_MUTEX(inode);
if (ia_valid & ATTR_SIZE)
UP_WRITE_I_ALLOC_SEM(inode);
- cfs_down(&lli->lli_trunc_sem);
+ cfs_down_write(&lli->lli_trunc_sem);
LOCK_INODE_MUTEX(inode);
if (ia_valid & ATTR_SIZE)
DOWN_WRITE_I_ALLOC_SEM(inode);
rc1 = ll_setattr_done_writing(inode, op_data, mod);
ll_finish_md_op_data(op_data);
}
- cfs_up(&lli->lli_trunc_sem);
+ cfs_up_write(&lli->lli_trunc_sem);
return rc ? rc : rc1;
}
}
run_test 217 "check lctl ping for hostnames with hiphen ('-')"
+test_218() {
+ # 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 218 "parallel read and truncate should not deadlock ======================="
+
#
# tests that do cleanup/setup should be run at the end
#