aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2021-04-26 23:47:27 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2021-05-17 00:35:22 +0000
commit8f28af0a445f32852d9c7de8bdcf890c2d27b86e (patch)
tree13166027512c9e195090c4df94188240191572d4
parented5c8820f4786ddca97ef0411c133bccee2ddd85 (diff)
downloadsrc-8f28af0a445f32852d9c7de8bdcf890c2d27b86e.tar.gz
src-8f28af0a445f32852d9c7de8bdcf890c2d27b86e.zip
Make fsck_ffs more persistent in creating a lost+found directory.
(cherry picked from commit 84a0e3f95700733695115fb2a9d84d6666efe5d9) Sponsored by: Netflix
-rw-r--r--sbin/fsck_ffs/dir.c2
-rw-r--r--sbin/fsck_ffs/fsutil.c6
-rw-r--r--sbin/fsck_ffs/inode.c19
3 files changed, 19 insertions, 8 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index 25ff6aa30018..09a561984c1b 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -696,6 +696,8 @@ allocdir(ino_t parent, ino_t request, int mode)
struct dirtemplate *dirp;
ino = allocino(request, IFDIR|mode);
+ if (ino == 0)
+ return (0);
dirp = &dirhead;
dirp->dot_ino = ino;
dirp->dotdot_ino = parent;
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 91be4234ae48..84c4437d3312 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -770,8 +770,10 @@ allocblk(long frags)
cg = dtog(&sblock, i + j);
cgbp = cglookup(cg);
cgp = cgbp->b_un.b_cg;
- if (!check_cgmagic(cg, cgbp))
- return (0);
+ if (!check_cgmagic(cg, cgbp)) {
+ i = (cg + 1) * sblock.fs_fpg - sblock.fs_frag;
+ continue;
+ }
baseblk = dtogd(&sblock, i + j);
for (k = 0; k < frags; k++) {
setbmap(i + j + k);
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index b88a2646ff04..bfc0c5e25240 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -668,22 +668,29 @@ allocino(ino_t request, int type)
union dinode *dp;
struct bufarea *cgbp;
struct cg *cgp;
- int cg;
+ int cg, anyino;
- if (request == 0)
+ anyino = 0;
+ if (request == 0) {
request = UFS_ROOTINO;
- else if (inoinfo(request)->ino_state != USTATE)
+ anyino = 1;
+ } else if (inoinfo(request)->ino_state != USTATE)
return (0);
+retry:
for (ino = request; ino < maxino; ino++)
if (inoinfo(ino)->ino_state == USTATE)
break;
- if (ino == maxino)
+ if (ino >= maxino)
return (0);
cg = ino_to_cg(&sblock, ino);
cgbp = cglookup(cg);
cgp = cgbp->b_un.b_cg;
- if (!check_cgmagic(cg, cgbp))
- return (0);
+ if (!check_cgmagic(cg, cgbp)) {
+ if (anyino == 0)
+ return (0);
+ request = (cg + 1) * sblock.fs_ipg;
+ goto retry;
+ }
setbit(cg_inosused(cgp), ino % sblock.fs_ipg);
cgp->cg_cs.cs_nifree--;
switch (type & IFMT) {