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.
This commit is contained in:
parent
1be9a5038c
commit
40ccbdf2b9
|
@ -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_softc *);
|
|||
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_type rw,
|
|||
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_int32_t cl)
|
|||
|
||||
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_int32_t cl)
|
|||
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue