summaryrefslogtreecommitdiff
path: root/sys/dev/fss.c
diff options
context:
space:
mode:
authorhannken <hannken@NetBSD.org>2004-02-14 00:00:56 +0000
committerhannken <hannken@NetBSD.org>2004-02-14 00:00:56 +0000
commit142e9d5deb9468d46ed366129e834f8d47e8a47b (patch)
tree4f15fb71f54da12d0f4a1c85c9ccff10cd82a261 /sys/dev/fss.c
parent4b4d77a7b281f1c5adc6a14b3d36727c3a715582 (diff)
Add a generic copy-on-write hook to add/remove functions that will be
called with every buffer written through spec_strategy(). Used by fss(4). Future file-system-internal snapshots will need them too. Welcome to 1.6ZK Approved by: Jason R. Thorpe <thorpej@netbsd.org>
Diffstat (limited to 'sys/dev/fss.c')
-rw-r--r--sys/dev/fss.c74
1 files changed, 20 insertions, 54 deletions
diff --git a/sys/dev/fss.c b/sys/dev/fss.c
index 98bfec7a346..ded77acb494 100644
--- a/sys/dev/fss.c
+++ b/sys/dev/fss.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fss.c,v 1.5 2004/01/25 18:06:48 hannken Exp $ */
+/* $NetBSD: fss.c,v 1.6 2004/02/14 00:00:56 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -43,10 +43,9 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.5 2004/01/25 18:06:48 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.6 2004/02/14 00:00:56 hannken Exp $");
#include "fss.h"
-#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -73,13 +72,6 @@ __KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.5 2004/01/25 18:06:48 hannken Exp $");
#include <machine/stdarg.h>
-#if defined(DEBUG) && defined(DDB)
-#include <ddb/ddbvar.h>
-#include <machine/db_machdep.h>
-#include <ddb/db_command.h>
-#include <ddb/db_interface.h>
-#endif
-
#ifdef DEBUG
#define FSS_STATISTICS
#endif
@@ -120,10 +112,7 @@ static struct fss_stat fss_stat[NFSS];
#define FSS_STAT_CLEAR(sc)
#endif /* FSS_STATISTICS */
-typedef enum {
- FSS_READ,
- FSS_WRITE
-} fss_io_type;
+static struct fss_softc fss_softc[NFSS];
void fssattach(int);
@@ -136,7 +125,10 @@ dev_type_strategy(fss_strategy);
dev_type_dump(fss_dump);
dev_type_size(fss_size);
+static void fss_copy_on_write(void *, struct buf *);
static inline void fss_error(struct fss_softc *, const char *, ...);
+static int fss_create_files(struct fss_softc *, struct fss_set *,
+ off_t *, struct proc *);
static int fss_create_snapshot(struct fss_softc *, struct fss_set *,
struct proc *);
static int fss_delete_snapshot(struct fss_softc *, struct proc *);
@@ -456,26 +448,12 @@ fss_umount_hook(struct mount *mp, int forced)
* A buffer is written to the snapshotted block device. Copy to
* backing store if needed.
*/
-void
-fss_copy_on_write(struct fss_softc *sc, struct buf *bp)
+static void
+fss_copy_on_write(void *v, struct buf *bp)
{
int s;
u_int32_t cl, ch, c;
-
-#ifdef DIAGNOSTIC
- /*
- * Buffer written on a suspended file system. This is always an error.
- */
- if (sc->sc_mount &&
- (sc->sc_mount->mnt_iflag & IMNT_SUSPENDED) == IMNT_SUSPENDED) {
- printf_nolog("fss%d: write while suspended, %lu@%" PRId64 "\n",
- sc->sc_unit, bp->b_bcount, bp->b_blkno);
-#if defined(DEBUG) && defined(DDB)
- db_stack_trace_print((db_expr_t)__builtin_frame_address(0),
- TRUE, 65535, "", printf_nolog);
-#endif /* DEBUG && DDB */
- }
-#endif /* DIAGNOSTIC */
+ struct fss_softc *sc = v;
FSS_LOCK(sc, s);
if (!FSS_ISVALID(sc)) {
@@ -483,8 +461,6 @@ fss_copy_on_write(struct fss_softc *sc, struct buf *bp)
return;
}
- sc->sc_cowcount++;
-
FSS_UNLOCK(sc, s);
FSS_STAT_INC(sc, cow_calls);
@@ -494,24 +470,17 @@ fss_copy_on_write(struct fss_softc *sc, struct buf *bp)
for (c = cl; c <= ch; c++)
fss_read_cluster(sc, c);
-
- FSS_LOCK(sc, s);
-
- if (--sc->sc_cowcount == 0 && !FSS_ISVALID(sc))
- wakeup(&sc->sc_cowcount);
-
- FSS_UNLOCK(sc, s);
}
/*
* Lookup and open needed files.
*
* Returns dev and size of the underlying block device.
- * Initializes the fields sc_mntname, sc_bs_vp and sc_mount
+ * Initializes sc_mntname, sc_mount_vp, sc_bdev, sc_bs_vp and sc_mount
*/
static int
fss_create_files(struct fss_softc *sc, struct fss_set *fss,
- dev_t *bdev, off_t *bsize, struct proc *p)
+ off_t *bsize, struct proc *p)
{
int error, fsbsize;
struct partinfo dpart;
@@ -555,7 +524,8 @@ fss_create_files(struct fss_softc *sc, struct fss_set *fss,
return error;
}
- *bdev = nd.ni_vp->v_rdev;
+ sc->sc_mount_vp = nd.ni_vp;
+ sc->sc_bdev = nd.ni_vp->v_rdev;
*bsize = (off_t)dpart.disklab->d_secsize*dpart.part->p_size;
vrele(nd.ni_vp);
@@ -614,13 +584,12 @@ fss_create_snapshot(struct fss_softc *sc, struct fss_set *fss, struct proc *p)
{
int len, error;
u_int32_t csize;
- dev_t bdev;
off_t bsize;
/*
* Open needed files.
*/
- if ((error = fss_create_files(sc, fss, &bdev, &bsize, p)) != 0)
+ if ((error = fss_create_files(sc, fss, &bsize, p)) != 0)
goto bad;
if (sc->sc_bs_vp->v_type == VREG &&
@@ -693,10 +662,11 @@ fss_create_snapshot(struct fss_softc *sc, struct fss_set *fss, struct proc *p)
microtime(&sc->sc_time);
- if (error == 0) {
+ if (error == 0)
+ error = vn_cow_establish(sc->sc_mount_vp,
+ fss_copy_on_write, sc);
+ if (error == 0)
sc->sc_flags |= FSS_ACTIVE;
- sc->sc_bdev = bdev;
- }
vfs_write_resume(sc->sc_mount);
@@ -729,14 +699,10 @@ fss_delete_snapshot(struct fss_softc *sc, struct proc *p)
{
int s;
- FSS_LOCK(sc, s);
+ vn_cow_disestablish(sc->sc_mount_vp, fss_copy_on_write, sc);
+ FSS_LOCK(sc, s);
sc->sc_flags &= ~(FSS_ACTIVE|FSS_ERROR);
-
- while (sc->sc_cowcount > 0) {
- ltsleep(&sc->sc_cowcount, PRIBIO, "cowwait1", 0, &sc->sc_slock);
- }
-
sc->sc_mount = NULL;
sc->sc_bdev = NODEV;
FSS_UNLOCK(sc, s);