summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2016-01-21 08:58:39 +0000
committersmh <smh@FreeBSD.org>2016-01-21 08:58:39 +0000
commitfb833979a52c5f88b1332a1f59570adb8fb62a05 (patch)
treec18700088609f757816f2873e9bdd79c31948057
parent680c06aefca13f257787b61d6fa84f13bc31ce8d (diff)
downloadFreeBSD-src-fb833979a52c5f88b1332a1f59570adb8fb62a05.zip
FreeBSD-src-fb833979a52c5f88b1332a1f59570adb8fb62a05.tar.gz
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
-rw-r--r--sys/boot/common/ufsread.c30
-rw-r--r--sys/boot/efi/boot1/ufs_module.c101
2 files changed, 39 insertions, 92 deletions
diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c
index 08ab697..6f499f9 100644
--- a/sys/boot/common/ufsread.c
+++ b/sys/boot/common/ufsread.c
@@ -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_t nbyte)
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_t nbyte)
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_t nbyte)
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);
+}
+
diff --git a/sys/boot/efi/boot1/ufs_module.c b/sys/boot/efi/boot1/ufs_module.c
index 9181b6e..07c7152 100644
--- a/sys/boot/efi/boot1/ufs_module.c
+++ b/sys/boot/efi/boot1/ufs_module.c
@@ -68,93 +68,23 @@ dskread(void *buf, u_int64_t lba, int nblk)
#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 *loader_path, void **bufp, size_t *bufsize)
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 *loader_path, void **bufp, size_t *bufsize)
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);
OpenPOWER on IntegriCloud