svn commit: r365919 - in head: lib/libufs sbin/fsck_ffs

Kirk McKusick mckusick at FreeBSD.org
Sat Sep 19 22:48:33 UTC 2020


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 at FreeBSD.org
+.An Marshall Kirk McKusick Aq Mt mckusick at 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 at freebsd.org
+.An Marshall Kirk McKusick Aq Mt mckusick at 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 at FreeBSD.org
+.An Marshall Kirk McKusick Aq Mt mckusick at 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 at FreeBSD.org
+.An Marshall Kirk McKusick Aq Mt mckusick at 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);
 }
 


More information about the svn-src-head mailing list