svn commit: r294493 - in head/sys/boot: common efi/boot1
Steven Hartland
smh at FreeBSD.org
Thu Jan 21 08:58:40 UTC 2016
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);
More information about the svn-src-all
mailing list