diff options
author | Kirk McKusick <mckusick@FreeBSD.org> | 2021-04-26 23:47:27 +0000 |
---|---|---|
committer | Kirk McKusick <mckusick@FreeBSD.org> | 2021-05-17 00:35:22 +0000 |
commit | 8f28af0a445f32852d9c7de8bdcf890c2d27b86e (patch) | |
tree | 13166027512c9e195090c4df94188240191572d4 | |
parent | ed5c8820f4786ddca97ef0411c133bccee2ddd85 (diff) | |
download | src-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.c | 2 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsutil.c | 6 | ||||
-rw-r--r-- | sbin/fsck_ffs/inode.c | 19 |
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) { |