public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
Subject: No free space left for GC
Date: Sun, 18 Aug 2002 00:35:26 +0200	[thread overview]
Message-ID: <1029623727.2142.495.camel@thomas.tec.linutronix.de> (raw)

Hi David ! 

You wanted to know, why free_size got that low. 

I just copied stuff to an empty partition, until it got full. 
But instead of returning with "not enough space" it keeps garbage 
collection until really no more space is left. 
One of the problems is, that we have at lot of blocks on the dirty list,
with less than 2*sizeof(struct jffs2_raw_inode) left. At scan time we
put these blocks on the clean_list. We must do this in normal operation
too. It's total crap to gc blocks with 4 byte dirty space ! 
The total sum of dirty space is 32K, when we start gc. The most dirty 
block has 1.2k dirty space. Many blocks have less than 512 bytes dirty,
which is the pagesize on my device. This is a result of padding, when we
flush wbuf. The dirty space on blocks with more than 512 byte dirty
space is 12048 Byte, which is less than 1 block. 

The real weird thing is, that we write to the device (from gc) until the
last block is used and we run into an endless loop, where no more space
is left for garbage collection. This happens, because we increase dirty
size during gc instead of decreasing it. Once we are there we cannot
mount the filesystem again, without running in that endless gc loop.

I changed nodemgmt.c so that blocks with less than 2*sizeof(struct
jffs2_raw_inode) dirty space are moved to clean_list. But the gc effect
was still the same. 

Now I noticed that we don't move blocks to the dirty list anymore,
neither on mount (pass1) nor during gc or write. The reason is that
mark_node_obsolete checks if the dirty_size == ref_totlen. Due to the
fact, that we have blocks with some dirty space in the clean list, these
blocks stay there until they are very dirty, which may never happen. I
changed this by checking used space against sector_size -
2*sizeof(struct jffs2_raw_inode). Result is better but not good.
I tried the same procedure on a larger partition (56MB, previous one was
8MB). There I was running in trouble again. I had enough dirty space in
the clean_list, that the check in jffs2_reserve_space c->dirty_size <
c->sector_size never lead to -ENOSPC. I added a check, which is done,
when dirty_size is less than blocksneeded * sector_size. It checks if
the dirty_size in the dirty_lists is > c->sector_size. If not it returns
-ENOSPC too. Same as above.

In both cases, we end up with 3 empty blocks and we can't even remove a
file from the filesystem.

The strange thing is, that the dirty_size is not always correct. When I
filled the filesystem complete, df tells me:
/dev/mtdblock1	8192	8164	28	100%	/mnt/data
The last dirty information from the log was dirty_space = 0x3e0c
After umount and mount I have suddenly dirty_space = 0xcfe8, which is
the real dirty size. The good thing on this is, that the endless gc on a
100% full filesystem stops. The bad thing is that we have only 3 blocks
left and I can't remove a file anymore. Have to add some more checks on
monday.

If we are at the point of a 100% full filesystem and the dirty space is
splitted into small pieces, we add for each gc'd block one or two blocks
to the dirty list and the block, we have written to ends up sometimes on
the dirty list too. Maybe we have to add a check, where we calc the
average dirty space per block on dirty_list. If this is less than a
defined threshold, we return ENOSPC and stop garbage collection instead
of screwing up the filesystem at least. It should always be possible to
delete a file.

-- 
Thomas 
____________________________________________________
linutronix - competence in embedded & realtime linux
http://www.linutronix.de
mail: tglx@linutronix.de

             reply	other threads:[~2002-08-17 22:36 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-08-17 22:35 Thomas Gleixner [this message]
2002-08-19  9:37 ` Massive file corruption Joakim Tjernlund
2002-08-19 21:47 ` No free space left for GC Thomas Gleixner
2002-08-19 22:34   ` Thomas Gleixner
2002-08-20 10:03     ` David Woodhouse
     [not found]   ` <015501c247f3$d13176a0$b30210ac@gv.com.tw>
2002-08-20  7:59     ` Thomas Gleixner
2002-08-20 15:47       ` Thomas Gleixner
2002-08-21  6:44         ` can i use the cvs code directly in kernel 2.2.19 ? 小明
2002-08-21  7:56           ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1029623727.2142.495.camel@thomas.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=dwmw2@infradead.org \
    --cc=linux-mtd@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox