|
|
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.