summaryrefslogtreecommitdiffstats
path: root/fs/umsdos
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/umsdos
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/umsdos')
-rw-r--r--fs/umsdos/README-WIP.txt10
-rw-r--r--fs/umsdos/check.c9
-rw-r--r--fs/umsdos/dir.c8
-rw-r--r--fs/umsdos/inode.c9
-rw-r--r--fs/umsdos/ioctl.c7
-rw-r--r--fs/umsdos/namei.c62
-rw-r--r--fs/umsdos/rdir.c3
-rw-r--r--fs/umsdos/symlink.c139
8 files changed, 76 insertions, 171 deletions
diff --git a/fs/umsdos/README-WIP.txt b/fs/umsdos/README-WIP.txt
index f53426a13..9c09891de 100644
--- a/fs/umsdos/README-WIP.txt
+++ b/fs/umsdos/README-WIP.txt
@@ -11,6 +11,16 @@ I'd call it pre-release, and ask for as many people as possible to
come and test it! See notes below for some more information, or if
you are trying to use UMSDOS as root partition.
+Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
+will compile and work on 2.2.x kernels and glibc based systems may be found
+at http://cvs.linux.hr/
+
+Also look at the quick-hack "homepage" for umsdos filesystem at
+http://www.voyager.hr/~mnalis/umsdos
+
+Information below is getting outdated slowly -- I'll fix it one day when I
+get enough time - there are more important things to fix right now.
+
Legend: those lines marked with '+' on the beggining of line indicates it
passed all of my tests, and performed perfect in all of them.
diff --git a/fs/umsdos/check.c b/fs/umsdos/check.c
index 1eda3df93..6eebff74a 100644
--- a/fs/umsdos/check.c
+++ b/fs/umsdos/check.c
@@ -60,6 +60,14 @@ void check_page_tables (void)
#if UMS_DEBUG
/*
+ * check for wait queue in 2.3.x
+ */
+inline void uq_log (char *txt, struct inode *inode)
+{
+ printk (KERN_ERR "%s: (%lu) magic=%lu creator=%lu lock=%u\n", txt, inode->i_ino, inode->u.umsdos_i.dir_info.p.__magic, inode->u.umsdos_i.dir_info.p.__creator, inode->u.umsdos_i.dir_info.p.lock.lock);
+}
+
+/*
* check a superblock
*/
@@ -213,6 +221,7 @@ void check_dentry_path (struct dentry *dentry, const char *desc)
}
}
#else
+inline void uq_log (char *txt, struct inode *inode) {};
void check_sb (struct super_block *sb, const char c) {};
void check_inode (struct inode *inode) {};
void checkd_inode (struct inode *inode) {};
diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c
index c09c293cf..af875aa79 100644
--- a/fs/umsdos/dir.c
+++ b/fs/umsdos/dir.c
@@ -49,9 +49,7 @@ struct dentry_operations umsdos_dentry_operations =
umsdos_dentry_validate, /* d_revalidate(struct dentry *, int) */
NULL, /* d_hash */
NULL, /* d_compare */
- umsdos_dentry_dput, /* d_delete(struct dentry *) */
- NULL,
- NULL,
+ umsdos_dentry_dput /* d_delete(struct dentry *) */
};
@@ -834,9 +832,7 @@ struct inode_operations umsdos_dir_inode_operations =
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
- NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
- NULL, /* smap */
- NULL, /* revalidate */
+ NULL /* revalidate */
};
diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c
index 171aa15dc..252f8a48b 100644
--- a/fs/umsdos/inode.c
+++ b/fs/umsdos/inode.c
@@ -94,6 +94,11 @@ void umsdos_setup_dir(struct dentry *dir)
printk(KERN_ERR "umsdos_setup_dir: %s/%s not a dir!\n",
dir->d_parent->d_name.name, dir->d_name.name);
+ init_waitqueue_head (&inode->u.umsdos_i.dir_info.p);
+ inode->u.umsdos_i.dir_info.looking = 0;
+ inode->u.umsdos_i.dir_info.creating = 0;
+ inode->u.umsdos_i.dir_info.pid = 0;
+
inode->i_op = &umsdos_rdir_inode_operations;
if (umsdos_have_emd(dir)) {
Printk((KERN_DEBUG "umsdos_setup_dir: %s/%s using EMD\n",
@@ -311,7 +316,7 @@ static struct super_operations umsdos_sops =
NULL, /* write_super */
fat_statfs, /* statfs */
NULL, /* remount_fs */
- fat_clear_inode, /* clear_inode */
+ fat_clear_inode /* clear_inode */
};
/*
@@ -333,7 +338,7 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
if (!res)
goto out_fail;
- printk (KERN_INFO "UMSDOS 0.85 "
+ printk (KERN_INFO "UMSDOS 0.86 "
"(compatibility level %d.%d, fast msdos)\n",
UMSDOS_VERSION, UMSDOS_RELEASE);
diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c
index f26d19ba8..239043318 100644
--- a/fs/umsdos/ioctl.c
+++ b/fs/umsdos/ioctl.c
@@ -217,14 +217,11 @@ dentry->d_parent->d_name.name, dentry->d_name.name, cmd, data_ptr));
*
* Return 0 if success.
*/
- extern struct inode_operations umsdos_rdir_inode_operations;
ret = umsdos_make_emd(dentry);
Printk(("UMSDOS_ioctl_dir: INIT_EMD %s/%s, ret=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name, ret));
- dir->i_op = (ret == 0)
- ? &umsdos_dir_inode_operations
- : &umsdos_rdir_inode_operations;
+ umsdos_setup_dir (dentry);
goto out;
}
@@ -280,6 +277,8 @@ printk("umsdos_ioctl: renaming %s/%s to %s/%s\n",
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
ret = msdos_rename (dir, old_dentry, dir, new_dentry);
+ d_drop(new_dentry);
+ d_drop(old_dentry);
dput(new_dentry);
}
dput(old_dentry);
diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c
index 444e9ffae..415f5e3fb 100644
--- a/fs/umsdos/namei.c
+++ b/fs/umsdos/namei.c
@@ -22,7 +22,20 @@
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
-#if 1
+#define UMSDOS_DIR_LOCK
+
+#ifdef UMSDOS_DIR_LOCK
+
+static inline void u_sleep_on (struct inode *dir)
+{
+ sleep_on (&dir->u.umsdos_i.dir_info.p);
+}
+
+static inline void u_wake_up (struct inode *dir)
+{
+ wake_up (&dir->u.umsdos_i.dir_info.p);
+}
+
/*
* Wait for creation exclusivity.
* Return 0 if the dir was already available.
@@ -34,9 +47,10 @@ static int umsdos_waitcreate (struct inode *dir)
{
int ret = 0;
- if (dir->u.umsdos_i.u.dir_info.creating
- && dir->u.umsdos_i.u.dir_info.pid != current->pid) {
- sleep_on (&dir->u.umsdos_i.u.dir_info.p);
+ if (dir->u.umsdos_i.dir_info.creating
+ && dir->u.umsdos_i.dir_info.pid != current->pid) {
+ PRINTK (("creating && dir_info.pid=%lu, current->pid=%u\n", dir->u.umsdos_i.dir_info.pid, current->pid));
+ u_sleep_on (dir);
ret = 1;
}
return ret;
@@ -47,8 +61,8 @@ static int umsdos_waitcreate (struct inode *dir)
*/
static void umsdos_waitlookup (struct inode *dir)
{
- while (dir->u.umsdos_i.u.dir_info.looking) {
- sleep_on (&dir->u.umsdos_i.u.dir_info.p);
+ while (dir->u.umsdos_i.dir_info.looking) {
+ u_sleep_on (dir);
}
}
@@ -90,8 +104,8 @@ void umsdos_lockcreate (struct inode *dir)
* if we (the process) own the lock
*/
while (umsdos_waitcreate (dir) != 0);
- dir->u.umsdos_i.u.dir_info.creating++;
- dir->u.umsdos_i.u.dir_info.pid = current->pid;
+ dir->u.umsdos_i.dir_info.creating++;
+ dir->u.umsdos_i.dir_info.pid = current->pid;
umsdos_waitlookup (dir);
}
@@ -110,10 +124,10 @@ static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
if (umsdos_waitcreate (dir1) == 0
&& umsdos_waitcreate (dir2) == 0) {
/* We own both now */
- dir1->u.umsdos_i.u.dir_info.creating++;
- dir1->u.umsdos_i.u.dir_info.pid = current->pid;
- dir2->u.umsdos_i.u.dir_info.creating++;
- dir2->u.umsdos_i.u.dir_info.pid = current->pid;
+ dir1->u.umsdos_i.dir_info.creating++;
+ dir1->u.umsdos_i.dir_info.pid = current->pid;
+ dir2->u.umsdos_i.dir_info.creating++;
+ dir2->u.umsdos_i.dir_info.pid = current->pid;
break;
}
}
@@ -127,7 +141,7 @@ static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
void umsdos_startlookup (struct inode *dir)
{
while (umsdos_waitcreate (dir) != 0);
- dir->u.umsdos_i.u.dir_info.looking++;
+ dir->u.umsdos_i.dir_info.looking++;
}
/*
@@ -135,12 +149,12 @@ void umsdos_startlookup (struct inode *dir)
*/
void umsdos_unlockcreate (struct inode *dir)
{
- dir->u.umsdos_i.u.dir_info.creating--;
- if (dir->u.umsdos_i.u.dir_info.creating < 0) {
- printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.creating < 0: %d"
- ,dir->u.umsdos_i.u.dir_info.creating);
+ dir->u.umsdos_i.dir_info.creating--;
+ if (dir->u.umsdos_i.dir_info.creating < 0) {
+ printk ("UMSDOS: dir->u.umsdos_i.dir_info.creating < 0: %d"
+ ,dir->u.umsdos_i.dir_info.creating);
}
- wake_up (&dir->u.umsdos_i.u.dir_info.p);
+ u_wake_up (dir);
}
/*
@@ -148,12 +162,12 @@ void umsdos_unlockcreate (struct inode *dir)
*/
void umsdos_endlookup (struct inode *dir)
{
- dir->u.umsdos_i.u.dir_info.looking--;
- if (dir->u.umsdos_i.u.dir_info.looking < 0) {
- printk ("UMSDOS: dir->u.umsdos_i.u.dir_info.looking < 0: %d"
- ,dir->u.umsdos_i.u.dir_info.looking);
+ dir->u.umsdos_i.dir_info.looking--;
+ if (dir->u.umsdos_i.dir_info.looking < 0) {
+ printk ("UMSDOS: dir->u.umsdos_i.dir_info.looking < 0: %d"
+ ,dir->u.umsdos_i.dir_info.looking);
}
- wake_up (&dir->u.umsdos_i.u.dir_info.p);
+ u_wake_up (dir);
}
#else
@@ -475,8 +489,6 @@ out:
* Let's go for simplicity...
*/
-extern struct inode_operations umsdos_symlink_inode_operations;
-
/*
* AV. Should be called with dir->i_sem down.
*/
diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c
index c7bb8fb1b..2b972a524 100644
--- a/fs/umsdos/rdir.c
+++ b/fs/umsdos/rdir.c
@@ -252,6 +252,5 @@ struct inode_operations umsdos_rdir_inode_operations =
NULL, /* get_block */
NULL, /* truncate */
NULL, /* permission */
- NULL, /* smap */
- NULL, /* revalidate */
+ NULL /* revalidate */
};
diff --git a/fs/umsdos/symlink.c b/fs/umsdos/symlink.c
index 8f94230e3..7bcd09e44 100644
--- a/fs/umsdos/symlink.c
+++ b/fs/umsdos/symlink.c
@@ -5,143 +5,18 @@
* inspired from linux/fs/msdos/file.c Werner Almesberger
*
* Extended MS-DOS regular file handling primitives
+ *
+ * Wow. It looks like we could support them on FAT with little (if any)
+ * problems. Oh, well...
*/
-#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/umsdos_fs.h>
-#include <linux/malloc.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-static struct file_operations umsdos_symlink_operations;
-
-
-/*
- * Read the data associate with the symlink.
- * Return length read in buffer or a negative error code.
- *
- */
-
-int umsdos_readlink_x ( struct dentry *dentry,
- char *buffer,
- int bufsiz)
-{
- size_t size = dentry->d_inode->i_size;
- loff_t loffs = 0;
- ssize_t ret;
- struct file filp;
-
-Printk((KERN_DEBUG "UMSDOS_read: %s/%s, size=%u\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, size));
-
- fill_new_filp (&filp, dentry);
- filp.f_reada = 0;
- filp.f_flags = O_RDONLY;
- filp.f_op = &umsdos_symlink_operations;
-
- if (size > bufsiz)
- size = bufsiz;
-
- ret = fat_file_read (&filp, buffer, size, &loffs);
- if (ret != size) {
- ret = -EIO;
- }
- return ret;
-}
-
-
-
-static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen)
-{
- return umsdos_readlink_x (dentry, buffer, buflen);
-}
-
-/* this one mostly stolen from romfs :) */
-static struct dentry *UMSDOS_followlink (struct dentry *dentry,
- struct dentry *base,
- unsigned int follow)
-{
- struct inode *inode = dentry->d_inode;
- char *symname;
- int len, cnt;
- mm_segment_t old_fs = get_fs ();
-
-Printk((KERN_DEBUG "UMSDOS_followlink /mn/: (%s/%s)\n",
-dentry->d_parent->d_name.name, dentry->d_name.name));
-
- len = inode->i_size;
-
- if (!(symname = kmalloc (len + 1, GFP_KERNEL))) {
- dentry = ERR_PTR (-ENOMEM);
- goto outnobuf;
- }
-
- set_fs (KERNEL_DS); /* we read into kernel space this time */
- cnt = umsdos_readlink_x (dentry, symname, len);
- set_fs (old_fs);
-
- if (len != cnt) {
- dentry = ERR_PTR (-EIO);
- goto out;
- }
-
- symname[len] = 0;
- dentry = lookup_dentry (symname, base, follow);
- kfree (symname);
-
- if (0) {
- out:
- kfree (symname);
- outnobuf:
- dput (base);
- }
- return dentry;
-}
-
-/* needed to patch the file structure */
-static struct file_operations umsdos_symlink_operations =
-{
- NULL, /* lseek - default */
- NULL, /* read */
- NULL, /* write */
- NULL, /* readdir - bad */
- NULL, /* poll - default */
- NULL, /* ioctl - default */
- NULL, /* mmap */
- NULL, /* no special open is needed */
- NULL, /* no flush code */
- NULL, /* release */
- NULL /* fsync */
-};
-
struct inode_operations umsdos_symlink_inode_operations =
{
- NULL, /* default file operations (none) */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- UMSDOS_readlink, /* readlink */
- UMSDOS_followlink, /* followlink */
- fat_get_block, /* get_block */
- block_read_full_page, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
+ readlink: page_readlink,
+ follow_link: page_follow_link,
+ get_block: fat_get_block,
+ readpage: block_read_full_page
};
-