Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Apr 2013 08:59:51 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r249330 - stable/9/sys/kern
Message-ID:  <201304100859.r3A8xpjh057216@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Apr 10 08:59:50 2013
New Revision: 249330
URL: http://svnweb.freebsd.org/changeset/base/249330

Log:
  MFC r248794:
  Fix a race with the vnode reclamation in the aio_qphysio().

Modified:
  stable/9/sys/kern/vfs_aio.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/vfs_aio.c
==============================================================================
--- stable/9/sys/kern/vfs_aio.c	Wed Apr 10 08:49:37 2013	(r249329)
+++ stable/9/sys/kern/vfs_aio.c	Wed Apr 10 08:59:50 2013	(r249330)
@@ -1254,9 +1254,11 @@ aio_qphysio(struct proc *p, struct aiocb
 	struct file *fp;
 	struct buf *bp;
 	struct vnode *vp;
+	struct cdevsw *csw;
+	struct cdev *dev;
 	struct kaioinfo *ki;
 	struct aioliojob *lj;
-	int error;
+	int error, ref;
 
 	cb = &aiocbe->uaiocb;
 	fp = aiocbe->fd_file;
@@ -1284,9 +1286,6 @@ aio_qphysio(struct proc *p, struct aiocb
  	if (cb->aio_nbytes % vp->v_bufobj.bo_bsize)
 		return (-1);
 
-	if (cb->aio_nbytes > vp->v_rdev->si_iosize_max)
-		return (-1);
-
 	if (cb->aio_nbytes >
 	    MAXPHYS - (((vm_offset_t) cb->aio_buf) & PAGE_MASK))
 		return (-1);
@@ -1295,6 +1294,15 @@ aio_qphysio(struct proc *p, struct aiocb
 	if (ki->kaio_buffer_count >= ki->kaio_ballowed_count)
 		return (-1);
 
+	ref = 0;
+	csw = devvn_refthread(vp, &dev, &ref);
+	if (csw == NULL)
+		return (ENXIO);
+	if (cb->aio_nbytes > dev->si_iosize_max) {
+		error = -1;
+		goto unref;
+	}
+
 	/* Create and build a buffer header for a transfer. */
 	bp = (struct buf *)getpbuf(NULL);
 	BUF_KERNPROC(bp);
@@ -1347,7 +1355,8 @@ aio_qphysio(struct proc *p, struct aiocb
 	TASK_INIT(&aiocbe->biotask, 0, biohelper, aiocbe);
 
 	/* Perform transfer. */
-	dev_strategy(vp->v_rdev, bp);
+	dev_strategy_csw(dev, csw, bp);
+	dev_relthread(dev, ref);
 	return (0);
 
 doerror:
@@ -1359,6 +1368,8 @@ doerror:
 	aiocbe->bp = NULL;
 	AIO_UNLOCK(ki);
 	relpbuf(bp, NULL);
+unref:
+	dev_relthread(dev, ref);
 	return (error);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304100859.r3A8xpjh057216>