~ubuntu-branches/debian/jessie/ufsutils/jessie

« back to all changes in this revision

Viewing changes to sbin/fsck_ffs/pass5.c

  • Committer: Package Import Robot
  • Author(s): Robert Millan
  • Date: 2013-11-29 14:21:12 UTC
  • mfrom: (11.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20131129142112-5tz5g7a4b6prb0dt
Tags: 9.2-2
* Avoid kfreebsd-kernel-headers versions prior to ino_t fix.
* Remove gratuitous dependency on libtermcap / libtinfo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include <inttypes.h>
46
46
#include <limits.h>
47
47
#include <string.h>
 
48
#include <libufs.h>
48
49
 
49
50
#include "fsck.h"
50
51
 
51
 
static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *, int *, int, int);
 
52
static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *,
 
53
                        int *, int, int, int);
 
54
static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end);
52
55
 
53
56
void
54
57
pass5(void)
56
59
        int c, i, j, blk, frags, basesize, mapsize;
57
60
        int inomapsize, blkmapsize;
58
61
        struct fs *fs = &sblock;
59
 
        struct cg *cg = &cgrp;
60
 
        ufs2_daddr_t d, dbase, dmax;
61
 
        int excessdirs, rewritecg = 0;
 
62
        ufs2_daddr_t d, dbase, dmax, start;
 
63
        int rewritecg = 0;
62
64
        struct csum *cs;
63
65
        struct csum_total cstotal;
64
66
        struct inodesc idesc[3];
65
67
        char buf[MAXBSIZE];
66
 
        struct cg *newcg = (struct cg *)buf;
 
68
        struct cg *cg, *newcg = (struct cg *)buf;
 
69
        struct bufarea *cgbp;
67
70
 
68
71
        inoinfo(WINO)->ino_state = USTATE;
69
72
        memset(newcg, 0, (size_t)fs->fs_cgsize);
159
162
                            c * 100 / sblock.fs_ncg);
160
163
                        got_sigalarm = 0;
161
164
                }
162
 
                getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
 
165
                cgbp = cgget(c);
 
166
                cg = cgbp->b_un.b_cg;
163
167
                if (!cg_chkmagic(cg))
164
168
                        pfatal("CG %d: BAD MAGIC NUMBER\n", c);
165
169
                newcg->cg_time = cg->cg_time;
241
245
                                setbit(cg_inosused(newcg), i);
242
246
                                newcg->cg_cs.cs_nifree--;
243
247
                        }
 
248
                start = -1;
244
249
                for (i = 0, d = dbase;
245
250
                     d < dmax;
246
251
                     d += fs->fs_frag, i += fs->fs_frag) {
247
252
                        frags = 0;
248
253
                        for (j = 0; j < fs->fs_frag; j++) {
249
 
                                if (testbmap(d + j))
 
254
                                if (testbmap(d + j)) {
 
255
                                        if ((Eflag || Zflag) && start != -1) {
 
256
                                                clear_blocks(start, d + j - 1);
 
257
                                                start = -1;
 
258
                                        }
250
259
                                        continue;
 
260
                                }
 
261
                                if (start == -1)
 
262
                                        start = d + j;
251
263
                                setbit(cg_blksfree(newcg), i + j);
252
264
                                frags++;
253
265
                        }
262
274
                                ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
263
275
                        }
264
276
                }
 
277
                if ((Eflag || Zflag) && start != -1)
 
278
                        clear_blocks(start, d - 1);
265
279
                if (fs->fs_contigsumsize > 0) {
266
280
                        int32_t *sump = cg_clustersum(newcg);
267
281
                        u_char *mapp = cg_clustersfree(newcg);
311
325
                }
312
326
                if (rewritecg) {
313
327
                        memmove(cg, newcg, (size_t)fs->fs_cgsize);
314
 
                        cgdirty();
 
328
                        dirty(cgbp);
315
329
                        continue;
316
330
                }
317
331
                if (cursnapshot == 0 &&
318
332
                    memcmp(newcg, cg, basesize) != 0 &&
319
333
                    dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
320
334
                        memmove(cg, newcg, (size_t)basesize);
321
 
                        cgdirty();
322
 
                }
323
 
                if (bkgrdflag != 0 || usedsoftdep || debug) {
324
 
                        excessdirs = cg->cg_cs.cs_ndir - newcg->cg_cs.cs_ndir;
325
 
                        if (excessdirs < 0) {
326
 
                                pfatal("LOST %d DIRECTORIES\n", -excessdirs);
327
 
                                excessdirs = 0;
328
 
                        }
329
 
                        if (excessdirs > 0)
330
 
                                check_maps(cg_inosused(newcg), cg_inosused(cg),
331
 
                                    inomapsize,
332
 
                                    cg->cg_cgx * (ufs2_daddr_t) fs->fs_ipg,
333
 
                                    "DIR",
334
 
                                    freedirs, 0, excessdirs);
335
 
                        check_maps(cg_inosused(newcg), cg_inosused(cg),
336
 
                            inomapsize,
337
 
                            cg->cg_cgx * (ufs2_daddr_t) fs->fs_ipg, "FILE",
338
 
                            freefiles, excessdirs, fs->fs_ipg);
339
 
                        check_maps(cg_blksfree(cg), cg_blksfree(newcg),
340
 
                            blkmapsize,
341
 
                            cg->cg_cgx * (ufs2_daddr_t) fs->fs_fpg, "FRAG",
342
 
                            freeblks, 0, fs->fs_fpg);
343
 
                }
 
335
                        dirty(cgbp);
 
336
                }
 
337
                if (bkgrdflag != 0 || usedsoftdep || debug)
 
338
                        update_maps(cg, newcg, bkgrdflag);
344
339
                if (cursnapshot == 0 &&
345
340
                    memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 &&
346
341
                    dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
347
342
                        memmove(cg_inosused(cg), cg_inosused(newcg),
348
343
                              (size_t)mapsize);
349
 
                        cgdirty();
 
344
                        dirty(cgbp);
350
345
                }
351
346
        }
352
347
        if (cursnapshot == 0 &&
413
408
        }
414
409
}
415
410
 
 
411
/*
 
412
 * Compare the original cylinder group inode and block bitmaps with the
 
413
 * updated cylinder group inode and block bitmaps. Free inodes and blocks
 
414
 * that have been added. Complain if any previously freed inodes blocks
 
415
 * are now allocated.
 
416
 */
 
417
void
 
418
update_maps(
 
419
        struct cg *oldcg,       /* cylinder group of claimed allocations */
 
420
        struct cg *newcg,       /* cylinder group of determined allocations */
 
421
        int usesysctl)          /* 1 => use sysctl interface to update maps */
 
422
{
 
423
        int inomapsize, excessdirs;
 
424
        struct fs *fs = &sblock;
 
425
 
 
426
        inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
 
427
        excessdirs = oldcg->cg_cs.cs_ndir - newcg->cg_cs.cs_ndir;
 
428
        if (excessdirs < 0) {
 
429
                pfatal("LOST %d DIRECTORIES\n", -excessdirs);
 
430
                excessdirs = 0;
 
431
        }
 
432
        if (excessdirs > 0)
 
433
                check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize,
 
434
                    oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "DIR", freedirs,
 
435
                    0, excessdirs, usesysctl);
 
436
        check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize,
 
437
            oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "FILE", freefiles,
 
438
            excessdirs, fs->fs_ipg, usesysctl);
 
439
        check_maps(cg_blksfree(oldcg), cg_blksfree(newcg),
 
440
            howmany(fs->fs_fpg, CHAR_BIT),
 
441
            oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_fpg, "FRAG",
 
442
            freeblks, 0, fs->fs_fpg, usesysctl);
 
443
}
 
444
 
416
445
static void
417
446
check_maps(
418
447
        u_char *map1,   /* map of claimed allocations */
422
451
        const char *name,       /* name of resource found in maps */
423
452
        int *opcode,    /* sysctl opcode to free resource */
424
453
        int skip,       /* number of entries to skip before starting to free */
425
 
        int limit)      /* limit on number of entries to free */
 
454
        int limit,      /* limit on number of entries to free */
 
455
        int usesysctl)  /* 1 => use sysctl interface to update maps */
426
456
{
427
457
#       define BUFSIZE 16
428
458
        char buf[BUFSIZE];
430
460
        ufs2_daddr_t n, astart, aend, ustart, uend;
431
461
        void (*msg)(const char *fmt, ...);
432
462
 
433
 
        if (bkgrdflag)
 
463
        if (usesysctl)
434
464
                msg = pfatal;
435
465
        else
436
466
                msg = pwarn;
493
523
                                            " MARKED USED\n",
494
524
                                            "UNALLOCATED", name, ustart,
495
525
                                            ustart + size - 1);
496
 
                                if (bkgrdflag != 0) {
 
526
                                if (usesysctl != 0) {
497
527
                                        cmd.value = ustart;
498
528
                                        cmd.size = size;
499
529
                                        if (sysctl(opcode, MIBSIZE, 0, 0,
539
569
                                    " MARKED USED\n",
540
570
                                    name, ustart, ustart + size - 1);
541
571
                }
542
 
                if (bkgrdflag != 0) {
 
572
                if (usesysctl != 0) {
543
573
                        cmd.value = ustart;
544
574
                        cmd.size = size;
545
575
                        if (sysctl(opcode, MIBSIZE, 0, 0, &cmd,
550
580
                }
551
581
        }
552
582
}
 
583
 
 
584
static void
 
585
clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end)
 
586
{
 
587
 
 
588
        if (debug)
 
589
                printf("Zero frags %jd to %jd\n", start, end);
 
590
        if (Zflag)
 
591
                blzero(fswritefd, fsbtodb(&sblock, start),
 
592
                    lfragtosize(&sblock, end - start + 1));
 
593
        if (Eflag)
 
594
                blerase(fswritefd, fsbtodb(&sblock, start),
 
595
                    lfragtosize(&sblock, end - start + 1));
 
596
}