Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/fs/msdosfs pcbmap(): We cannot use bread() here as for t...



details:   https://anonhg.NetBSD.org/src/rev/b9651beb296a
branches:  trunk
changeset: 778705:b9651beb296a
user:      hannken <hannken%NetBSD.org@localhost>
date:      Mon Apr 09 11:10:06 2012 +0000

description:
pcbmap(): We cannot use bread() here as for the pagedaemon getblk()
          may fail leading to a panic in bread().
          Replace bread() with getblk() / VOP_STRATEGY() and return
          an error if getblk() fails.

Fixes PR#46282: 6.0_BETA crash: msdosfs_bmap -> pcbmap -> bread -> bio_doread

This is an interim solution for easy pullup.  The final solution
is be to change bread() to not return a buffer on error.  As
we have to change all callers of bread() this will not qualify
for a pullup.

diffstat:

 sys/fs/msdosfs/msdosfs_fat.c |  29 ++++++++++++++++++++++-------
 1 files changed, 22 insertions(+), 7 deletions(-)

diffs (50 lines):

diff -r 18d10d133f8f -r b9651beb296a sys/fs/msdosfs/msdosfs_fat.c
--- a/sys/fs/msdosfs/msdosfs_fat.c      Mon Apr 09 10:18:16 2012 +0000
+++ b/sys/fs/msdosfs/msdosfs_fat.c      Mon Apr 09 11:10:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_fat.c,v 1.19 2010/01/26 20:25:52 joerg Exp $   */
+/*     $NetBSD: msdosfs_fat.c,v 1.20 2012/04/09 11:10:06 hannken Exp $ */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.19 2010/01/26 20:25:52 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.20 2012/04/09 11:10:06 hannken Exp $");
 
 /*
  * kernel include files.
@@ -254,11 +254,26 @@
                if (bn != bp_bn) {
                        if (bp)
                                brelse(bp, 0);
-                       error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
-                           NOCRED, 0, &bp);
-                       if (error) {
-                               brelse(bp, 0);
-                               return (error);
+                       bp = getblk(pmp->pm_devvp, de_bn2kb(pmp, bn), bsize,
+                           0, 0);
+                       if (bp == NULL) {
+                               /*
+                                * getblk() above returns NULL only iff we are
+                                * pagedaemon.  See the implementation of getblk
+                                * for detail.
+                                */
+                               return ENOMEM;
+                       }
+                       if (!ISSET(bp->b_oflags, (BO_DONE | BO_DELWRI))) {
+                               SET(bp->b_flags, B_READ);
+                               BIO_SETPRIO(bp, BPRIO_TIMECRITICAL);
+                               VOP_STRATEGY(pmp->pm_devvp, bp);
+                               curlwp->l_ru.ru_inblock++;
+                               error = biowait(bp);
+                               if (error) {
+                                       brelse(bp, 0);
+                                       return error;
+                               }
                        }
                        bp_bn = bn;
                }



Home | Main Index | Thread Index | Old Index