From 07fb737fb60c08eaaa41989d531fc23009523546 Mon Sep 17 00:00:00 2001 From: Robert Yang Date: Wed, 31 Dec 2014 16:09:18 +0800 Subject: [PATCH 2/9] 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 Tested-by: Du Dolpher --- linux/Makefile | 2 +- linux/syslinux.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/linux/Makefile b/linux/Makefile index 11667e1..ac1ac58 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -51,7 +51,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 36fc202..cc4e7da 100755 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -72,6 +72,7 @@ #include "syslxfs.h" #include "setadv.h" #include "syslxopt.h" /* unified options */ +#include extern const char *program; /* Name of program */ @@ -82,6 +83,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); @@ -266,6 +270,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 */ -- 1.9.1