Deleted Added
full compact
suj.c (240463) suj.c (241012)
1/*-
2 * Copyright 2009, 2010 Jeffrey W. Roberson <jeff@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright 2009, 2010 Jeffrey W. Roberson <jeff@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sbin/fsck_ffs/suj.c 240463 2012-09-13 12:55:10Z zont $");
28__FBSDID("$FreeBSD: head/sbin/fsck_ffs/suj.c 241012 2012-09-27 23:30:58Z mdf $");
29
30#include <sys/param.h>
31#include <sys/disk.h>
32#include <sys/disklabel.h>
33#include <sys/mount.h>
34#include <sys/stat.h>
35
36#include <ufs/ufs/ufsmount.h>

--- 789 unchanged lines hidden (view full) ---

826 ufs2_daddr_t blk;
827 uint8_t *block;
828 ufs_lbn_t lbn;
829 int blksize;
830 int frags;
831 int doff;
832
833 if (debug)
29
30#include <sys/param.h>
31#include <sys/disk.h>
32#include <sys/disklabel.h>
33#include <sys/mount.h>
34#include <sys/stat.h>
35
36#include <ufs/ufs/ufsmount.h>

--- 789 unchanged lines hidden (view full) ---

826 ufs2_daddr_t blk;
827 uint8_t *block;
828 ufs_lbn_t lbn;
829 int blksize;
830 int frags;
831 int doff;
832
833 if (debug)
834 printf("Clearing inode %d from parent %d at offset %jd\n",
835 child, parent, diroff);
834 printf("Clearing inode %ju from parent %ju at offset %jd\n",
835 (uintmax_t)child, (uintmax_t)parent, diroff);
836
837 lbn = lblkno(fs, diroff);
838 doff = blkoff(fs, diroff);
839 dip = ino_read(parent);
840 blk = ino_blkatoff(dip, parent, lbn, &frags);
841 blksize = sblksize(fs, DIP(dip, di_size), lbn);
842 block = dblk_read(blk, blksize);
843 dp = (struct direct *)&block[doff];
844 if (dp->d_ino != child)
836
837 lbn = lblkno(fs, diroff);
838 doff = blkoff(fs, diroff);
839 dip = ino_read(parent);
840 blk = ino_blkatoff(dip, parent, lbn, &frags);
841 blksize = sblksize(fs, DIP(dip, di_size), lbn);
842 block = dblk_read(blk, blksize);
843 dp = (struct direct *)&block[doff];
844 if (dp->d_ino != child)
845 errx(1, "Inode %d does not exist in %d at %jd",
846 child, parent, diroff);
845 errx(1, "Inode %ju does not exist in %ju at %jd",
846 (uintmax_t)child, (uintmax_t)parent, diroff);
847 dp->d_ino = 0;
848 dblk_dirty(blk);
849 /*
850 * The actual .. reference count will already have been removed
851 * from the parent by the .. remref record.
852 */
853}
854

--- 19 unchanged lines hidden (view full) ---

874 *mode = DIP(dip, di_mode);
875 if ((*mode & IFMT) != IFDIR) {
876 if (debug) {
877 /*
878 * This can happen if the parent inode
879 * was reallocated.
880 */
881 if (*mode != 0)
847 dp->d_ino = 0;
848 dblk_dirty(blk);
849 /*
850 * The actual .. reference count will already have been removed
851 * from the parent by the .. remref record.
852 */
853}
854

--- 19 unchanged lines hidden (view full) ---

874 *mode = DIP(dip, di_mode);
875 if ((*mode & IFMT) != IFDIR) {
876 if (debug) {
877 /*
878 * This can happen if the parent inode
879 * was reallocated.
880 */
881 if (*mode != 0)
882 printf("Directory %d has bad mode %o\n",
883 parent, *mode);
882 printf("Directory %ju has bad mode %o\n",
883 (uintmax_t)parent, *mode);
884 else
884 else
885 printf("Directory %d has zero mode\n", parent);
885 printf("Directory %ju has zero mode\n",
886 (uintmax_t)parent);
886 }
887 return (0);
888 }
889 lbn = lblkno(fs, diroff);
890 doff = blkoff(fs, diroff);
891 blksize = sblksize(fs, DIP(dip, di_size), lbn);
892 if (diroff + DIRECTSIZ(1) > DIP(dip, di_size) || doff >= blksize) {
893 if (debug)
887 }
888 return (0);
889 }
890 lbn = lblkno(fs, diroff);
891 doff = blkoff(fs, diroff);
892 blksize = sblksize(fs, DIP(dip, di_size), lbn);
893 if (diroff + DIRECTSIZ(1) > DIP(dip, di_size) || doff >= blksize) {
894 if (debug)
894 printf("ino %d absent from %d due to offset %jd"
895 printf("ino %ju absent from %ju due to offset %jd"
895 " exceeding size %jd\n",
896 " exceeding size %jd\n",
896 child, parent, diroff, DIP(dip, di_size));
897 (uintmax_t)child, (uintmax_t)parent, diroff,
898 DIP(dip, di_size));
897 return (0);
898 }
899 blk = ino_blkatoff(dip, parent, lbn, &frags);
900 if (blk <= 0) {
901 if (debug)
899 return (0);
900 }
901 blk = ino_blkatoff(dip, parent, lbn, &frags);
902 if (blk <= 0) {
903 if (debug)
902 printf("Sparse directory %d", parent);
904 printf("Sparse directory %ju", (uintmax_t)parent);
903 return (0);
904 }
905 block = dblk_read(blk, blksize);
906 /*
907 * Walk through the records from the start of the block to be
908 * certain we hit a valid record and not some junk in the middle
909 * of a file name. Stop when we reach or pass the expected offset.
910 */
911 dpoff = (doff / DIRBLKSIZ) * DIRBLKSIZ;
912 do {
913 dp = (struct direct *)&block[dpoff];
914 if (dpoff == doff)
915 break;
916 if (dp->d_reclen == 0)
917 break;
918 dpoff += dp->d_reclen;
919 } while (dpoff <= doff);
920 if (dpoff > fs->fs_bsize)
905 return (0);
906 }
907 block = dblk_read(blk, blksize);
908 /*
909 * Walk through the records from the start of the block to be
910 * certain we hit a valid record and not some junk in the middle
911 * of a file name. Stop when we reach or pass the expected offset.
912 */
913 dpoff = (doff / DIRBLKSIZ) * DIRBLKSIZ;
914 do {
915 dp = (struct direct *)&block[dpoff];
916 if (dpoff == doff)
917 break;
918 if (dp->d_reclen == 0)
919 break;
920 dpoff += dp->d_reclen;
921 } while (dpoff <= doff);
922 if (dpoff > fs->fs_bsize)
921 err_suj("Corrupt directory block in dir ino %d\n", parent);
923 err_suj("Corrupt directory block in dir ino %ju\n",
924 (uintmax_t)parent);
922 /* Not found. */
923 if (dpoff != doff) {
924 if (debug)
925 /* Not found. */
926 if (dpoff != doff) {
927 if (debug)
925 printf("ino %d not found in %d, lbn %jd, dpoff %d\n",
926 child, parent, lbn, dpoff);
928 printf("ino %ju not found in %ju, lbn %jd, dpoff %d\n",
929 (uintmax_t)child, (uintmax_t)parent, lbn, dpoff);
927 return (0);
928 }
929 /*
930 * We found the item in question. Record the mode and whether it's
931 * a . or .. link for the caller.
932 */
933 if (dp->d_ino == child) {
934 if (child == parent)
935 *isdot = 1;
936 else if (dp->d_namlen == 2 &&
937 dp->d_name[0] == '.' && dp->d_name[1] == '.')
938 *isdot = 1;
939 *mode = DTTOIF(dp->d_type);
940 return (1);
941 }
942 if (debug)
930 return (0);
931 }
932 /*
933 * We found the item in question. Record the mode and whether it's
934 * a . or .. link for the caller.
935 */
936 if (dp->d_ino == child) {
937 if (child == parent)
938 *isdot = 1;
939 else if (dp->d_namlen == 2 &&
940 dp->d_name[0] == '.' && dp->d_name[1] == '.')
941 *isdot = 1;
942 *mode = DTTOIF(dp->d_type);
943 return (1);
944 }
945 if (debug)
943 printf("ino %d doesn't match dirent ino %d in parent %d\n",
944 child, dp->d_ino, parent);
946 printf("ino %ju doesn't match dirent ino %ju in parent %ju\n",
947 (uintmax_t)child, (uintmax_t)dp->d_ino, (uintmax_t)parent);
945 return (0);
946}
947
948#define VISIT_INDIR 0x0001
949#define VISIT_EXT 0x0002
950#define VISIT_ROOT 0x0004 /* Operation came via root & valid pointers. */
951
952/*

--- 19 unchanged lines hidden (view full) ---

972 */
973 if (blk == 0)
974 return;
975 level = lbn_level(lbn);
976 if (level == -1)
977 err_suj("Invalid level for lbn %jd\n", lbn);
978 if ((flags & VISIT_ROOT) == 0 && blk_isindir(blk, ino, lbn) == 0) {
979 if (debug)
948 return (0);
949}
950
951#define VISIT_INDIR 0x0001
952#define VISIT_EXT 0x0002
953#define VISIT_ROOT 0x0004 /* Operation came via root & valid pointers. */
954
955/*

--- 19 unchanged lines hidden (view full) ---

975 */
976 if (blk == 0)
977 return;
978 level = lbn_level(lbn);
979 if (level == -1)
980 err_suj("Invalid level for lbn %jd\n", lbn);
981 if ((flags & VISIT_ROOT) == 0 && blk_isindir(blk, ino, lbn) == 0) {
982 if (debug)
980 printf("blk %jd ino %d lbn %jd(%d) is not indir.\n",
981 blk, ino, lbn, level);
983 printf("blk %jd ino %ju lbn %jd(%d) is not indir.\n",
984 blk, (uintmax_t)ino, lbn, level);
982 goto out;
983 }
984 lbnadd = 1;
985 for (i = level; i > 0; i--)
986 lbnadd *= NINDIR(fs);
987 bap1 = (void *)dblk_read(blk, fs->fs_bsize);
988 bap2 = (void *)bap1;
989 for (i = 0; i < NINDIR(fs); i++) {

--- 136 unchanged lines hidden (view full) ---

1126 isize = size;
1127 /* Always truncate to free any unpopulated indirects. */
1128 ino_trunc(sino->si_ino, isize);
1129 return;
1130 }
1131 if (blocks == DIP(ip, di_blocks))
1132 return;
1133 if (debug)
985 goto out;
986 }
987 lbnadd = 1;
988 for (i = level; i > 0; i--)
989 lbnadd *= NINDIR(fs);
990 bap1 = (void *)dblk_read(blk, fs->fs_bsize);
991 bap2 = (void *)bap1;
992 for (i = 0; i < NINDIR(fs); i++) {

--- 136 unchanged lines hidden (view full) ---

1129 isize = size;
1130 /* Always truncate to free any unpopulated indirects. */
1131 ino_trunc(sino->si_ino, isize);
1132 return;
1133 }
1134 if (blocks == DIP(ip, di_blocks))
1135 return;
1136 if (debug)
1134 printf("ino %d adjusting block count from %jd to %jd\n",
1135 ino, DIP(ip, di_blocks), blocks);
1137 printf("ino %ju adjusting block count from %jd to %jd\n",
1138 (uintmax_t)ino, DIP(ip, di_blocks), blocks);
1136 DIP_SET(ip, di_blocks, blocks);
1137 ino_dirty(ino);
1138}
1139
1140static void
1141blk_free_visit(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
1142{
1143 int mask;

--- 115 unchanged lines hidden (view full) ---

1259 continue;
1260 if (dp->d_namlen == 1 && dp->d_name[0] == '.')
1261 continue;
1262 isdotdot = dp->d_namlen == 2 && dp->d_name[0] == '.' &&
1263 dp->d_name[1] == '.';
1264 if (isdotdot && skipparent == 1)
1265 continue;
1266 if (debug)
1139 DIP_SET(ip, di_blocks, blocks);
1140 ino_dirty(ino);
1141}
1142
1143static void
1144blk_free_visit(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, int frags)
1145{
1146 int mask;

--- 115 unchanged lines hidden (view full) ---

1262 continue;
1263 if (dp->d_namlen == 1 && dp->d_name[0] == '.')
1264 continue;
1265 isdotdot = dp->d_namlen == 2 && dp->d_name[0] == '.' &&
1266 dp->d_name[1] == '.';
1267 if (isdotdot && skipparent == 1)
1268 continue;
1269 if (debug)
1267 printf("Directory %d removing ino %d name %s\n",
1268 ino, dp->d_ino, dp->d_name);
1270 printf("Directory %ju removing ino %ju name %s\n",
1271 (uintmax_t)ino, (uintmax_t)dp->d_ino, dp->d_name);
1269 diroff = lblktosize(fs, lbn) + dpoff;
1270 ino_remref(ino, dp->d_ino, diroff, isdotdot);
1271 }
1272}
1273
1274/*
1275 * Reclaim an inode, freeing all blocks and decrementing all children's
1276 * link counts. Free the inode back to the cg.
1277 */
1278static void
1279ino_reclaim(union dinode *ip, ino_t ino, int mode)
1280{
1281 uint32_t gen;
1282
1283 if (ino == ROOTINO)
1284 err_suj("Attempting to free ROOTINO\n");
1285 if (debug)
1272 diroff = lblktosize(fs, lbn) + dpoff;
1273 ino_remref(ino, dp->d_ino, diroff, isdotdot);
1274 }
1275}
1276
1277/*
1278 * Reclaim an inode, freeing all blocks and decrementing all children's
1279 * link counts. Free the inode back to the cg.
1280 */
1281static void
1282ino_reclaim(union dinode *ip, ino_t ino, int mode)
1283{
1284 uint32_t gen;
1285
1286 if (ino == ROOTINO)
1287 err_suj("Attempting to free ROOTINO\n");
1288 if (debug)
1286 printf("Truncating and freeing ino %d, nlink %d, mode %o\n",
1287 ino, DIP(ip, di_nlink), DIP(ip, di_mode));
1289 printf("Truncating and freeing ino %ju, nlink %d, mode %o\n",
1290 (uintmax_t)ino, DIP(ip, di_nlink), DIP(ip, di_mode));
1288
1289 /* We are freeing an inode or directory. */
1290 if ((DIP(ip, di_mode) & IFMT) == IFDIR)
1291 ino_visit(ip, ino, ino_free_children, 0);
1292 DIP_SET(ip, di_nlink, 0);
1293 ino_visit(ip, ino, blk_free_visit, VISIT_EXT | VISIT_INDIR);
1294 /* Here we have to clear the inode and release any blocks it holds. */
1295 gen = DIP(ip, di_gen);

--- 27 unchanged lines hidden (view full) ---

1323 err_suj("Inode %d has a link of %d with 0 mode\n", ino, nlink);
1324 nlink--;
1325 if ((mode & IFMT) == IFDIR)
1326 reqlink = 2;
1327 else
1328 reqlink = 1;
1329 if (nlink < reqlink) {
1330 if (debug)
1291
1292 /* We are freeing an inode or directory. */
1293 if ((DIP(ip, di_mode) & IFMT) == IFDIR)
1294 ino_visit(ip, ino, ino_free_children, 0);
1295 DIP_SET(ip, di_nlink, 0);
1296 ino_visit(ip, ino, blk_free_visit, VISIT_EXT | VISIT_INDIR);
1297 /* Here we have to clear the inode and release any blocks it holds. */
1298 gen = DIP(ip, di_gen);

--- 27 unchanged lines hidden (view full) ---

1326 err_suj("Inode %d has a link of %d with 0 mode\n", ino, nlink);
1327 nlink--;
1328 if ((mode & IFMT) == IFDIR)
1329 reqlink = 2;
1330 else
1331 reqlink = 1;
1332 if (nlink < reqlink) {
1333 if (debug)
1331 printf("ino %d not enough links to live %d < %d\n",
1332 ino, nlink, reqlink);
1334 printf("ino %ju not enough links to live %d < %d\n",
1335 (uintmax_t)ino, nlink, reqlink);
1333 ino_reclaim(ip, ino, mode);
1334 return;
1335 }
1336 DIP_SET(ip, di_nlink, nlink);
1337 ino_dirty(ino);
1338}
1339
1340/*

--- 28 unchanged lines hidden (view full) ---

1369 rrec = (struct jrefrec *)srec->sr_rec;
1370 if (ino_isat(rrec->jr_parent, rrec->jr_diroff, ino,
1371 &recmode, &isdot) == 0)
1372 continue;
1373 ino_clrat(rrec->jr_parent, rrec->jr_diroff, ino);
1374 break;
1375 }
1376 if (srec == NULL)
1336 ino_reclaim(ip, ino, mode);
1337 return;
1338 }
1339 DIP_SET(ip, di_nlink, nlink);
1340 ino_dirty(ino);
1341}
1342
1343/*

--- 28 unchanged lines hidden (view full) ---

1372 rrec = (struct jrefrec *)srec->sr_rec;
1373 if (ino_isat(rrec->jr_parent, rrec->jr_diroff, ino,
1374 &recmode, &isdot) == 0)
1375 continue;
1376 ino_clrat(rrec->jr_parent, rrec->jr_diroff, ino);
1377 break;
1378 }
1379 if (srec == NULL)
1377 errx(1, "Directory %d name not found", ino);
1380 errx(1, "Directory %ju name not found", (uintmax_t)ino);
1378 }
1379 /*
1380 * If it's a directory with no real names pointing to it go ahead
1381 * and truncate it. This will free any children.
1382 */
1383 if (mode == IFDIR && nlink - sino->si_dotlinks == 0) {
1384 sino->si_nlink = nlink = 0;
1385 /*

--- 7 unchanged lines hidden (view full) ---

1393 if (stmp)
1394 ino_setskip(stmp, ino);
1395 }
1396 }
1397 }
1398 ip = ino_read(ino);
1399 mode = DIP(ip, di_mode) & IFMT;
1400 if (nlink > LINK_MAX)
1381 }
1382 /*
1383 * If it's a directory with no real names pointing to it go ahead
1384 * and truncate it. This will free any children.
1385 */
1386 if (mode == IFDIR && nlink - sino->si_dotlinks == 0) {
1387 sino->si_nlink = nlink = 0;
1388 /*

--- 7 unchanged lines hidden (view full) ---

1396 if (stmp)
1397 ino_setskip(stmp, ino);
1398 }
1399 }
1400 }
1401 ip = ino_read(ino);
1402 mode = DIP(ip, di_mode) & IFMT;
1403 if (nlink > LINK_MAX)
1401 err_suj(
1402 "ino %d nlink manipulation error, new link %d, old link %d\n",
1403 ino, nlink, DIP(ip, di_nlink));
1404 err_suj("ino %ju %s, new link %d, old link %d\n",
1405 (uintmax_t)ino, "nlink manipulation error", nlink,
1406 DIP(ip, di_nlink));
1404 if (debug)
1407 if (debug)
1405 printf("Adjusting ino %d, nlink %d, old link %d lastmode %o\n",
1406 ino, nlink, DIP(ip, di_nlink), sino->si_mode);
1408 printf("Adjusting ino %ju, nlink %d, old link %d lastmode %o\n",
1409 (uintmax_t)ino, nlink, DIP(ip, di_nlink), sino->si_mode);
1407 if (mode == 0) {
1408 if (debug)
1410 if (mode == 0) {
1411 if (debug)
1409 printf("ino %d, zero inode freeing bitmap\n", ino);
1412 printf("ino %ju, zero inode freeing bitmap\n",
1413 (uintmax_t)ino);
1410 ino_free(ino, sino->si_mode);
1411 return;
1412 }
1413 /* XXX Should be an assert? */
1414 if (mode != sino->si_mode && debug)
1414 ino_free(ino, sino->si_mode);
1415 return;
1416 }
1417 /* XXX Should be an assert? */
1418 if (mode != sino->si_mode && debug)
1415 printf("ino %d, mode %o != %o\n", ino, mode, sino->si_mode);
1419 printf("ino %ju, mode %o != %o\n",
1420 (uintmax_t)ino, mode, sino->si_mode);
1416 if ((mode & IFMT) == IFDIR)
1417 reqlink = 2;
1418 else
1419 reqlink = 1;
1420 /* If the inode doesn't have enough links to live, free it. */
1421 if (nlink < reqlink) {
1422 if (debug)
1421 if ((mode & IFMT) == IFDIR)
1422 reqlink = 2;
1423 else
1424 reqlink = 1;
1425 /* If the inode doesn't have enough links to live, free it. */
1426 if (nlink < reqlink) {
1427 if (debug)
1423 printf("ino %d not enough links to live %d < %d\n",
1424 ino, nlink, reqlink);
1428 printf("ino %ju not enough links to live %d < %d\n",
1429 (uintmax_t)ino, nlink, reqlink);
1425 ino_reclaim(ip, ino, mode);
1426 return;
1427 }
1428 /* If required write the updated link count. */
1429 if (DIP(ip, di_nlink) == nlink) {
1430 if (debug)
1430 ino_reclaim(ip, ino, mode);
1431 return;
1432 }
1433 /* If required write the updated link count. */
1434 if (DIP(ip, di_nlink) == nlink) {
1435 if (debug)
1431 printf("ino %d, link matches, skipping.\n", ino);
1436 printf("ino %ju, link matches, skipping.\n",
1437 (uintmax_t)ino);
1432 return;
1433 }
1434 DIP_SET(ip, di_nlink, nlink);
1435 ino_dirty(ino);
1436}
1437
1438/*
1439 * Truncate some or all blocks in an indirect, freeing any that are required

--- 82 unchanged lines hidden (view full) ---

1522 off_t cursize;
1523 off_t off;
1524 int mode;
1525
1526 ip = ino_read(ino);
1527 mode = DIP(ip, di_mode) & IFMT;
1528 cursize = DIP(ip, di_size);
1529 if (debug)
1438 return;
1439 }
1440 DIP_SET(ip, di_nlink, nlink);
1441 ino_dirty(ino);
1442}
1443
1444/*
1445 * Truncate some or all blocks in an indirect, freeing any that are required

--- 82 unchanged lines hidden (view full) ---

1528 off_t cursize;
1529 off_t off;
1530 int mode;
1531
1532 ip = ino_read(ino);
1533 mode = DIP(ip, di_mode) & IFMT;
1534 cursize = DIP(ip, di_size);
1535 if (debug)
1530 printf("Truncating ino %d, mode %o to size %jd from size %jd\n",
1531 ino, mode, size, cursize);
1536 printf("Truncating ino %ju, mode %o to size %jd from size %jd\n",
1537 (uintmax_t)ino, mode, size, cursize);
1532
1533 /* Skip datablocks for short links and devices. */
1534 if (mode == 0 || mode == IFBLK || mode == IFCHR ||
1535 (mode == IFLNK && cursize < fs->fs_maxsymlinklen))
1536 return;
1537 /* Don't extend. */
1538 if (size > cursize)
1539 size = cursize;

--- 41 unchanged lines hidden (view full) ---

1581 * If we're truncating direct blocks we have to adjust frags
1582 * accordingly.
1583 */
1584 if (visitlbn < NDADDR && totalfrags) {
1585 long oldspace, newspace;
1586
1587 bn = DIP(ip, di_db[visitlbn]);
1588 if (bn == 0)
1538
1539 /* Skip datablocks for short links and devices. */
1540 if (mode == 0 || mode == IFBLK || mode == IFCHR ||
1541 (mode == IFLNK && cursize < fs->fs_maxsymlinklen))
1542 return;
1543 /* Don't extend. */
1544 if (size > cursize)
1545 size = cursize;

--- 41 unchanged lines hidden (view full) ---

1587 * If we're truncating direct blocks we have to adjust frags
1588 * accordingly.
1589 */
1590 if (visitlbn < NDADDR && totalfrags) {
1591 long oldspace, newspace;
1592
1593 bn = DIP(ip, di_db[visitlbn]);
1594 if (bn == 0)
1589 err_suj("Bad blk at ino %d lbn %jd\n", ino, visitlbn);
1595 err_suj("Bad blk at ino %ju lbn %jd\n",
1596 (uintmax_t)ino, visitlbn);
1590 oldspace = sblksize(fs, cursize, visitlbn);
1591 newspace = sblksize(fs, size, visitlbn);
1592 if (oldspace != newspace) {
1593 bn += numfrags(fs, newspace);
1594 frags = numfrags(fs, oldspace - newspace);
1595 blk_free(bn, 0, frags);
1596 totalfrags -= frags;
1597 }

--- 7 unchanged lines hidden (view full) ---

1605 */
1606 off = blkoff(fs, size);
1607 if (off && DIP(ip, di_mode) != IFDIR) {
1608 uint8_t *buf;
1609 long clrsize;
1610
1611 bn = ino_blkatoff(ip, ino, visitlbn, &frags);
1612 if (bn == 0)
1597 oldspace = sblksize(fs, cursize, visitlbn);
1598 newspace = sblksize(fs, size, visitlbn);
1599 if (oldspace != newspace) {
1600 bn += numfrags(fs, newspace);
1601 frags = numfrags(fs, oldspace - newspace);
1602 blk_free(bn, 0, frags);
1603 totalfrags -= frags;
1604 }

--- 7 unchanged lines hidden (view full) ---

1612 */
1613 off = blkoff(fs, size);
1614 if (off && DIP(ip, di_mode) != IFDIR) {
1615 uint8_t *buf;
1616 long clrsize;
1617
1618 bn = ino_blkatoff(ip, ino, visitlbn, &frags);
1619 if (bn == 0)
1613 err_suj("Block missing from ino %d at lbn %jd\n",
1614 ino, visitlbn);
1620 err_suj("Block missing from ino %ju at lbn %jd\n",
1621 (uintmax_t)ino, visitlbn);
1615 clrsize = frags * fs->fs_fsize;
1616 buf = dblk_read(bn, clrsize);
1617 clrsize -= off;
1618 buf += off;
1619 bzero(buf, clrsize);
1620 dblk_dirty(bn);
1621 }
1622 return;

--- 28 unchanged lines hidden (view full) ---

1651 TAILQ_FOREACH(srec, &sino->si_recs, sr_next) {
1652 rrec = (struct jrefrec *)srec->sr_rec;
1653 isat = ino_isat(rrec->jr_parent, rrec->jr_diroff,
1654 rrec->jr_ino, &mode, &isdot);
1655 if (isat && (mode & IFMT) != (rrec->jr_mode & IFMT))
1656 err_suj("Inode mode/directory type mismatch %o != %o\n",
1657 mode, rrec->jr_mode);
1658 if (debug)
1622 clrsize = frags * fs->fs_fsize;
1623 buf = dblk_read(bn, clrsize);
1624 clrsize -= off;
1625 buf += off;
1626 bzero(buf, clrsize);
1627 dblk_dirty(bn);
1628 }
1629 return;

--- 28 unchanged lines hidden (view full) ---

1658 TAILQ_FOREACH(srec, &sino->si_recs, sr_next) {
1659 rrec = (struct jrefrec *)srec->sr_rec;
1660 isat = ino_isat(rrec->jr_parent, rrec->jr_diroff,
1661 rrec->jr_ino, &mode, &isdot);
1662 if (isat && (mode & IFMT) != (rrec->jr_mode & IFMT))
1663 err_suj("Inode mode/directory type mismatch %o != %o\n",
1664 mode, rrec->jr_mode);
1665 if (debug)
1659 printf("jrefrec: op %d ino %d, nlink %d, parent %d, "
1666 printf("jrefrec: op %d ino %ju, nlink %d, parent %d, "
1660 "diroff %jd, mode %o, isat %d, isdot %d\n",
1667 "diroff %jd, mode %o, isat %d, isdot %d\n",
1661 rrec->jr_op, rrec->jr_ino, rrec->jr_nlink,
1662 rrec->jr_parent, rrec->jr_diroff, rrec->jr_mode,
1663 isat, isdot);
1668 rrec->jr_op, (uintmax_t)rrec->jr_ino,
1669 rrec->jr_nlink, rrec->jr_parent, rrec->jr_diroff,
1670 rrec->jr_mode, isat, isdot);
1664 mode = rrec->jr_mode & IFMT;
1665 if (rrec->jr_op == JOP_REMREF)
1666 removes++;
1667 newlinks += isat;
1668 if (isdot)
1669 dotlinks += isat;
1670 }
1671 /*
1672 * The number of links that remain are the starting link count
1673 * subtracted by the total number of removes with the total
1674 * links discovered back in. An incomplete remove thus
1675 * makes no change to the link count but an add increases
1676 * by one.
1677 */
1678 if (debug)
1671 mode = rrec->jr_mode & IFMT;
1672 if (rrec->jr_op == JOP_REMREF)
1673 removes++;
1674 newlinks += isat;
1675 if (isdot)
1676 dotlinks += isat;
1677 }
1678 /*
1679 * The number of links that remain are the starting link count
1680 * subtracted by the total number of removes with the total
1681 * links discovered back in. An incomplete remove thus
1682 * makes no change to the link count but an add increases
1683 * by one.
1684 */
1685 if (debug)
1679 printf("ino %d nlink %d newlinks %d removes %d dotlinks %d\n",
1680 ino, nlink, newlinks, removes, dotlinks);
1686 printf("ino %ju nlink %d newlinks %d removes %d dotlinks %d\n",
1687 (uintmax_t)ino, nlink, newlinks, removes, dotlinks);
1681 nlink += newlinks;
1682 nlink -= removes;
1683 sino->si_linkadj = 1;
1684 sino->si_nlink = nlink;
1685 sino->si_dotlinks = dotlinks;
1686 sino->si_mode = mode;
1687 ino_adjust(sino);
1688}

--- 24 unchanged lines hidden (view full) ---

1713 frags = brec->jb_frags;
1714 blk = brec->jb_blkno + brec->jb_oldfrags;
1715 isat = blk_isat(brec->jb_ino, brec->jb_lbn, blk, &frags);
1716 if (sino == NULL || sino->si_ino != brec->jb_ino) {
1717 sino = ino_lookup(brec->jb_ino, 1);
1718 sino->si_blkadj = 1;
1719 }
1720 if (debug)
1688 nlink += newlinks;
1689 nlink -= removes;
1690 sino->si_linkadj = 1;
1691 sino->si_nlink = nlink;
1692 sino->si_dotlinks = dotlinks;
1693 sino->si_mode = mode;
1694 ino_adjust(sino);
1695}

--- 24 unchanged lines hidden (view full) ---

1720 frags = brec->jb_frags;
1721 blk = brec->jb_blkno + brec->jb_oldfrags;
1722 isat = blk_isat(brec->jb_ino, brec->jb_lbn, blk, &frags);
1723 if (sino == NULL || sino->si_ino != brec->jb_ino) {
1724 sino = ino_lookup(brec->jb_ino, 1);
1725 sino->si_blkadj = 1;
1726 }
1727 if (debug)
1721 printf("op %d blk %jd ino %d lbn %jd frags %d isat %d (%d)\n",
1722 brec->jb_op, blk, brec->jb_ino, brec->jb_lbn,
1723 brec->jb_frags, isat, frags);
1728 printf("op %d blk %jd ino %ju lbn %jd frags %d isat %d (%d)\n",
1729 brec->jb_op, blk, (uintmax_t)brec->jb_ino,
1730 brec->jb_lbn, brec->jb_frags, isat, frags);
1724 /*
1725 * If we found the block at this address we still have to
1726 * determine if we need to free the tail end that was
1727 * added by adding contiguous fragments from the same block.
1728 */
1729 if (isat == 1) {
1730 if (frags == brec->jb_frags)
1731 continue;

--- 200 unchanged lines hidden (view full) ---

1932 mode = DIP(ip, di_mode) & IFMT;
1933 inon = DIP(ip, di_freelink);
1934 DIP_SET(ip, di_freelink, 0);
1935 /*
1936 * XXX Should this be an errx?
1937 */
1938 if (DIP(ip, di_nlink) == 0) {
1939 if (debug)
1731 /*
1732 * If we found the block at this address we still have to
1733 * determine if we need to free the tail end that was
1734 * added by adding contiguous fragments from the same block.
1735 */
1736 if (isat == 1) {
1737 if (frags == brec->jb_frags)
1738 continue;

--- 200 unchanged lines hidden (view full) ---

1939 mode = DIP(ip, di_mode) & IFMT;
1940 inon = DIP(ip, di_freelink);
1941 DIP_SET(ip, di_freelink, 0);
1942 /*
1943 * XXX Should this be an errx?
1944 */
1945 if (DIP(ip, di_nlink) == 0) {
1946 if (debug)
1940 printf("Freeing unlinked ino %d mode %o\n",
1947 printf("Freeing unlinked ino %ju mode %o\n",
1941 ino, mode);
1942 ino_reclaim(ip, ino, mode);
1943 } else if (debug)
1948 ino, mode);
1949 ino_reclaim(ip, ino, mode);
1950 } else if (debug)
1944 printf("Skipping ino %d mode %o with link %d\n",
1945 ino, mode, DIP(ip, di_nlink));
1951 printf("Skipping ino %ju mode %o with link %d\n",
1952 (uintmax_t)ino, mode, DIP(ip, di_nlink));
1946 ino = inon;
1947 }
1948}
1949
1950/*
1951 * Append a new record to the list of records requiring processing.
1952 */
1953static void

--- 406 unchanged lines hidden (view full) ---

2360/*
2361 * Verify the journal inode before attempting to read records.
2362 */
2363static int
2364suj_verifyino(union dinode *ip)
2365{
2366
2367 if (DIP(ip, di_nlink) != 1) {
1953 ino = inon;
1954 }
1955}
1956
1957/*
1958 * Append a new record to the list of records requiring processing.
1959 */
1960static void

--- 406 unchanged lines hidden (view full) ---

2367/*
2368 * Verify the journal inode before attempting to read records.
2369 */
2370static int
2371suj_verifyino(union dinode *ip)
2372{
2373
2374 if (DIP(ip, di_nlink) != 1) {
2368 printf("Invalid link count %d for journal inode %d\n",
2369 DIP(ip, di_nlink), sujino);
2375 printf("Invalid link count %d for journal inode %ju\n",
2376 DIP(ip, di_nlink), (uintmax_t)sujino);
2370 return (-1);
2371 }
2372
2373 if ((DIP(ip, di_flags) & (SF_IMMUTABLE | SF_NOUNLINK)) !=
2374 (SF_IMMUTABLE | SF_NOUNLINK)) {
2377 return (-1);
2378 }
2379
2380 if ((DIP(ip, di_flags) & (SF_IMMUTABLE | SF_NOUNLINK)) !=
2381 (SF_IMMUTABLE | SF_NOUNLINK)) {
2375 printf("Invalid flags 0x%X for journal inode %d\n",
2376 DIP(ip, di_flags), sujino);
2382 printf("Invalid flags 0x%X for journal inode %ju\n",
2383 DIP(ip, di_flags), (uintmax_t)sujino);
2377 return (-1);
2378 }
2379
2380 if (DIP(ip, di_mode) != (IFREG | IREAD)) {
2384 return (-1);
2385 }
2386
2387 if (DIP(ip, di_mode) != (IFREG | IREAD)) {
2381 printf("Invalid mode %o for journal inode %d\n",
2382 DIP(ip, di_mode), sujino);
2388 printf("Invalid mode %o for journal inode %ju\n",
2389 DIP(ip, di_mode), (uintmax_t)sujino);
2383 return (-1);
2384 }
2385
2386 if (DIP(ip, di_size) < SUJ_MIN) {
2390 return (-1);
2391 }
2392
2393 if (DIP(ip, di_size) < SUJ_MIN) {
2387 printf("Invalid size %jd for journal inode %d\n",
2388 DIP(ip, di_size), sujino);
2394 printf("Invalid size %jd for journal inode %ju\n",
2395 DIP(ip, di_size), (uintmax_t)sujino);
2389 return (-1);
2390 }
2391
2392 if (DIP(ip, di_modrev) != fs->fs_mtime) {
2393 printf("Journal timestamp does not match fs mount time\n");
2394 return (-1);
2395 }
2396

--- 311 unchanged lines hidden (view full) ---

2708 jip = ino_read(sujino);
2709 printf("** SU+J Recovering %s\n", filesys);
2710 if (suj_verifyino(jip) != 0)
2711 return (-1);
2712 /*
2713 * Build a list of journal blocks in jblocks before parsing the
2714 * available journal blocks in with suj_read().
2715 */
2396 return (-1);
2397 }
2398
2399 if (DIP(ip, di_modrev) != fs->fs_mtime) {
2400 printf("Journal timestamp does not match fs mount time\n");
2401 return (-1);
2402 }
2403

--- 311 unchanged lines hidden (view full) ---

2715 jip = ino_read(sujino);
2716 printf("** SU+J Recovering %s\n", filesys);
2717 if (suj_verifyino(jip) != 0)
2718 return (-1);
2719 /*
2720 * Build a list of journal blocks in jblocks before parsing the
2721 * available journal blocks in with suj_read().
2722 */
2716 printf("** Reading %jd byte journal from inode %d.\n",
2717 DIP(jip, di_size), sujino);
2723 printf("** Reading %jd byte journal from inode %ju.\n",
2724 DIP(jip, di_size), (uintmax_t)sujino);
2718 suj_jblocks = jblocks_create();
2719 blocks = ino_visit(jip, sujino, suj_add_block, 0);
2720 if (blocks != numfrags(fs, DIP(jip, di_size))) {
2725 suj_jblocks = jblocks_create();
2726 blocks = ino_visit(jip, sujino, suj_add_block, 0);
2727 if (blocks != numfrags(fs, DIP(jip, di_size))) {
2721 printf("Sparse journal inode %d.\n", sujino);
2728 printf("Sparse journal inode %ju.\n", (uintmax_t)sujino);
2722 return (-1);
2723 }
2724 suj_read();
2725 jblocks_destroy(suj_jblocks);
2726 suj_jblocks = NULL;
2727 if (preen || reply("RECOVER")) {
2728 printf("** Building recovery table.\n");
2729 suj_prune();

--- 32 unchanged lines hidden ---
2729 return (-1);
2730 }
2731 suj_read();
2732 jblocks_destroy(suj_jblocks);
2733 suj_jblocks = NULL;
2734 if (preen || reply("RECOVER")) {
2735 printf("** Building recovery table.\n");
2736 suj_prune();

--- 32 unchanged lines hidden ---