summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorhannken <hannken@NetBSD.org>2007-12-02 13:56:15 +0000
committerhannken <hannken@NetBSD.org>2007-12-02 13:56:15 +0000
commitd556dc98b0f75faaa4eff532000a425bb669dd50 (patch)
tree57708fbc87a2d1c54d66576841e47901a53fdf48 /sys
parent587600728d3d1bdb8ea4937aaf2f510a046665a2 (diff)
Fscow_run(): add a flag "bool data_valid" to note still valid data.
Buffers run through copy-on-write are marked B_COWDONE. This condition is valid until the buffer has run through bwrite() and gets cleared from biodone(). Welcome to 4.99.39. Reviewed by: YAMAMOTO Takashi <yamt@netbsd.org>
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fss.c8
-rw-r--r--sys/kern/vfs_bio.c5
-rw-r--r--sys/kern/vfs_trans.c27
-rw-r--r--sys/kern/vfs_vnops.c38
-rw-r--r--sys/miscfs/specfs/spec_vnops.c6
-rw-r--r--sys/sys/buf.h5
-rw-r--r--sys/sys/fstrans.h9
-rw-r--r--sys/sys/param.h4
-rw-r--r--sys/sys/vnode.h6
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c12
10 files changed, 47 insertions, 73 deletions
diff --git a/sys/dev/fss.c b/sys/dev/fss.c
index d025d1e2876..7c897611186 100644
--- a/sys/dev/fss.c
+++ b/sys/dev/fss.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fss.c,v 1.38 2007/11/26 19:01:35 pooka Exp $ */
+/* $NetBSD: fss.c,v 1.39 2007/12/02 13:56:15 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.38 2007/11/26 19:01:35 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.39 2007/12/02 13:56:15 hannken Exp $");
#include "fss.h"
@@ -126,7 +126,7 @@ dev_type_strategy(fss_strategy);
dev_type_dump(fss_dump);
dev_type_size(fss_size);
-static int fss_copy_on_write(void *, struct buf *);
+static int fss_copy_on_write(void *, struct buf *, bool);
static inline void fss_error(struct fss_softc *, const char *, ...);
static int fss_create_files(struct fss_softc *, struct fss_set *,
off_t *, struct lwp *);
@@ -492,7 +492,7 @@ fss_umount_hook(struct mount *mp, int forced)
* backing store if needed.
*/
static int
-fss_copy_on_write(void *v, struct buf *bp)
+fss_copy_on_write(void *v, struct buf *bp, bool data_valid)
{
int s;
u_int32_t cl, ch, c;
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index fe6731f9b0f..3d8dd03a99c 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_bio.c,v 1.180 2007/10/21 23:27:16 martin Exp $ */
+/* $NetBSD: vfs_bio.c,v 1.181 2007/12/02 13:56:16 hannken Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.180 2007/10/21 23:27:16 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.181 2007/12/02 13:56:16 hannken Exp $");
#include "fs_ffs.h"
#include "opt_bufcache.h"
@@ -1383,6 +1383,7 @@ biodone(struct buf *bp)
simple_lock(&bp->b_interlock);
if (ISSET(bp->b_flags, B_DONE))
panic("biodone already");
+ CLR(bp->b_flags, B_COWDONE);
SET(bp->b_flags, B_DONE); /* note that it's done */
BIO_SETPRIO(bp, BPRIO_DEFAULT);
diff --git a/sys/kern/vfs_trans.c b/sys/kern/vfs_trans.c
index 6ea039677e3..aa00af5024c 100644
--- a/sys/kern/vfs_trans.c
+++ b/sys/kern/vfs_trans.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_trans.c,v 1.14 2007/10/08 09:09:47 hannken Exp $ */
+/* $NetBSD: vfs_trans.c,v 1.15 2007/12/02 13:56:16 hannken Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.14 2007/10/08 09:09:47 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.15 2007/12/02 13:56:16 hannken Exp $");
/*
* File system transaction operations.
@@ -486,7 +486,7 @@ fstrans_dump(int full)
struct fscow_handler {
SLIST_ENTRY(fscow_handler) ch_list;
- int (*ch_func)(void *, struct buf *);
+ int (*ch_func)(void *, struct buf *, bool);
void *ch_arg;
};
@@ -535,7 +535,8 @@ fscow_mount_init(struct mount *mp)
}
int
-fscow_establish(struct mount *mp, int (*func)(void *, struct buf *), void *arg)
+fscow_establish(struct mount *mp, int (*func)(void *, struct buf *, bool),
+ void *arg)
{
struct fscow_mount_info *cmi;
struct fscow_handler *new;
@@ -557,7 +558,7 @@ fscow_establish(struct mount *mp, int (*func)(void *, struct buf *), void *arg)
}
int
-fscow_disestablish(struct mount *mp, int (*func)(void *, struct buf *),
+fscow_disestablish(struct mount *mp, int (*func)(void *, struct buf *, bool),
void *arg)
{
struct fscow_mount_info *cmi;
@@ -580,30 +581,36 @@ fscow_disestablish(struct mount *mp, int (*func)(void *, struct buf *),
}
int
-fscow_run(struct buf *bp)
+fscow_run(struct buf *bp, bool data_valid)
{
int error = 0;
struct mount *mp;
struct fscow_mount_info *cmi;
struct fscow_handler *hp;
+ if ((bp->b_flags & B_COWDONE))
+ goto done;
if (bp->b_vp == NULL)
- return 0;
+ goto done;
if (bp->b_vp->v_type == VBLK)
mp = bp->b_vp->v_specmountpoint;
else
mp = bp->b_vp->v_mount;
if (mp == NULL)
- return 0;
+ goto done;
if ((cmi = mount_getspecific(mp, mount_cow_key)) == NULL)
- return 0;
+ goto done;
rw_enter(&cmi->cmi_lock, RW_READER);
SLIST_FOREACH(hp, &cmi->cmi_handler, ch_list)
- if ((error = (*hp->ch_func)(hp->ch_arg, bp)) != 0)
+ if ((error = (*hp->ch_func)(hp->ch_arg, bp, data_valid)) != 0)
break;
rw_exit(&cmi->cmi_lock);
+done:
+ if (error == 0)
+ bp->b_flags |= B_COWDONE;
+
return error;
}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 9292e403107..cb0a481ece9 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnops.c,v 1.146 2007/11/30 16:52:21 yamt Exp $ */
+/* $NetBSD: vfs_vnops.c,v 1.147 2007/12/02 13:56:17 hannken Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.146 2007/11/30 16:52:21 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.147 2007/12/02 13:56:17 hannken Exp $");
#include "fs_union.h"
#include "veriexec.h"
@@ -746,40 +746,6 @@ vn_restorerecurse(struct vnode *vp, u_int flags)
}
/*
- * Obsolete: this function will be removed from 6.0
- * Please use fscow_establish() instead.
- */
-int
-vn_cow_establish(struct vnode *vp,
- int (*func)(void *, struct buf *), void *cookie)
-{
- static int firstrun = 1;
-
- if (firstrun) {
- printf("%s: this function is obsolete.\n", __FUNCTION__);
- firstrun = 0;
- }
- if (vp->v_type == VBLK)
- return fscow_establish(vp->v_specmountpoint, func, cookie);
- else
- return fscow_establish(vp->v_mount, func, cookie);
-}
-
-/*
- * Obsolete: this function will be removed from 6.0
- * Please use fscow_disestablish() instead.
- */
-int
-vn_cow_disestablish(struct vnode *vp,
- int (*func)(void *, struct buf *), void *cookie)
-{
- if (vp->v_type == VBLK)
- return fscow_disestablish(vp->v_specmountpoint, func, cookie);
- else
- return fscow_disestablish(vp->v_mount, func, cookie);
-}
-
-/*
* Simplified in-kernel wrapper calls for extended attribute access.
* Both calls pass in a NULL credential, authorizing a "kernel" access.
* Set IO_NODELOCKED in ioflg if the vnode is already locked.
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 6260df27a8c..cd899defadf 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: spec_vnops.c,v 1.109 2007/11/26 19:02:17 pooka Exp $ */
+/* $NetBSD: spec_vnops.c,v 1.110 2007/12/02 13:56:18 hannken Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.109 2007/11/26 19:02:17 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.110 2007/12/02 13:56:18 hannken Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -565,7 +565,7 @@ spec_strategy(void *v)
bioopsp->io_start(bp);
if (!(bp->b_flags & B_READ))
- error = fscow_run(bp);
+ error = fscow_run(bp, false);
if (error) {
bp->b_error = error;
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 3b8d61babd3..16cb56ec3dd 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.h,v 1.99 2007/11/21 16:30:01 pooka Exp $ */
+/* $NetBSD: buf.h,v 1.100 2007/12/02 13:56:18 hannken Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -200,6 +200,7 @@ do { \
#define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */
#define B_DIRTY 0x00000100 /* Dirty page to be pushed out async. */
#define B_DONE 0x00000200 /* I/O completed. */
+#define B_COWDONE 0x00000400 /* Copy-on-write already done. */
#define B_GATHERED 0x00001000 /* LFS: already in a segment. */
#define B_INVAL 0x00002000 /* Does not contain valid info. */
#define B_LOCKED 0x00004000 /* Locked in core (not reusable). */
@@ -217,7 +218,7 @@ do { \
#define BUF_FLAGBITS \
"\20\1AGE\3ASYNC\4BAD\5BUSY\6SCANNED\7CALL\10DELWRI" \
- "\11DIRTY\12DONE\15GATHERED\16INVAL\17LOCKED\20NOCACHE" \
+ "\11DIRTY\12DONE\13COWDONE\15GATHERED\16INVAL\17LOCKED\20NOCACHE" \
"\22CACHE\23PHYS\24RAW\25READ\26TAPE\30WANTED\31FSPRIVATE\32DEVPRIVATE" \
"\33VFLUSH"
diff --git a/sys/sys/fstrans.h b/sys/sys/fstrans.h
index e455995cb52..bcef8c1352a 100644
--- a/sys/sys/fstrans.h
+++ b/sys/sys/fstrans.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fstrans.h,v 1.6 2007/10/07 13:39:04 hannken Exp $ */
+/* $NetBSD: fstrans.h,v 1.7 2007/12/02 13:56:19 hannken Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -76,10 +76,11 @@ int fstrans_is_owner(struct mount *);
int fstrans_setstate(struct mount *, enum fstrans_state);
enum fstrans_state fstrans_getstate(struct mount *);
-int fscow_establish(struct mount *, int (*)(void *, struct buf *), void *);
-int fscow_disestablish(struct mount *, int (*)(void *, struct buf *),
+int fscow_establish(struct mount *, int (*)(void *, struct buf *, bool),
void *);
-int fscow_run(struct buf *);
+int fscow_disestablish(struct mount *, int (*)(void *, struct buf *, bool),
+ void *);
+int fscow_run(struct buf *, bool);
int vfs_suspend(struct mount *, int);
void vfs_resume(struct mount *);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index e32acaee3cb..9fb4196c79c 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.287 2007/11/26 19:04:28 pooka Exp $ */
+/* $NetBSD: param.h,v 1.288 2007/12/02 13:56:19 hannken Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 499003800 /* NetBSD 4.99.38 */
+#define __NetBSD_Version__ 499003900 /* NetBSD 4.99.39 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 10572d506e1..ddbf630d51d 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vnode.h,v 1.176 2007/11/30 16:52:19 yamt Exp $ */
+/* $NetBSD: vnode.h,v 1.177 2007/12/02 13:56:20 hannken Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -577,10 +577,6 @@ int vn_extattr_get(struct vnode *, int, int, const char *, size_t *,
int vn_extattr_set(struct vnode *, int, int, const char *, size_t,
const void *, struct lwp *);
int vn_extattr_rm(struct vnode *, int, int, const char *, struct lwp *);
-int vn_cow_establish(struct vnode *, int (*)(void *, struct buf *),
- void *);
-int vn_cow_disestablish(struct vnode *, int (*)(void *, struct buf *),
- void *);
void vn_ra_allocctx(struct vnode *);
/* initialise global vnode management */
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index c2fe5fc834a..38bcdb90aa8 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_snapshot.c,v 1.54 2007/11/26 19:02:29 pooka Exp $ */
+/* $NetBSD: ffs_snapshot.c,v 1.55 2007/12/02 13:56:20 hannken Exp $ */
/*
* Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.54 2007/11/26 19:02:29 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.55 2007/12/02 13:56:20 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -116,7 +116,7 @@ static int readvnblk(struct vnode *, void *, ufs2_daddr_t);
static void si_mount_dtor(void *);
static struct snap_info *si_mount_init(struct mount *);
-static int ffs_copyonwrite(void *, struct buf *);
+static int ffs_copyonwrite(void *, struct buf *, bool);
static int readfsblk(struct vnode *, void *, ufs2_daddr_t);
static int writevnblk(struct vnode *, void *, ufs2_daddr_t);
static inline int cow_enter(void);
@@ -1883,7 +1883,7 @@ ffs_snapshot_unmount(struct mount *mp)
* copying the block if necessary.
*/
static int
-ffs_copyonwrite(void *v, struct buf *bp)
+ffs_copyonwrite(void *v, struct buf *bp, bool data_valid)
{
struct buf *ibp;
struct fs *fs;
@@ -1933,6 +1933,8 @@ ffs_copyonwrite(void *v, struct buf *bp)
/*
* Not in the precomputed list, so check the snapshots.
*/
+ if (data_valid && bp->b_bcount == fs->fs_bsize)
+ saved_data = bp->b_data;
retry:
gen = si->si_gen;
TAILQ_FOREACH(ip, &si->si_snapshots, i_nextsnap) {
@@ -2043,7 +2045,7 @@ retry:
* a crash, to ensure their integrity.
*/
mutex_exit(&si->si_lock);
- if (saved_data)
+ if (saved_data && saved_data != bp->b_data)
free(saved_data, M_UFSMNT);
if (snapshot_locked)
VOP_UNLOCK(vp, 0);