Skip site navigation (1)Skip section navigation (2)
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>