1 /* $OpenBSD: ext2fs_alloc.c,v 1.39 2021/05/16 15:10:20 deraadt Exp $ */
2 /* $NetBSD: ext2fs_alloc.c,v 1.10 2001/07/05 08:38:27 toshii Exp $ */
3
4 /*
5 * Copyright (c) 1997 Manuel Bouyer.
6 * Copyright (c) 1982, 1986, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ffs_alloc.c 8.11 (Berkeley) 10/27/94
34 * Modified for ext2fs by Manuel Bouyer.
35 */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/buf.h>
40 #include <sys/vnode.h>
41 #include <sys/mount.h>
42 #include <sys/syslog.h>
43
44 #include <ufs/ufs/quota.h>
45 #include <ufs/ufs/inode.h>
46 #include <ufs/ufs/ufsmount.h>
47 #include <ufs/ufs/ufs_extern.h>
48
49 #include <ufs/ext2fs/ext2fs.h>
50 #include <ufs/ext2fs/ext2fs_extern.h>
51
52 u_long ext2gennumber;
53
54 static u_int32_t ext2fs_alloccg(struct inode *, int, u_int32_t, int);
55 static int ext2fs_dirpref(struct m_ext2fs *);
56 static void ext2fs_fserr(struct m_ext2fs *, uid_t, char *);
57 static u_int32_t ext2fs_hashalloc(struct inode *, int, u_int32_t, int,
58 u_int32_t (*)(struct inode *, int, u_int32_t, int));
59 static ufsino_t ext2fs_nodealloccg(struct inode *, int, ufsino_t, int);
60 static u_int32_t ext2fs_mapsearch(struct m_ext2fs *, char *, u_int32_t);
61
62 /*
63 * Allocate a block in the file system.
64 *
65 * A preference may be optionally specified. If a preference is given
66 * the following hierarchy is used to allocate a block:
67 * 1) allocate the requested block.
68 * 2) allocate a rotationally optimal block in the same cylinder.
69 * 3) allocate a block in the same cylinder group.
70 * 4) quadratically rehash into other cylinder groups, until an
71 * available block is located.
72 * If no block preference is given the following hierarchy is used
73 * to allocate a block:
74 * 1) allocate a block in the cylinder group that contains the
75 * inode for the file.
76 * 2) quadratically rehash into other cylinder groups, until an
77 * available block is located.
78 */
79 int
ext2fs_alloc(struct inode * ip,u_int32_t lbn,u_int32_t bpref,struct ucred * cred,u_int32_t * bnp)80 ext2fs_alloc(struct inode *ip, u_int32_t lbn, u_int32_t bpref,
81 struct ucred *cred, u_int32_t *bnp)
82 {
83 struct m_ext2fs *fs;
84 u_int32_t bno;
85 int cg;
86
87 *bnp = 0;
88 fs = ip->i_e2fs;
89 #ifdef DIAGNOSTIC
90 if (cred == NOCRED)
91 panic("ext2fs_alloc: missing credential");
92 #endif /* DIAGNOSTIC */
93 if (fs->e2fs.e2fs_fbcount == 0)
94 goto nospace;
95 if (cred->cr_uid != 0 && freespace(fs) <= 0)
96 goto nospace;
97 if (bpref >= fs->e2fs.e2fs_bcount)
98 bpref = 0;
99 if (bpref == 0)
100 cg = ino_to_cg(fs, ip->i_number);
101 else
102 cg = dtog(fs, bpref);
103 bno = ext2fs_hashalloc(ip, cg, bpref, fs->e2fs_bsize, ext2fs_alloccg);
104 if (bno > 0) {
105 ip->i_e2fs_nblock += btodb(fs->e2fs_bsize);
106 ip->i_flag |= IN_CHANGE | IN_UPDATE;
107 *bnp = bno;
108 return (0);
109 }
110 nospace:
111 ext2fs_fserr(fs, cred->cr_uid, "file system full");
112 uprintf("\n%s: write failed, file system is full\n", fs->e2fs_fsmnt);
113 return (ENOSPC);
114 }
115
116 /*
117 * Allocate an inode in the file system.
118 *
119 * If allocating a directory, use ext2fs_dirpref to select the inode.
120 * If allocating in a directory, the following hierarchy is followed:
121 * 1) allocate the preferred inode.
122 * 2) allocate an inode in the same cylinder group.
123 * 3) quadratically rehash into other cylinder groups, until an
124 * available inode is located.
125 * If no inode preference is given the following hierarchy is used
126 * to allocate an inode:
127 * 1) allocate an inode in cylinder group 0.
128 * 2) quadratically rehash into other cylinder groups, until an
129 * available inode is located.
130 */
131 int
ext2fs_inode_alloc(struct inode * pip,mode_t mode,struct ucred * cred,struct vnode ** vpp)132 ext2fs_inode_alloc(struct inode *pip, mode_t mode, struct ucred *cred,
133 struct vnode **vpp)
134 {
135 struct vnode *pvp;
136 struct m_ext2fs *fs;
137 struct inode *ip;
138 ufsino_t ino, ipref;
139 int cg, error;
140
141 *vpp = NULL;
142 pvp = ITOV(pip);
143 fs = pip->i_e2fs;
144 if (fs->e2fs.e2fs_ficount == 0)
145 goto noinodes;
146
147 if ((mode & IFMT) == IFDIR)
148 cg = ext2fs_dirpref(fs);
149 else
150 cg = ino_to_cg(fs, pip->i_number);
151 ipref = cg * fs->e2fs.e2fs_ipg + 1;
152 ino = ext2fs_hashalloc(pip, cg, ipref, mode, ext2fs_nodealloccg);
153 if (ino == 0)
154 goto noinodes;
155 error = VFS_VGET(pvp->v_mount, ino, vpp);
156 if (error) {
157 ext2fs_inode_free(pip, ino, mode);
158 return (error);
159 }
160 ip = VTOI(*vpp);
161 if (ip->i_e2fs_mode && ip->i_e2fs_nlink != 0) {
162 printf("mode = 0%o, nlinks %u, inum = %u, fs = %s\n",
163 ip->i_e2fs_mode, ip->i_e2fs_nlink, ip->i_number,
164 fs->e2fs_fsmnt);
165 panic("ext2fs_valloc: dup alloc");
166 }
167
168 memset(ip->i_e2din, 0, sizeof(struct ext2fs_dinode));
169
170 /*
171 * Set up a new generation number for this inode.
172 */
173 if (++ext2gennumber < (u_long)gettime())
174 ext2gennumber = gettime();
175 ip->i_e2fs_gen = ext2gennumber;
176 return (0);
177 noinodes:
178 ext2fs_fserr(fs, cred->cr_uid, "out of inodes");
179 uprintf("\n%s: create/symlink failed, no inodes free\n", fs->e2fs_fsmnt);
180 return (ENOSPC);
181 }
182
183 /*
184 * Find a cylinder to place a directory.
185 *
186 * The policy implemented by this algorithm is to select from
187 * among those cylinder groups with above the average number of
188 * free inodes, the one with the smallest number of directories.
189 */
190 static int
ext2fs_dirpref(struct m_ext2fs * fs)191 ext2fs_dirpref(struct m_ext2fs *fs)
192 {
193 int cg, maxspace, mincg, avgifree;
194
195 avgifree = fs->e2fs.e2fs_ficount / fs->e2fs_ncg;
196 maxspace = 0;
197 mincg = -1;
198 for (cg = 0; cg < fs->e2fs_ncg; cg++)
199 if ( fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree) {
200 if (mincg == -1 || fs->e2fs_gd[cg].ext2bgd_nbfree > maxspace) {
201 mincg = cg;
202 maxspace = fs->e2fs_gd[cg].ext2bgd_nbfree;
203 }
204 }
205 return mincg;
206 }
207
208 /*
209 * Select the desired position for the next block in a file. The file is
210 * logically divided into sections. The first section is composed of the
211 * direct blocks. Each additional section contains fs_maxbpg blocks.
212 *
213 * If no blocks have been allocated in the first section, the policy is to
214 * request a block in the same cylinder group as the inode that describes
215 * the file. Otherwise, the policy is to try to allocate the blocks
216 * contiguously. The two fields of the ext2 inode extension (see
217 * ufs/ufs/inode.h) help this.
218 */
219 daddr_t
ext2fs_blkpref(struct inode * ip,u_int32_t lbn,int baps,u_int32_t * bap)220 ext2fs_blkpref(struct inode *ip, u_int32_t lbn, int baps, u_int32_t *bap)
221 {
222 struct m_ext2fs *fs;
223 int cg, i;
224
225 fs = ip->i_e2fs;
226 /*
227 * if we are doing contiguous lbn allocation, try to alloc blocks
228 * contiguously on disk
229 */
230
231 if ( ip->i_e2fs_last_blk && lbn == ip->i_e2fs_last_lblk + 1) {
232 return ip->i_e2fs_last_blk + 1;
233 }
234
235 /*
236 * bap, if provided, gives us a list of blocks to which we want to
237 * stay close
238 */
239
240 if (bap) {
241 for (i = baps; i >= 0 ; i--) {
242 if (bap[i]) {
243 return letoh32(bap[i]) + 1;
244 }
245 }
246 }
247
248 /* fall back to the first block of the cylinder containing the inode */
249
250 cg = ino_to_cg(fs, ip->i_number);
251 return fs->e2fs.e2fs_bpg * cg + fs->e2fs.e2fs_first_dblock + 1;
252 }
253
254 /*
255 * Implement the cylinder overflow algorithm.
256 *
257 * The policy implemented by this algorithm is:
258 * 1) allocate the block in its requested cylinder group.
259 * 2) quadratically rehash on the cylinder group number.
260 * 3) brute force search for a free block.
261 */
262 static u_int32_t
ext2fs_hashalloc(struct inode * ip,int cg,u_int32_t pref,int size,u_int32_t (* allocator)(struct inode *,int,u_int32_t,int))263 ext2fs_hashalloc(struct inode *ip, int cg, u_int32_t pref, int size,
264 u_int32_t (*allocator)(struct inode *, int, u_int32_t, int))
265 {
266 struct m_ext2fs *fs;
267 long result;
268 int i, icg = cg;
269
270 fs = ip->i_e2fs;
271 /*
272 * 1: preferred cylinder group
273 */
274 result = (*allocator)(ip, cg, pref, size);
275 if (result)
276 return (result);
277 /*
278 * 2: quadratic rehash
279 */
280 for (i = 1; i < fs->e2fs_ncg; i *= 2) {
281 cg += i;
282 if (cg >= fs->e2fs_ncg)
283 cg -= fs->e2fs_ncg;
284 result = (*allocator)(ip, cg, 0, size);
285 if (result)
286 return (result);
287 }
288 /*
289 * 3: brute force search
290 * Note that we start at i == 2, since 0 was checked initially,
291 * and 1 is always checked in the quadratic rehash.
292 */
293 cg = (icg + 2) % fs->e2fs_ncg;
294 for (i = 2; i < fs->e2fs_ncg; i++) {
295 result = (*allocator)(ip, cg, 0, size);
296 if (result)
297 return (result);
298 cg++;
299 if (cg == fs->e2fs_ncg)
300 cg = 0;
301 }
302 return (0);
303 }
304
305 /*
306 * Determine whether a block can be allocated.
307 *
308 * Check to see if a block of the appropriate size is available,
309 * and if it is, allocate it.
310 */
311 static u_int32_t
ext2fs_alloccg(struct inode * ip,int cg,u_int32_t bpref,int size)312 ext2fs_alloccg(struct inode *ip, int cg, u_int32_t bpref, int size)
313 {
314 struct m_ext2fs *fs;
315 char *bbp;
316 struct buf *bp;
317 u_int32_t bno;
318 int error, start, end, loc;
319
320 fs = ip->i_e2fs;
321 if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0)
322 return (0);
323 error = bread(ip->i_devvp, fsbtodb(fs,
324 fs->e2fs_gd[cg].ext2bgd_b_bitmap), (int)fs->e2fs_bsize, &bp);
325 if (error || fs->e2fs_gd[cg].ext2bgd_nbfree == 0) {
326 brelse(bp);
327 return (0);
328 }
329 bbp = (char *)bp->b_data;
330
331 if (dtog(fs, bpref) != cg)
332 bpref = 0;
333 if (bpref != 0) {
334 bpref = dtogd(fs, bpref);
335 /*
336 * if the requested block is available, use it
337 */
338 if (isclr(bbp, bpref)) {
339 bno = bpref;
340 goto gotit;
341 }
342 }
343 /*
344 * no blocks in the requested cylinder, so take next
345 * available one in this cylinder group.
346 * first try to get 8 contiguous blocks, then fall back to a single
347 * block.
348 */
349 if (bpref)
350 start = dtogd(fs, bpref) / NBBY;
351 else
352 start = 0;
353 end = howmany(fs->e2fs.e2fs_fpg, NBBY) - start;
354 for (loc = start; loc < end; loc++) {
355 if (bbp[loc] == 0) {
356 bno = loc * NBBY;
357 goto gotit;
358 }
359 }
360 for (loc = 0; loc < start; loc++) {
361 if (bbp[loc] == 0) {
362 bno = loc * NBBY;
363 goto gotit;
364 }
365 }
366
367 bno = ext2fs_mapsearch(fs, bbp, bpref);
368 gotit:
369 #ifdef DIAGNOSTIC
370 if (isset(bbp, bno)) {
371 panic("%s: dup alloc: cg=%d bno=%u fs=%s",
372 __func__, cg, bno, fs->e2fs_fsmnt);
373 }
374 #endif
375 setbit(bbp, bno);
376 fs->e2fs.e2fs_fbcount--;
377 fs->e2fs_gd[cg].ext2bgd_nbfree--;
378 fs->e2fs_fmod = 1;
379 bdwrite(bp);
380 return (cg * fs->e2fs.e2fs_fpg + fs->e2fs.e2fs_first_dblock + bno);
381 }
382
383 /*
384 * Determine whether an inode can be allocated.
385 *
386 * Check to see if an inode is available, and if it is,
387 * allocate it using the following policy:
388 * 1) allocate the requested inode.
389 * 2) allocate the next available inode after the requested
390 * inode in the specified cylinder group.
391 */
392 static ufsino_t
ext2fs_nodealloccg(struct inode * ip,int cg,ufsino_t ipref,int mode)393 ext2fs_nodealloccg(struct inode *ip, int cg, ufsino_t ipref, int mode)
394 {
395 struct m_ext2fs *fs;
396 char *ibp;
397 struct buf *bp;
398 int error, start, len, loc, map, i;
399
400 ipref--; /* to avoid a lot of (ipref -1) */
401 fs = ip->i_e2fs;
402 if (fs->e2fs_gd[cg].ext2bgd_nifree == 0)
403 return (0);
404 error = bread(ip->i_devvp, fsbtodb(fs,
405 fs->e2fs_gd[cg].ext2bgd_i_bitmap), (int)fs->e2fs_bsize, &bp);
406 if (error) {
407 brelse(bp);
408 return (0);
409 }
410 ibp = (char *)bp->b_data;
411 if (ipref) {
412 ipref %= fs->e2fs.e2fs_ipg;
413 if (isclr(ibp, ipref))
414 goto gotit;
415 }
416 start = ipref / NBBY;
417 len = howmany(fs->e2fs.e2fs_ipg - ipref, NBBY);
418 loc = skpc(0xff, len, &ibp[start]);
419 if (loc == 0) {
420 len = start + 1;
421 start = 0;
422 loc = skpc(0xff, len, &ibp[0]);
423 if (loc == 0) {
424 printf("cg = %d, ipref = %u, fs = %s\n",
425 cg, ipref, fs->e2fs_fsmnt);
426 panic("ext2fs_nodealloccg: map corrupted");
427 /* NOTREACHED */
428 }
429 }
430 i = start + len - loc;
431 map = ibp[i];
432 ipref = i * NBBY;
433 for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) {
434 if ((map & i) == 0) {
435 goto gotit;
436 }
437 }
438 printf("fs = %s\n", fs->e2fs_fsmnt);
439 panic("ext2fs_nodealloccg: block not in map");
440 /* NOTREACHED */
441 gotit:
442 setbit(ibp, ipref);
443 fs->e2fs.e2fs_ficount--;
444 fs->e2fs_gd[cg].ext2bgd_nifree--;
445 fs->e2fs_fmod = 1;
446 if ((mode & IFMT) == IFDIR) {
447 fs->e2fs_gd[cg].ext2bgd_ndirs++;
448 }
449 bdwrite(bp);
450 return (cg * fs->e2fs.e2fs_ipg + ipref + 1);
451 }
452
453 /*
454 * Free a block.
455 *
456 * The specified block is placed back in the
457 * free map.
458 */
459 void
ext2fs_blkfree(struct inode * ip,u_int32_t bno)460 ext2fs_blkfree(struct inode *ip, u_int32_t bno)
461 {
462 struct m_ext2fs *fs;
463 char *bbp;
464 struct buf *bp;
465 int error, cg;
466
467 fs = ip->i_e2fs;
468 cg = dtog(fs, bno);
469 if (bno >= fs->e2fs.e2fs_bcount) {
470 printf("bad block %u, ino %u\n", bno, ip->i_number);
471 ext2fs_fserr(fs, ip->i_e2fs_uid, "bad block");
472 return;
473 }
474 error = bread(ip->i_devvp,
475 fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap),
476 (int)fs->e2fs_bsize, &bp);
477 if (error) {
478 brelse(bp);
479 return;
480 }
481 bbp = (char *)bp->b_data;
482 bno = dtogd(fs, bno);
483 if (isclr(bbp, bno))
484 panic("%s: freeing free block: dev = 0x%x, block = %u, fs = %s",
485 __func__, ip->i_dev, bno, fs->e2fs_fsmnt);
486
487 clrbit(bbp, bno);
488 fs->e2fs.e2fs_fbcount++;
489 fs->e2fs_gd[cg].ext2bgd_nbfree++;
490
491 fs->e2fs_fmod = 1;
492 bdwrite(bp);
493 }
494
495 /*
496 * Free an inode.
497 *
498 * The specified inode is placed back in the free map.
499 */
500 void
ext2fs_inode_free(struct inode * pip,ufsino_t ino,mode_t mode)501 ext2fs_inode_free(struct inode *pip, ufsino_t ino, mode_t mode)
502 {
503 struct m_ext2fs *fs;
504 char *ibp;
505 struct buf *bp;
506 int error, cg;
507
508 fs = pip->i_e2fs;
509 if (ino > fs->e2fs.e2fs_icount || ino < EXT2_FIRSTINO)
510 panic("ifree: range: dev = 0x%x, ino = %u, fs = %s",
511 pip->i_dev, ino, fs->e2fs_fsmnt);
512 cg = ino_to_cg(fs, ino);
513 error = bread(pip->i_devvp,
514 fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_i_bitmap),
515 (int)fs->e2fs_bsize, &bp);
516 if (error) {
517 brelse(bp);
518 return;
519 }
520 ibp = (char *)bp->b_data;
521 ino = (ino - 1) % fs->e2fs.e2fs_ipg;
522 if (isclr(ibp, ino)) {
523 printf("dev = 0x%x, ino = %d, fs = %s\n",
524 pip->i_dev, ino, fs->e2fs_fsmnt);
525 if (fs->e2fs_ronly == 0)
526 panic("ifree: freeing free inode");
527 }
528 clrbit(ibp, ino);
529 fs->e2fs.e2fs_ficount++;
530 fs->e2fs_gd[cg].ext2bgd_nifree++;
531 if ((mode & IFMT) == IFDIR) {
532 fs->e2fs_gd[cg].ext2bgd_ndirs--;
533 }
534 fs->e2fs_fmod = 1;
535 bdwrite(bp);
536 }
537
538 /*
539 * Find a block in the specified cylinder group.
540 *
541 * It is a panic if a request is made to find a block if none are
542 * available.
543 */
544
545 static u_int32_t
ext2fs_mapsearch(struct m_ext2fs * fs,char * bbp,u_int32_t bpref)546 ext2fs_mapsearch(struct m_ext2fs *fs, char *bbp, u_int32_t bpref)
547 {
548 u_int32_t bno;
549 int start, len, loc, i, map;
550
551 /*
552 * find the fragment by searching through the free block
553 * map for an appropriate bit pattern
554 */
555 if (bpref)
556 start = dtogd(fs, bpref) / NBBY;
557 else
558 start = 0;
559 len = howmany(fs->e2fs.e2fs_fpg, NBBY) - start;
560 loc = skpc(0xff, len, &bbp[start]);
561 if (loc == 0) {
562 len = start + 1;
563 start = 0;
564 loc = skpc(0xff, len, &bbp[start]);
565 if (loc == 0) {
566 printf("start = %d, len = %d, fs = %s\n",
567 start, len, fs->e2fs_fsmnt);
568 panic("ext2fs_alloccg: map corrupted");
569 /* NOTREACHED */
570 }
571 }
572 i = start + len - loc;
573 map = bbp[i];
574 bno = i * NBBY;
575 for (i = 1; i < (1 << NBBY); i <<= 1, bno++) {
576 if ((map & i) == 0)
577 return (bno);
578 }
579 printf("fs = %s\n", fs->e2fs_fsmnt);
580 panic("ext2fs_mapsearch: block not in map");
581 /* NOTREACHED */
582 }
583
584 /*
585 * Fserr prints the name of a file system with an error diagnostic.
586 *
587 * The form of the error message is:
588 * fs: error message
589 */
590 static void
ext2fs_fserr(struct m_ext2fs * fs,uid_t uid,char * cp)591 ext2fs_fserr(struct m_ext2fs *fs, uid_t uid, char *cp)
592 {
593 log(LOG_ERR, "uid %u on %s: %s\n", uid, fs->e2fs_fsmnt, cp);
594 }
595