blob: 1acd9b0b6958552a8bc4c82dd03fefb2c5ff20cf [file] [log] [blame]
From c6ddb179577dd4c4ea4d1d154f979e90e53d6bf1 Mon Sep 17 00:00:00 2001
From: Robert Yang <liezhi.yang@windriver.com>
Date: Wed, 31 Dec 2014 16:09:18 +0800
Subject: [PATCH] linux/syslinux: implement open_ext2_fs()
The open_ext2_fs() checks whether it is an ext2/ext3/ext4 device, and
return:
0: It is an ext2, ext3 or ext4.
1: Not an ext2, ext3 or ext4.
-1: unexpected error.
Upstream-Status: Submitted
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Tested-by: Du Dolpher <dolpher.du@intel.com>
---
linux/Makefile | 2 +-
linux/syslinux.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/linux/Makefile b/linux/Makefile
index 5a49d81..67cbbb4 100644
--- a/linux/Makefile
+++ b/linux/Makefile
@@ -52,7 +52,7 @@ spotless: clean
installer: syslinux syslinux-nomtools
syslinux: $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $^
+ $(CC) $(LDFLAGS) -o $@ $^ -lext2fs
syslinux-nomtools: syslinux
ln -f $< $@
diff --git a/linux/syslinux.c b/linux/syslinux.c
index 1cc276b..f3727ea 100755
--- a/linux/syslinux.c
+++ b/linux/syslinux.c
@@ -73,6 +73,7 @@
#include "syslxfs.h"
#include "setadv.h"
#include "syslxopt.h" /* unified options */
+#include <ext2fs/ext2fs.h>
extern const char *program; /* Name of program */
@@ -83,6 +84,9 @@ char *mntpath = NULL; /* Path on which to mount */
int loop_fd = -1; /* Loop device */
#endif
+ext2_filsys e2fs = NULL; /* Ext2/3/4 filesystem */
+ext2_ino_t root, cwd; /* The root and cwd of e2fs */
+
void __attribute__ ((noreturn)) die(const char *msg)
{
fprintf(stderr, "%s: %s\n", program, msg);
@@ -267,6 +271,82 @@ int do_open_file(char *name)
*/
static int open_ext2_fs(const char *device, const char *subdir)
{
+ int retval;
+ int open_flag = EXT2_FLAG_RW, mount_flags;
+ ext2_ino_t dirino;
+ char opt_string[40];
+
+ if (opt.offset) {
+ sprintf(opt_string, "offset=%llu", (unsigned long long)opt.offset);
+ retval = ext2fs_open2(device, opt_string, open_flag, 0, 0, unix_io_manager, &e2fs);
+ } else
+ retval = ext2fs_open(device, open_flag, 0, 0, unix_io_manager, &e2fs);
+ if (retval) {
+ /* It might not be an extN fs, so we need check magic firstly */
+ if (retval == EXT2_ET_BAD_MAGIC) {
+ /* Do nothing, return silently */
+ return 1;
+ } else {
+ fprintf(stderr, "%s: error while trying to open: %s\n",
+ program, device);
+ return -1;
+ }
+ }
+
+ /* Stop if it is mounted */
+ retval = ext2fs_check_if_mounted(device, &mount_flags);
+ if (retval) {
+ fprintf(stderr, "%s: ext2fs_check_if_mount() error on %s\n",
+ program, device);
+ goto fail;
+ }
+
+ if (mount_flags & EXT2_MF_MOUNTED) {
+ fprintf(stderr, "%s: %s is mounted\n", program, device);
+ goto fail;
+ }
+
+ e2fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
+
+ /* Read the inode map */
+ retval = ext2fs_read_inode_bitmap(e2fs);
+ if (retval) {
+ fprintf(stderr, "%s: while reading inode bitmap: %s\n",
+ program, device);
+ goto fail;
+ }
+
+ /* Read the block map */
+ retval = ext2fs_read_block_bitmap(e2fs);
+ if (retval) {
+ fprintf(stderr, "%s: while reading block bitmap: %s\n",
+ program, device);
+ goto fail;
+ }
+
+ root = cwd = EXT2_ROOT_INO;
+ /* Check the subdir */
+ if (strcmp(subdir, "/")) {
+ retval = ext2fs_namei(e2fs, root, cwd, subdir, &dirino);
+ if (retval) {
+ fprintf(stderr, "%s: failed to find dir %s on %s\n",
+ program, subdir, device);
+ goto fail;
+ }
+
+ retval = ext2fs_check_directory(e2fs, dirino);
+ if (retval) {
+ fprintf(stderr, "%s: failed to cd to: %s\n", program, subdir);
+ goto fail;
+ }
+ cwd = dirino;
+ }
+
+ return 0;
+
+fail:
+ (void) ext2fs_close(e2fs);
+ return -1;
}
/* The install func for ext2, ext3 and ext4 */