diff options
| author | hannken <hannken@NetBSD.org> | 2007-12-02 13:56:15 +0000 |
|---|---|---|
| committer | hannken <hannken@NetBSD.org> | 2007-12-02 13:56:15 +0000 |
| commit | d556dc98b0f75faaa4eff532000a425bb669dd50 (patch) | |
| tree | 57708fbc87a2d1c54d66576841e47901a53fdf48 /sys | |
| parent | 587600728d3d1bdb8ea4937aaf2f510a046665a2 (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.c | 8 | ||||
| -rw-r--r-- | sys/kern/vfs_bio.c | 5 | ||||
| -rw-r--r-- | sys/kern/vfs_trans.c | 27 | ||||
| -rw-r--r-- | sys/kern/vfs_vnops.c | 38 | ||||
| -rw-r--r-- | sys/miscfs/specfs/spec_vnops.c | 6 | ||||
| -rw-r--r-- | sys/sys/buf.h | 5 | ||||
| -rw-r--r-- | sys/sys/fstrans.h | 9 | ||||
| -rw-r--r-- | sys/sys/param.h | 4 | ||||
| -rw-r--r-- | sys/sys/vnode.h | 6 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 12 |
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); |
