From 59223edaa18759982db0a8aced0e77457d10c68e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Jun 1999 13:25:08 +0000 Subject: Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't have a MIPS box at hand. --- fs/umsdos/README-WIP.txt | 25 +++++++++++------------ fs/umsdos/check.c | 2 +- fs/umsdos/dir.c | 22 ++++++++++++++++++-- fs/umsdos/inode.c | 52 ++++++++++++++---------------------------------- 4 files changed, 48 insertions(+), 53 deletions(-) (limited to 'fs/umsdos') diff --git a/fs/umsdos/README-WIP.txt b/fs/umsdos/README-WIP.txt index 4535ec6ab..f53426a13 100644 --- a/fs/umsdos/README-WIP.txt +++ b/fs/umsdos/README-WIP.txt @@ -14,7 +14,7 @@ you are trying to use UMSDOS as root partition. Legend: those lines marked with '+' on the beggining of line indicates it passed all of my tests, and performed perfect in all of them. -Current status (981129) - UMSDOS dentry-pre 0.84: +Current status (990202) - UMSDOS 0.85: (1) pure MSDOS (no --linux-.--- EMD file): @@ -56,7 +56,7 @@ READ: WRITE: + create symlink - works -- create hardlink - works, but see portability WARNING below +- create hardlink - works + create file - works + create special file - works + write to file - works @@ -90,24 +90,23 @@ example is specs file about it. Specifically, moving directory which contains hardlinks will break them. Note: (about pseudoroot) If you are currently trying to use UMSDOS as root -partition (with linux installed in c:\linux) it will boot, but there are +partition (with linux installed in c:\linux) it will boot, but there may be some problems. Volunteers ready to test pseudoroot are needed (preferably -ones with working backups or unimportant data). There are problems with -different interpretation of hard links in normal in pseudo-root modes, -resulting is 'silent delete' of them sometimes. Also, '/DOS' pseudo +ones with working backups or unimportant data). For example, '/DOS' pseudo directory is only partially re-implemented and buggy. It works most of the time, though. Update: should work ok in 0.84, although it still does not work correctly in combination with initrd featere. Working on this! -Warning: (about creating hardlinks in pseudoroot mode) - hardlinks created in -pseudoroot mode are not compatibile with 'normal' hardlinks, and vice versa. -That is because harlink which is /foo in pseudoroot mode, becomes -/linux/foo in normal mode. I'm thinking about this one. However, since most -people either always use pseudoroot, or always use normal umsdos filesystem, -this is no showstopper. +Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in +pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice +versa. Thanks to Sorin Iordachescu for providing fix. -Warning: (about hardlinks) - modifying hardlinks (esp. if there are in +Warning: (about hardlinks) - modifying hardlinks (esp. if they are in different directories) are currently somewhat broken, I'm working on it. +Problem seems to be that code uses and updates EMD of directory where 'real +hardlink' is stored, not EMD of directory where our pseudo-hardlink is +located! I'm looking for ideas how to work around this in clean way, since +without it modifying hardlinks in any but most simple ways is broken! ------------------------------------------------------------------------------ diff --git a/fs/umsdos/check.c b/fs/umsdos/check.c index 6516fb57d..e9860caae 100644 --- a/fs/umsdos/check.c +++ b/fs/umsdos/check.c @@ -212,7 +212,7 @@ void check_dentry_path (struct dentry *dentry, const char *desc) while (dentry && count < 10) { check_dent_int (dentry, count++); - if (dentry == dentry->d_parent) { + if (IS_ROOT(dentry)) { printk (KERN_DEBUG "*** end checking dentry (root reached ok)\n"); break; } diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c index 799f685de..a780a9587 100644 --- a/fs/umsdos/dir.c +++ b/fs/umsdos/dir.c @@ -670,10 +670,20 @@ char * umsdos_d_path(struct dentry *dentry, char * buffer, int len) /* N.B. not safe -- fix this soon! */ current->fs->root = dentry->d_sb->s_root; path = d_path(dentry, buffer, len); + + if (*path == '/') + path++; /* skip leading '/' */ + + if (old_root->d_inode == pseudo_root) + { + *(path-1) = '/'; + path -= (UMSDOS_PSDROOT_LEN+1); + memcpy(path, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN); + } + current->fs->root = old_root; return path; } - /* * Return the dentry which points to a pseudo-hardlink. @@ -718,7 +728,14 @@ hlink->d_parent->d_name.name, hlink->d_name.name, path); /* start at root dentry */ dentry_dst = dget(base); path[len] = '\0'; - pt = path + 1; /* skip leading '/' */ + + pt = path; + if (*path == '/') + pt++; /* skip leading '/' */ + + if (base->d_inode == pseudo_root) + pt += (UMSDOS_PSDROOT_LEN + 1); + while (1) { struct dentry *dir = dentry_dst, *demd; char *start = pt; @@ -741,6 +758,7 @@ printk ("umsdos_solve_hlink: dir %s/%s, name=%s, real=%d\n", dir->d_parent->d_name.name, dir->d_name.name, start, real); #endif dentry_dst = umsdos_lookup_dentry(dir, start, len, real); +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ if (real) d_drop(dir); dput (dir); diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c index c7c94b558..81806ca18 100644 --- a/fs/umsdos/inode.c +++ b/fs/umsdos/inode.c @@ -60,8 +60,8 @@ void UMSDOS_put_inode (struct inode *inode) " Notify jacques@solucorp.qc.ca\n"); } - inode->u.umsdos_i.i_patched = 0; - fat_put_inode (inode); + if (inode->i_count == 1) + inode->u.umsdos_i.i_patched = 0; } @@ -163,36 +163,9 @@ dentry, f_pos)); umsdos_setup_dir(dentry); } else if (S_ISLNK (inode->i_mode)) { inode->i_op = &umsdos_symlink_inode_operations; - } else if (S_ISCHR (inode->i_mode)) { - inode->i_op = &chrdev_inode_operations; - } else if (S_ISBLK (inode->i_mode)) { - inode->i_op = &blkdev_inode_operations; - } else if (S_ISFIFO (inode->i_mode)) { - init_fifo (inode); - } -} - - -/* - * Load an inode from disk. - */ -/* #Specification: Inode / post initialisation - * To completely initialise an inode, we need access to the owner - * directory, so we can locate more info in the EMD file. This is - * not available the first time the inode is accessed, so we use - * a value in the inode to tell if it has been finally initialised. - * - * New inodes are obtained by the lookup and create routines, and - * each of these must ensure that the inode gets patched. - */ -void UMSDOS_read_inode (struct inode *inode) -{ - Printk ((KERN_DEBUG "UMSDOS_read_inode %p ino = %lu ", - inode, inode->i_ino)); - msdos_read_inode (inode); - - /* inode needs patching */ - inode->u.umsdos_i.i_patched = 0; + } else + init_special_inode(inode, inode->i_mode, + kdev_t_to_nr(inode->i_rdev)); } @@ -341,7 +314,7 @@ void UMSDOS_write_inode (struct inode *inode) static struct super_operations umsdos_sops = { - UMSDOS_read_inode, /* read_inode */ + NULL, /* read_inode */ UMSDOS_write_inode, /* write_inode */ UMSDOS_put_inode, /* put_inode */ fat_delete_inode, /* delete_inode */ @@ -349,7 +322,8 @@ static struct super_operations umsdos_sops = UMSDOS_put_super, /* put_super */ NULL, /* write_super */ fat_statfs, /* statfs */ - NULL /* remount_fs */ + NULL, /* remount_fs */ + fat_clear_inode, /* clear_inode */ }; /* @@ -371,7 +345,7 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data, if (!res) goto out_fail; - printk (KERN_INFO "UMSDOS dentry-pre 0.84 " + printk (KERN_INFO "UMSDOS 0.85 " "(compatibility level %d.%d, fast msdos)\n", UMSDOS_VERSION, UMSDOS_RELEASE); @@ -416,16 +390,20 @@ out_fail: /* * Check for an alternate root if we're the root device. */ + +extern kdev_t ROOT_DEV; static struct dentry *check_pseudo_root(struct super_block *sb) { struct dentry *root, *init; /* * Check whether we're mounted as the root device. - * If so, this should be the only superblock. + * must check like this, because we can be used with initrd */ - if (sb->s_list.next->next != &sb->s_list) + + if (sb->s_dev != ROOT_DEV) goto out_noroot; + printk("check_pseudo_root: mounted as root\n"); root = lookup_dentry(UMSDOS_PSDROOT_NAME, dget(sb->s_root), 0); -- cgit v1.2.3