Skip to contentSkip to conversation

ext3 weirdness

DISCUSSION CaT 3 participants 5 messages Apr 11, 2003

lore
Share & tools
lore

CaT

author
#0 lore raw

Why would this:

while true; do dd if=/dev/zero of=foo count=100 bs=10000; rm foo; done

Produce the following result?

...
100+0 records in
100+0 records out
100+0 records in
100+0 records out
dd: writing `foo': No space left on device
70+0 records in
69+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
...
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out
100+0 records in
100+0 records out
100+0 records in
100+0 records out
...

Signature · 6 lines
Martin's distress was in contrast to the bitter satisfaction of some
of his fellow marines as they surveyed the scene. "The Iraqis are sick
people and we are the chemotherapy," said Corporal Ryan Dupre. "I am
starting to hate this country. Wait till I get hold of a friggin' Iraqi.
No, I won't get hold of one. I'll just kill him."
	- http://www.informationclearinghouse.info/article2479.htm
#1 lore raw
Quoted 6 lines · CaT

Why would this:

while true; do dd if=/dev/zero of=foo count=100 bs=10000; rm foo; done

Produce the following result?

Quoted 11 lines

...
100+0 records in
100+0 records out
100+0 records in
100+0 records out
dd: writing `foo': No space left on device
70+0 records in
69+0 records out
dd: writing `foo': No space left on device
1+0 records in
0+0 records out

:

Quoted 8 lines

dd: writing `foo': No space left on device
1+0 records in
0+0 records out
100+0 records in
100+0 records out
100+0 records in
100+0 records out
...

Because you can't reallocate in-use blocks until the dirty bitmaps have been committed to disk in a transaction.

What should probably happen is that in ext3_new_block() we should flush the journal (once!) if we are going to return -ENOSPC and restart the allocation attempt.

This may be easy (just calling journal_flush()) or it may be more effort, depending on how the locking looks. I think journal_flush() is no good, because by the time ext3_new_block() is called we always have a journal handle, and I believe journal_flush() will wait for all transactions to complete -> deadlock.

Maybe something like (just a guess):

+ int flushed = 0;

	:
	:
+repeat:
	/*
	 * First, test whether the goal block is free.
	 */

	:
	:

	/* No space left on the device */

+ if (!flushed && journal->j_committing_transaction) {
+ transaction = journal->j_committing_transaction;
+ log_wait_commit(journal, transaction->t_tid);
+ flushed = 1;
+ goto repeat;
+ }
+

	goto out;

search_back:

Cheers, Andreas
--
Andreas Dilger
http://sourceforge.net/projects/ext2resize/
http://www-mddsp.enel.ucalgary.ca/People/adilger/

#2 lore raw
Quoted 3 lines · Andreas Dilger

Because you can't reallocate in-use blocks until the dirty bitmaps have been committed to disk in a transaction.

Also, in 2.5 pdflush will take a ref on the inode while writing it out. So an unlink while pdflush is writing back the inode's pages will be magically instantaneous, and pdflush actually does the truncate.

This is pretty ugly, because it is reasonable to expect that if you know there are no other refs to the inode, your disk space should be available when the unlink returns.

I don't know what to do about it though. The userspace workaround is to run sync before rm.

#3 lore raw
Quoted 7 lines · Andrew Morton
Quoted 2 lines · Andreas Dilger

Because you can't reallocate in-use blocks until the dirty bitmaps have been committed to disk in a transaction.

Also, in 2.5 pdflush will take a ref on the inode while writing it out. So an unlink while pdflush is writing back the inode's pages will be magically instantaneous, and pdflush actually does the truncate.

It should be possible to have pdflush check for i_nlink == 0 and i_count == 1 periodically, indicating it is the only one that has a reference and then immediately iput the node (truncating the pages instead of writing them out).

Cheers, Andreas
--
Andreas Dilger
http://sourceforge.net/projects/ext2resize/
http://www-mddsp.enel.ucalgary.ca/People/adilger/

#4 lore raw
Quoted 6 lines · Andreas Dilger
Quoted 4 lines · Andrew Morton
Quoted 2 lines · Andreas Dilger

Because you can't reallocate in-use blocks until the dirty bitmaps have been committed to disk in a transaction.

Quoted 8 lines
Quoted 3 lines

Also, in 2.5 pdflush will take a ref on the inode while writing it out. So an unlink while pdflush is writing back the inode's pages will be magically instantaneous, and pdflush actually does the truncate.

It should be possible to have pdflush check for i_nlink == 0 and i_count == 1 periodically, indicating it is the only one that has a reference and then immediately iput the node (truncating the pages instead of writing them out).

Yes. It is supposed to iput() the inode every sync_writeback_pages() (up to 1024 pages) anyway, partly for this reason.

But I have a vague feeling that this is not working. I'll take a look.