1/* 2 * modified for Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/* 8 * Copyright (c) 1982, 1986, 1989, 1993 9 * The Regents of the University of California. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93
| 1/* 2 * modified for Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/* 8 * Copyright (c) 1982, 1986, 1989, 1993 9 * The Regents of the University of California. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93
|
40 * $FreeBSD: head/sys/gnu/fs/ext2fs/ext2_balloc.c 96752 2002-05-16 19:43:28Z iedowse $
| 40 * $FreeBSD: head/sys/gnu/fs/ext2fs/ext2_balloc.c 96877 2002-05-18 19:12:38Z iedowse $
|
41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bio.h> 46#include <sys/buf.h> 47#include <sys/lock.h> 48#include <sys/ucred.h> 49#include <sys/vnode.h> 50 51#include <gnu/ext2fs/inode.h> 52#include <gnu/ext2fs/ext2_fs.h> 53#include <gnu/ext2fs/ext2_fs_sb.h> 54#include <gnu/ext2fs/fs.h> 55#include <gnu/ext2fs/ext2_extern.h> 56 57/* 58 * Balloc defines the structure of file system storage 59 * by allocating the physical blocks on a device given 60 * the inode and the logical block number in a file. 61 */ 62int 63ext2_balloc(ip, bn, size, cred, bpp, flags) 64 struct inode *ip;
| 41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bio.h> 46#include <sys/buf.h> 47#include <sys/lock.h> 48#include <sys/ucred.h> 49#include <sys/vnode.h> 50 51#include <gnu/ext2fs/inode.h> 52#include <gnu/ext2fs/ext2_fs.h> 53#include <gnu/ext2fs/ext2_fs_sb.h> 54#include <gnu/ext2fs/fs.h> 55#include <gnu/ext2fs/ext2_extern.h> 56 57/* 58 * Balloc defines the structure of file system storage 59 * by allocating the physical blocks on a device given 60 * the inode and the logical block number in a file. 61 */ 62int 63ext2_balloc(ip, bn, size, cred, bpp, flags) 64 struct inode *ip;
|
65 daddr_t bn;
| 65 int32_t bn;
|
66 int size; 67 struct ucred *cred; 68 struct buf **bpp; 69 int flags; 70{ 71 struct ext2_sb_info *fs;
| 66 int size; 67 struct ucred *cred; 68 struct buf **bpp; 69 int flags; 70{ 71 struct ext2_sb_info *fs;
|
72 daddr_t nb;
| 72 int32_t nb;
|
73 struct buf *bp, *nbp; 74 struct vnode *vp = ITOV(ip); 75 struct indir indirs[NIADDR + 2];
| 73 struct buf *bp, *nbp; 74 struct vnode *vp = ITOV(ip); 75 struct indir indirs[NIADDR + 2];
|
76 daddr_t newb, lbn, *bap, pref;
| 76 int32_t newb, lbn, *bap, pref;
|
77 int osize, nsize, num, i, error; 78/* 79ext2_debug("ext2_balloc called (%d, %d, %d)\n", 80 ip->i_number, (int)bn, (int)size); 81*/ 82 *bpp = NULL; 83 if (bn < 0) 84 return (EFBIG); 85 fs = ip->i_e2fs; 86 lbn = bn; 87 88 /* 89 * check if this is a sequential block allocation. 90 * If so, increment next_alloc fields to allow ext2_blkpref 91 * to make a good guess 92 */ 93 if (lbn == ip->i_next_alloc_block + 1) { 94 ip->i_next_alloc_block++; 95 ip->i_next_alloc_goal++; 96 } 97 98 /* 99 * The first NDADDR blocks are direct blocks 100 */ 101 if (bn < NDADDR) { 102 nb = ip->i_db[bn]; 103 /* no new block is to be allocated, and no need to expand 104 the file */ 105 if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) { 106 error = bread(vp, bn, fs->s_blocksize, NOCRED, &bp); 107 if (error) { 108 brelse(bp); 109 return (error); 110 } 111 bp->b_blkno = fsbtodb(fs, nb); 112 *bpp = bp; 113 return (0); 114 } 115 if (nb != 0) { 116 /* 117 * Consider need to reallocate a fragment. 118 */ 119 osize = fragroundup(fs, blkoff(fs, ip->i_size)); 120 nsize = fragroundup(fs, size); 121 if (nsize <= osize) { 122 error = bread(vp, bn, osize, NOCRED, &bp); 123 if (error) { 124 brelse(bp); 125 return (error); 126 } 127 bp->b_blkno = fsbtodb(fs, nb); 128 } else { 129 /* Godmar thinks: this shouldn't happen w/o fragments */ 130 printf("nsize %d(%d) > osize %d(%d) nb %d\n", 131 (int)nsize, (int)size, (int)osize, 132 (int)ip->i_size, (int)nb); 133 panic( 134 "ext2_balloc: Something is terribly wrong"); 135/* 136 * please note there haven't been any changes from here on - 137 * FFS seems to work. 138 */ 139 } 140 } else { 141 if (ip->i_size < (bn + 1) * fs->s_blocksize) 142 nsize = fragroundup(fs, size); 143 else 144 nsize = fs->s_blocksize; 145 error = ext2_alloc(ip, bn, 146 ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0), 147 nsize, cred, &newb); 148 if (error) 149 return (error); 150 bp = getblk(vp, bn, nsize, 0, 0); 151 bp->b_blkno = fsbtodb(fs, newb); 152 if (flags & B_CLRBUF) 153 vfs_bio_clrbuf(bp); 154 } 155 ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); 156 ip->i_flag |= IN_CHANGE | IN_UPDATE; 157 *bpp = bp; 158 return (0); 159 } 160 /* 161 * Determine the number of levels of indirection. 162 */ 163 pref = 0; 164 if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0) 165 return(error); 166#if DIAGNOSTIC 167 if (num < 1) 168 panic ("ext2_balloc: ext2_getlbns returned indirect block"); 169#endif 170 /* 171 * Fetch the first indirect block allocating if necessary. 172 */ 173 --num; 174 nb = ip->i_ib[indirs[0].in_off]; 175 if (nb == 0) { 176#if 0
| 77 int osize, nsize, num, i, error; 78/* 79ext2_debug("ext2_balloc called (%d, %d, %d)\n", 80 ip->i_number, (int)bn, (int)size); 81*/ 82 *bpp = NULL; 83 if (bn < 0) 84 return (EFBIG); 85 fs = ip->i_e2fs; 86 lbn = bn; 87 88 /* 89 * check if this is a sequential block allocation. 90 * If so, increment next_alloc fields to allow ext2_blkpref 91 * to make a good guess 92 */ 93 if (lbn == ip->i_next_alloc_block + 1) { 94 ip->i_next_alloc_block++; 95 ip->i_next_alloc_goal++; 96 } 97 98 /* 99 * The first NDADDR blocks are direct blocks 100 */ 101 if (bn < NDADDR) { 102 nb = ip->i_db[bn]; 103 /* no new block is to be allocated, and no need to expand 104 the file */ 105 if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) { 106 error = bread(vp, bn, fs->s_blocksize, NOCRED, &bp); 107 if (error) { 108 brelse(bp); 109 return (error); 110 } 111 bp->b_blkno = fsbtodb(fs, nb); 112 *bpp = bp; 113 return (0); 114 } 115 if (nb != 0) { 116 /* 117 * Consider need to reallocate a fragment. 118 */ 119 osize = fragroundup(fs, blkoff(fs, ip->i_size)); 120 nsize = fragroundup(fs, size); 121 if (nsize <= osize) { 122 error = bread(vp, bn, osize, NOCRED, &bp); 123 if (error) { 124 brelse(bp); 125 return (error); 126 } 127 bp->b_blkno = fsbtodb(fs, nb); 128 } else { 129 /* Godmar thinks: this shouldn't happen w/o fragments */ 130 printf("nsize %d(%d) > osize %d(%d) nb %d\n", 131 (int)nsize, (int)size, (int)osize, 132 (int)ip->i_size, (int)nb); 133 panic( 134 "ext2_balloc: Something is terribly wrong"); 135/* 136 * please note there haven't been any changes from here on - 137 * FFS seems to work. 138 */ 139 } 140 } else { 141 if (ip->i_size < (bn + 1) * fs->s_blocksize) 142 nsize = fragroundup(fs, size); 143 else 144 nsize = fs->s_blocksize; 145 error = ext2_alloc(ip, bn, 146 ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0), 147 nsize, cred, &newb); 148 if (error) 149 return (error); 150 bp = getblk(vp, bn, nsize, 0, 0); 151 bp->b_blkno = fsbtodb(fs, newb); 152 if (flags & B_CLRBUF) 153 vfs_bio_clrbuf(bp); 154 } 155 ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); 156 ip->i_flag |= IN_CHANGE | IN_UPDATE; 157 *bpp = bp; 158 return (0); 159 } 160 /* 161 * Determine the number of levels of indirection. 162 */ 163 pref = 0; 164 if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0) 165 return(error); 166#if DIAGNOSTIC 167 if (num < 1) 168 panic ("ext2_balloc: ext2_getlbns returned indirect block"); 169#endif 170 /* 171 * Fetch the first indirect block allocating if necessary. 172 */ 173 --num; 174 nb = ip->i_ib[indirs[0].in_off]; 175 if (nb == 0) { 176#if 0
|
177 pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0);
| 177 pref = ext2_blkpref(ip, lbn, 0, (int32_t *)0, 0);
|
178#else 179 /* see the comment by ext2_blkpref. What we do here is 180 to pretend that it'd be good for a block holding indirect 181 pointers to be allocated near its predecessor in terms 182 of indirection, or the last direct block. 183 We shamelessly exploit the fact that i_ib immediately 184 follows i_db. 185 Godmar thinks it make sense to allocate i_ib[0] immediately 186 after i_db[11], but it's not utterly clear whether this also 187 applies to i_ib[1] and i_ib[0] 188 */ 189 190 pref = ext2_blkpref(ip, lbn, indirs[0].in_off + 191 EXT2_NDIR_BLOCKS, &ip->i_db[0], 0); 192#endif 193 if ((error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, 194 cred, &newb)) != 0) 195 return (error); 196 nb = newb; 197 bp = getblk(vp, indirs[1].in_lbn, fs->s_blocksize, 0, 0); 198 bp->b_blkno = fsbtodb(fs, newb); 199 vfs_bio_clrbuf(bp); 200 /* 201 * Write synchronously so that indirect blocks 202 * never point at garbage. 203 */ 204 if ((error = bwrite(bp)) != 0) { 205 ext2_blkfree(ip, nb, fs->s_blocksize); 206 return (error); 207 } 208 ip->i_ib[indirs[0].in_off] = newb; 209 ip->i_flag |= IN_CHANGE | IN_UPDATE; 210 } 211 /* 212 * Fetch through the indirect blocks, allocating as necessary. 213 */ 214 for (i = 1;;) { 215 error = bread(vp, 216 indirs[i].in_lbn, (int)fs->s_blocksize, NOCRED, &bp); 217 if (error) { 218 brelse(bp); 219 return (error); 220 }
| 178#else 179 /* see the comment by ext2_blkpref. What we do here is 180 to pretend that it'd be good for a block holding indirect 181 pointers to be allocated near its predecessor in terms 182 of indirection, or the last direct block. 183 We shamelessly exploit the fact that i_ib immediately 184 follows i_db. 185 Godmar thinks it make sense to allocate i_ib[0] immediately 186 after i_db[11], but it's not utterly clear whether this also 187 applies to i_ib[1] and i_ib[0] 188 */ 189 190 pref = ext2_blkpref(ip, lbn, indirs[0].in_off + 191 EXT2_NDIR_BLOCKS, &ip->i_db[0], 0); 192#endif 193 if ((error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, 194 cred, &newb)) != 0) 195 return (error); 196 nb = newb; 197 bp = getblk(vp, indirs[1].in_lbn, fs->s_blocksize, 0, 0); 198 bp->b_blkno = fsbtodb(fs, newb); 199 vfs_bio_clrbuf(bp); 200 /* 201 * Write synchronously so that indirect blocks 202 * never point at garbage. 203 */ 204 if ((error = bwrite(bp)) != 0) { 205 ext2_blkfree(ip, nb, fs->s_blocksize); 206 return (error); 207 } 208 ip->i_ib[indirs[0].in_off] = newb; 209 ip->i_flag |= IN_CHANGE | IN_UPDATE; 210 } 211 /* 212 * Fetch through the indirect blocks, allocating as necessary. 213 */ 214 for (i = 1;;) { 215 error = bread(vp, 216 indirs[i].in_lbn, (int)fs->s_blocksize, NOCRED, &bp); 217 if (error) { 218 brelse(bp); 219 return (error); 220 }
|
221 bap = (daddr_t *)bp->b_data;
| 221 bap = (int32_t *)bp->b_data;
|
222 nb = bap[indirs[i].in_off]; 223 if (i == num) 224 break; 225 i += 1; 226 if (nb != 0) { 227 brelse(bp); 228 continue; 229 } 230 if (pref == 0) 231#if 1 232 /* see the comment above and by ext2_blkpref 233 * I think this implements Linux policy, but 234 * does it really make sense to allocate to 235 * block containing pointers together ? 236 * Also, will it ever succeed ? 237 */ 238 pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap, 239 bp->b_lblkno); 240#else
| 222 nb = bap[indirs[i].in_off]; 223 if (i == num) 224 break; 225 i += 1; 226 if (nb != 0) { 227 brelse(bp); 228 continue; 229 } 230 if (pref == 0) 231#if 1 232 /* see the comment above and by ext2_blkpref 233 * I think this implements Linux policy, but 234 * does it really make sense to allocate to 235 * block containing pointers together ? 236 * Also, will it ever succeed ? 237 */ 238 pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap, 239 bp->b_lblkno); 240#else
|
241 pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0);
| 241 pref = ext2_blkpref(ip, lbn, 0, (int32_t *)0, 0);
|
242#endif 243 if ((error = 244 ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) { 245 brelse(bp); 246 return (error); 247 } 248 nb = newb; 249 nbp = getblk(vp, indirs[i].in_lbn, fs->s_blocksize, 0, 0); 250 nbp->b_blkno = fsbtodb(fs, nb); 251 vfs_bio_clrbuf(nbp); 252 /* 253 * Write synchronously so that indirect blocks 254 * never point at garbage. 255 */ 256 if ((error = bwrite(nbp)) != 0) { 257 ext2_blkfree(ip, nb, fs->s_blocksize); 258 brelse(bp); 259 return (error); 260 } 261 bap[indirs[i - 1].in_off] = nb; 262 /* 263 * If required, write synchronously, otherwise use 264 * delayed write. 265 */ 266 if (flags & B_SYNC) { 267 bwrite(bp); 268 } else { 269 bdwrite(bp); 270 } 271 } 272 /* 273 * Get the data block, allocating if necessary. 274 */ 275 if (nb == 0) { 276 pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0], 277 bp->b_lblkno); 278 if ((error = ext2_alloc(ip, 279 lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) { 280 brelse(bp); 281 return (error); 282 } 283 nb = newb; 284 nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); 285 nbp->b_blkno = fsbtodb(fs, nb); 286 if (flags & B_CLRBUF) 287 vfs_bio_clrbuf(nbp); 288 bap[indirs[i].in_off] = nb; 289 /* 290 * If required, write synchronously, otherwise use 291 * delayed write. 292 */ 293 if (flags & B_SYNC) { 294 bwrite(bp); 295 } else { 296 bdwrite(bp); 297 } 298 *bpp = nbp; 299 return (0); 300 } 301 brelse(bp); 302 if (flags & B_CLRBUF) { 303 error = bread(vp, lbn, (int)fs->s_blocksize, NOCRED, &nbp); 304 if (error) { 305 brelse(nbp); 306 return (error); 307 } 308 } else { 309 nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); 310 nbp->b_blkno = fsbtodb(fs, nb); 311 } 312 *bpp = nbp; 313 return (0); 314}
| 242#endif 243 if ((error = 244 ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) { 245 brelse(bp); 246 return (error); 247 } 248 nb = newb; 249 nbp = getblk(vp, indirs[i].in_lbn, fs->s_blocksize, 0, 0); 250 nbp->b_blkno = fsbtodb(fs, nb); 251 vfs_bio_clrbuf(nbp); 252 /* 253 * Write synchronously so that indirect blocks 254 * never point at garbage. 255 */ 256 if ((error = bwrite(nbp)) != 0) { 257 ext2_blkfree(ip, nb, fs->s_blocksize); 258 brelse(bp); 259 return (error); 260 } 261 bap[indirs[i - 1].in_off] = nb; 262 /* 263 * If required, write synchronously, otherwise use 264 * delayed write. 265 */ 266 if (flags & B_SYNC) { 267 bwrite(bp); 268 } else { 269 bdwrite(bp); 270 } 271 } 272 /* 273 * Get the data block, allocating if necessary. 274 */ 275 if (nb == 0) { 276 pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0], 277 bp->b_lblkno); 278 if ((error = ext2_alloc(ip, 279 lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) { 280 brelse(bp); 281 return (error); 282 } 283 nb = newb; 284 nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); 285 nbp->b_blkno = fsbtodb(fs, nb); 286 if (flags & B_CLRBUF) 287 vfs_bio_clrbuf(nbp); 288 bap[indirs[i].in_off] = nb; 289 /* 290 * If required, write synchronously, otherwise use 291 * delayed write. 292 */ 293 if (flags & B_SYNC) { 294 bwrite(bp); 295 } else { 296 bdwrite(bp); 297 } 298 *bpp = nbp; 299 return (0); 300 } 301 brelse(bp); 302 if (flags & B_CLRBUF) { 303 error = bread(vp, lbn, (int)fs->s_blocksize, NOCRED, &nbp); 304 if (error) { 305 brelse(nbp); 306 return (error); 307 } 308 } else { 309 nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); 310 nbp->b_blkno = fsbtodb(fs, nb); 311 } 312 *bpp = nbp; 313 return (0); 314}
|