linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] jffs2: fixes for file creation failed halfway
@ 2019-02-20 10:21 Hou Tao
  2019-02-20 10:21 ` [PATCH 1/2] jffs2: reset pino_nlink to 0 when inode creation failed Hou Tao
  2019-02-20 10:21 ` [PATCH 2/2] jffs2: handle INO_STATE_CLEARING in jffs2_do_read_inode() Hou Tao
  0 siblings, 2 replies; 3+ messages in thread
From: Hou Tao @ 2019-02-20 10:21 UTC (permalink / raw)
  To: linux-mtd; +Cc: Richard Weinberger, David Woodhouse, linux-kernel, houtao1

Hi,

There are the fixes for file creation which failed halfway, the first
one is used to reclaim flash spaces had been used by the inode, and
the second one fixes a BUG assertion in jffs2_do_read_inode().

These two problems can be reproduced by concurrently creating files
until no space is left, and then removing these files, and repeating.

Comments are welcome.

Hou

Hou Tao (2):
  jffs2: reset pino_nlink to 0 when inode creation failed
  jffs2: handle INO_STATE_CLEARING in jffs2_do_read_inode()

 fs/jffs2/dir.c       | 28 ++++++++++++++++++++++++----
 fs/jffs2/readinode.c |  1 +
 2 files changed, 25 insertions(+), 4 deletions(-)

-- 
2.16.2.dirty


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] jffs2: reset pino_nlink to 0 when inode creation failed
  2019-02-20 10:21 [PATCH 0/2] jffs2: fixes for file creation failed halfway Hou Tao
@ 2019-02-20 10:21 ` Hou Tao
  2019-02-20 10:21 ` [PATCH 2/2] jffs2: handle INO_STATE_CLEARING in jffs2_do_read_inode() Hou Tao
  1 sibling, 0 replies; 3+ messages in thread
From: Hou Tao @ 2019-02-20 10:21 UTC (permalink / raw)
  To: linux-mtd; +Cc: Richard Weinberger, David Woodhouse, linux-kernel, houtao1

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.

Cc: stable@vger.kernel.org
Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 fs/jffs2/dir.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index f20cff1194bb..e02f85e516cb 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -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;
 }
 
@@ -748,7 +768,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;
 }
 
-- 
2.16.2.dirty


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] jffs2: handle INO_STATE_CLEARING in jffs2_do_read_inode()
  2019-02-20 10:21 [PATCH 0/2] jffs2: fixes for file creation failed halfway Hou Tao
  2019-02-20 10:21 ` [PATCH 1/2] jffs2: reset pino_nlink to 0 when inode creation failed Hou Tao
@ 2019-02-20 10:21 ` Hou Tao
  1 sibling, 0 replies; 3+ messages in thread
From: Hou Tao @ 2019-02-20 10:21 UTC (permalink / raw)
  To: linux-mtd; +Cc: Richard Weinberger, David Woodhouse, linux-kernel, houtao1

For inode that fails to be created midway, GC procedure may
try to GC its dnode, and in the following case BUG() will be
triggered:

CPU 0                       CPU 1
in jffs2_do_create()        in jffs2_garbage_collect_pass()

jffs2_write_dnode succeed
// for dirent
jffs2_reserve_space fail

			    inum = ic->ino
			    nlink = ic->pino_nlink (> 0)

iget_failed
  make_bad_inode
    remove_inode_hash
  iput
    jffs2_evict_inode
      jffs2_do_clear_inode
        jffs2_set_inocache_state(INO_STATE_CLEARING)

			    jffs2_gc_fetch_inode
			      jffs2_iget
			        // a new inode is created because
			        // the old inode had been unhashed
			        iget_locked
			      jffs2_do_read_inode
			        jffs2_get_ino_cache
				// assert BUG()
				f->inocache->state = INO_STATE_CLEARING

Fix it by waiting for its state changes to INO_STATE_CHECKEDABSENT.

Fixes: 67e345d17ff8 ("[JFFS2] Prevent ino cache removal for inodes in use")
Cc: stable@vger.kernel.org
Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 fs/jffs2/readinode.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 389ea53ea487..0bae0583106e 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -1328,6 +1328,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
 
 		case INO_STATE_CHECKING:
 		case INO_STATE_GC:
+		case INO_STATE_CLEARING:
 			/* If it's in either of these states, we need
 			   to wait for whoever's got it to finish and
 			   put it back. */
-- 
2.16.2.dirty


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-02-20 10:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-20 10:21 [PATCH 0/2] jffs2: fixes for file creation failed halfway Hou Tao
2019-02-20 10:21 ` [PATCH 1/2] jffs2: reset pino_nlink to 0 when inode creation failed Hou Tao
2019-02-20 10:21 ` [PATCH 2/2] jffs2: handle INO_STATE_CLEARING in jffs2_do_read_inode() Hou Tao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).