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, flags);
+ descr->cld_enq_flags = flags;
+ result = cl_io_lock_alloc_add(env, io, descr);
if (result < 0)
RETURN(result);
int ast_flags = 0;
LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
- LASSERT(vvp_env_io(env)->cui_oneshot == 0);
ENTRY;
ccc_io_update_iov(env, cio, io);
struct cl_io *io = ios->cis_io;
loff_t start;
loff_t end;
- int result;
- if (cl2vvp_io(env, ios)->cui_oneshot == 0) {
- if (io->u.ci_wr.wr_append) {
- start = 0;
- end = OBD_OBJECT_EOF;
- } else {
- start = io->u.ci_wr.wr.crw_pos;
- end = start + io->u.ci_wr.wr.crw_count - 1;
- }
- result = vvp_io_rw_lock(env, io, CLM_WRITE, start, end);
- } else
- result = 0;
- return result;
+ if (io->u.ci_wr.wr_append) {
+ start = 0;
+ end = OBD_OBJECT_EOF;
+ } else {
+ start = io->u.ci_wr.wr.crw_pos;
+ end = start + io->u.ci_wr.wr.crw_count - 1;
+ }
+ return vvp_io_rw_lock(env, io, CLM_WRITE, start, end);
}
static int vvp_io_trunc_iter_init(const struct lu_env *env,
{
struct ccc_io *vio = cl2ccc_io(env, ios);
struct cl_io *io = ios->cis_io;
- size_t new_size = io->u.ci_truncate.tr_size;
+ loff_t new_size = io->u.ci_truncate.tr_size;
__u32 enqflags = new_size == 0 ? CEF_DISCARD_DATA : 0;
int result;
return result;
}
+static int vvp_do_vmtruncate(struct inode *inode, size_t size)
+{
+ int result;
+ /*
+ * 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);
+ result = vmtruncate(inode, size);
+ if (result != 0)
+ ll_inode_size_unlock(inode, 0);
+
+ return result;
+}
+
static int vvp_io_trunc_start(const struct lu_env *env,
const struct cl_io_slice *ios)
{
struct cl_io *io = ios->cis_io;
struct inode *inode = ccc_object_inode(io->ci_obj);
struct cl_object *obj = ios->cis_obj;
- size_t size = io->u.ci_truncate.tr_size;
+ loff_t size = io->u.ci_truncate.tr_size;
pgoff_t start = cl_index(obj, size);
int result;
LASSERT(cio->u.trunc.cui_locks_released);
- LASSERT(vio->cui_oneshot == 0);
LOCK_INODE_MUTEX(inode);
DOWN_WRITE_I_ALLOC_SEM(inode);
cio->u.trunc.cui_locks_released = 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);
- result = vmtruncate(inode, size);
- if (result != 0)
- ll_inode_size_unlock(inode, 0);
+ result = vvp_do_vmtruncate(inode, size);
+
/*
* If a page is partially truncated, keep it owned across truncate to
* prevent... races.
struct cl_object_header *hdr;
hdr = cl_object_header(obj);
- spin_lock(&hdr->coh_page_guard);
+ cfs_spin_lock(&hdr->coh_page_guard);
vio->cui_partpage = cl_page_lookup(hdr, start);
- spin_unlock(&hdr->coh_page_guard);
+ cfs_spin_unlock(&hdr->coh_page_guard);
if (vio->cui_partpage != NULL)
/*
static void vvp_io_trunc_end(const struct lu_env *env,
const struct cl_io_slice *ios)
{
- struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct vvp_io *vio = cl2vvp_io(env, ios);
+ struct cl_io *io = ios->cis_io;
+ struct inode *inode = ccc_object_inode(io->ci_obj);
+ loff_t size = io->u.ci_truncate.tr_size;
if (vio->cui_partpage != NULL) {
cl_page_disown(env, ios->cis_io, vio->cui_partpage);
cl_page_put(env, vio->cui_partpage);
vio->cui_partpage = NULL;
}
+
+ /*
+ * Do vmtruncate again, to remove possible stale pages populated by
+ * competing read threads. bz20645.
+ */
+ vvp_do_vmtruncate(inode, size);
}
static void vvp_io_trunc_fini(const struct lu_env *env,
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);
CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt);
- if (cl2vvp_io(env, ios)->cui_oneshot > 0)
+ if (cio->cui_iov == NULL) /* from a temp io in ll_cl_init(). */
result = 0;
else
result = lustre_generic_file_write(file, cio, &pos);
loff_t size;
pgoff_t last; /* last page in a file data region */
- LASSERT(vio->cui_oneshot == 0);
-
if (fio->ft_executable &&
LTIME_S(inode->i_mtime) != vio->u.fault.ft_mtime)
CWARN("binary "DFID
int rc;
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
- LASSERT(cl2vvp_io(env, ios)->cui_oneshot == 0);
LASSERT(slice->cpl_obj == obj);
ENTRY;
size = cl_offset(obj, pg->cp_index) + to;
+ ll_inode_size_lock(inode, 0);
if (result == 0) {
if (size > i_size_read(inode))
- i_size_write(inode, size);
+ cl_isize_write_nolock(inode, size);
cl_page_export(env, pg, 1);
- } else if (size > i_size_read(inode))
- cl_page_discard(env, io, pg);
+ } else {
+ if (size > i_size_read(inode))
+ cl_page_discard(env, io, pg);
+ }
+ ll_inode_size_unlock(inode, 0);
+
RETURN(result);
}
CL_IO_SLICE_CLEAN(cio, cui_cl);
cl_io_slice_add(io, &cio->cui_cl, obj, &vvp_io_ops);
- vio->cui_oneshot = 0;
vio->cui_ra_window_set = 0;
result = 0;
if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE) {