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);