Module Name:    src
Committed By:   snj
Date:           Sat Jan 13 05:38:54 UTC 2018

Modified Files:
        src/sys/dev [netbsd-8]: fss.c
        src/usr.sbin/fssconfig [netbsd-8]: fssconfig.c

Log Message:
Pull up following revision(s) (requested by hannken in ticket #475):
        sys/dev/fss.c: revision 1.101-1.103
        usr.sbin/fssconfig/fssconfig.c: revision 1.13
Bounds check against media size for non-persistent snapshots.
--
Treat partial read from backing store as I/O error.
--
Pass residual back to b_resid for persistent snapshots.
--
Use stat() information to decide if the backing store is a directory.
Depending on open() returning EISDIR fails for mount points.


To generate a diff of this commit:
cvs rdiff -u -r1.98.2.1 -r1.98.2.2 src/sys/dev/fss.c
cvs rdiff -u -r1.12 -r1.12.6.1 src/usr.sbin/fssconfig/fssconfig.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/fss.c
diff -u src/sys/dev/fss.c:1.98.2.1 src/sys/dev/fss.c:1.98.2.2
--- src/sys/dev/fss.c:1.98.2.1	Thu Dec 21 21:50:16 2017
+++ src/sys/dev/fss.c	Sat Jan 13 05:38:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: fss.c,v 1.98.2.1 2017/12/21 21:50:16 snj Exp $	*/
+/*	$NetBSD: fss.c,v 1.98.2.2 2018/01/13 05:38:54 snj Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.98.2.1 2017/12/21 21:50:16 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.98.2.2 2018/01/13 05:38:54 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -89,7 +89,7 @@ static void fss_softc_free(struct fss_so
 static int fss_read_cluster(struct fss_softc *, u_int32_t);
 static void fss_bs_thread(void *);
 static int fss_bs_io(struct fss_softc *, fss_io_type,
-    u_int32_t, off_t, int, void *);
+    u_int32_t, off_t, int, void *, size_t *);
 static u_int32_t *fss_bs_indir(struct fss_softc *, u_int32_t);
 
 static kmutex_t fss_device_lock;	/* Protect all units. */
@@ -281,20 +281,26 @@ fss_strategy(struct buf *bp)
 	mutex_enter(&sc->sc_slock);
 
 	if (write || !FSS_ISVALID(sc)) {
-
-		mutex_exit(&sc->sc_slock);
-
 		bp->b_error = (write ? EROFS : ENXIO);
-		bp->b_resid = bp->b_bcount;
-		biodone(bp);
-		return;
+		goto done;
 	}
+	/* Check bounds for non-persistent snapshots. */
+	if ((sc->sc_flags & FSS_PERSISTENT) == 0 &&
+	    bounds_check_with_mediasize(bp, DEV_BSIZE,
+	    btodb(FSS_CLTOB(sc, sc->sc_clcount - 1) + sc->sc_clresid)) <= 0)
+		goto done;
 
 	bp->b_rawblkno = bp->b_blkno;
 	bufq_put(sc->sc_bufq, bp);
 	cv_signal(&sc->sc_work_cv);
 
 	mutex_exit(&sc->sc_slock);
+	return;
+
+done:
+	mutex_exit(&sc->sc_slock);
+	bp->b_resid = bp->b_bcount;
+	biodone(bp);
 }
 
 int
@@ -981,6 +987,8 @@ restart:
 		todo -= len;
 	}
 	error = biowait(mbp);
+	if (error == 0 && mbp->b_resid != 0)
+		error = EIO;
 	putiobuf(mbp);
 
 	mutex_enter(&sc->sc_slock);
@@ -1002,7 +1010,7 @@ restart:
  */
 static int
 fss_bs_io(struct fss_softc *sc, fss_io_type rw,
-    u_int32_t cl, off_t off, int len, void *data)
+    u_int32_t cl, off_t off, int len, void *data, size_t *resid)
 {
 	int error;
 
@@ -1013,7 +1021,7 @@ fss_bs_io(struct fss_softc *sc, fss_io_t
 	error = vn_rdwr((rw == FSS_READ ? UIO_READ : UIO_WRITE), sc->sc_bs_vp,
 	    data, len, off, UIO_SYSSPACE,
 	    IO_ADV_ENCODE(POSIX_FADV_NOREUSE) | IO_NODELOCKED,
-	    sc->sc_bs_lwp->l_cred, NULL, NULL);
+	    sc->sc_bs_lwp->l_cred, resid, NULL);
 	if (error == 0) {
 		mutex_enter(sc->sc_bs_vp->v_interlock);
 		error = VOP_PUTPAGES(sc->sc_bs_vp, trunc_page(off),
@@ -1042,7 +1050,7 @@ fss_bs_indir(struct fss_softc *sc, u_int
 
 	if (sc->sc_indir_dirty) {
 		if (fss_bs_io(sc, FSS_WRITE, sc->sc_indir_cur, 0,
-		    FSS_CLSIZE(sc), (void *)sc->sc_indir_data) != 0)
+		    FSS_CLSIZE(sc), (void *)sc->sc_indir_data, NULL) != 0)
 			return NULL;
 		setbit(sc->sc_indir_valid, sc->sc_indir_cur);
 	}
@@ -1052,7 +1060,7 @@ fss_bs_indir(struct fss_softc *sc, u_int
 
 	if (isset(sc->sc_indir_valid, sc->sc_indir_cur)) {
 		if (fss_bs_io(sc, FSS_READ, sc->sc_indir_cur, 0,
-		    FSS_CLSIZE(sc), (void *)sc->sc_indir_data) != 0)
+		    FSS_CLSIZE(sc), (void *)sc->sc_indir_data, NULL) != 0)
 			return NULL;
 	} else
 		memset(sc->sc_indir_data, 0, FSS_CLSIZE(sc));
@@ -1073,6 +1081,7 @@ fss_bs_thread(void *arg)
 	long off;
 	char *addr;
 	u_int32_t c, cl, ch, *indirp;
+	size_t resid;
 	struct buf *bp, *nbp;
 	struct fss_softc *sc;
 	struct fss_cache *scp, *scl;
@@ -1109,14 +1118,18 @@ fss_bs_thread(void *arg)
 				disk_busy(sc->sc_dkdev);
 				error = fss_bs_io(sc, FSS_READ, 0,
 				    dbtob(bp->b_blkno), bp->b_bcount,
-				    bp->b_data);
+				    bp->b_data, &resid);
+				if (error)
+					resid = bp->b_bcount;
 				disk_unbusy(sc->sc_dkdev,
 				    (error ? 0 : bp->b_bcount), is_read);
-			} else
+			} else {
 				error = ENXIO;
+				resid = bp->b_bcount;
+			}
 
 			bp->b_error = error;
-			bp->b_resid = (error ? bp->b_bcount : 0);
+			bp->b_resid = resid;
 			biodone(bp);
 
 			mutex_enter(&sc->sc_slock);
@@ -1137,7 +1150,7 @@ fss_bs_thread(void *arg)
 			indirp = fss_bs_indir(sc, scp->fc_cluster);
 			if (indirp != NULL) {
 				error = fss_bs_io(sc, FSS_WRITE, sc->sc_clnext,
-				    0, FSS_CLSIZE(sc), scp->fc_data);
+				    0, FSS_CLSIZE(sc), scp->fc_data, NULL);
 			} else
 				error = EIO;
 
@@ -1205,6 +1218,8 @@ fss_bs_thread(void *arg)
 			bdev_strategy(nbp);
 
 			error = biowait(nbp);
+			if (error == 0 && nbp->b_resid != 0)
+				error = EIO;
 			if (error != 0) {
 				bp->b_resid = bp->b_bcount;
 				bp->b_error = nbp->b_error;
@@ -1256,8 +1271,8 @@ fss_bs_thread(void *arg)
 			/*
 			 * Read from backing store.
 			 */
-			error =
-			    fss_bs_io(sc, FSS_READ, *indirp, off, len, addr);
+			error = fss_bs_io(sc, FSS_READ,
+			    *indirp, off, len, addr, NULL);
 
 			mutex_enter(&sc->sc_slock);
 			if (error) {

Index: src/usr.sbin/fssconfig/fssconfig.c
diff -u src/usr.sbin/fssconfig/fssconfig.c:1.12 src/usr.sbin/fssconfig/fssconfig.c:1.12.6.1
--- src/usr.sbin/fssconfig/fssconfig.c:1.12	Sun Jul 31 02:13:26 2016
+++ src/usr.sbin/fssconfig/fssconfig.c	Sat Jan 13 05:38:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: fssconfig.c,v 1.12 2016/07/31 02:13:26 pgoyette Exp $	*/
+/*	$NetBSD: fssconfig.c,v 1.12.6.1 2018/01/13 05:38:54 snj Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -130,16 +130,19 @@ config(int argc, char **argv)
 	    prog_stat(argv[1], &sbuf) != 0)
 		err(1, "stat %s", argv[1]);
 	mountdev = sbuf.st_dev;
-	if (stat(argv[2], &sbuf) == 0 &&
-	    S_ISREG(sbuf.st_mode) &&
-	    sbuf.st_dev == mountdev) {
-		if ((sbuf.st_flags & SF_SNAPSHOT) == 0)
-			errx(1, "%s: exists and is not a snapshot", argv[2]);
-		if (argc != 3)
-			usage();
-		isreg = ispersistent = 1;
+	if (stat(argv[2], &sbuf) == 0) {
+		if (S_ISREG(sbuf.st_mode) && sbuf.st_dev == mountdev) {
+			if ((sbuf.st_flags & SF_SNAPSHOT) == 0)
+				errx(1, "%s: exists and is not a snapshot",
+				    argv[2]);
+			if (argc != 3)
+				usage();
+			isreg = ispersistent = 1;
 
-		goto configure;
+			goto configure;
+		} else if (S_ISDIR(sbuf.st_mode)) {
+			istmp = 1;
+		}
 	}
 
 	if (argc > 5)
@@ -155,18 +158,17 @@ config(int argc, char **argv)
 		bssize = (off_t)fsbuf.f_blocks*fsbuf.f_frsize;
 
 	/*
-	 * Create the backing store. If it is a directory, create a temporary
-	 * file and set the unlink flag.
+	 * Create the backing store.
 	 */
-	fd = prog_open(fss.fss_bstore, O_CREAT|O_TRUNC|O_WRONLY, 0600);
-	if (fd < 0) {
-		if (errno != EISDIR)
-			err(1, "create: %s", fss.fss_bstore);
-		snprintf(path, sizeof(path), "%s/XXXXXXXXXX", fss.fss_bstore);
-		if ((fd = mkstemp(path)) < 0)
-			err(1, "mkstemp: %s", path);
+	if (istmp) {
+		snprintf(path, sizeof(path), "%s/XXXXXXXXXX", argv[2]);
 		fss.fss_bstore = path;
-		istmp = 1;
+		fd = mkstemp(fss.fss_bstore);
+	} else {
+		fd = prog_open(fss.fss_bstore, O_CREAT|O_TRUNC|O_WRONLY, 0600);
+	}
+	if (fd < 0) {
+		err(1, "create: %s", fss.fss_bstore);
 	}
 	if (prog_fstat(fd, &sbuf) < 0)
 		err(1, "stat: %s", fss.fss_bstore);

Reply via email to