diff --git a/fs/lustre/llite/vvp_io.c b/fs/lustre/llite/vvp_io.c
index b0b31c37..ac6aef0 100644
--- a/fs/lustre/llite/vvp_io.c
+++ b/fs/lustre/llite/vvp_io.c
@@ -647,7 +647,7 @@ static int vvp_io_setattr_lock(const struct lu_env *env,
 			enqflags = CEF_DISCARD_DATA;
 	} else if (cl_io_is_fallocate(io)) {
 		lock_start = io->u.ci_setattr.sa_falloc_offset;
-		lock_end = lock_start + io->u.ci_setattr.sa_attr.lvb_size;
+		lock_end = io->u.ci_setattr.sa_falloc_end;
 	} else {
 		unsigned int valid = io->u.ci_setattr.sa_avalid;
 
diff --git a/fs/lustre/lov/lov_io.c b/fs/lustre/lov/lov_io.c
index c9600bc..2297e53 100644
--- a/fs/lustre/lov/lov_io.c
+++ b/fs/lustre/lov/lov_io.c
@@ -677,17 +677,16 @@ static void lov_io_sub_inherit(struct lov_io_sub *sub, struct lov_io *lio,
 			parent->u.ci_setattr.sa_parent_fid;
 		/* For SETATTR(fallocate) pass the subtype to lower IO */
 		io->u.ci_setattr.sa_subtype = parent->u.ci_setattr.sa_subtype;
-		if (cl_io_is_trunc(io)) {
+		if (cl_io_is_fallocate(io)) {
+			io->u.ci_setattr.sa_falloc_offset = start;
+			io->u.ci_setattr.sa_falloc_end = end;
+		}
+		if (cl_io_is_trunc(io) || cl_io_is_fallocate(io)) {
 			loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size;
 
 			new_size = lov_size_to_stripe(lsm, index, new_size,
 						      stripe);
 			io->u.ci_setattr.sa_attr.lvb_size = new_size;
-		} else if (cl_io_is_fallocate(io)) {
-			io->u.ci_setattr.sa_falloc_offset = start;
-			io->u.ci_setattr.sa_falloc_end = end;
-			io->u.ci_setattr.sa_attr.lvb_size =
-				parent->u.ci_setattr.sa_attr.lvb_size;
 		}
 		lov_lsm2layout(lsm, lsm->lsm_entries[index],
 			       &io->u.ci_setattr.sa_layout);
diff --git a/fs/lustre/osc/osc_cache.c b/fs/lustre/osc/osc_cache.c
index d511ece..4abe8ba 100644
--- a/fs/lustre/osc/osc_cache.c
+++ b/fs/lustre/osc/osc_cache.c
@@ -1159,7 +1159,8 @@ static int osc_extent_make_ready(const struct lu_env *env,
 		int last_oap_count = osc_refresh_count(env, last,
 						       OBD_BRW_WRITE);
 
-		LASSERT(last_oap_count > 0);
+		LASSERTF(last_oap_count > 0,
+			 "last_oap_count %d\n", last_oap_count);
 		LASSERT(last->oap_page_off + last_oap_count <= PAGE_SIZE);
 		last->oap_count = last_oap_count;
 		spin_lock(&last->oap_lock);
diff --git a/fs/lustre/osc/osc_io.c b/fs/lustre/osc/osc_io.c
index a0537b8..ce0f7ec 100644
--- a/fs/lustre/osc/osc_io.c
+++ b/fs/lustre/osc/osc_io.c
@@ -569,8 +569,14 @@ static int osc_io_setattr_start(const struct lu_env *env,
 			unsigned int cl_valid = 0;
 
 			if (ia_avalid & ATTR_SIZE) {
-				attr->cat_size = size;
-				attr->cat_kms = size;
+				if (io_is_falloc) {
+					attr->cat_size =
+						io->u.ci_setattr.sa_attr.lvb_size;
+					attr->cat_kms = attr->cat_size;
+				} else {
+					attr->cat_size = size;
+					attr->cat_kms = size;
+				}
 				cl_valid = CAT_SIZE | CAT_KMS;
 			}
 			if (ia_avalid & ATTR_MTIME_SET) {
@@ -707,22 +713,17 @@ void osc_io_setattr_end(const struct lu_env *env,
 	}
 
 	if (cl_io_is_fallocate(io)) {
-		cl_object_attr_lock(obj);
-
-		/* update blocks */
-		if (oa->o_valid & OBD_MD_FLBLOCKS) {
-			attr->cat_blocks = oa->o_blocks;
-			cl_valid |= CAT_BLOCKS;
-		}
+		if (result == 0) {
+			cl_object_attr_lock(obj);
+			/* update blocks */
+			if (oa->o_valid & OBD_MD_FLBLOCKS) {
+				attr->cat_blocks = oa->o_blocks;
+				cl_valid |= CAT_BLOCKS;
+			}
 
-		/* update size */
-		if (oa->o_valid & OBD_MD_FLSIZE) {
-			attr->cat_size = oa->o_size;
-			cl_valid |= CAT_SIZE;
+			cl_object_attr_update(env, obj, attr, cl_valid);
+			cl_object_attr_unlock(obj);
 		}
-
-		cl_object_attr_update(env, obj, attr, cl_valid);
-		cl_object_attr_unlock(obj);
 	}
 }
 EXPORT_SYMBOL(osc_io_setattr_end);
diff --git a/fs/lustre/osc/osc_object.c b/fs/lustre/osc/osc_object.c
index 273098a..00f2800 100644
--- a/fs/lustre/osc/osc_object.c
+++ b/fs/lustre/osc/osc_object.c
@@ -218,7 +218,9 @@ static int osc_object_ast_clear(struct ldlm_lock *lock, void *data)
 			   lvb->lvb_atime, oinfo->loi_lvb.lvb_size,
 			   oinfo->loi_lvb.lvb_blocks, oinfo->loi_lvb.lvb_ctime,
 			   oinfo->loi_lvb.lvb_mtime, oinfo->loi_lvb.lvb_atime);
-		LASSERT(oinfo->loi_lvb.lvb_size >= oinfo->loi_kms);
+		LASSERTF(oinfo->loi_lvb.lvb_size >= oinfo->loi_kms,
+			 "lvb_size %#llx, loi_kms %#llx\n",
+			 oinfo->loi_lvb.lvb_size, oinfo->loi_kms);
 
 		cl_object_attr_lock(&osc->oo_cl);
 		memcpy(lvb, &oinfo->loi_lvb, sizeof(oinfo->loi_lvb));
