Add functions to deal with keeping track of commit ranges.

This commit is contained in:
fvdl 2000-09-19 22:13:55 +00:00
parent 45460eabe0
commit 9ed021b771

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_subs.c,v 1.82 2000/09/19 17:04:51 bjh21 Exp $ */
/* $NetBSD: nfs_subs.c,v 1.83 2000/09/19 22:13:55 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@ -38,6 +38,41 @@
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
*/
/*
* Copyright 2000 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Frank van der Linden for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs_nfs.h"
#include "opt_nfs.h"
#include "opt_nfsserver.h"
@ -1395,25 +1430,6 @@ nfs_invaldircache(vp, forcefree)
void
nfs_init()
{
#if !defined(alpha) && !defined(_LP64) && defined(DIAGNOSTIC)
/*
* Check to see if major data structures haven't bloated.
*/
if (sizeof (struct nfsnode) > NFS_NODEALLOC) {
printf("struct nfsnode bloated (> %dbytes)\n", NFS_NODEALLOC);
printf("Try reducing NFS_SMALLFH\n");
}
if (sizeof (struct nfssvc_sock) > NFS_SVCALLOC) {
printf("struct nfssvc_sock bloated (> %dbytes)\n",NFS_SVCALLOC);
printf("Try reducing NFS_UIDHASHSIZ\n");
}
if (sizeof (struct nfsuid) > NFS_UIDALLOC) {
printf("struct nfsuid bloated (> %dbytes)\n",NFS_UIDALLOC);
printf("Try unionizing the nu_nickname and nu_flag fields\n");
}
#endif
nfsrtt.pos = 0;
rpc_vers = txdr_unsigned(RPC_VER2);
rpc_call = txdr_unsigned(RPC_CALL);
@ -2356,6 +2372,7 @@ nfs_clearcommit(mp)
{
struct vnode *vp, *nvp;
struct buf *bp, *nbp;
struct nfsnode *np;
int s;
s = splbio();
@ -2363,6 +2380,11 @@ loop:
for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) {
if (vp->v_mount != mp) /* Paranoia */
goto loop;
np = VTONFS(vp);
np->n_pushlo = np->n_pushhi = np->n_pushedlo =
np->n_pushedhi = 0;
np->n_commitflags &=
~(NFS_COMMIT_PUSH_VALID | NFS_COMMIT_PUSHED_VALID);
nvp = vp->v_mntvnodes.le_next;
for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
nbp = bp->b_vnbufs.le_next;
@ -2374,6 +2396,193 @@ loop:
splx(s);
}
void
nfs_merge_commit_ranges(vp)
struct vnode *vp;
{
struct nfsnode *np = VTONFS(vp);
if (!(np->n_commitflags & NFS_COMMIT_PUSHED_VALID)) {
np->n_pushedlo = np->n_pushlo;
np->n_pushedhi = np->n_pushhi;
np->n_commitflags |= NFS_COMMIT_PUSHED_VALID;
} else {
if (np->n_pushlo < np->n_pushedlo)
np->n_pushedlo = np->n_pushlo;
if (np->n_pushhi > np->n_pushedhi)
np->n_pushedhi = np->n_pushhi;
}
np->n_pushlo = np->n_pushhi = 0;
np->n_commitflags &= ~NFS_COMMIT_PUSH_VALID;
#ifdef fvdl_debug
printf("merge: committed: %u - %u\n", (unsigned)np->n_pushedlo,
(unsigned)np->n_pushedhi);
#endif
}
int
nfs_in_committed_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
if (!(np->n_commitflags & NFS_COMMIT_PUSHED_VALID))
return 0;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
return (lo >= np->n_pushedlo && hi <= np->n_pushedhi);
}
int
nfs_in_tobecommitted_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
if (!(np->n_commitflags & NFS_COMMIT_PUSH_VALID))
return 0;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
return (lo >= np->n_pushlo && hi <= np->n_pushhi);
}
void
nfs_add_committed_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
if (!(np->n_commitflags & NFS_COMMIT_PUSHED_VALID)) {
np->n_pushedlo = lo;
np->n_pushedhi = hi;
np->n_commitflags |= NFS_COMMIT_PUSHED_VALID;
} else {
if (hi > np->n_pushedhi)
np->n_pushedhi = hi;
if (lo < np->n_pushedlo)
np->n_pushedlo = lo;
}
#ifdef fvdl_debug
printf("add: committed: %u - %u\n", (unsigned)np->n_pushedlo,
(unsigned)np->n_pushedhi);
#endif
}
void
nfs_del_committed_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
if (!(np->n_commitflags & NFS_COMMIT_PUSHED_VALID))
return;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
if (lo > np->n_pushedhi || hi < np->n_pushedlo)
return;
if (lo <= np->n_pushedlo)
np->n_pushedlo = hi;
else if (hi >= np->n_pushedhi)
np->n_pushedhi = lo;
else {
/*
* XXX There's only one range. If the deleted range
* is in the middle, pick the largest of the
* contiguous ranges that it leaves.
*/
if ((np->n_pushedlo - lo) > (hi - np->n_pushedhi))
np->n_pushedhi = lo;
else
np->n_pushedlo = hi;
}
#ifdef fvdl_debug
printf("del: committed: %u - %u\n", (unsigned)np->n_pushedlo,
(unsigned)np->n_pushedhi);
#endif
}
void
nfs_add_tobecommitted_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
if (!(np->n_commitflags & NFS_COMMIT_PUSH_VALID)) {
np->n_pushlo = lo;
np->n_pushhi = hi;
np->n_commitflags |= NFS_COMMIT_PUSH_VALID;
} else {
if (lo < np->n_pushlo)
np->n_pushlo = lo;
if (hi > np->n_pushhi)
np->n_pushhi = hi;
}
#ifdef fvdl_debug
printf("add: tobecommitted: %u - %u\n", (unsigned)np->n_pushlo,
(unsigned)np->n_pushhi);
#endif
}
void
nfs_del_tobecommitted_range(vp, bp)
struct vnode *vp;
struct buf *bp;
{
struct nfsnode *np = VTONFS(vp);
off_t lo, hi;
if (!(np->n_commitflags & NFS_COMMIT_PUSH_VALID))
return;
lo = (off_t)bp->b_blkno * DEV_BSIZE;
hi = lo + bp->b_dirtyend;
if (lo > np->n_pushhi || hi < np->n_pushlo)
return;
if (lo <= np->n_pushlo)
np->n_pushlo = hi;
else if (hi >= np->n_pushhi)
np->n_pushhi = lo;
else {
/*
* XXX There's only one range. If the deleted range
* is in the middle, pick the largest of the
* contiguous ranges that it leaves.
*/
if ((np->n_pushlo - lo) > (hi - np->n_pushhi))
np->n_pushhi = lo;
else
np->n_pushlo = hi;
}
#ifdef fvdl_debug
printf("del: tobecommitted: %u - %u\n", (unsigned)np->n_pushlo,
(unsigned)np->n_pushhi);
#endif
}
/*
* Map errnos to NFS error numbers. For Version 3 also filter out error
* numbers not specified for the associated procedure.