summaryrefslogtreecommitdiffstats
path: root/fs/umsdos
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
commit59223edaa18759982db0a8aced0e77457d10c68e (patch)
tree89354903b01fa0a447bffeefe00df3044495db2e /fs/umsdos
parentdb7d4daea91e105e3859cf461d7e53b9b77454b2 (diff)
Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't
have a MIPS box at hand.
Diffstat (limited to 'fs/umsdos')
-rw-r--r--fs/umsdos/README-WIP.txt25
-rw-r--r--fs/umsdos/check.c2
-rw-r--r--fs/umsdos/dir.c22
-rw-r--r--fs/umsdos/inode.c52
4 files changed, 48 insertions, 53 deletions
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 <sorin@rodae.ro> 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);