|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* $NetBSD: lfs_bio.c,v 1.3 1995/01/18 06:19:52 mycroft Exp $ */ ! 26: ! 27: /* ! 28: * Copyright (c) 1991, 1993 ! 29: * The Regents of the University of California. All rights reserved. ! 30: * ! 31: * Redistribution and use in source and binary forms, with or without ! 32: * modification, are permitted provided that the following conditions ! 33: * are met: ! 34: * 1. Redistributions of source code must retain the above copyright ! 35: * notice, this list of conditions and the following disclaimer. ! 36: * 2. Redistributions in binary form must reproduce the above copyright ! 37: * notice, this list of conditions and the following disclaimer in the ! 38: * documentation and/or other materials provided with the distribution. ! 39: * 3. All advertising materials mentioning features or use of this software ! 40: * must display the following acknowledgement: ! 41: * This product includes software developed by the University of ! 42: * California, Berkeley and its contributors. ! 43: * 4. Neither the name of the University nor the names of its contributors ! 44: * may be used to endorse or promote products derived from this software ! 45: * without specific prior written permission. ! 46: * ! 47: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 48: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 49: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 50: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 51: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 52: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 53: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 54: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 55: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 56: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 57: * SUCH DAMAGE. ! 58: * ! 59: * @(#)lfs_bio.c 8.4 (Berkeley) 12/30/93 ! 60: */ ! 61: ! 62: #include <sys/param.h> ! 63: #include <sys/proc.h> ! 64: #include <sys/buf.h> ! 65: #include <sys/vnode.h> ! 66: #include <sys/resourcevar.h> ! 67: #include <sys/mount.h> ! 68: #include <sys/kernel.h> ! 69: ! 70: #include <ufs/ufs/quota.h> ! 71: #include <ufs/ufs/inode.h> ! 72: #include <ufs/ufs/ufsmount.h> ! 73: ! 74: #include <ufs/lfs/lfs.h> ! 75: #include <ufs/lfs/lfs_extern.h> ! 76: ! 77: /* ! 78: * LFS block write function. ! 79: * ! 80: * XXX ! 81: * No write cost accounting is done. ! 82: * This is almost certainly wrong for synchronous operations and NFS. ! 83: */ ! 84: int lfs_allclean_wakeup; /* Cleaner wakeup address. */ ! 85: int locked_queue_count; /* XXX Count of locked-down buffers. */ ! 86: int lfs_writing; /* Set if already kicked off a writer ! 87: because of buffer space */ ! 88: /* ! 89: #define WRITE_THRESHHOLD ((nbuf >> 2) - 10) ! 90: #define WAIT_THRESHHOLD ((nbuf >> 1) - 10) ! 91: */ ! 92: #define WAIT_THRESHHOLD (nbuf - (nbuf >> 2) - 10) ! 93: #define WRITE_THRESHHOLD ((nbuf >> 1) - 10) ! 94: #define LFS_BUFWAIT 2 ! 95: ! 96: int ! 97: lfs_bwrite(ap) ! 98: struct vop_bwrite_args /* { ! 99: struct buf *a_bp; ! 100: } */ *ap; ! 101: { ! 102: register struct buf *bp = ap->a_bp; ! 103: struct lfs *fs; ! 104: struct inode *ip; ! 105: int error, s; ! 106: ! 107: /* ! 108: * Set the delayed write flag and use reassignbuf to move the buffer ! 109: * from the clean list to the dirty one. ! 110: * ! 111: * Set the B_LOCKED flag and unlock the buffer, causing brelse to move ! 112: * the buffer onto the LOCKED free list. This is necessary, otherwise ! 113: * getnewbuf() would try to reclaim the buffers using bawrite, which ! 114: * isn't going to work. ! 115: * ! 116: * XXX we don't let meta-data writes run out of space because they can ! 117: * come from the segment writer. We need to make sure that there is ! 118: * enough space reserved so that there's room to write meta-data ! 119: * blocks. ! 120: */ ! 121: if (!(bp->b_flags & B_LOCKED)) { ! 122: fs = VFSTOUFS(bp->b_vp->v_mount)->um_lfs; ! 123: while (!LFS_FITS(fs, fsbtodb(fs, 1)) && !IS_IFILE(bp) && ! 124: bp->b_lblkno > 0) { ! 125: /* Out of space, need cleaner to run */ ! 126: wakeup(&lfs_allclean_wakeup); ! 127: if (error = tsleep(&fs->lfs_avail, PCATCH | PUSER, ! 128: "cleaner", NULL)) { ! 129: brelse(bp); ! 130: return (error); ! 131: } ! 132: } ! 133: ip = VTOI((bp)->b_vp); ! 134: if (!(ip->i_flag & IN_MODIFIED)) ! 135: ++fs->lfs_uinodes; ! 136: ip->i_flag |= IN_CHANGE | IN_MODIFIED | IN_UPDATE; ! 137: fs->lfs_avail -= fsbtodb(fs, 1); ! 138: ++locked_queue_count; ! 139: bp->b_flags |= B_DELWRI | B_LOCKED; ! 140: bp->b_flags &= ~(B_READ | B_ERROR); ! 141: s = splbio(); ! 142: reassignbuf(bp, bp->b_vp); ! 143: splx(s); ! 144: } ! 145: brelse(bp); ! 146: return (0); ! 147: } ! 148: ! 149: /* ! 150: * XXX ! 151: * This routine flushes buffers out of the B_LOCKED queue when LFS has too ! 152: * many locked down. Eventually the pageout daemon will simply call LFS ! 153: * when pages need to be reclaimed. Note, we have one static count of locked ! 154: * buffers, so we can't have more than a single file system. To make this ! 155: * work for multiple file systems, put the count into the mount structure. ! 156: */ ! 157: void ! 158: lfs_flush() ! 159: { ! 160: register struct mount *mp; ! 161: ! 162: #ifdef DOSTATS ! 163: ++lfs_stats.write_exceeded; ! 164: #endif ! 165: if (lfs_writing) ! 166: return; ! 167: lfs_writing = 1; ! 168: for (mp = mountlist.cqh_first; mp != (void *)&mountlist; ! 169: mp = mp->mnt_list.cqe_next) { ! 170: /* The lock check below is to avoid races with unmount. */ ! 171: if (!strcmp(&mp->mnt_stat.f_fstypename[0], MOUNT_LFS) && ! 172: (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_UNMOUNT)) == 0 && ! 173: !((((struct ufsmount *)mp->mnt_data))->ufsmount_u.lfs)->lfs_dirops ) { ! 174: /* ! 175: * We set the queue to 0 here because we are about to ! 176: * write all the dirty buffers we have. If more come ! 177: * in while we're writing the segment, they may not ! 178: * get written, so we want the count to reflect these ! 179: * new writes after the segwrite completes. ! 180: */ ! 181: #ifdef DOSTATS ! 182: ++lfs_stats.flush_invoked; ! 183: #endif ! 184: lfs_segwrite(mp, 0); ! 185: } ! 186: } ! 187: lfs_writing = 0; ! 188: } ! 189: ! 190: int ! 191: lfs_check(vp, blkno) ! 192: struct vnode *vp; ! 193: daddr_t blkno; ! 194: { ! 195: extern int lfs_allclean_wakeup; ! 196: int error; ! 197: ! 198: error = 0; ! 199: if (incore(vp, blkno)) ! 200: return (0); ! 201: if (locked_queue_count > WRITE_THRESHHOLD) ! 202: lfs_flush(); ! 203: ! 204: /* If out of buffers, wait on writer */ ! 205: while (locked_queue_count > WAIT_THRESHHOLD) { ! 206: #ifdef DOSTATS ! 207: ++lfs_stats.wait_exceeded; ! 208: #endif ! 209: error = tsleep(&locked_queue_count, PCATCH | PUSER, "buffers", ! 210: hz * LFS_BUFWAIT); ! 211: } ! 212: ! 213: return (error); ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.