Date: Wed, 27 Mar 2002 13:51:00 -0800 From: Terry Lambert <tlambert2@mindspring.com> To: Kirk McKusick <mckusick@beastie.mckusick.com> Cc: Ollivier Robert <roberto@eurocontrol.fr>, arch@FreeBSD.ORG Subject: Re: [PATCH] MFC the full filesystem softupdates fix ? Message-ID: <3CA23EC4.EB6E8508@mindspring.com> References: <200203272134.g2RLYTD97258@beastie.mckusick.com>
next in thread | previous in thread | raw e-mail | index | archive | help
I think Kirk meant "-stable", not "-current"; in any case, I'd like to see it handled and brought back into -stable anyway. I look at -stable as a pruned -current. Some of the growth in -current should/will never see the light of day in a realease... -- Terry Kirk McKusick wrote: > > If it was easy as your patch, there would be no problem in > putting it in. The problem is that -current does not have > the code to maintain the fs_pendingblocks variable. At a > minimum you would have to add that code as well. It is a > good deal more extensive, though at this point well enough > tested that I am less fearful of adding it. > > Kirk McKusick > > =-=-=-=-=-= > > Date: Wed, 27 Mar 2002 11:19:47 +0100 > From: Ollivier Robert <roberto@eurocontrol.fr> > To: mckusick@mckusick.com > Cc: arch@FreeBSD.ORG > Subject: [PATCH] MFC the full filesystem softupdates fix ? > > Following some discussions in the French fr.comp.os.bsd newsgroup about > softupdates and the full filesystem problem (which is fixed in CURRENT > thanks to you), here a proposed diff to merge the fix into STABLE. > > Can you (and -arch) review it ? It would be nice to have this fixed in > STABLE as well. > > Thanks. > > Index: ffs_alloc.c > =================================================================== > RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_alloc.c,v > retrieving revision 1.64.2.2 > diff -u -2 -r1.64.2.2 ffs_alloc.c > --- ffs_alloc.c 21 Sep 2001 19:15:21 -0000 1.64.2.2 > +++ ffs_alloc.c 27 Mar 2002 10:08:29 -0000 > @@ -107,5 +107,5 @@ > register struct fs *fs; > ufs_daddr_t bno; > - int cg; > + int cg, reclaimed; > #ifdef QUOTA > int error; > @@ -124,4 +124,6 @@ > panic("ffs_alloc: missing credential"); > #endif /* DIAGNOSTIC */ > + reclaimed = 0; > +retry: > if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) > goto nospace; > @@ -155,4 +157,9 @@ > #endif > nospace: > + if (fs->fs_pendingblocks > 0 && reclaimed == 0) { > + reclaimed = 1; > + softdep_request_cleanup(fs, ITOV(ip)); > + goto retry; > + } > ffs_fserr(fs, cred->cr_uid, "file system full"); > uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); > @@ -177,7 +184,7 @@ > struct buf **bpp; > { > - register struct fs *fs; > + struct fs *fs; > struct buf *bp; > - int cg, request, error; > + int cg, request, error, reclaimed; > ufs_daddr_t bprev, bno; > > @@ -198,4 +205,6 @@ > if (cred->cr_uid != 0 && > freespace(fs, fs->fs_minfree) - numfrags(fs, nsize - osize) < 0) > + reclaimed = 0; > +retry: > goto nospace; > if ((bprev = ip->i_db[lbprev]) == 0) { > @@ -208,5 +217,5 @@ > * Allocate the extra space in the buffer. > */ > - error = bread(ITOV(ip), lbprev, osize, NOCRED, &bp); > + error = bread(vp, lbprev, osize, NOCRED, &bp); > if (error) { > brelse(bp); > @@ -295,5 +304,5 @@ > if (bno > 0) { > bp->b_blkno = fsbtodb(fs, bno); > - if (!DOINGSOFTDEP(ITOV(ip))) > + if (!DOINGSOFTDEP(vp)) > ffs_blkfree(ip, bprev, (long)osize); > if (nsize < request) > @@ -319,4 +328,9 @@ > * no space available > */ > + if (fs->fs_pendingblocks > 0 && reclaimed == 0) { > + reclaimed = 1; > + softdep_request_cleanup(fs, vp); > + goto retry; > + } > ffs_fserr(fs, cred->cr_uid, "file system full"); > uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); > Index: ffs_extern.h > =================================================================== > RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_extern.h,v > retrieving revision 1.30 > diff -u -2 -r1.30 ffs_extern.h > --- ffs_extern.h 9 Jan 2000 22:40:02 -0000 1.30 > +++ ffs_extern.h 27 Mar 2002 10:05:03 -0000 > @@ -115,4 +115,5 @@ > void softdep_load_inodeblock __P((struct inode *)); > void softdep_freefile __P((struct vnode *, ino_t, int)); > +int softdep_request_cleanup __P((struct fs *, struct vnode *)); > void softdep_setup_freeblocks __P((struct inode *, off_t)); > void softdep_setup_inomapdep __P((struct buf *, struct inode *, ino_t)); > Index: ffs_softdep.c > =================================================================== > RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_softdep.c,v > retrieving revision 1.57.2.11 > diff -u -2 -r1.57.2.11 ffs_softdep.c > --- ffs_softdep.c 5 Feb 2002 18:46:53 -0000 1.57.2.11 > +++ ffs_softdep.c 27 Mar 2002 10:12:48 -0000 > @@ -508,7 +508,8 @@ > static struct proc *filesys_syncer; /* proc of filesystem syncer process */ > static int req_clear_inodedeps; /* syncer process flush some inodedeps */ > -#define FLUSH_INODES 1 > +#define FLUSH_INODES 1 > static int req_clear_remove; /* syncer process flush some freeblks */ > -#define FLUSH_REMOVE 2 > +#define FLUSH_REMOVE 2 > +#define FLUSH_REMOVE_WAIT 3 > /* > * runtime statistics > @@ -703,5 +704,5 @@ > if (wk == 0) { > FREE_LOCK(&lk); > - return (0); > + return (-1); > } > WORKLIST_REMOVE(wk); > @@ -4561,4 +4562,39 @@ > > /* > + * Called by the allocation routines when they are about to fail > + * in the hope that we can free up some disk space. > + * > + * First check to see if the work list has anything on it. If it has, > + * clean up entries until we successfully free some space. Because this > + * process holds inodes locked, we cannot handle any remove requests > + * that might block on a locked inode as that could lead to deadlock. > + * If the worklist yields no free space, encourage the syncer daemon > + * to help us. In no event will we try for longer than tickdelay seconds. > + */ > +int > +softdep_request_cleanup(fs, vp) > + struct fs *fs; > + struct vnode *vp; > +{ > + long starttime, needed; > + > + needed = fs->fs_cstotal.cs_nbfree + fs->fs_contigsumsize; > + starttime = time_second + tickdelay; > + if (UFS_UPDATE(vp, 1) != 0) > + return (0); > + while (fs->fs_pendingblocks > 0 && fs->fs_cstotal.cs_nbfree <= needed) { > + if (time_second > starttime) > + return (0); > + if (num_on_worklist > 0 && > + process_worklist_item(NULL, LK_NOWAIT) != -1) { > + stat_worklist_push += 1; > + continue; > + } > + request_cleanup(FLUSH_REMOVE_WAIT, 0); > + } > + return (1); > +} > + > +/* > * If memory utilization has gotten too high, deliberately slow things > * down and speed up the I/O processing. > @@ -4595,4 +4631,10 @@ > > /* > + * Next, we attempt to speed up the syncer process. If that > + * is successful, then we allow the process to continue. > + */ > + if (speedup_syncer() && resource != FLUSH_REMOVE_WAIT) > + return(0); > + /* > * If we are resource constrained on inode dependencies, try > * flushing some dirty inodes. Otherwise, we are constrained > @@ -4613,4 +4655,5 @@ > > case FLUSH_REMOVE: > + case FLUSH_REMOVE_WAIT: > stat_blk_limit_push += 1; > req_clear_remove += 1; > > -- > Ollivier ROBERT -=- Eurocontrol EEC/ITM -=- Ollivier.Robert@eurocontrol.fr > FreeBSD caerdonn.eurocontrol.fr 5.0-CURRENT #46: Wed Jan 3 15:52:00 CET 2001 > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-arch" in the body of the message > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-arch" in the body of the message To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3CA23EC4.EB6E8508>