Liu Aleaxander
2009-Oct-25 08:42 UTC
[syslinux] [Syslinux][fsc]Adding a generic path_lookup function in VFS
Hi hpa, I just added the generic path_lookup function for EXTLINUX. hpa, It changed a lot, so I want hear something from you. First , here is the main skeleton of the generic path_lookup function:> if (*name == '/') { > inode = this_fs->fs_ops->iget_root(); // The way to get the root > inode is different from different fs > while(*name == '/') > name++; > } else { > inode = this_inode; // pwd > } > parent = inode; > > while (*name) { > p = part; > while(*name && *name != '/') > *p++ = *name++; > *p = '\0'; > inode = this_fs->fs_ops->iget(part, parent); // get the inode > if (!inode) > goto err; > if (inode->mode == I_SYMLINK) { // handle the SYMLINK > file here > if (!this_fs->fs_ops->follow_symlink || > --symlink_count == 0 || /* limit check > */ > inode->size >= (uint32_t)inode->blksize) > goto err; > name = this_fs->fs_ops->follow_symlink(inode, name); > free_inode(inode); > continue; > } > > if (parent != this_inode) // we can't free > 'pwd' > free_inode(parent); > parent = inode; > if (! *name) // done > break; > while(*name == '/') > name++; > } >For I just applied it to EXTLINUX, and I don't want to break the other fs, I added two union structure in file structure:> struct file { > struct fs_info *fs; > union { > struct inode *inode; > struct open_file_t *open_file; > } u1; > union { > uint32_t offset; > uint32_t file_len; > } u2; > }; >the inode--offset pair is used in the generic path_lookup method, while the open_file--file_len pair is for the old method. And with the inode-offset pair, we don't need a more open_file_t structure in all fs more, and I did remove the open_file_t structure in ext2.c. And as I expected, it did not break the sys/iso/pxelinux. So for those haven't applied the generic path_lookup method, I added a detection in the beginning of searhdir function to make the older one work: /* for now, we just applied the universal path_lookup to EXTLINUX */> if (strcmp(this_fs->fs_ops->fs_name, "ext2") != 0) { > file->fs->fs_ops->searchdir(name, file); > > if (file->u1.open_file) { > regs->esi.w[0] = file_to_handle(file); > regs->eax.l = file->u2.file_len; > regs->eflags.l &= ~EFLAGS_ZF; > return; > } > > goto err; > } >then, followed by the generic path_lookup part. And here is the inode struct:> /* > * The inode structure, including the detail file information > */ > struct inode { > int mode; /* FILE , DIR or SYMLINK */ > uint32_t size; > uint32_t ino; /* Inode number */ > uint32_t atime; /* Access time */ > uint32_t mtime; /* Modify time */ > uint32_t ctime; /* Create time */ > uint32_t dtime; /* Delete time */ > int blocks; /* How many blocks the file take */ > uint32_t * data; /* The block address array where the file stored > */ > uint32_t flags; > int blkbits; > int blksize; > uint32_t file_acl; > }; >maybe it's a little complicated, since we didn't need that much filed, say the time fields. But I think it would be useful when we want to implement a fs tool in Syslinux, like the dir or ls command, or maybe even in hdt;) And the next, I added a pair of *local* malloc-free functions in core directory. The 'local' means temp, means it would be easily removed when we have a powerful memory manage system--- removing the malloc.c in core is OK. hpa, be honest, I haven't checked the malloc function in com32/lib carefully, since found it a little more complicated to be a *temp* method. So, I added a really independent and temp-enough one. Just as I expected, I removed a lots of 'local variables , structures and functions' in ext2.c. The open_file_t is gone, and the ext2_searchdir is gone, too. So, there is no definition of 'global variables' in the beginning of ext2.c now. Anyway, with my limit test, it works.And if you find anything wrong, please tell me. Thanks. Last, you can check the commit here<http://git.zytor.com/?p=users/liu/gsoc09_liu.git;a=commit;h=84b1443afbfe24eb6e338e8636e8e3759b9093d5> : -- regards Liu Aleaxander