Date: Wed, 17 Feb 2010 03:07:09 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r203982 - projects/suj/head/sbin/fsck_ffs Message-ID: <201002170307.o1H379u2015460@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jeff Date: Wed Feb 17 03:07:08 2010 New Revision: 203982 URL: http://svn.freebsd.org/changeset/base/203982 Log: - Rename blk_isfree to blk_freemask to more accruately describe the function. - Add a blk_isfree() that simply returns whether a block is free in the bitmaps. - Check whether a block is free in the bitmaps before considering it a valid indirect. This will facilitate future optimizations when reallocating indirects. - Don't print statistics if we don't write anything as nothing has changed. Modified: projects/suj/head/sbin/fsck_ffs/suj.c Modified: projects/suj/head/sbin/fsck_ffs/suj.c ============================================================================== --- projects/suj/head/sbin/fsck_ffs/suj.c Wed Feb 17 03:04:31 2010 (r203981) +++ projects/suj/head/sbin/fsck_ffs/suj.c Wed Feb 17 03:07:08 2010 (r203982) @@ -142,10 +142,11 @@ uint64_t jbytes; uint64_t jrecs; typedef void (*ino_visitor)(ino_t, ufs_lbn_t, ufs2_daddr_t, int); -static void ino_trunc(ino_t ino, off_t size); +static void ino_trunc(ino_t, off_t); static void ino_decr(ino_t); static void ino_adjust(struct suj_ino *); -static void ino_build(struct suj_ino *sino); +static void ino_build(struct suj_ino *); +static int blk_isfree(ufs2_daddr_t); static void * errmalloc(size_t n) @@ -496,7 +497,7 @@ blk_setmask(struct jblkrec *brec, int *m * to be freed. The mask value can be used to free partial blocks. */ static int -blk_isfree(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t lbn, int frags) +blk_freemask(ufs2_daddr_t blk, ino_t ino, ufs_lbn_t lbn, int frags) { struct suj_blk *sblk; struct suj_rec *srec; @@ -532,7 +533,7 @@ blk_isfree(ufs2_daddr_t blk, ino_t ino, blk_setmask(brec, &mask); } if (debug) - printf("blk_isfree: blk %jd sblk %jd off %d mask 0x%X\n", + printf("blk_freemask: blk %jd sblk %jd off %d mask 0x%X\n", blk, sblk->sb_blk, off, mask); return (mask >> off); } @@ -542,6 +543,9 @@ blk_isfree(ufs2_daddr_t blk, ino_t ino, * if any part of the indirect has been reallocated or the last journal * entry was an allocation. Just allocated indirects may not have valid * pointers yet and all of their children will have their own records. + * It is also not safe to follow an indirect if the cg bitmap has been + * cleared as a new allocation may write to the block prior to the journal + * being written. * * Returns 1 if it's safe to follow the indirect and 0 otherwise. */ @@ -559,7 +563,7 @@ blk_isindir(ufs2_daddr_t blk, ino_t ino, brec = (struct jblkrec *)TAILQ_LAST(&sblk->sb_recs, srechd)->sr_rec; if (blk_equals(brec, ino, lbn, blk, fs->fs_frag)) if (brec->jb_op == JOP_FREEBLK) - return (1); + return (!blk_isfree(blk)); return (0); } @@ -644,6 +648,19 @@ blk_free(ufs2_daddr_t bno, int mask, int } /* + * Returns 1 if the whole block starting at 'bno' is marked free and 0 + * otherwise. + */ +static int +blk_isfree(ufs2_daddr_t bno) +{ + struct suj_cg *sc; + + sc = cg_lookup(dtog(fs, bno)); + return ffs_isblock(fs, cg_blksfree(sc->sc_cgp), dtogd(fs, bno)); +} + +/* * Fetch an indirect block to find the block at a given lbn. The lbn * may be negative to fetch a specific indirect block pointer or positive * to fetch a specific block. @@ -1059,7 +1076,7 @@ blk_free_visit(ino_t ino, ufs_lbn_t lbn, { int mask; - mask = blk_isfree(blk, ino, lbn, frags); + mask = blk_freemask(blk, ino, lbn, frags); if (debug) printf("blk %jd freemask 0x%X\n", blk, mask); blk_free(blk, mask, frags); @@ -1076,7 +1093,7 @@ blk_free_lbn(ufs2_daddr_t blk, ino_t ino uint64_t resid; int mask; - mask = blk_isfree(blk, ino, lbn, frags); + mask = blk_freemask(blk, ino, lbn, frags); if (debug) printf("blk %jd freemask 0x%X\n", blk, mask); resid = 0; @@ -1615,7 +1632,7 @@ blk_check(struct suj_blk *sblk) if (isat == 1) { if (frags == brec->jb_frags) continue; - mask = blk_isfree(blk, brec->jb_ino, brec->jb_lbn, + mask = blk_freemask(blk, brec->jb_ino, brec->jb_lbn, brec->jb_frags); mask >>= frags; blk += frags; @@ -2259,7 +2276,8 @@ suj_verifyino(union dinode *ip) return (-1); } - if (DIP(ip, di_flags) != (SF_IMMUTABLE | SF_NOUNLINK)) { + if ((DIP(ip, di_flags) & (SF_IMMUTABLE | SF_NOUNLINK)) != + (SF_IMMUTABLE | SF_NOUNLINK)) { printf("Invalid flags 0x%X for journal inode %d\n", DIP(ip, di_flags), sujino); return (-1); @@ -2595,19 +2613,19 @@ suj_check(const char *filesys) cg_apply(cg_check_blk); cg_apply(cg_check_ino); } + if (preen == 0 && reply("WRITE CHANGES") == 0) + return (0); /* * To remain idempotent with partial truncations the free bitmaps * must be written followed by indirect blocks and lastly inode * blocks. This preserves access to the modified pointers until * they are freed. */ - if (preen || reply("WRITE CHANGES")) { - cg_apply(cg_write); - dblk_write(); - cg_apply(cg_write_inos); - /* Write back superblock. */ - closedisk(filesys); - } + cg_apply(cg_write); + dblk_write(); + cg_apply(cg_write_inos); + /* Write back superblock. */ + closedisk(filesys); printf("** %jd journal records in %jd bytes for %.2f%% utilization\n", jrecs, jbytes, ((float)jrecs / (float)(jbytes / JREC_SIZE)) * 100); printf("** Freed %jd inodes (%jd dirs) %jd blocks, and %jd frags.\n",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002170307.o1H379u2015460>