summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-10 16:21:55 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-10 16:21:55 -0800
commit3db9073fdd604c253ab0ea0ce83373dc89f633f3 (patch)
tree57484aeaa33308e99eaade1f2f7e2d217a0f4b71
parentddd58320f422651a418731d6f8bd75f61df43293 (diff)
downloadsyslinux-4.00-pre18.tar.gz
fs: fix cwd setting for FAT/iso9660/extfssyslinux-4.00-pre18
Fix the cwd setting for FAT, iso9660 and ext*fs. In particular: When FS_THISIND is set in the filesystem flags, only memoize the parent directory iff we are currently doing a config file walk. Use this feature for ext*fs as well, this makes the pathbased branch fully featured. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs.c16
-rw-r--r--core/fs/ext2/ext2.c17
-rw-r--r--core/fs/fat/fat.c1
-rw-r--r--core/include/fs.h11
4 files changed, 19 insertions, 26 deletions
diff --git a/core/fs.c b/core/fs.c
index 0eac0f26..ecd5257d 100644
--- a/core/fs.c
+++ b/core/fs.c
@@ -5,14 +5,19 @@
#include <cache.h>
/* The currently mounted filesystem */
-struct fs_info *this_fs = NULL;
+struct fs_info *this_fs = NULL; /* Root filesystem */
static struct fs_info fs;
-struct inode *this_inode = NULL;
+static struct inode *this_inode = NULL; /* Current working directory */
/* Actual file structures (we don't have malloc yet...) */
struct file files[MAX_OPEN];
/*
+ * Set to FS_THISIND during the execution of load_config.
+ */
+enum fs_flags is_load_config = 0;
+
+/*
* Get a new inode structure
*/
struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data)
@@ -72,7 +77,10 @@ inline struct file *handle_to_file(uint16_t handle)
void load_config(void)
{
int err;
+
+ is_load_config = FS_THISIND;
err = this_fs->fs_ops->load_config();
+ is_load_config = 0;
#if 0
printf("Loading config file %s\n", err ? "failed" : "successed");
@@ -195,7 +203,7 @@ void searchdir(com32sys_t *regs)
/*
* For the relative path searching used in FAT and ISO fs.
*/
- if ((this_fs->fs_ops->fs_flags & FS_THISIND) &&
+ if ((this_fs->fs_ops->fs_flags & is_load_config) &&
(this_inode != parent)){
if (this_inode)
free_inode(this_inode);
@@ -297,4 +305,6 @@ void fs_init(com32sys_t *regs)
if (fs.fs_ops->iget_current)
this_inode = fs.fs_ops->iget_current(&fs);
+ else
+ this_inode = fs.fs_ops->iget_root(&fs); /* Will be set later */
}
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index fbb57be0..9cdbb3b7 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -303,13 +303,6 @@ static struct inode *ext2_iget_root(struct fs_info *fs)
return ext2_iget_by_inr(fs, EXT2_ROOT_INO);
}
-static struct inode *ext2_iget_current(struct fs_info *fs)
-{
- static int CurrentDir = 2;
-
- return ext2_iget_by_inr(fs, CurrentDir);
-}
-
static struct inode *ext2_iget(char *dname, struct inode *parent)
{
struct ext2_dir_entry *de;
@@ -323,7 +316,7 @@ static struct inode *ext2_iget(char *dname, struct inode *parent)
}
-static char * ext2_follow_symlink(struct inode *inode, const char *name_left)
+static char *ext2_follow_symlink(struct inode *inode, const char *name_left)
{
struct fs_info *fs = inode->fs;
int sec_per_block = 1 << (fs->block_shift - fs->sector_shift);
@@ -399,10 +392,8 @@ static int ext2_load_config(void)
char *config_name = "extlinux.conf";
com32sys_t regs;
- strcpy(ConfigName, config_name);
- *(uint32_t *)CurrentDirName = 0x00002f2e;
-
memset(&regs, 0, sizeof regs);
+ snprintf(ConfigName, FILENAME_MAX, "%s/extlinux.conf", CurrentDirName);
regs.edi.w[0] = OFFS_WRT(ConfigName, 0);
call16(core_open, &regs, &regs);
@@ -460,7 +451,7 @@ static int ext2_fs_init(struct fs_info *fs)
const struct fs_ops ext2_fs_ops = {
.fs_name = "ext2",
- .fs_flags = FS_USEMEM,
+ .fs_flags = FS_THISIND | FS_USEMEM,
.fs_init = ext2_fs_init,
.searchdir = NULL,
.getfssec = ext2_getfssec,
@@ -469,7 +460,7 @@ const struct fs_ops ext2_fs_ops = {
.unmangle_name = generic_unmangle_name,
.load_config = ext2_load_config,
.iget_root = ext2_iget_root,
- .iget_current = ext2_iget_current,
+ .iget_current = NULL,
.iget = ext2_iget,
.follow_symlink = ext2_follow_symlink,
.readdir = ext2_readdir
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index d723f288..c388dba7 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -759,7 +759,6 @@ static int vfat_load_config(void)
if (*CurrentDirName) { /* installed by extlinux not syslinux */
sprintf(ConfigName, "%s/extlinux.conf", CurrentDirName);
call16(core_open, &regs, &regs);
- strcpy(ConfigName, "extlinux.conf");
return regs.eflags.l & EFLAGS_ZF;
}
/* installed by syslinux */
diff --git a/core/include/fs.h b/core/include/fs.h
index 394b2ae1..2477e4e3 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -40,13 +40,8 @@ struct dirent; /* Directory entry structure */
struct file;
enum fs_flags {
FS_NODEV = 1 << 0,
- FS_USEMEM = 1 << 1, /* If we need a malloc routine, set it */
-
- /*
- * Update the this_inode pointer at each part of path searching. This
- * flag is just used for FAT and ISO fs for now.
- */
- FS_THISIND = 1 << 2,
+ FS_USEMEM = 1 << 1, /* If we need a malloc routine, set it */
+ FS_THISIND = 1 << 2, /* Set cwd based on config file location */
};
struct fs_ops {
@@ -91,8 +86,6 @@ struct inode {
char pvt[0]; /* Private filesystem data */
};
-extern struct inode *this_inode;
-
struct open_file_t;
struct file {