Author: attilio
Date: Tue Sep  8 14:19:14 2009
New Revision: 196973
URL: http://svn.freebsd.org/changeset/base/196973

Log:
  MFC r180758:
  Prevent the bdflush() activity when trying to lock an indirect block buffer
  setting TDP_INBDFUSH in the appropriate code paths.
  
  Sponsored by: Sandvine Incorporated

Modified:
  stable/6/sys/ufs/ffs/ffs_balloc.c

Modified: stable/6/sys/ufs/ffs/ffs_balloc.c
==============================================================================
--- stable/6/sys/ufs/ffs/ffs_balloc.c   Tue Sep  8 14:15:14 2009        
(r196972)
+++ stable/6/sys/ufs/ffs/ffs_balloc.c   Tue Sep  8 14:19:14 2009        
(r196973)
@@ -104,6 +104,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
        ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
        ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1];
        int unwindidx = -1;
+       int saved_inbdflush;
 
        ip = VTOI(vp);
        dp = ip->i_din1;
@@ -225,6 +226,9 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
        if (num < 1)
                panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block");
 #endif
+       saved_inbdflush = ~TDP_INBDFLUSH | (curthread->td_pflags &
+           TDP_INBDFLUSH);
+       curthread->td_pflags |= TDP_INBDFLUSH;
        /*
         * Fetch the first indirect block allocating if necessary.
         */
@@ -237,8 +241,10 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                UFS_LOCK(ump);
                pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
                if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
-                   cred, &newb)) != 0)
+                   cred, &newb)) != 0) {
+                       curthread->td_pflags &= saved_inbdflush;
                        return (error);
+               }
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = indirs[1].in_lbn;
@@ -329,6 +335,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
         * If asked only for the indirect block, then return it.
         */
        if (flags & BA_METAONLY) {
+               curthread->td_pflags &= saved_inbdflush;
                *bpp = bp;
                return (0);
        }
@@ -366,6 +373,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                                bp->b_flags |= B_CLUSTEROK;
                        bdwrite(bp);
                }
+               curthread->td_pflags &= saved_inbdflush;
                *bpp = nbp;
                return (0);
        }
@@ -387,9 +395,11 @@ ffs_balloc_ufs1(struct vnode *vp, off_t 
                nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
                nbp->b_blkno = fsbtodb(fs, nb);
        }
+       curthread->td_pflags &= saved_inbdflush;
        *bpp = nbp;
        return (0);
 fail:
+       curthread->td_pflags &= saved_inbdflush;
        /*
         * If we have failed to allocate any blocks, simply return the error.
         * This is the usual case and avoids the need to fsync the file.
@@ -489,6 +499,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
        ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1];
        int deallocated, osize, nsize, num, i, error;
        int unwindidx = -1;
+       int saved_inbdflush;
 
        ip = VTOI(vp);
        dp = ip->i_din2;
@@ -719,6 +730,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
        if (num < 1)
                panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
 #endif
+       saved_inbdflush = ~TDP_INBDFLUSH | (curthread->td_pflags &
+           TDP_INBDFLUSH);
+       curthread->td_pflags |= TDP_INBDFLUSH;
        /*
         * Fetch the first indirect block allocating if necessary.
         */
@@ -731,8 +745,10 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                UFS_LOCK(ump);
                pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
                if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
-                   cred, &newb)) != 0)
+                   cred, &newb)) != 0) {
+                       curthread->td_pflags &= saved_inbdflush;
                        return (error);
+               }
                nb = newb;
                *allocblk++ = nb;
                *lbns_remfree++ = indirs[1].in_lbn;
@@ -823,6 +839,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
         * If asked only for the indirect block, then return it.
         */
        if (flags & BA_METAONLY) {
+               curthread->td_pflags &= saved_inbdflush;
                *bpp = bp;
                return (0);
        }
@@ -860,6 +877,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                                bp->b_flags |= B_CLUSTEROK;
                        bdwrite(bp);
                }
+               curthread->td_pflags &= saved_inbdflush;
                *bpp = nbp;
                return (0);
        }
@@ -887,9 +905,11 @@ ffs_balloc_ufs2(struct vnode *vp, off_t 
                nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, 0);
                nbp->b_blkno = fsbtodb(fs, nb);
        }
+       curthread->td_pflags &= saved_inbdflush;
        *bpp = nbp;
        return (0);
 fail:
+       curthread->td_pflags &= saved_inbdflush;
        /*
         * If we have failed to allocate any blocks, simply return the error.
         * This is the usual case and avoids the need to fsync the file.
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to