kern/152991: [ufs] false disk full with a too slow flash module

Luca Pizzamiglio luca.pizzamiglio at
Fri Dec 10 14:10:09 UTC 2010

>Number:         152991
>Category:       kern
>Synopsis:       [ufs] false disk full with a too slow flash module
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 10 14:10:08 UTC 2010
>Originator:     Luca Pizzamiglio
>Release:        FreeBSD 7-stable and 8-stable
FreeBSD pizzamig 7.3-STABLE FreeBSD 7.3-STABLE #22: Thu Nov 11 10:10:06 CET 2010     root at pizzamig:/usr/obj/usr/src/sys/PIZZAMIG  i386
I use a 4 GB PATA flash module with about 1 GB free space.

I launch restore(8) to restore the filesystem (dump of ~ 3 GB) and after about 1 GB I receive a "write: disk full" error msg. After this message, everything is fine and at the end I've just one file corrupted, the message related one.

The speed of my flash module vary a lot during this procedure. When the speed is extremely/dramatically low, the file system allocate routine invokes softdep_request_cleanup to free pending blocks.

In my case, this function is not able to free any pending blocks, so the disk is considered full. 
This function computes timeout at start, then call ffs_update() to update some metadata and start to free pending blocks if timeout is not expired.
In my case, the ffs_update() is so slow that the timeout expires and the disk is considered full.

I propose to compute the timeout after the ffs_update(), I guess it is more coherent. A patch is attached.

Patch attached with submission follows:

Index: ffs_softdep.c
--- ffs_softdep.c	(revision 3162)
+++ ffs_softdep.c	(working copy)
@@ -5796,7 +5796,6 @@
 	ump = VTOI(vp)->i_ump;
 	mtx_assert(UFS_MTX(ump), MA_OWNED);
 	needed = fs->fs_cstotal.cs_nbfree + fs->fs_contigsumsize;
-	starttime = time_second + tickdelay;
 	 * If we are being called because of a process doing a
 	 * copy-on-write, then it is not safe to update the vnode
@@ -5809,6 +5808,7 @@
 		if (error != 0)
 			return (0);
+	starttime = time_second + tickdelay;
 	while (fs->fs_pendingblocks > 0 && fs->fs_cstotal.cs_nbfree <= needed) {
 		if (time_second > starttime)
 			return (0);


More information about the freebsd-bugs mailing list