Commit 70ac77a3 authored by Hou Tao's avatar Hou Tao Committed by ZhaoLong Wang
Browse files

jffs2: reset pino_nlink to 0 when inode creation failed

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8TYET
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>
Signed-off-by: default avatarZhaoLong Wang <wangzhaolong1@huawei.com>
parent c386ce75
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -159,6 +159,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 mnt_idmap *idmap, struct inode *dir_i,
			struct dentry *dentry, umode_t mode, bool excl)
@@ -217,7 +237,7 @@ static int jffs2_create(struct mnt_idmap *idmap, struct inode *dir_i,
	return 0;

 fail:
	iget_failed(inode);
	jffs2_iget_failed(c, inode);
	jffs2_free_raw_inode(ri);
	return ret;
}
@@ -439,7 +459,7 @@ static int jffs2_symlink (struct mnt_idmap *idmap, struct inode *dir_i,
	return 0;

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

@@ -585,7 +605,7 @@ static int jffs2_mkdir (struct mnt_idmap *idmap, struct inode *dir_i,
	return 0;

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

@@ -762,7 +782,7 @@ static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
	return 0;

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