count += addr & (~CFS_PAGE_MASK);
addr &= CFS_PAGE_MASK;
while((vma = our_vma(addr, count)) != NULL) {
- LASSERT(vma->vm_file);
+ struct file *file = vma->vm_file;
+ struct ll_file_data *fd;
+
+ LASSERT(file);
+ fd = LUSTRE_FPRIVATE(file);
+
+ inode = file->f_dentry->d_inode;
+ if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK ||
+ ll_i2sbi(inode)->ll_flags & LL_SBI_NOLCK))
+ goto cont;
- inode = vma->vm_file->f_dentry->d_inode;
/*
* XXX: Required lock mode can be weakened: CIT_WRITE
* io only ever reads user level buffer, and CIT_READ
policy.l_extent.start);
descr->cld_end = cl_index(descr->cld_obj,
policy.l_extent.end);
- result = cl_io_lock_alloc_add(env, io, descr);
+ result = cl_io_lock_alloc_add(env, io, descr, CEF_MUST);
if (result < 0)
RETURN(result);
+
+ cont:
if (vma->vm_end - addr >= count)
break;
count -= vma->vm_end - addr;
* Wait for the transfer completion for a partially
* truncated page to avoid dead-locking an OST with
* the concurrent page-wise overlapping WRITE and
- * PUNCH requests.
+ * PUNCH requests. BUG:17397.
*
* Partial page is disowned in vvp_io_trunc_end().
*/
loff_t pos = io->u.ci_rd.rd.crw_pos;
size_t cnt = io->u.ci_rd.rd.crw_count;
size_t tot = cio->cui_tot_count;
+ int exceed = 0;
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
LASSERT(vio->cui_oneshot == 0);
CDEBUG(D_VFSTRACE, "read: -> [%lli, %lli)\n", pos, pos + cnt);
- result = ccc_prep_size(env, obj, io, pos + tot - 1, 1);
+ result = ccc_prep_size(env, obj, io, pos, tot, 1, &exceed);
if (result != 0)
return result;
+ else if (exceed != 0)
+ goto out;
LU_OBJECT_HEADER(D_INODE, env, &obj->co_lu,
"Read ino %lu, "LPSZ" bytes, offset %lld, size %llu\n",
result = lustre_generic_file_read(file, cio, &pos);
}
+out:
if (result >= 0) {
if (result < cnt)
io->ci_continue = 0;
/* offset of the last byte on the page */
offset = cl_offset(obj, fio->ft_index + 1) - 1;
LASSERT(cl_index(obj, offset) == fio->ft_index);
- result = ccc_prep_size(env, obj, io, offset, 0);
+ result = ccc_prep_size(env, obj, io, 0, offset + 1, 0, NULL);
if (result != 0)
return result;
static int vvp_page_sync_io(const struct lu_env *env, struct cl_io *io,
struct cl_page *page, struct ccc_page *cp,
- int from, int to, enum cl_req_type crt)
+ int to, enum cl_req_type crt)
{
struct cl_2queue *queue;
struct ccc_object *cobo = cl2ccc(page->cp_obj);
cl_sync_io_init(anchor, 1);
cp->cpg_sync_io = anchor;
- cl_page_clip(env, page, from, to);
- result = cl_io_submit_rw(env, io, crt, queue);
+ cl_page_clip(env, page, 0, to);
+ result = cl_io_submit_rw(env, io, crt, queue, CRP_NORMAL);
if (result == 0)
result = cl_sync_io_wait(env, io, &queue->c2_qout, anchor);
else
cp->cpg_ra_used = 1;
else
result = vvp_page_sync_io(env, io, pg, cp,
- 0, CFS_PAGE_SIZE, CRT_READ);
+ CFS_PAGE_SIZE, CRT_READ);
/*
* In older implementations, obdo_refresh_inode is called here
* to update the inode because the write might modify the
* being.
*/
result = vvp_page_sync_io(env, io, pg, cp,
- from, to, CRT_WRITE);
+ to, CRT_WRITE);
} else {
tallyop = LPROC_LL_DIRTY_HITS;
result = 0;