Commit 97a21e98 authored by Hou Tao's avatar Hou Tao Committed by Zheng Zengkai
Browse files

jffs2: reset pino_nlink to 0 when inode creation failed

hulk inclusion
category: bugfix
bugzilla: 47446
CVE: NA
-------------------------------------------------

So jffs2_do_clear_inode() could mark all flash nodes used by
the inode as obsolete and GC procedure will reclaim these
flash nodes, else these flash spaces will not be reclaimable
forever.

Link: http://lists.infradead.org/pipermail/linux-mtd/2019-February/087763.html


Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
Reviewed-by: default avatarWei Fang <fangwei1@huawei.com>
Signed-off-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avataryangerkun <yangerkun@huawei.com>
Reviewed-by: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 5c27edc5
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -156,6 +156,26 @@ static int jffs2_readdir(struct file *file, struct dir_context *ctx)

/***********************************************************************/

static void jffs2_iget_failed(struct jffs2_sb_info *c, struct inode *inode)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);

	/*
	 * Reset pino_nlink to zero, so jffs2_do_clear_inode() will mark
	 * all flash nodes used by the inode as obsolete and GC procedure
	 * will reclaim these flash nodes, else these flash spaces will be
	 * unreclaimable forever.
	 *
	 * Update pino_nlink under inocache_lock, because no proceses could
	 * get the inode due to I_NEW flag, and only GC procedure may try to
	 * read pino_nlink under inocache_lock.
	 */
	spin_lock(&c->inocache_lock);
	f->inocache->pino_nlink = 0;
	spin_unlock(&c->inocache_lock);

	iget_failed(inode);
}

static int jffs2_create(struct inode *dir_i, struct dentry *dentry,
			umode_t mode, bool excl)
@@ -213,7 +233,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry,
	return 0;

 fail:
	iget_failed(inode);
	jffs2_iget_failed(c, inode);
	jffs2_free_raw_inode(ri);
	return ret;
}
@@ -433,7 +453,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
	return 0;

 fail:
	iget_failed(inode);
	jffs2_iget_failed(c, inode);
	return ret;
}

@@ -577,7 +597,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode
	return 0;

 fail:
	iget_failed(inode);
	jffs2_iget_failed(c, inode);
	return ret;
}

@@ -752,7 +772,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode
	return 0;

 fail:
	iget_failed(inode);
	jffs2_iget_failed(c, inode);
	return ret;
}