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
This commit is contained in:
Kirk McKusick 2020-09-19 22:48:30 +00:00
parent a29c0348f0
commit 85ee267a3e
10 changed files with 95 additions and 35 deletions

View File

@ -13,7 +13,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 19, 2018 .Dd September 2, 2020
.Dt CGREAD 3 .Dt CGREAD 3
.Os .Os
.Sh NAME .Sh NAME
@ -29,9 +29,9 @@
.In ufs/ffs/fs.h .In ufs/ffs/fs.h
.In libufs.h .In libufs.h
.Ft int .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 .Ft int
.Fn cgput "struct uufsd *disk" "struct cg *cgp" .Fn cgput "int devfd" "struct fs *fs" "struct cg *cgp"
.Ft int .Ft int
.Fn cgread "struct uufsd *disk" .Fn cgread "struct uufsd *disk"
.Ft int .Ft int
@ -64,7 +64,11 @@ function reads the cylinder group specified by
.Fa cg .Fa cg
into the buffer pointed to by into the buffer pointed to by
.Fa cgp .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 The
.Fn cgget .Fn cgget
function is the only cylinder group read function that is safe to use function is the only cylinder group read function that is safe to use
@ -74,7 +78,11 @@ The
.Fn cgput .Fn cgput
function writes the cylinder group specified by function writes the cylinder group specified by
.Va cgp .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 The
.Fn cgput .Fn cgput
function is the only cylinder group write function that is safe to use function is the only cylinder group write function that is safe to use
@ -172,3 +180,4 @@ in
.Fx 5.1 . .Fx 5.1 .
.Sh AUTHORS .Sh AUTHORS
.An Juli Mallett Aq Mt jmallett@FreeBSD.org .An Juli Mallett Aq Mt jmallett@FreeBSD.org
.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org

View File

@ -188,25 +188,54 @@ cgread(struct uufsd *disk)
return (cgread1(disk, disk->d_ccg++)); return (cgread1(disk, disk->d_ccg++));
} }
/* Short read/write error messages from cgget()/cgput() */
static const char *failmsg;
int int
cgread1(struct uufsd *disk, int c) 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); 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); return (-1);
} }
int 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; uint32_t cghash, calchash;
size_t cnt;
fs = &disk->d_fs; failmsg = NULL;
if (bread(disk, fsbtodb(fs, cgtod(fs, cg)), (void *)cgp, if ((cnt = pread(devfd, cgp, fs->fs_cgsize,
fs->fs_cgsize) == -1) { fsbtodb(fs, cgtod(fs, cg)) * (fs->fs_fsize / fsbtodb(fs,1)))) < 0)
ERROR(disk, "unable to read cylinder group"); 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); return (-1);
} }
calchash = cgp->cg_ckhash; calchash = cgp->cg_ckhash;
@ -218,11 +247,9 @@ cgget(struct uufsd *disk, int cg, struct cg *cgp)
} }
if (cgp->cg_ckhash != calchash || !cg_chkmagic(cgp) || if (cgp->cg_ckhash != calchash || !cg_chkmagic(cgp) ||
cgp->cg_cgx != cg) { cgp->cg_cgx != cg) {
ERROR(disk, "cylinder group checks failed"); errno = EINTEGRITY;
errno = EIO;
return (-1); return (-1);
} }
disk->d_lcg = cg;
return (0); return (0);
} }
@ -230,7 +257,7 @@ int
cgwrite(struct uufsd *disk) cgwrite(struct uufsd *disk)
{ {
return (cgput(disk, &disk->d_cg)); return (cgwrite1(disk, disk->d_cg.cg_cgx));
} }
int int
@ -238,8 +265,24 @@ cgwrite1(struct uufsd *disk, int cg)
{ {
static char errmsg[BUFSIZ]; static char errmsg[BUFSIZ];
if (cg == disk->d_cg.cg_cgx) if (cg == disk->d_cg.cg_cgx) {
return (cgput(disk, &disk->d_cg)); 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 " snprintf(errmsg, BUFSIZ, "Cylinder group %d in buffer does not match "
"the cylinder group %d that cgwrite1 requested", "the cylinder group %d that cgwrite1 requested",
disk->d_cg.cg_cgx, cg); disk->d_cg.cg_cgx, cg);
@ -249,19 +292,22 @@ cgwrite1(struct uufsd *disk, int cg)
} }
int 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) { if ((fs->fs_metackhash & CK_CYLGRP) != 0) {
cgp->cg_ckhash = 0; cgp->cg_ckhash = 0;
cgp->cg_ckhash = cgp->cg_ckhash =
calculate_crc32c(~0L, (void *)cgp, fs->fs_cgsize); calculate_crc32c(~0L, (void *)cgp, fs->fs_cgsize);
} }
if (bwrite(disk, fsbtodb(fs, cgtod(fs, cgp->cg_cgx)), cgp, failmsg = NULL;
fs->fs_cgsize) == -1) { if ((cnt = pwrite(devfd, cgp, fs->fs_cgsize,
ERROR(disk, "unable to write cylinder group"); 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 (-1);
} }
return (0); return (0);

View File

@ -9,7 +9,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd November 10, 2018 .Dd September 2, 2020
.Dt GETINODE 3 .Dt GETINODE 3
.Os .Os
.Sh NAME .Sh NAME
@ -128,4 +128,4 @@ These functions first appeared as part of
in in
.Fx 13.0 . .Fx 13.0 .
.Sh AUTHORS .Sh AUTHORS
.An Marshall Kirk McKusick Aq Mt mckusick@freebsd.org .An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org

View File

@ -7,7 +7,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd November 26, 2018 .Dd September 2, 2020
.Dt LIBUFS 3 .Dt LIBUFS 3
.Os .Os
.Sh NAME .Sh NAME
@ -80,6 +80,7 @@ library first appeared in
.Fx 5.0 . .Fx 5.0 .
.Sh AUTHORS .Sh AUTHORS
.An Juli Mallett Aq Mt jmallett@FreeBSD.org .An Juli Mallett Aq Mt jmallett@FreeBSD.org
.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org
.Pp .Pp
.An -nosplit .An -nosplit
Additional design, feedback, and ideas were provided by Additional design, feedback, and ideas were provided by

View File

@ -136,8 +136,8 @@ int berase(struct uufsd *, ufs2_daddr_t, ufs2_daddr_t);
ufs2_daddr_t cgballoc(struct uufsd *); ufs2_daddr_t cgballoc(struct uufsd *);
int cgbfree(struct uufsd *, ufs2_daddr_t, long); int cgbfree(struct uufsd *, ufs2_daddr_t, long);
ino_t cgialloc(struct uufsd *); ino_t cgialloc(struct uufsd *);
int cgget(struct uufsd *, int, struct cg *); int cgget(int, struct fs *, int, struct cg *);
int cgput(struct uufsd *, struct cg *); int cgput(int, struct fs *, struct cg *);
int cgread(struct uufsd *); int cgread(struct uufsd *);
int cgread1(struct uufsd *, int); int cgread1(struct uufsd *, int);
int cgwrite(struct uufsd *); int cgwrite(struct uufsd *);

View File

@ -186,7 +186,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite)
use_pwrite)) != 0) { use_pwrite)) != 0) {
fs->fs_sblockactualloc = savedactualloc; fs->fs_sblockactualloc = savedactualloc;
fs->fs_csp = savedcsp; fs->fs_csp = savedcsp;
return (-1); return (error);
} }
} }
fs->fs_sblockactualloc = savedactualloc; fs->fs_sblockactualloc = savedactualloc;

View File

@ -11,7 +11,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 19, 2018 .Dd September 2, 2020
.Dt SBREAD 3 .Dt SBREAD 3
.Os .Os
.Sh NAME .Sh NAME
@ -145,3 +145,4 @@ in
.Fx 5.0 . .Fx 5.0 .
.Sh AUTHORS .Sh AUTHORS
.An Juli Mallett Aq Mt jmallett@FreeBSD.org .An Juli Mallett Aq Mt jmallett@FreeBSD.org
.An Marshall Kirk McKusick Aq Mt mckusick@FreeBSD.org

View File

@ -217,6 +217,9 @@ bufinit(void)
/* /*
* Manage cylinder group buffers. * 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 struct bufarea *cgbufs; /* header for cylinder group cache */
static int flushtries; /* number of tries to reclaim memory */ static int flushtries; /* number of tries to reclaim memory */
@ -370,7 +373,7 @@ flush(int fd, struct bufarea *bp)
fsmodified = 1; fsmodified = 1;
break; break;
case BT_CYLGRP: case BT_CYLGRP:
if (cgput(&disk, bp->b_un.b_cg) == 0) if (cgput(fswritefd, &sblock, bp->b_un.b_cg) == 0)
fsmodified = 1; fsmodified = 1;
break; break;
default: default:

View File

@ -133,7 +133,7 @@ getcg(int cg)
if (cgc == NULL) if (cgc == NULL)
err(1, "malloc(%zu)", sizeof(*cgc)); 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); err(1, "cgget(%d)", cg);
cgc->cgc_busy = 0; cgc->cgc_busy = 0;
cgc->cgc_dirty = 0; cgc->cgc_dirty = 0;
@ -189,7 +189,7 @@ putcgs(void)
LIST_REMOVE(cgc, cgc_next); LIST_REMOVE(cgc, cgc_next);
ncgs--; ncgs--;
if (cgc->cgc_dirty) { 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); err(1, "cgput(%d)", cgc->cgc_cg.cg_cgx);
//printf("%s: Wrote cg=%d\n", __func__, //printf("%s: Wrote cg=%d\n", __func__,
// cgc->cgc_cg.cg_cgx); // cgc->cgc_cg.cg_cgx);

View File

@ -1912,7 +1912,7 @@ cg_write(struct suj_cg *sc)
* before writing the block. * before writing the block.
*/ */
fs->fs_cs(fs, sc->sc_cgx) = cgp->cg_cs; 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); err_suj("Unable to write cylinder group %d\n", sc->sc_cgx);
} }