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