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 jmall...@freebsd.org
+.An Marshall Kirk McKusick Aq Mt mckus...@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 mckus...@freebsd.org
+.An Marshall Kirk McKusick Aq Mt mckus...@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 jmall...@freebsd.org
+.An Marshall Kirk McKusick Aq Mt mckus...@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 jmall...@freebsd.org
+.An Marshall Kirk McKusick Aq Mt mckus...@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);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to