Commit 043c8323 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: compress: fix error path of inc_valid_block_count()



If inc_valid_block_count() can not allocate all requested blocks,
it needs to release block count in .total_valid_block_count and
resevation blocks in inode.

Fixes: 54607494 ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent a3a0bc6c
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -2306,7 +2306,7 @@ static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
				 struct inode *inode, blkcnt_t *count, bool partial)
{
	blkcnt_t diff = 0, release = 0;
	long long diff = 0, release = 0;
	block_t avail_user_block_count;
	int ret;

@@ -2326,26 +2326,27 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
	percpu_counter_add(&sbi->alloc_valid_block_count, (*count));

	spin_lock(&sbi->stat_lock);
	sbi->total_valid_block_count += (block_t)(*count);
	avail_user_block_count = get_available_block_count(sbi, inode, true);

	if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
	avail_user_block_count = get_available_block_count(sbi, inode, true);
	diff = (long long)sbi->total_valid_block_count + *count -
						avail_user_block_count;
	if (unlikely(diff > 0)) {
		if (!partial) {
			spin_unlock(&sbi->stat_lock);
			release = *count;
			goto enospc;
		}

		diff = sbi->total_valid_block_count - avail_user_block_count;
		if (diff > *count)
			diff = *count;
		*count -= diff;
		release = diff;
		sbi->total_valid_block_count -= diff;
		if (!*count) {
			spin_unlock(&sbi->stat_lock);
			goto enospc;
		}
	}
	sbi->total_valid_block_count += (block_t)(*count);

	spin_unlock(&sbi->stat_lock);

	if (unlikely(release)) {