- 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;
- __u32 enqflags = new_size == 0 ? CEF_DISCARD_DATA : 0;
- int result;
+ struct ccc_io *cio = ccc_env_io(env);
+ struct cl_io *io = ios->cis_io;
+ size_t new_size;
+ __u32 enqflags = 0;
+
+ if (cl_io_is_trunc(io)) {
+ new_size = io->u.ci_setattr.sa_attr.lvb_size;
+ if (new_size == 0)
+ enqflags = CEF_DISCARD_DATA;
+ } else {
+ LASSERT((io->u.ci_setattr.sa_attr.lvb_mtime <
+ io->u.ci_setattr.sa_attr.lvb_ctime) ||
+ (io->u.ci_setattr.sa_attr.lvb_atime <
+ io->u.ci_setattr.sa_attr.lvb_ctime));
+ new_size = 0;
+ }
+ cio->u.setattr.cui_local_lock = SETATTR_EXTENT_LOCK;
+ return ccc_io_one_lock(env, io, enqflags, CLM_WRITE,
+ new_size, OBD_OBJECT_EOF);
+}
+
+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);