aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2020-09-19 22:48:30 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2020-09-19 22:48:30 +0000
commit85ee267a3eb58f9aa1a73a1abcf033c5c460b324 (patch)
tree76560a561871fae0dc3150bedadc7fd8751ceb9c
parenta29c0348f0653c25adb65e340e6f5a7edc86b8a2 (diff)
downloadsrc-85ee267a3eb58f9aa1a73a1abcf033c5c460b324.tar.gz
src-85ee267a3eb58f9aa1a73a1abcf033c5c460b324.zip
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
Notes
Notes: svn path=/head/; revision=365919
-rw-r--r--lib/libufs/cgread.319
-rw-r--r--lib/libufs/cgroup.c84
-rw-r--r--lib/libufs/getinode.34
-rw-r--r--lib/libufs/libufs.33
-rw-r--r--lib/libufs/libufs.h4
-rw-r--r--lib/libufs/sblock.c2
-rw-r--r--lib/libufs/sbread.33
-rw-r--r--sbin/fsck_ffs/fsutil.c5
-rw-r--r--sbin/fsck_ffs/gjournal.c4
-rw-r--r--sbin/fsck_ffs/suj.c2
10 files changed, 95 insertions, 35 deletions
diff --git a/lib/libufs/cgread.3 b/lib/libufs/cgread.3
index 70d4c78202d9..cbc633708506 100644
--- a/lib/libufs/cgread.3
+++ b/lib/libufs/cgread.3
@@ -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
diff --git a/lib/libufs/cgroup.c b/lib/libufs/cgroup.c
index 1f42155ba4e7..1c3e271c4295 100644
--- a/lib/libufs/cgroup.c
+++ b/lib/libufs/cgroup.c
@@ -188,25 +188,54 @@ 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;
@@ -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);
diff --git a/lib/libufs/getinode.3 b/lib/libufs/getinode.3
index 6aa5388cbd6d..fde249e86102 100644
--- a/lib/libufs/getinode.3
+++ b/lib/libufs/getinode.3
@@ -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
diff --git a/lib/libufs/libufs.3 b/lib/libufs/libufs.3
index f4f44a6d8de6..578b63d87345 100644
--- a/lib/libufs/libufs.3
+++ b/lib/libufs/libufs.3
@@ -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
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index ad990bbc0930..8160fdcd68a9 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -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 *);
diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c
index 54e6234633e3..1d687d6d41aa 100644
--- a/lib/libufs/sblock.c
+++ b/lib/libufs/sblock.c
@@ -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;
diff --git a/lib/libufs/sbread.3 b/lib/libufs/sbread.3
index 13cadd39d9b2..e97469f86873 100644
--- a/lib/libufs/sbread.3
+++ b/lib/libufs/sbread.3
@@ -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
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 98db9e2d50f5..94ea2cf792bf 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -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:
diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c
index 88d5c0e6c668..6e3dbd2da41e 100644
--- a/sbin/fsck_ffs/gjournal.c
+++ b/sbin/fsck_ffs/gjournal.c
@@ -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);
diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c
index e1e3da19e195..8ecd1f686ea7 100644
--- a/sbin/fsck_ffs/suj.c
+++ b/sbin/fsck_ffs/suj.c
@@ -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);
}