From owner-svn-src-all@freebsd.org Sat Sep 19 22:48:33 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 3371C3F1A4C; Sat, 19 Sep 2020 22:48:33 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Bv5TY0V7Lz4bwr; Sat, 19 Sep 2020 22:48:33 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E7FEA1361F; Sat, 19 Sep 2020 22:48:32 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 08JMmWnM055042; Sat, 19 Sep 2020 22:48:32 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 08JMmUfl055032; Sat, 19 Sep 2020 22:48:30 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <202009192248.08JMmUfl055032@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Sat, 19 Sep 2020 22:48:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r365919 - in head: lib/libufs sbin/fsck_ffs X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: in head: lib/libufs sbin/fsck_ffs X-SVN-Commit-Revision: 365919 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Sep 2020 22:48:33 -0000 Author: mckusick Date: Sat Sep 19 22:48:30 2020 New Revision: 365919 URL: https://svnweb.freebsd.org/changeset/base/365919 Log: Update the libufs cgget() and cgput() interfaces to have a similar API to the sbget() and sbput() interfaces. Specifically they take a file descriptor pointer rather than the struct uufsd *disk pointer used by the libufs cgread() and cgwrite() interfaces. Update fsck_ffs to use these revised interfaces. No functional changes intended. Sponsored by: Netflix Modified: head/lib/libufs/cgread.3 head/lib/libufs/cgroup.c head/lib/libufs/getinode.3 head/lib/libufs/libufs.3 head/lib/libufs/libufs.h head/lib/libufs/sblock.c head/lib/libufs/sbread.3 head/sbin/fsck_ffs/fsutil.c head/sbin/fsck_ffs/gjournal.c head/sbin/fsck_ffs/suj.c Modified: head/lib/libufs/cgread.3 ============================================================================== --- head/lib/libufs/cgread.3 Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/cgread.3 Sat Sep 19 22:48:30 2020 (r365919) @@ -13,7 +13,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 19, 2018 +.Dd September 2, 2020 .Dt CGREAD 3 .Os .Sh NAME @@ -29,9 +29,9 @@ .In ufs/ffs/fs.h .In libufs.h .Ft int -.Fn cgget "struct uufsd *disk" "int cg" "struct cg *cgp" +.Fn cgget "int devfd" "struct fs *fs" "int cg" "struct cg *cgp" .Ft int -.Fn cgput "struct uufsd *disk" "struct cg *cgp" +.Fn cgput "int devfd" "struct fs *fs" "struct cg *cgp" .Ft int .Fn cgread "struct uufsd *disk" .Ft int @@ -64,7 +64,11 @@ function reads the cylinder group specified by .Fa cg into the buffer pointed to by .Fa cgp -from the disk referenced by the user-land UFS-disk structure. +from the filesystem described by the +.Fa fs +superblock using the +.Fa devfd +file descriptor that references the filesystem disk. The .Fn cgget function is the only cylinder group read function that is safe to use @@ -74,7 +78,11 @@ The .Fn cgput function writes the cylinder group specified by .Va cgp -to the disk referenced by the user-land UFS-disk structure. +to the filesystem described by the +.Fa fs +superblock using the +.Fa devfd +file descriptor that references the filesystem disk. The .Fn cgput function is the only cylinder group write function that is safe to use @@ -172,3 +180,4 @@ in .Fx 5.1 . .Sh AUTHORS .An Juli Mallett Aq Mt jmallett@FreeBSD.org +.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org Modified: head/lib/libufs/cgroup.c ============================================================================== --- head/lib/libufs/cgroup.c Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/cgroup.c Sat Sep 19 22:48:30 2020 (r365919) @@ -188,27 +188,56 @@ cgread(struct uufsd *disk) return (cgread1(disk, disk->d_ccg++)); } +/* Short read/write error messages from cgget()/cgput() */ +static const char *failmsg; + int cgread1(struct uufsd *disk, int c) { - if ((cgget(disk, c, &disk->d_cg)) == 0) + if (cgget(disk->d_fd, &disk->d_fs, c, &disk->d_cg) == 0) { + disk->d_lcg = c; return (1); + } + ERROR(disk, NULL); + if (failmsg != NULL) { + ERROR(disk, failmsg); + return (-1); + } + switch (errno) { + case EINTEGRITY: + ERROR(disk, "cylinder group checks failed"); + break; + case EIO: + ERROR(disk, "read error from block device"); + break; + default: + ERROR(disk, strerror(errno)); + break; + } return (-1); } int -cgget(struct uufsd *disk, int cg, struct cg *cgp) +cgget(int devfd, struct fs *fs, int cg, struct cg *cgp) { - struct fs *fs; uint32_t cghash, calchash; + size_t cnt; - fs = &disk->d_fs; - if (bread(disk, fsbtodb(fs, cgtod(fs, cg)), (void *)cgp, - fs->fs_cgsize) == -1) { - ERROR(disk, "unable to read cylinder group"); + failmsg = NULL; + if ((cnt = pread(devfd, cgp, fs->fs_cgsize, + fsbtodb(fs, cgtod(fs, cg)) * (fs->fs_fsize / fsbtodb(fs,1)))) < 0) return (-1); + if (cnt == 0) { + failmsg = "end of file from block device"; + errno = EIO; + return (-1); } + if (cnt != fs->fs_cgsize) { + failmsg = "short read from block device"; + errno = EIO; + return (-1); + } calchash = cgp->cg_ckhash; if ((fs->fs_metackhash & CK_CYLGRP) != 0) { cghash = cgp->cg_ckhash; @@ -218,11 +247,9 @@ cgget(struct uufsd *disk, int cg, struct cg *cgp) } if (cgp->cg_ckhash != calchash || !cg_chkmagic(cgp) || cgp->cg_cgx != cg) { - ERROR(disk, "cylinder group checks failed"); - errno = EIO; + errno = EINTEGRITY; return (-1); } - disk->d_lcg = cg; return (0); } @@ -230,7 +257,7 @@ int cgwrite(struct uufsd *disk) { - return (cgput(disk, &disk->d_cg)); + return (cgwrite1(disk, disk->d_cg.cg_cgx)); } int @@ -238,8 +265,24 @@ cgwrite1(struct uufsd *disk, int cg) { static char errmsg[BUFSIZ]; - if (cg == disk->d_cg.cg_cgx) - return (cgput(disk, &disk->d_cg)); + if (cg == disk->d_cg.cg_cgx) { + if (cgput(disk->d_fd, &disk->d_fs, &disk->d_cg) == 0) + return (0); + ERROR(disk, NULL); + if (failmsg != NULL) { + ERROR(disk, failmsg); + return (-1); + } + switch (errno) { + case EIO: + ERROR(disk, "unable to write cylinder group"); + break; + default: + ERROR(disk, strerror(errno)); + break; + } + return (-1); + } snprintf(errmsg, BUFSIZ, "Cylinder group %d in buffer does not match " "the cylinder group %d that cgwrite1 requested", disk->d_cg.cg_cgx, cg); @@ -249,19 +292,22 @@ cgwrite1(struct uufsd *disk, int cg) } int -cgput(struct uufsd *disk, struct cg *cgp) +cgput(int devfd, struct fs *fs, struct cg *cgp) { - struct fs *fs; + size_t cnt; - fs = &disk->d_fs; if ((fs->fs_metackhash & CK_CYLGRP) != 0) { cgp->cg_ckhash = 0; cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, fs->fs_cgsize); } - if (bwrite(disk, fsbtodb(fs, cgtod(fs, cgp->cg_cgx)), cgp, - fs->fs_cgsize) == -1) { - ERROR(disk, "unable to write cylinder group"); + failmsg = NULL; + if ((cnt = pwrite(devfd, cgp, fs->fs_cgsize, + fsbtodb(fs, cgtod(fs, cgp->cg_cgx)) * + (fs->fs_fsize / fsbtodb(fs,1)))) < 0) + return (-1); + if (cnt != fs->fs_cgsize) { + failmsg = "short write to block device"; return (-1); } return (0); Modified: head/lib/libufs/getinode.3 ============================================================================== --- head/lib/libufs/getinode.3 Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/getinode.3 Sat Sep 19 22:48:30 2020 (r365919) @@ -9,7 +9,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 10, 2018 +.Dd September 2, 2020 .Dt GETINODE 3 .Os .Sh NAME @@ -128,4 +128,4 @@ These functions first appeared as part of in .Fx 13.0 . .Sh AUTHORS -.An Marshall Kirk McKusick Aq Mt mckusick@freebsd.org +.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org Modified: head/lib/libufs/libufs.3 ============================================================================== --- head/lib/libufs/libufs.3 Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/libufs.3 Sat Sep 19 22:48:30 2020 (r365919) @@ -7,7 +7,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 26, 2018 +.Dd September 2, 2020 .Dt LIBUFS 3 .Os .Sh NAME @@ -80,6 +80,7 @@ library first appeared in .Fx 5.0 . .Sh AUTHORS .An Juli Mallett Aq Mt jmallett@FreeBSD.org +.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org .Pp .An -nosplit Additional design, feedback, and ideas were provided by Modified: head/lib/libufs/libufs.h ============================================================================== --- head/lib/libufs/libufs.h Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/libufs.h Sat Sep 19 22:48:30 2020 (r365919) @@ -136,8 +136,8 @@ int berase(struct uufsd *, ufs2_daddr_t, ufs2_daddr_t) ufs2_daddr_t cgballoc(struct uufsd *); int cgbfree(struct uufsd *, ufs2_daddr_t, long); ino_t cgialloc(struct uufsd *); -int cgget(struct uufsd *, int, struct cg *); -int cgput(struct uufsd *, struct cg *); +int cgget(int, struct fs *, int, struct cg *); +int cgput(int, struct fs *, struct cg *); int cgread(struct uufsd *); int cgread1(struct uufsd *, int); int cgwrite(struct uufsd *); Modified: head/lib/libufs/sblock.c ============================================================================== --- head/lib/libufs/sblock.c Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/sblock.c Sat Sep 19 22:48:30 2020 (r365919) @@ -186,7 +186,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite) use_pwrite)) != 0) { fs->fs_sblockactualloc = savedactualloc; fs->fs_csp = savedcsp; - return (-1); + return (error); } } fs->fs_sblockactualloc = savedactualloc; Modified: head/lib/libufs/sbread.3 ============================================================================== --- head/lib/libufs/sbread.3 Sat Sep 19 22:37:45 2020 (r365918) +++ head/lib/libufs/sbread.3 Sat Sep 19 22:48:30 2020 (r365919) @@ -11,7 +11,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 19, 2018 +.Dd September 2, 2020 .Dt SBREAD 3 .Os .Sh NAME @@ -145,3 +145,4 @@ in .Fx 5.0 . .Sh AUTHORS .An Juli Mallett Aq Mt jmallett@FreeBSD.org +.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org Modified: head/sbin/fsck_ffs/fsutil.c ============================================================================== --- head/sbin/fsck_ffs/fsutil.c Sat Sep 19 22:37:45 2020 (r365918) +++ head/sbin/fsck_ffs/fsutil.c Sat Sep 19 22:48:30 2020 (r365919) @@ -217,6 +217,9 @@ bufinit(void) /* * Manage cylinder group buffers. + * + * Use getblk() here rather than cgget() because the cylinder group + * may be corrupted but we want it anyway so we can fix it. */ static struct bufarea *cgbufs; /* header for cylinder group cache */ static int flushtries; /* number of tries to reclaim memory */ @@ -370,7 +373,7 @@ flush(int fd, struct bufarea *bp) fsmodified = 1; break; case BT_CYLGRP: - if (cgput(&disk, bp->b_un.b_cg) == 0) + if (cgput(fswritefd, &sblock, bp->b_un.b_cg) == 0) fsmodified = 1; break; default: Modified: head/sbin/fsck_ffs/gjournal.c ============================================================================== --- head/sbin/fsck_ffs/gjournal.c Sat Sep 19 22:37:45 2020 (r365918) +++ head/sbin/fsck_ffs/gjournal.c Sat Sep 19 22:48:30 2020 (r365919) @@ -133,7 +133,7 @@ getcg(int cg) if (cgc == NULL) err(1, "malloc(%zu)", sizeof(*cgc)); } - if (cgget(diskp, cg, &cgc->cgc_cg) == -1) + if (cgget(fsreadfd, fs, cg, &cgc->cgc_cg) == -1) err(1, "cgget(%d)", cg); cgc->cgc_busy = 0; cgc->cgc_dirty = 0; @@ -189,7 +189,7 @@ putcgs(void) LIST_REMOVE(cgc, cgc_next); ncgs--; if (cgc->cgc_dirty) { - if (cgput(diskp, &cgc->cgc_cg) == -1) + if (cgput(fswritefd, fs, &cgc->cgc_cg) == -1) err(1, "cgput(%d)", cgc->cgc_cg.cg_cgx); //printf("%s: Wrote cg=%d\n", __func__, // cgc->cgc_cg.cg_cgx); Modified: head/sbin/fsck_ffs/suj.c ============================================================================== --- head/sbin/fsck_ffs/suj.c Sat Sep 19 22:37:45 2020 (r365918) +++ head/sbin/fsck_ffs/suj.c Sat Sep 19 22:48:30 2020 (r365919) @@ -1912,7 +1912,7 @@ cg_write(struct suj_cg *sc) * before writing the block. */ fs->fs_cs(fs, sc->sc_cgx) = cgp->cg_cs; - if (cgput(&disk, cgp) == -1) + if (cgput(fswritefd, fs, cgp) == -1) err_suj("Unable to write cylinder group %d\n", sc->sc_cgx); }