File remove problem

Don Lewis truckman at FreeBSD.org
Fri Nov 30 23:27:11 PST 2007


On  1 Dec, Bruce Evans wrote:

> Something like that seems to be right.  The folowing hack in ufs_inactive()
> seems to fix the problem with sift updates, as does unsetting MNT_RDONLY
> for the whole VOP_SYNC() in ffs_mount().
> 
> % Index: ufs_inode.c
> % ===================================================================
> % RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_inode.c,v
> % retrieving revision 1.53
> % diff -u -2 -r1.53 ufs_inode.c
> % --- ufs_inode.c	7 Apr 2004 03:47:20 -0000	1.53
> % +++ ufs_inode.c	30 Nov 2007 12:58:39 -0000
> % @@ -59,4 +59,6 @@
> %  #endif
> % 
> % +#include <ufs/ffs/fs.h>
> % +
> %  /*
> %   * Last reference to an inode.  If necessary, write or delete it.
> % @@ -118,6 +120,15 @@
> %  			ip->i_flag &= ~IN_ACCESS;
> %  		} else {
> % +			int wasro = 0;
> % +
> %  			(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
> % +			if (vp->v_mount->mnt_flag & MNT_RDONLY &&
> % +			    ip->i_fs->fs_ronly == 0) {
> % +				vp->v_mount->mnt_flag &= ~MNT_RDONLY;
> % +				wasro = 1;
> % +			}
> %  			UFS_UPDATE(vp, 0);
> % +			if (wasro)
> % +				vp->v_mount->mnt_flag |= MNT_RDONLY;
> %  		}
> %  	}

I'm somewhat suprised that this makes a difference.  I didn't see
anything obvious under UFS_UPDATE() that looks at MNT_RDONLY.
 
> I didn't bother with correct locking here (only tested under UP).

I suspect that clearing MNT_RDONLY like this could allow more write
operations to be started from userland.

> With this change, the VOP_SYNC() in ffs_mount() for MNT_UPDATE seems
> to flush everything in simple cases (with no open files), just like
> the VOP_SYNC() in unmount() flushes everything before ffs_unmount() is
> reached.  OTOH, without a forced flush, soft updates takes a long
> time to flush things -- more like 3 syncer periods than 1 for
> non-waitfor syncs.  With soft updates, the above is called from deep
> in VOP_SYNC().  It's strange that the above non-waitfor UFS_UPDATE()
> is used inside of waitfor syncs.  It apparently works because the
> waitfor syncs wait for it later, but only if it is non-null.

I think the intent is that this call to UFS_UPDATE() is to trigger the
writes of any dirty data blocks, which must be written before the inode
can be written.  The write of the inode itself will probably be
triggered by the next iteration of the syncer, by vflush() (in the
unmount or remount case), or possibly by a soft updates callback.  Also,
I think that waiting to flush the inode might allow multiple inodes in
the same block to be written at once.




More information about the freebsd-fs mailing list