diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 3d9e9301a9f..7639471edf2 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -811,6 +811,14 @@ struct buffer_head *isofs_bread(struct inode *inode, sector_t block)
 	return sb_bread(inode->i_sb, blknr);
 }
 
+struct buffer_head *isofs_bread_uncached(struct inode *inode, sector_t block)
+{
+	sector_t blknr = isofs_bmap(inode, block);
+	if (!blknr)
+		return NULL;
+	return sb_bread_uncached(inode->i_sb, blknr);
+}
+
 static int isofs_read_folio(struct file *file, struct folio *folio)
 {
 	return mpage_read_folio(folio, isofs_get_block);
diff --git a/fs/isofs/interface.c b/fs/isofs/interface.c
index 6f07f9951f1..5f8cc749e08 100644
--- a/fs/isofs/interface.c
+++ b/fs/isofs/interface.c
@@ -478,8 +478,13 @@ int isofs_read(const char *filename, void *buf, loff_t offset, loff_t len,
 		block = offset / blksize;
 		blk_off = offset % blksize;
 
-		/* Read the block using isofs_bread (handles block mapping) */
-		bh = isofs_bread(inode, block);
+		/*
+		 * Use the uncached read path: the buffer cache is shared
+		 * across the whole VFS layer, and populating it from a
+		 * streaming file read of an arbitrarily large file would
+		 * exhaust the malloc heap before the read completes.
+		 */
+		bh = isofs_bread_uncached(inode, block);
 		if (!bh)
 			return -EIO;
 
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index 95d85f58733..7382bcc62b5 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -126,6 +126,22 @@ int get_acorn_filename(struct iso_directory_record *, char *, struct inode *);
 
 extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int flags);
 extern struct buffer_head *isofs_bread(struct inode *, sector_t);
+
+/**
+ * isofs_bread_uncached() - Read a file block without populating the cache
+ *
+ * Mirrors isofs_bread() but uses sb_bread_uncached() so the block is freed
+ * the moment the caller drops its reference. Useful for streaming large
+ * files (e.g. the casper kernel/initrd), where caching every block would
+ * exhaust the U-Boot malloc heap long before the read completes.
+ *
+ * @inode: Inode the block belongs to
+ * @block: Logical block number within the inode
+ * Return: buffer_head with the block contents, or NULL if the logical
+ *	   block does not map to a disk block
+ */
+extern struct buffer_head *isofs_bread_uncached(struct inode *inode,
+						sector_t block);
 extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
 
 struct inode *__isofs_iget(struct super_block *sb,
