Author: smh
Date: Thu Jan 21 08:58:39 2016
New Revision: 294493
URL: https://svnweb.freebsd.org/changeset/base/294493

Log:
  Fix EFI UFS caching
  
  EFI was mixing caching in two separate places causing issues when multiple
  partitions where tested.
  
  Eliminate this by removing fsstat and re-factoring fsread into fsread_size,
  adding basic parameter validation.
  
  Also:
  * Enhance some error print outs.
  * Fix compilation under UFS1_ONLY and UFS2_ONLY
  * Use sizeof on vars instead of structs.
  * Add basic parameter validation to fsread_size.
  
  MFC after:    1 week
  X-MFC-With:   r293268
  Sponsored by: Multiplay
  Differential Revision:        https://reviews.freebsd.org/D4989

Modified:
  head/sys/boot/common/ufsread.c
  head/sys/boot/efi/boot1/ufs_module.c

Modified: head/sys/boot/common/ufsread.c
==============================================================================
--- head/sys/boot/common/ufsread.c      Thu Jan 21 08:51:24 2016        
(r294492)
+++ head/sys/boot/common/ufsread.c      Thu Jan 21 08:58:39 2016        
(r294493)
@@ -165,7 +165,7 @@ static int sblock_try[] = SBLOCKSEARCH;
 #endif
 
 static ssize_t
-fsread(ufs_ino_t inode, void *buf, size_t nbyte)
+fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep)
 {
 #ifndef UFS2_ONLY
        static struct ufs1_dinode dp1;
@@ -185,6 +185,10 @@ fsread(ufs_ino_t inode, void *buf, size_
        static ufs2_daddr_t blkmap, indmap;
        u_int u;
 
+       /* Basic parameter validation. */
+       if ((buf == NULL && nbyte != 0) || dmadat == NULL)
+               return (-1);
+
        blkbuf = dmadat->blkbuf;
        indbuf = dmadat->indbuf;
 
@@ -231,18 +235,18 @@ fsread(ufs_ino_t inode, void *buf, size_
                        return -1;
                n = INO_TO_VBO(n, inode);
 #if defined(UFS1_ONLY)
-               memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
-                   sizeof(struct ufs1_dinode));
+               memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
+                   sizeof(dp1));
 #elif defined(UFS2_ONLY)
-               memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
-                   sizeof(struct ufs2_dinode));
+               memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
+                   sizeof(dp2));
 #else
                if (fs.fs_magic == FS_UFS1_MAGIC)
                        memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
-                           sizeof(struct ufs1_dinode));
+                           sizeof(dp1));
                else
                        memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
-                           sizeof(struct ufs2_dinode));
+                           sizeof(dp2));
 #endif
                inomap = inode;
                fs_off = 0;
@@ -306,5 +310,17 @@ fsread(ufs_ino_t inode, void *buf, size_
                fs_off += n;
                nb -= n;
        }
+
+       if (fsizep != NULL)
+               *fsizep = size;
+
        return nbyte;
 }
+
+static ssize_t
+fsread(ufs_ino_t inode, void *buf, size_t nbyte)
+{
+
+       return fsread_size(inode, buf, nbyte, NULL);
+}
+

Modified: head/sys/boot/efi/boot1/ufs_module.c
==============================================================================
--- head/sys/boot/efi/boot1/ufs_module.c        Thu Jan 21 08:51:24 2016        
(r294492)
+++ head/sys/boot/efi/boot1/ufs_module.c        Thu Jan 21 08:58:39 2016        
(r294493)
@@ -68,93 +68,23 @@ dskread(void *buf, u_int64_t lba, int nb
 
 #include "ufsread.c"
 
-static ssize_t
-fsstat(ufs_ino_t inode)
+static struct dmadat __dmadat;
+
+static int
+init_dev(dev_info_t* dev)
 {
-#ifndef UFS2_ONLY
-       static struct ufs1_dinode dp1;
-#endif
-#ifndef UFS1_ONLY
-       static struct ufs2_dinode dp2;
-#endif
-       static struct fs fs;
-       static ufs_ino_t inomap;
-       char *blkbuf;
-       void *indbuf;
-       size_t n, size;
-       static ufs2_daddr_t blkmap, indmap;
-
-       blkbuf = dmadat->blkbuf;
-       indbuf = dmadat->indbuf;
-       if (!dsk_meta) {
-               inomap = 0;
-               for (n = 0; sblock_try[n] != -1; n++) {
-                       if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
-                           SBLOCKSIZE / DEV_BSIZE))
-                               return (-1);
-                       memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-                       if ((
-#if defined(UFS1_ONLY)
-                           fs.fs_magic == FS_UFS1_MAGIC
-#elif defined(UFS2_ONLY)
-                           (fs.fs_magic == FS_UFS2_MAGIC &&
-                           fs.fs_sblockloc == sblock_try[n])
-#else
-                           fs.fs_magic == FS_UFS1_MAGIC ||
-                           (fs.fs_magic == FS_UFS2_MAGIC &&
-                           fs.fs_sblockloc == sblock_try[n])
-#endif
-                           ) &&
-                           fs.fs_bsize <= MAXBSIZE &&
-                           fs.fs_bsize >= (int32_t)sizeof(struct fs))
-                               break;
-               }
-               if (sblock_try[n] == -1) {
-                       return (-1);
-               }
-               dsk_meta++;
-       } else
-               memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-       if (!inode)
-               return (0);
-       if (inomap != inode) {
-               n = IPERVBLK(&fs);
-               if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
-                       return (-1);
-               n = INO_TO_VBO(n, inode);
-#if defined(UFS1_ONLY)
-               memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
-                   sizeof(struct ufs1_dinode));
-#elif defined(UFS2_ONLY)
-               memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
-                   sizeof(struct ufs2_dinode));
-#else
-               if (fs.fs_magic == FS_UFS1_MAGIC)
-                       memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
-                           sizeof(struct ufs1_dinode));
-               else
-                       memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
-                           sizeof(struct ufs2_dinode));
-#endif
-               inomap = inode;
-               fs_off = 0;
-               blkmap = indmap = 0;
-       }
-       size = DIP(di_size);
-       n = size - fs_off;
 
-       return (n);
-}
+       devinfo = dev;
+       dmadat = &__dmadat;
 
-static struct dmadat __dmadat;
+       return fsread(0, NULL, 0);
+}
 
 static EFI_STATUS
 probe(dev_info_t* dev)
 {
 
-       devinfo = dev;
-       dmadat = &__dmadat;
-       if (fsread(0, NULL, 0) < 0)
+       if (init_dev(dev) < 0)
                return (EFI_UNSUPPORTED);
 
        add_device(&devices, dev);
@@ -171,14 +101,15 @@ try_load(dev_info_t *dev, const char *lo
        ssize_t read;
        void *buf;
 
-       dsk_meta = 0;
-       devinfo = dev;
+       if (init_dev(dev) < 0)
+               return (EFI_UNSUPPORTED);
+
        if ((ino = lookup(loader_path)) == 0)
                return (EFI_NOT_FOUND);
 
-       size = fsstat(ino);
-       if (size <= 0) {
-               printf("Failed to fsstat %s ino: %d\n", loader_path, ino);
+       if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
+               printf("Failed to read size of '%s' ino: %d\n", loader_path,
+                   ino);
                return (EFI_INVALID_PARAMETER);
        }
 
@@ -191,7 +122,7 @@ try_load(dev_info_t *dev, const char *lo
 
        read = fsread(ino, buf, size);
        if ((size_t)read != size) {
-               printf("Failed to read %s (%zd != %zu)\n", loader_path, read,
+               printf("Failed to read '%s' (%zd != %zu)\n", loader_path, read,
                    size);
                (void)bs->FreePool(buf);
                return (EFI_INVALID_PARAMETER);
_______________________________________________
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