|
|
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_subr.c,v 1.2 1994/06/29 06:47:00 cgd 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_subr.c 8.2 (Berkeley) 9/21/93 ! 57: */ ! 58: ! 59: #include <sys/param.h> ! 60: #include <sys/namei.h> ! 61: #include <sys/vnode.h> ! 62: #include <sys/buf.h> ! 63: #include <sys/mount.h> ! 64: #include <sys/malloc.h> ! 65: #include <sys/proc.h> ! 66: ! 67: #include <ufs/ufs/quota.h> ! 68: #include <ufs/ufs/inode.h> ! 69: #include <ufs/lfs/lfs.h> ! 70: #include <ufs/lfs/lfs_extern.h> ! 71: ! 72: /* ! 73: * Return buffer with the contents of block "offset" from the beginning of ! 74: * directory "ip". If "res" is non-zero, fill it in with a pointer to the ! 75: * remaining space in the directory. ! 76: */ ! 77: int ! 78: lfs_blkatoff(ap) ! 79: struct vop_blkatoff_args /* { ! 80: struct vnode *a_vp; ! 81: off_t a_offset; ! 82: char **a_res; ! 83: struct buf **a_bpp; ! 84: } */ *ap; ! 85: { ! 86: register struct lfs *fs; ! 87: struct inode *ip; ! 88: struct buf *bp; ! 89: daddr_t lbn; ! 90: int bsize, error; ! 91: ! 92: ip = VTOI(ap->a_vp); ! 93: fs = ip->i_lfs; ! 94: lbn = lblkno(fs, ap->a_offset); ! 95: bsize = blksize(fs); ! 96: ! 97: *ap->a_bpp = NULL; ! 98: if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { ! 99: brelse(bp); ! 100: return (error); ! 101: } ! 102: if (ap->a_res) ! 103: *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset); ! 104: *ap->a_bpp = bp; ! 105: return (0); ! 106: } ! 107: ! 108: ! 109: /* ! 110: * lfs_seglock -- ! 111: * Single thread the segment writer. ! 112: */ ! 113: void ! 114: lfs_seglock(fs, flags) ! 115: struct lfs *fs; ! 116: unsigned long flags; ! 117: { ! 118: struct segment *sp; ! 119: int s; ! 120: ! 121: if (fs->lfs_seglock) ! 122: if (fs->lfs_lockpid == curproc->p_pid) { ! 123: ++fs->lfs_seglock; ! 124: fs->lfs_sp->seg_flags |= flags; ! 125: return; ! 126: } else while (fs->lfs_seglock) ! 127: (void)tsleep(&fs->lfs_seglock, PRIBIO + 1, ! 128: "lfs seglock", 0); ! 129: ! 130: fs->lfs_seglock = 1; ! 131: fs->lfs_lockpid = curproc->p_pid; ! 132: ! 133: // sp = fs->lfs_sp = malloc(sizeof(struct segment), M_SEGMENT, M_WAITOK); ! 134: MALLOC(fs->lfs_sp, struct segment *, sizeof(struct segment), M_SEGMENT, M_WAITOK); ! 135: sp = fs->lfs_sp; ! 136: // sp->bpp = malloc(((LFS_SUMMARY_SIZE - sizeof(SEGSUM)) / ! 137: // sizeof(daddr_t) + 1) * sizeof(struct buf *), M_SEGMENT, M_WAITOK); ! 138: MALLOC(sp->bpp, caddr_t, ((LFS_SUMMARY_SIZE - sizeof(SEGSUM)) / ! 139: sizeof(daddr_t) + 1) * sizeof(struct buf *), M_SEGMENT, M_WAITOK); ! 140: sp->seg_flags = flags; ! 141: sp->vp = NULL; ! 142: (void) lfs_initseg(fs); ! 143: ! 144: /* ! 145: * Keep a cumulative count of the outstanding I/O operations. If the ! 146: * disk drive catches up with us it could go to zero before we finish, ! 147: * so we artificially increment it by one until we've scheduled all of ! 148: * the writes we intend to do. ! 149: */ ! 150: s = splbio(); ! 151: ++fs->lfs_iocount; ! 152: splx(s); ! 153: } ! 154: /* ! 155: * lfs_segunlock -- ! 156: * Single thread the segment writer. ! 157: */ ! 158: void ! 159: lfs_segunlock(fs) ! 160: struct lfs *fs; ! 161: { ! 162: struct segment *sp; ! 163: unsigned long sync, ckp; ! 164: int s; ! 165: ! 166: if (fs->lfs_seglock == 1) { ! 167: ! 168: sp = fs->lfs_sp; ! 169: sync = sp->seg_flags & SEGM_SYNC; ! 170: ckp = sp->seg_flags & SEGM_CKP; ! 171: if (sp->bpp != sp->cbpp) { ! 172: /* Free allocated segment summary */ ! 173: fs->lfs_offset -= LFS_SUMMARY_SIZE / DEV_BSIZE; ! 174: brelvp(*sp->bpp); ! 175: free((*sp->bpp)->b_data, M_SEGMENT); ! 176: free(*sp->bpp, M_SEGMENT); ! 177: } else ! 178: printf ("unlock to 0 with no summary"); ! 179: free(sp->bpp, M_SEGMENT); ! 180: free(sp, M_SEGMENT); ! 181: ! 182: /* ! 183: * If the I/O count is non-zero, sleep until it reaches zero. ! 184: * At the moment, the user's process hangs around so we can ! 185: * sleep. ! 186: */ ! 187: s = splbio(); ! 188: --fs->lfs_iocount; ! 189: /* ! 190: * We let checkpoints happen asynchronously. That means ! 191: * that during recovery, we have to roll forward between ! 192: * the two segments described by the first and second ! 193: * superblocks to make sure that the checkpoint described ! 194: * by a superblock completed. ! 195: */ ! 196: if (sync && fs->lfs_iocount) ! 197: (void)tsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs vflush", 0); ! 198: splx(s); ! 199: if (ckp) { ! 200: fs->lfs_nactive = 0; ! 201: lfs_writesuper(fs); ! 202: } ! 203: --fs->lfs_seglock; ! 204: fs->lfs_lockpid = 0; ! 205: wakeup(&fs->lfs_seglock); ! 206: } else if (fs->lfs_seglock == 0) { ! 207: panic ("Seglock not held"); ! 208: } else { ! 209: --fs->lfs_seglock; ! 210: } ! 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.