Unverified Commit 5f7c9fb3 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8325 ocfs2: fix data corruption after conversion from inline format

parents 001ab205 c9149852
Loading
Loading
Loading
Loading
+12 −34
Original line number Diff line number Diff line
@@ -7048,7 +7048,7 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
int ocfs2_convert_inline_data_to_extents(struct inode *inode,
					 struct buffer_head *di_bh)
{
	int ret, i, has_data, num_pages = 0;
	int ret, has_data, num_pages = 0;
	int need_free = 0;
	u32 bit_off, num;
	handle_t *handle;
@@ -7057,26 +7057,17 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
	struct ocfs2_alloc_context *data_ac = NULL;
	struct page **pages = NULL;
	loff_t end = osb->s_clustersize;
	struct page *page = NULL;
	struct ocfs2_extent_tree et;
	int did_quota = 0;

	has_data = i_size_read(inode) ? 1 : 0;

	if (has_data) {
		pages = kcalloc(ocfs2_pages_per_cluster(osb->sb),
				sizeof(struct page *), GFP_NOFS);
		if (pages == NULL) {
			ret = -ENOMEM;
			mlog_errno(ret);
			return ret;
		}

		ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
		if (ret) {
			mlog_errno(ret);
			goto free_pages;
			goto out;
		}
	}

@@ -7096,7 +7087,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
	}

	if (has_data) {
		unsigned int page_end;
		unsigned int page_end = min_t(unsigned, PAGE_SIZE,
							osb->s_clustersize);
		u64 phys;

		ret = dquot_alloc_space_nodirty(inode,
@@ -7120,15 +7112,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
		 */
		block = phys = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);

		/*
		 * Non sparse file systems zero on extend, so no need
		 * to do that now.
		 */
		if (!ocfs2_sparse_alloc(osb) &&
		    PAGE_SIZE < osb->s_clustersize)
			end = PAGE_SIZE;

		ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages);
		ret = ocfs2_grab_eof_pages(inode, 0, page_end, &page,
					   &num_pages);
		if (ret) {
			mlog_errno(ret);
			need_free = 1;
@@ -7139,20 +7124,15 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
		 * This should populate the 1st page for us and mark
		 * it up to date.
		 */
		ret = ocfs2_read_inline_data(inode, pages[0], di_bh);
		ret = ocfs2_read_inline_data(inode, page, di_bh);
		if (ret) {
			mlog_errno(ret);
			need_free = 1;
			goto out_unlock;
		}

		page_end = PAGE_SIZE;
		if (PAGE_SIZE > osb->s_clustersize)
			page_end = osb->s_clustersize;

		for (i = 0; i < num_pages; i++)
			ocfs2_map_and_dirty_page(inode, handle, 0, page_end,
						 pages[i], i > 0, &phys);
		ocfs2_map_and_dirty_page(inode, handle, 0, page_end, page, 0,
					 &phys);
	}

	spin_lock(&oi->ip_lock);
@@ -7183,8 +7163,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
	}

out_unlock:
	if (pages)
		ocfs2_unlock_and_free_pages(pages, num_pages);
	if (page)
		ocfs2_unlock_and_free_pages(&page, num_pages);

out_commit:
	if (ret < 0 && did_quota)
@@ -7208,8 +7188,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
out:
	if (data_ac)
		ocfs2_free_alloc_context(data_ac);
free_pages:
	kfree(pages);
	return ret;
}