patch-2.1.121 linux/fs/umsdos/inode.c
Next file: linux/fs/umsdos/ioctl.c
Previous file: linux/fs/umsdos/emd.c
Back to the patch index
Back to the overall index
- Lines: 1249
- Date:
Wed Sep 9 09:01:19 1998
- Orig file:
v2.1.120/linux/fs/umsdos/inode.c
- Orig date:
Sat Sep 5 16:46:41 1998
diff -u --recursive --new-file v2.1.120/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c
@@ -28,244 +28,55 @@
/*
* returns inode->i_dentry
- *
+ * Note: Deprecated; won't work reliably
*/
-inline struct dentry *geti_dentry (struct inode *inode)
+struct dentry *geti_dentry (struct inode *inode)
{
struct dentry *ret;
+
if (!inode) {
printk (KERN_ERR "geti_dentry: ERROR: inode is NULL!\n");
return NULL;
}
- if (inode->i_dentry.next == inode->i_dentry.next->next) {
- printk (KERN_WARNING "geti_dentry: WARNING: inode does not have an dentry. returning NULL.\n");
+ if (list_empty(&inode->i_dentry)) {
+ printk (KERN_WARNING
+ "geti_dentry: WARNING: no dentry for inode %ld\n",
+ inode->i_ino);
return NULL;
}
ret = list_entry (inode->i_dentry.next, struct dentry, d_alias);
- if (IS_ERR(ret)) {
- Printk ((KERN_WARNING "geti_dentry: checking dentry... it is ERR(%ld) !\n", PTR_ERR(ret)));
- }
-
- PRINTK ((KERN_DEBUG "geti_dentry : inode %lu: i_dentry is %p\n", inode->i_ino, ret));
+ PRINTK ((KERN_DEBUG "geti_dentry : inode %lu, dentry is %s/%s\n",
+ inode->i_ino, ret->d_parent->d_name.name, ret->d_name.name));
return ret;
}
-
-/*
- * makes inode->i_count++
- *
- */
-
-inline void inc_count (struct inode *inode)
-{
- inode->i_count++;
- PRINTK ((KERN_DEBUG "inc_count: inode %lu incremented count to %d\n", inode->i_ino, inode->i_count));
-}
-
-
/*
- * makes empty filp
- *
+ * Initialize a private filp
*/
-
void fill_new_filp (struct file *filp, struct dentry *dentry)
{
- Printk (("/mn/ fill_new_filp: filling empty filp at %p\n", filp));
- if (dentry)
- Printk ((" dentry=%.*s\n", (int) dentry->d_name.len, dentry->d_name.name));
- else
- Printk ((" dentry is NULL ! you must fill it later...\n"));
+ if (!dentry)
+ printk("fill_new_filp: NULL dentry!\n");
memset (filp, 0, sizeof (struct file));
-
- filp->f_pos = 0;
filp->f_reada = 1;
filp->f_flags = O_RDWR;
filp->f_dentry = dentry;
- filp->f_op = &umsdos_file_operations; /* /mn/ - we have to fill it with SOMETHING */
+ filp->f_op = &umsdos_file_operations;
}
-
-#if UMS_DEBUG
-/*
- * check a superblock
- */
-
-void check_sb (struct super_block *sb, const char c)
-{
- if (sb) {
- Printk ((" (has %c_sb=%d, %d)", c, MAJOR (sb->s_dev), MINOR (sb->s_dev)));
- } else {
- Printk ((" (%c_sb is NULL)", c));
- }
-}
-
-/*
- * check an inode
- */
-
-void check_inode (struct inode *inode)
-{
- if (inode) {
- Printk ((KERN_DEBUG "* inode is %lu (i_count=%d)", inode->i_ino, inode->i_count));
- check_sb (inode->i_sb, 'i');
-
- if (inode->i_dentry.next) { /* FIXME: does this work ? */
- Printk ((" (has i_dentry)"));
- } else {
- Printk ((" (NO i_dentry)"));
- }
-
- if (inode->i_op == NULL) {
- Printk ((" (i_op is NULL)\n"));
- } else if (inode->i_op == &umsdos_dir_inode_operations) {
- Printk ((" (i_op is umsdos_dir_inode_operations)\n"));
- } else if (inode->i_op == &umsdos_file_inode_operations) {
- Printk ((" (i_op is umsdos_file_inode_operations)\n"));
- } else if (inode->i_op == &umsdos_file_inode_operations_no_bmap) {
- Printk ((" (i_op is umsdos_file_inode_operations_no_bmap)\n"));
- } else if (inode->i_op == &umsdos_file_inode_operations_readpage) {
- Printk ((" (i_op is umsdos_file_inode_operations_readpage)\n"));
- } else if (inode->i_op == &umsdos_rdir_inode_operations) {
- Printk ((" (i_op is umsdos_rdir_inode_operations)\n"));
- } else if (inode->i_op == &umsdos_symlink_inode_operations) {
- Printk ((" (i_op is umsdos_symlink_inode_operations)\n"));
- } else {
- Printk ((" (i_op is UNKNOWN: %p)\n", inode->i_op));
- }
- } else {
- Printk ((KERN_DEBUG "* inode is NULL\n"));
- }
-}
-
-/*
- * checks all inode->i_dentry
- *
- */
-void checkd_inode (struct inode *inode)
-{
- struct dentry *ret;
- struct list_head *cur;
- int count = 0;
- if (!inode) {
- printk (KERN_ERR "checkd_inode: inode is NULL!\n");
- return;
- }
-
- Printk ((KERN_DEBUG "checkd_inode: inode %lu\n", inode->i_ino));
- cur = inode->i_dentry.next;
- while (count++ < 10) {
- PRINTK (("1..."));
- if (!cur) {
- Printk ((KERN_ERR "checkd_inode: *** NULL reached. exit.\n"));
- return;
- }
- PRINTK (("2..."));
- ret = list_entry (cur, struct dentry, d_alias);
- PRINTK (("3..."));
- if (cur == cur->next) {
- Printk ((KERN_DEBUG "checkd_inode: *** cur=cur->next: normal exit.\n"));
- return;
- }
- PRINTK (("4..."));
- if (!ret) {
- Printk ((KERN_ERR "checkd_inode: *** ret dentry is NULL. exit.\n"));
- return;
- }
- PRINTK (("5... (ret=%p)...", ret));
- PRINTK (("5.1.. (ret->d_dname=%p)...", &(ret->d_name)));
- PRINTK (("5.1.1. (ret->d_dname.len=%d)...", (int) ret->d_name.len));
- PRINTK (("5.1.2. (ret->d_dname.name=%c)...", ret->d_name.name));
- Printk ((KERN_DEBUG "checkd_inode: i_dentry is %.*s\n", (int) ret->d_name.len, ret->d_name.name));
- PRINTK (("6..."));
- cur = cur->next;
- PRINTK (("7..."));
-#if 1
- Printk ((KERN_DEBUG "checkd_inode: *** finished after count 1 (operator forced)\n"));
- return;
-#endif
- }
- Printk ((KERN_ERR "checkd_inode: *** OVER LIMIT (loop?) !\n"));
- return;
-}
-
-/*
- * internal part of check_dentry. does the real job.
- *
- */
-
-void check_dent_int (struct dentry *dentry, int parent)
-{
- if (parent) {
- Printk ((KERN_DEBUG "* parent(%d) dentry: %.*s\n", parent, (int) dentry->d_name.len, dentry->d_name.name));
- } else {
- Printk ((KERN_DEBUG "* checking dentry: %.*s\n", (int) dentry->d_name.len, dentry->d_name.name));
- }
- check_inode (dentry->d_inode);
- Printk ((KERN_DEBUG "* d_count=%d", dentry->d_count));
- check_sb (dentry->d_sb, 'd');
- if (dentry->d_op == NULL) {
- Printk ((" (d_op is NULL)\n"));
- } else {
- Printk ((" (d_op is UNKNOWN: %p)\n", dentry->d_op));
- }
-}
-
-/*
- * checks dentry with full traceback to root and prints info. Limited to 10 recursive depths to avoid infinite loops.
- *
- */
-
-void check_dentry_path (struct dentry *dentry, const char *desc)
-{
- int count=0;
- Printk ((KERN_DEBUG "*** check_dentry_path: %.60s\n", desc));
-
- if (!dentry) {
- Printk ((KERN_DEBUG "*** checking dentry... it is NULL !\n"));
- return;
- }
- if (IS_ERR(dentry)) {
- Printk ((KERN_DEBUG "*** checking dentry... it is ERR(%ld) !\n", PTR_ERR(dentry)));
- return;
- }
-
- while (dentry && count < 10) {
- check_dent_int (dentry, count++);
- if (dentry == dentry->d_parent) {
- Printk ((KERN_DEBUG "*** end checking dentry (root reached ok)\n"));
- break;
- }
- dentry = dentry->d_parent;
- }
-
- if (count >= 10) { /* if infinite loop detected */
- Printk ((KERN_ERR "*** WARNING ! INFINITE LOOP ! check_dentry_path aborted !\n"));
- }
-
- if (!dentry) {
- Printk ((KERN_ERR "*** WARNING ! found NULL dentry ! check_dentry_path aborted !\n"));
- }
-}
-#else
-void check_sb (struct super_block *sb, const char c) {};
-void check_inode (struct inode *inode) {};
-void checkd_inode (struct inode *inode) {};
-void check_dentry_path (struct dentry *dentry, const char *desc) {};
-#endif /* UMS_DEBUG */
-
-
-
/*
* makes dentry. for name name with length len.
* if inode is not NULL, puts it also.
+ * Note: Deprecated; use umsdos_lookup_dentry
*/
-struct dentry *creat_dentry (const char *name, const int len, struct inode *inode, struct dentry *parent)
+struct dentry *creat_dentry (const char *name, const int len,
+ struct inode *inode, struct dentry *parent)
{
/* FIXME /mn/: parent is not passed many times... if it is not, dentry should be destroyed before someone else gets to use it */
@@ -279,15 +90,9 @@
qname.name = name;
qname.len = len;
-#if 1
- #warning is full_name_hash OK for normal filenames? And for MSDOSFS accessed EMD files?
qname.hash = full_name_hash (name, len);
-#else
- qname.hash = 0;
-#endif
ret = d_alloc (parent, &qname); /* create new dentry */
- ret->d_inode = NULL;
if (parent) {
#if 0
@@ -303,7 +108,10 @@
if (inode) {
- if (!ret->d_sb) ret->d_sb = inode->i_sb; /* try to fill it in if available. If available in parent->d_sb, d_alloc will add it automatically */
+ /* try to fill it in if available. If available in
+ * parent->d_sb, d_alloc will add it automatically
+ */
+ if (!ret->d_sb) ret->d_sb = inode->i_sb;
d_add (ret, inode);
}
@@ -317,72 +125,17 @@
}
-/*
- * removes temporary dentry created by creat_dentry
- * it must have d_count of 1, and associated inode i_count of 1
- * to be completely cleared.
- *
- */
-
-void kill_dentry (struct dentry *dentry)
-{
- if (dentry) {
- check_dentry_path (dentry, "KILL_DENTRY B4");
- /* this idea for killing dentry (d_drop/dput pair) from NFS code. dcache.c code&comments seems to agree */
-#if 0
- d_drop (dentry);
- dput (dentry); /* we are done with it */
-#endif
- check_dentry_path (dentry, "KILL_DENTRY AFT");
- } else {
- Printk (("kill_dentry: dentry is NULL ?!\n"));
- }
-
-
- Printk ((KERN_DEBUG "kill_dentry: exiting...\n"));
- return;
-}
-
-
-/*
- * finishes work with dentry
- * it must have d_count of 1, and associated inode i_count of 1
- * to be completely cleared.
- *
- * Currently, this is same as kill_dentry, but this may (will) change.
- * kill_dentry will eventualy be killed (he who lives by the sword, dies
- * by the sword :-) when all faked dentries are nuked out...
- *
- */
-
-void fin_dentry (struct dentry *dentry)
-{
- if (dentry) {
- if (IS_ERR(dentry)) {
- Printk ((KERN_WARNING "fin_dentry: dentry is IS_ERR (%ld)?!\n", PTR_ERR (dentry)));
- } else {
- /* this idea for killing dentry (d_drop/dput pair) from NFS code. dcache.c code&comments seems to agree */
- d_drop (dentry);
- dput (dentry); /* we are done with it */
- }
- } else {
- Printk ((KERN_WARNING "fin_dentry: dentry is NULL ?!\n"));
- }
-
- PRINTK ((KERN_DEBUG "fin_dentry: exiting...\n"));
- return;
-}
-
-
void UMSDOS_put_inode (struct inode *inode)
{
- PRINTK ((KERN_DEBUG "put inode %p (%lu) owner %lu pos %lu dir %lu count=%d\n", inode
- ,inode->i_ino
+ PRINTK ((KERN_DEBUG
+ "put inode %p (%lu) owner %lu pos %lu dir %lu count=%d\n"
+ ,inode, inode->i_ino
,inode->u.umsdos_i.i_emd_owner, inode->u.umsdos_i.pos
,inode->u.umsdos_i.i_emd_dir, inode->i_count));
if (inode && pseudo_root && inode == pseudo_root) {
- printk (KERN_ERR "Umsdos: Oops releasing pseudo_root. Notify jacques@solucorp.qc.ca\n");
+ printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
+ " Notify jacques@solucorp.qc.ca\n");
}
fat_put_inode (inode);
@@ -392,61 +145,84 @@
void UMSDOS_put_super (struct super_block *sb)
{
Printk ((KERN_DEBUG "UMSDOS_put_super: entering\n"));
- check_dentry_path (sb->s_root, "put_super: START");
msdos_put_super (sb);
MOD_DEC_USE_COUNT;
}
-
/*
* Call msdos_lookup, but set back the original msdos function table.
* Return 0 if OK, or a negative error code if not.
+ * Dentry will hold inode of the file, if successful
*/
-int umsdos_real_lookup ( struct inode *dir,
- struct dentry *dentry) /* Will hold inode of the file, if successful */
+int umsdos_real_lookup (struct inode *dir, struct dentry *dentry)
{
int ret;
- PRINTK ((KERN_DEBUG "umsdos_real_lookup: looking for %.*s /", dentry->d_name.len, dentry->d_name.name));
- inc_count (dir);
+ PRINTK ((KERN_DEBUG "umsdos_real_lookup: looking for %s/%s /",
+ dentry->d_parent->d_name.name, dentry->d_name.name));
ret = msdos_lookup (dir, dentry);
- dentry->d_op = NULL; /* FIXME: Not needed? - if it was good once for MSDOS, it will be good any other time also. I hope :) */
- iput (dir); /* pair to inc_count(dir) above */
PRINTK (("/ returned %d\n", ret));
return ret;
}
/*
+ * Complete the setup of an directory dentry.
+ * First, it completes the function pointers, then
+ * it locates the EMD file. If the EMD is there, then plug the
+ * umsdos function table. If not, use the msdos one.
+ *
+ * {i,d}_counts are untouched by this function.
+ */
+void umsdos_setup_dir(struct dentry *dir)
+{
+ struct inode *inode = dir->d_inode;
+
+ if (!S_ISDIR(inode->i_mode))
+ printk(KERN_ERR "umsdos_setup_dir: %s/%s not a dir!\n",
+ dir->d_parent->d_name.name, dir->d_name.name);
+
+ inode->u.umsdos_i.i_emd_dir = 0;
+ inode->i_op = &umsdos_rdir_inode_operations;
+ if (umsdos_have_emd(dir)) {
+Printk((KERN_DEBUG "umsdos_setup_dir: %s/%s using EMD\n",
+dir->d_parent->d_name.name, dir->d_name.name));
+ inode->i_op = &umsdos_dir_inode_operations;
+ }
+}
+
+/*
* Complete the setup of an directory inode.
* First, it completes the function pointers, then
* it locates the EMD file. If the EMD is there, then plug the
* umsdos function table. If not, use the msdos one.
*
* {i,d}_counts are untouched by this function.
+ * Note: Deprecated; use above function if possible.
*/
void umsdos_setup_dir_inode (struct inode *inode)
{
+ struct inode *emd_dir;
+
inode->u.umsdos_i.i_emd_dir = 0;
- {
- struct inode *emd_dir;
- Printk ((KERN_DEBUG "umsdos_setup_dir_inode: Entering for inode=%lu\n", inode->i_ino));
- check_inode (inode);
- emd_dir = umsdos_emd_dir_lookup (inode, 0);
- Printk ((KERN_DEBUG "umsdos_setup_dir_inode: umsdos_emd_dir_lookup for inode=%lu returned %p\n", inode->i_ino, emd_dir));
- check_inode (inode);
- check_inode (emd_dir);
-
- if (emd_dir == NULL) {
- Printk ((KERN_DEBUG "umsdos_setup_dir_inode /mn/: Setting up rdir_inode_ops --> eg. NOT using EMD.\n"));
- inode->i_op = &umsdos_rdir_inode_operations;
- } else {
- Printk ((KERN_DEBUG "umsdos_setup_dir_inode /mn/: Setting up dir_inode_ops --> eg. using EMD.\n"));
- inode->i_op = &umsdos_dir_inode_operations;
- iput (emd_dir);
- }
+ Printk ((KERN_DEBUG
+ "umsdos_setup_dir_inode: Entering for inode=%lu\n",
+ inode->i_ino));
+ check_inode (inode);
+ emd_dir = umsdos_emd_dir_lookup (inode, 0);
+ Printk ((KERN_DEBUG "umsdos_setup_dir_inode: "
+ "umsdos_emd_dir_lookup for inode=%lu returned %p\n",
+ inode->i_ino, emd_dir));
+ check_inode (inode);
+ check_inode (emd_dir);
+
+ inode->i_op = &umsdos_rdir_inode_operations;
+ if (emd_dir) {
+ Printk ((KERN_DEBUG "umsdos_setup_dir_inode: using EMD.\n"));
+ inode->i_op = &umsdos_dir_inode_operations;
+ iput (emd_dir);
}
}
@@ -454,20 +230,20 @@
/*
* Add some info into an inode so it can find its owner quickly
*/
-void umsdos_set_dirinfo ( struct inode *inode,
- struct inode *dir,
- off_t f_pos)
-{
- struct inode *emd_owner;
-
- /* FIXME, I don't have a clue on this one - /mn/ Hmmm? OK? */
-/* Printk ((KERN_WARNING "umsdos_set_dirinfo: /mn/ FIXME: no clue. inode=%lu dir=%lu\n", inode->i_ino, dir->i_ino)); */
- emd_owner = umsdos_emd_dir_lookup (dir, 1);
- Printk (("umsdos_set_dirinfo: emd_owner is %lu for dir %lu\n", emd_owner->i_ino, dir->i_ino));
+void umsdos_set_dirinfo (struct inode *inode, struct inode *dir, off_t f_pos)
+{
+ struct inode *emd_owner = umsdos_emd_dir_lookup (dir, 1);
+
+ if (!emd_owner)
+ goto out;
+ Printk (("umsdos_set_dirinfo: emd_owner is %lu for dir %lu\n",
+ emd_owner->i_ino, dir->i_ino));
inode->u.umsdos_i.i_dir_owner = dir->i_ino;
inode->u.umsdos_i.i_emd_owner = emd_owner->i_ino;
- /* iput (emd_owner); / * FIXME? */
inode->u.umsdos_i.pos = f_pos;
+ iput (emd_owner);
+out:
+ return;
}
@@ -477,150 +253,143 @@
*/
int umsdos_isinit (struct inode *inode)
{
-#if 1
return inode->u.umsdos_i.i_emd_owner != 0;
-#elif 0
- return inode->i_atime != 0;
-#else
- return atomic_read (&inode->i_count) > 1;
-#endif
}
/*
* Connect the proper tables in the inode and add some info.
* i_counts is not changed.
+ *
+ * This function is called very early to setup the inode, somewhat
+ * too early (called by UMSDOS_read_inode). At this point, we can't
+ * do too much, such as lookup up EMD files and so on. This causes
+ * confusion in the kernel. This is why some initialisation
+ * will be done when dir != NULL only.
+ *
+ * UMSDOS do run piggy back on top of msdos fs. It looks like something
+ * is missing in the VFS to accommodate stacked fs. Still unclear what
+ * (quite honestly).
+ *
+ * Well, maybe one! A new entry "may_unmount" which would allow
+ * the stacked fs to allocate some inode permanently and release
+ * them at the end. Doing that now introduce a problem. unmount
+ * always fail because some inodes are in use.
+ */
+/* #Specification: inode / umsdos info
+ * The first time an inode is seen (inode->i_count == 1),
+ * the inode number of the EMD file which controls this inode
+ * is tagged to this inode. It allows operations such as
+ * notify_change to be handled.
*/
-
-void umsdos_patch_inode ( struct inode *inode,
- struct inode *dir, /* May be NULL */
- off_t f_pos)
+void umsdos_patch_inode (struct inode *inode, struct inode *dir, off_t f_pos)
{
- /*
- * This function is called very early to setup the inode, somewhat
- * too early (called by UMSDOS_read_inode). At this point, we can't
- * do too much, such as lookup up EMD files and so on. This causes
- * confusion in the kernel. This is why some initialisation
- * will be done when dir != NULL only.
- *
- * UMSDOS do run piggy back on top of msdos fs. It looks like something
- * is missing in the VFS to accommodate stacked fs. Still unclear what
- * (quite honestly).
- *
- * Well, maybe one! A new entry "may_unmount" which would allow
- * the stacked fs to allocate some inode permanently and release
- * them at the end. Doing that now introduce a problem. unmount
- * always fail because some inodes are in use.
- */
+ Printk ((KERN_DEBUG "Entering umsdos_patch_inode for inode=%lu\n",
+ inode->i_ino));
- Printk ((KERN_DEBUG "Entering umsdos_patch_inode for inode=%lu\n", inode->i_ino));
+ if (umsdos_isinit (inode))
+ goto already_init;
- if (!umsdos_isinit (inode)) {
- inode->u.umsdos_i.i_emd_dir = 0;
- if (S_ISREG (inode->i_mode)) {
- if (MSDOS_SB (inode->i_sb)->cvf_format) {
- if (MSDOS_SB (inode->i_sb)->cvf_format->flags & CVF_USE_READPAGE) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations_readpage\n"));
- inode->i_op = &umsdos_file_inode_operations_readpage;
- } else {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations_no_bmap\n"));
- inode->i_op = &umsdos_file_inode_operations_no_bmap;
- }
+ inode->u.umsdos_i.i_emd_dir = 0;
+ if (S_ISREG (inode->i_mode)) {
+ if (MSDOS_SB (inode->i_sb)->cvf_format) {
+ if (MSDOS_SB (inode->i_sb)->cvf_format->flags & CVF_USE_READPAGE) {
+Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations_readpage\n"));
+ inode->i_op = &umsdos_file_inode_operations_readpage;
} else {
- if (inode->i_op->bmap != NULL) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations\n"));
- inode->i_op = &umsdos_file_inode_operations;
- } else {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_file_inode_operations_no_bmap\n"));
- inode->i_op = &umsdos_file_inode_operations_no_bmap;
- }
+Printk ((KERN_DEBUG "umsdos_patch_inode: umsdos_file_inode_ops_no_bmap\n"));
+ inode->i_op = &umsdos_file_inode_operations_no_bmap;
}
- } else if (S_ISDIR (inode->i_mode)) {
- if (dir != NULL) {
- umsdos_setup_dir_inode (inode);
+ } else {
+ if (inode->i_op->bmap != NULL) {
+Printk ((KERN_DEBUG "umsdos_patch_inode: umsdos_file_inode_ops\n"));
+ inode->i_op = &umsdos_file_inode_operations;
+ } else {
+Printk ((KERN_DEBUG "umsdos_patch_inode: umsdos_file_inode_ops_no_bmap\n"));
+ inode->i_op = &umsdos_file_inode_operations_no_bmap;
}
- } else if (S_ISLNK (inode->i_mode)) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = umsdos_symlink_inode_operations\n"));
- inode->i_op = &umsdos_symlink_inode_operations;
- } else if (S_ISCHR (inode->i_mode)) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = chrdev_inode_operations\n"));
- inode->i_op = &chrdev_inode_operations;
- } else if (S_ISBLK (inode->i_mode)) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: setting i_op = blkdev_inode_operations\n"));
- inode->i_op = &blkdev_inode_operations;
- } else if (S_ISFIFO (inode->i_mode)) {
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: uhm, init_fifo\n"));
- init_fifo (inode);
}
+ } else if (S_ISDIR (inode->i_mode)) {
if (dir != NULL) {
- /* #Specification: inode / umsdos info
- * The first time an inode is seen (inode->i_count == 1),
- * the inode number of the EMD file which control this inode
- * is tagged to this inode. It allows operation such
- * as notify_change to be handled.
- */
- /*
- * This is done last because it also control the
- * status of umsdos_isinit()
- */
- Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: here we go: calling umsdos_set_dirinfo (%p,%p,%lu)\n", inode, dir, f_pos));
- umsdos_set_dirinfo (inode, dir, f_pos);
+ umsdos_setup_dir_inode (inode);
}
- } else if (dir != NULL) {
+ } else if (S_ISLNK (inode->i_mode)) {
+ Printk ((KERN_DEBUG
+ "umsdos_patch_inode: umsdos_symlink_inode_ops\n"));
+ inode->i_op = &umsdos_symlink_inode_operations;
+ } else if (S_ISCHR (inode->i_mode)) {
+ Printk ((KERN_DEBUG "umsdos_patch_inode: chrdev_inode_ops\n"));
+ inode->i_op = &chrdev_inode_operations;
+ } else if (S_ISBLK (inode->i_mode)) {
+ Printk ((KERN_DEBUG "umsdos_patch_inode: blkdev_inode_ops\n"));
+ inode->i_op = &blkdev_inode_operations;
+ } else if (S_ISFIFO (inode->i_mode)) {
+ Printk ((KERN_DEBUG "umsdos_patch_inode /mn/: uhm, init_fifo\n"));
+ init_fifo (inode);
+ }
+ if (dir != NULL) {
+ /*
+ * This is done last because it also control the
+ * status of umsdos_isinit()
+ */
+ Printk ((KERN_DEBUG
+ "umsdos_patch_inode: call x_set_dirinfo(%p,%p,%lu)\n",
+ inode, dir, f_pos));
+ umsdos_set_dirinfo (inode, dir, f_pos);
+ }
+ return;
+
+already_init:
+ if (dir != NULL) {
/*
* Test to see if the info is maintained.
* This should be removed when the file system will be proven.
*/
- /* FIXME, again, not a clue */
- struct inode *emd_owner;
-
- Printk ((KERN_WARNING "umsdos_patch_inode: /mn/ Warning: untested emd_owner thingy...\n"));
- emd_owner = umsdos_emd_dir_lookup (dir, 1);
- /* iput (emd_owner); / * FIXME? */
+ struct inode *emd_owner = umsdos_emd_dir_lookup (dir, 1);
+ if (!emd_owner)
+ goto out;
if (emd_owner->i_ino != inode->u.umsdos_i.i_emd_owner) {
- printk ("UMSDOS: *** EMD_OWNER ??? *** ino = %ld %ld <> %ld "
- ,inode->i_ino, emd_owner->i_ino, inode->u.umsdos_i.i_emd_owner);
+printk ("UMSDOS: *** EMD_OWNER ??? *** ino = %ld %ld <> %ld ",
+inode->i_ino, emd_owner->i_ino, inode->u.umsdos_i.i_emd_owner);
}
+ iput (emd_owner);
+ out:
+ return;
}
}
-
/*
- * Get the inode of the directory which owns this inode.
- * Return 0 if OK, -EIO if error.
+ * Patch the inode in a dentry.
*/
-int umsdos_get_dirowner ( struct inode *inode,
- struct inode **result) /* Hold NULL if any error */
-{
- /* else, the inode of the directory */
- int ret = -EIO;
- unsigned long ino = inode->u.umsdos_i.i_dir_owner;
-
- *result = NULL;
- if (ino == 0) {
- printk ("UMSDOS: umsdos_get_dirowner ino == 0\n");
- } else {
- struct inode *dir = *result = iget (inode->i_sb, ino);
-
- if (dir != NULL) {
- umsdos_patch_inode (dir, NULL, 0);
- /* iput (dir); / * FIXME: /mn/ added this. Is it OK? */
- ret = 0;
- }
- }
- return ret;
+void umsdos_patch_dentry_inode(struct dentry *dentry, off_t f_pos)
+{
+ umsdos_patch_inode(dentry->d_inode, dentry->d_parent->d_inode, f_pos);
}
-
/*
* 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 access, we use
+ * a value in the inode to tell if it has been finally initialised.
+ *
+ * At first, we have tried testing i_count but it was causing
+ * problem. It is possible that two or more process use the
+ * newly accessed inode. While the first one block during
+ * the initialisation (probably while reading the EMD file), the
+ * others believe all is well because i_count > 1. They go banana
+ * with a broken inode. See umsdos_lookup_patch and umsdos_patch_inode.
+ */
void UMSDOS_read_inode (struct inode *inode)
{
- PRINTK ((KERN_DEBUG "UMSDOS_read_inode %p ino = %lu ", inode, inode->i_ino));
+ PRINTK ((KERN_DEBUG "UMSDOS_read_inode %p ino = %lu ",
+ inode, inode->i_ino));
msdos_read_inode (inode);
- PRINTK (("ino after msdos_read_inode= %lu i_count=%d\n", inode->i_ino, inode->i_count));
+ PRINTK (("ino after msdos_read_inode= %lu i_count=%d\n",
+ inode->i_ino, inode->i_count));
if (S_ISDIR (inode->i_mode)
&& (inode->u.umsdos_i.u.dir_info.creating != 0
|| inode->u.umsdos_i.u.dir_info.looking != 0
@@ -630,116 +399,92 @@
,inode->u.umsdos_i.u.dir_info.looking
,inode->u.umsdos_i.u.dir_info.p));
}
- /* #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 access, we use
- * a value in the inode to tell if it has been finally initialised.
- *
- * At first, we have tried testing i_count but it was causing
- * problem. It is possible that two or more process use the
- * newly accessed inode. While the first one block during
- * the initialisation (probably while reading the EMD file), the
- * others believe all is well because i_count > 1. They go banana
- * with a broken inode. See umsdos_lookup_patch and umsdos_patch_inode.
- */
+
+ /* N.B. Defer this until we have a dentry ... */
umsdos_patch_inode (inode, NULL, 0);
}
-int internal_notify_change (struct inode *inode, struct iattr *attr)
+/* #Specification: notify_change / i_nlink > 0
+ * notify change is only done for inode with nlink > 0. An inode
+ * with nlink == 0 is no longer associated with any entry in
+ * the EMD file, so there is nothing to update.
+ */
+static int internal_notify_change (struct inode *inode, struct iattr *attr)
{
- int ret = 0;
- struct inode *root;
+ unsigned long i_emd_owner = inode->u.umsdos_i.i_emd_owner;
+ int ret;
Printk ((KERN_DEBUG "UMSDOS_notify_change: entering\n"));
if ((ret = inode_change_ok (inode, attr)) != 0)
- return ret;
+ goto out;
- if (inode->i_nlink > 0) {
- /* #Specification: notify_change / i_nlink > 0
- * notify change is only done for inode with nlink > 0. An inode
- * with nlink == 0 is no longer associated with any entry in
- * the EMD file, so there is nothing to update.
- */
- unsigned long i_emd_owner = inode->u.umsdos_i.i_emd_owner;
+ if (inode->i_nlink == 0)
+ goto out_nolink;
- root = iget (inode->i_sb, UMSDOS_ROOT_INO);
- if (inode == root) {
- /* #Specification: root inode / attributes
- * I don't know yet how this should work. Normally
- * the attributes (permissions bits, owner, times) of
- * a directory are stored in the EMD file of its parent.
- *
- * One thing we could do is store the attributes of the root
- * inode in its own EMD file. A simple entry named "." could
- * be used for this special case. It would be read once
- * when the file system is mounted and update in
- * UMSDOS_notify_change() (right here).
- *
- * I am not sure of the behavior of the root inode for
- * a real Unix file system. For now, this is a nop.
- */
- } else if (i_emd_owner != 0xffffffff && i_emd_owner != 0) {
- /* This inode is not a EMD file nor an inode used internally
- * by MSDOS, so we can update its status.
- * See emd.c
- */
- struct inode *emd_owner;
+ if (inode->i_ino == UMSDOS_ROOT_INO)
+ goto out_nolink;
- emd_owner = iget (inode->i_sb, i_emd_owner);
- Printk (("notify change %p ", inode));
- if (emd_owner == NULL) {
- printk ("UMSDOS: emd_owner = NULL ???");
- ret = -EPERM;
- } else {
- struct file filp;
- struct umsdos_dirent entry;
- struct dentry *emd_dentry;
-
- emd_dentry = geti_dentry (emd_owner); /* FIXME? */
- fill_new_filp (&filp, emd_dentry);
-
- filp.f_pos = inode->u.umsdos_i.pos;
- filp.f_reada = 0;
- Printk (("pos = %Lu ", filp.f_pos));
- /* Read only the start of the entry since we don't touch */
- /* the name */
- ret = umsdos_emd_dir_read (&filp, (char *) &entry, UMSDOS_REC_SIZE);
- if (ret == 0) {
- if (attr->ia_valid & ATTR_UID)
- entry.uid = attr->ia_uid;
- if (attr->ia_valid & ATTR_GID)
- entry.gid = attr->ia_gid;
- if (attr->ia_valid & ATTR_MODE)
- entry.mode = attr->ia_mode;
- if (attr->ia_valid & ATTR_ATIME)
- entry.atime = attr->ia_atime;
- if (attr->ia_valid & ATTR_MTIME)
- entry.mtime = attr->ia_mtime;
- if (attr->ia_valid & ATTR_CTIME)
- entry.ctime = attr->ia_ctime;
-
- entry.nlink = inode->i_nlink;
- filp.f_pos = inode->u.umsdos_i.pos;
- ret = umsdos_emd_dir_write (&filp, (char *) &entry, UMSDOS_REC_SIZE);
-
- Printk (("notify pos %lu ret %d nlink %d ", inode->u.umsdos_i.pos, ret, entry.nlink));
- /* #Specification: notify_change / msdos fs
- * notify_change operation are done only on the
- * EMD file. The msdos fs is not even called.
- */
- }
- /* iput (emd_owner); / * FIXME? /mn/ */
- }
- Printk (("\n"));
+ if (i_emd_owner != 0xffffffff && i_emd_owner != 0) {
+ /* This inode is not a EMD file nor an inode used internally
+ * by MSDOS, so we can update its status.
+ * See emd.c
+ */
+ struct inode *emd_owner;
+ struct file filp;
+ struct umsdos_dirent entry;
+ struct dentry *emd_dentry;
+
+ Printk (("notify change %p ", inode));
+ ret = -EPERM;
+ emd_owner = iget (inode->i_sb, i_emd_owner);
+ if (!emd_owner) {
+ printk ("UMSDOS: emd_owner = NULL ???");
+ goto out_nolink;
+ }
+ emd_dentry = geti_dentry (emd_owner); /* FIXME? */
+ fill_new_filp (&filp, emd_dentry);
+
+ filp.f_pos = inode->u.umsdos_i.pos;
+ filp.f_reada = 0;
+ Printk (("pos = %Lu ", filp.f_pos));
+ /* Read only the start of the entry since we don't touch */
+ /* the name */
+ ret = umsdos_emd_dir_read (&filp, (char *) &entry,
+ UMSDOS_REC_SIZE);
+ if (!ret) {
+ if (attr->ia_valid & ATTR_UID)
+ entry.uid = attr->ia_uid;
+ if (attr->ia_valid & ATTR_GID)
+ entry.gid = attr->ia_gid;
+ if (attr->ia_valid & ATTR_MODE)
+ entry.mode = attr->ia_mode;
+ if (attr->ia_valid & ATTR_ATIME)
+ entry.atime = attr->ia_atime;
+ if (attr->ia_valid & ATTR_MTIME)
+ entry.mtime = attr->ia_mtime;
+ if (attr->ia_valid & ATTR_CTIME)
+ entry.ctime = attr->ia_ctime;
+
+ entry.nlink = inode->i_nlink;
+ filp.f_pos = inode->u.umsdos_i.pos;
+ ret = umsdos_emd_dir_write (&filp, (char *) &entry,
+ UMSDOS_REC_SIZE);
+
+ Printk (("notify pos %lu ret %d nlink %d ",
+ inode->u.umsdos_i.pos, ret, entry.nlink));
+ /* #Specification: notify_change / msdos fs
+ * notify_change operation are done only on the
+ * EMD file. The msdos fs is not even called.
+ */
}
- /* iput (root); / * FIXME - /mn/ This is should be OK. */
+ iput(emd_owner);
}
+out_nolink:
if (ret == 0)
inode_setattr (inode, attr);
-
+out:
return ret;
}
@@ -756,7 +501,8 @@
{
struct iattr newattrs;
- PRINTK (("UMSDOS_write_inode emd %d (FIXME: missing notify_change)\n", inode->u.umsdos_i.i_emd_owner));
+ PRINTK (("UMSDOS_write_inode emd %d (FIXME: missing notify_change)\n",
+ inode->u.umsdos_i.i_emd_owner));
fat_write_inode (inode);
newattrs.ia_mtime = inode->i_mtime;
newattrs.ia_atime = inode->i_atime;
@@ -767,26 +513,12 @@
* to update the EMD entry associated with this inode.
* But it has the side effect to re"dirt" the inode.
*/
-
/*
* internal_notify_change (inode, &newattrs);
* inode->i_state &= ~I_DIRTY; / * FIXME: this doesn't work. We need to remove ourselves from list on dirty inodes. /mn/ */
}
-
-
-
-/* #Specification: function name / convention
- * A simple convention for function names has been used in
- * the UMSDOS filesystem. First, all functions use the prefix
- * umsdos_ to avoid name clashes with other parts of the kernel.
- *
- * Standard VFS entry points use the prefix UMSDOS (upper case)
- * so it's easier to tell them apart.
- * N.B. (FIXME) PTW, the order and contents of this struct changed.
- */
-
static struct super_operations umsdos_sops =
{
UMSDOS_read_inode, /* read_inode */
@@ -803,169 +535,127 @@
/*
* Read the super block of an Extended MS-DOS FS.
*/
-struct super_block *UMSDOS_read_super ( struct super_block *sb,
- void *data,
- int silent)
-{
- /* #Specification: mount / options
- * Umsdos run on top of msdos. Currently, it supports no
- * mount option, but happily pass all option received to
- * the msdos driver. I am not sure if all msdos mount option
- * make sense with Umsdos. Here are at least those who
- * are useful.
- * uid=
- * gid=
- *
- * These options affect the operation of umsdos in directories
- * which do not have an EMD file. They behave like normal
- * msdos directory, with all limitation of msdos.
- */
+struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
+ int silent)
+{
struct super_block *res;
struct inode *pseudo = NULL;
- Printk ((KERN_DEBUG "UMSDOS /mn/: starting UMSDOS_read_super\n"));
MOD_INC_USE_COUNT;
- Printk ((KERN_DEBUG "UMSDOS /mn/: sb = %p\n", sb));
-
MSDOS_SB(sb)->options.isvfat = 0;
+ /*
+ * Call msdos-fs to mount the disk.
+ * Note: this returns res == sb or NULL
+ */
res = msdos_read_super (sb, data, silent);
- sb->s_op = &umsdos_sops;
- Printk ((KERN_DEBUG "UMSDOS /mn/: res = %p\n", res));
- printk (KERN_INFO "UMSDOS dentry-WIP-Beta 0.82-7 (compatibility level %d.%d, fast msdos)\n", UMSDOS_VERSION, UMSDOS_RELEASE);
+ if (!res)
+ goto out_fail;
- if (res == NULL) {
- sb->s_dev = 0;
- MOD_DEC_USE_COUNT;
- Printk ((KERN_DEBUG "UMSDOS: msdos_read_super failed ! mount aborted.\n"));
- return NULL;
- }
-
- MSDOS_SB (res)->options.dotsOK = 0; /* disable hidden==dotfile */
-#if 1
- res->s_root->d_op = NULL; /* FIXME:?? clear d_op on root so it will not be inherited */
-#endif
-
- Printk ((KERN_DEBUG "umsdos /mn/: here goes the iget ROOT_INO\n"));
+ printk (KERN_INFO "UMSDOS dentry-WIP-Beta 0.82-7 "
+ "(compatibility level %d.%d, fast msdos)\n",
+ UMSDOS_VERSION, UMSDOS_RELEASE);
-/* pseudo = iget (res, UMSDOS_ROOT_INO); // we probably could do it as below (and remove iput() below), but we want use_count to go up. Do we ? :) */
- pseudo = res->s_root->d_inode; /* msdos_read_super already did iget() it */
-
- Printk ((KERN_DEBUG "umsdos_read_super pseudo=%p\n", pseudo));
+ sb->s_op = &umsdos_sops;
+ MSDOS_SB(sb)->options.dotsOK = 0; /* disable hidden==dotfile */
+
+ /* FIXME:?? clear d_op on root so it will not be inherited */
+ sb->s_root->d_op = NULL;
- umsdos_setup_dir_inode (pseudo);
- Printk ((KERN_DEBUG "umsdos_setup_dir_inode passed. pseudo i_count=%d\n", pseudo->i_count));
+ pseudo = sb->s_root->d_inode;
+ umsdos_setup_dir(sb->s_root);
- /* if (s == super_blocks){ FIXME, super_blocks no longer exported */
+#if 0
if (pseudo) {
-#if 0 /* FIXME URGENT: disable pseudo root-for the moment of testing. re-enable this before release ! */
- /* #Specification: pseudo root / mount
- * When a umsdos fs is mounted, a special handling is done
- * if it is the root partition. We check for the presence
- * of the file /linux/etc/init or /linux/etc/rc or
- * /linux/sbin/init. If one is there, we do a chroot("/linux").
- *
- * We check both because (see init/main.c) the kernel
- * try to exec init at different place and if it fails
- * it tries /bin/sh /etc/rc. To be consistent with
- * init/main.c, many more test would have to be done
- * to locate init. Any complain ?
- *
- * The chroot is done manually in init/main.c but the
- * info (the inode) is located at mount time and store
- * in a global variable (pseudo_root) which is used at
- * different place in the umsdos driver. There is no
- * need to store this variable elsewhere because it
- * will always be one, not one per mount.
- *
- * This feature allows the installation
- * of a linux system within a DOS system in a subdirectory.
- *
- * A user may install its linux stuff in c:\linux
- * avoiding any clash with existing DOS file and subdirectory.
- * When linux boots, it hides this fact, showing a normal
- * root directory with /etc /bin /tmp ...
- *
- * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h
- * in the macro UMSDOS_PSDROOT_NAME.
- */
- struct dentry *root, *etc, *etc_rc, *sbin, *init = NULL;
+ pseudo_root_stuff();
+ }
+#endif
+
+ /* if d_count is not 1, mount will fail with -EBUSY! */
+ if (sb->s_root->d_count > 1) {
+ shrink_dcache_sb(sb);
+ }
+ return sb;
+
+out_fail:
+ printk(KERN_INFO "UMSDOS: msdos_read_super failed, mount aborted.\n");
+ sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
+ return NULL;
+}
+
+/*
+ * FIXME URGENT:
+ * disable pseudo root-for the moment of testing.
+ * re-enable this before release !
+ */
+#if 0
+void pseudo_root_stuff(void)
+{
+ struct dentry *root, *etc, *etc_rc, *sbin, *init = NULL;
- root = creat_dentry (UMSDOS_PSDROOT_NAME, strlen (UMSDOS_PSDROOT_NAME), NULL, res->s_root);
- sbin = creat_dentry ("sbin", 4, NULL, NULL); /* FIXME: should last NULL be root or res->s_root ? Not NULL in any case.. */
+ root = creat_dentry (UMSDOS_PSDROOT_NAME,
+ strlen (UMSDOS_PSDROOT_NAME),
+ NULL, res->s_root);
+ sbin = creat_dentry ("sbin", 4, NULL, root);
- Printk ((KERN_DEBUG "Mounting root\n"));
- if (umsdos_real_lookup (pseudo, root) == 0
- && (root->d_inode != NULL)
- && S_ISDIR (root->d_inode->i_mode)) {
+ Printk ((KERN_DEBUG "Mounting root\n"));
+ if (umsdos_real_lookup (pseudo, root) == 0
+ && (root->d_inode != NULL)
+ && S_ISDIR (root->d_inode->i_mode)) {
- int pseudo_ok = 0;
+ int pseudo_ok = 0;
- Printk ((KERN_DEBUG "/%s is there\n", UMSDOS_PSDROOT_NAME));
- etc = creat_dentry ("etc", 3, NULL, root);
+Printk ((KERN_DEBUG "/%s is there\n", UMSDOS_PSDROOT_NAME));
+ etc = creat_dentry ("etc", 3, NULL, root);
- if (umsdos_real_lookup (pseudo, etc) == 0
- && S_ISDIR (etc->d_inode->i_mode)) {
+ if (umsdos_real_lookup (pseudo, etc) == 0
+ && S_ISDIR (etc->d_inode->i_mode)) {
- Printk ((KERN_DEBUG "/%s/etc is there\n", UMSDOS_PSDROOT_NAME));
+Printk ((KERN_DEBUG "/%s/etc is there\n", UMSDOS_PSDROOT_NAME));
- init = creat_dentry ("init", 4, NULL, etc);
- etc_rc = creat_dentry ("rc", 2, NULL, etc);
+ init = creat_dentry ("init", 4, NULL, etc);
+ etc_rc = creat_dentry ("rc", 2, NULL, etc);
- if ((umsdos_real_lookup (pseudo, init) == 0
- && S_ISREG (init->d_inode->i_mode))
- || (umsdos_real_lookup (pseudo, etc_rc) == 0
- && S_ISREG (etc_rc->d_inode->i_mode))) {
- pseudo_ok = 1;
- }
- /* iput (pseudo); iput (pseudo); / * because msdos_real_lookup does inc_count (pseudo) */
+ if ((umsdos_real_lookup (pseudo, init) == 0
+ && S_ISREG (init->d_inode->i_mode))
+ || (umsdos_real_lookup (pseudo, etc_rc) == 0
+ && S_ISREG (etc_rc->d_inode->i_mode))) {
+ pseudo_ok = 1;
+ }
/* FIXME !!!!!! */
- /* iput(init); */
- /* iput(rc); */
- }
- if (!pseudo_ok
- /* && umsdos_real_lookup (pseudo, "sbin", 4, sbin)==0 */
- && umsdos_real_lookup (pseudo, sbin) == 0
- && S_ISDIR (sbin->d_inode->i_mode)) {
-
- Printk ((KERN_DEBUG "/%s/sbin is there\n", UMSDOS_PSDROOT_NAME));
- if (umsdos_real_lookup (pseudo, init) == 0
- && S_ISREG (init->d_inode->i_mode)) {
- pseudo_ok = 1;
- }
- /*iput (pseudo);*/
- /* FIXME !!!
- * iput (init); */
- }
- if (pseudo_ok) {
- umsdos_setup_dir_inode (pseudo);
- Printk ((KERN_INFO "Activating pseudo root /%s\n", UMSDOS_PSDROOT_NAME));
- pseudo_root = pseudo;
- inc_count (pseudo);
- pseudo = NULL;
+ /* iput(init); */
+ /* iput(rc); */
+ }
+ if (!pseudo_ok
+ /* && umsdos_real_lookup (pseudo, "sbin", 4, sbin)==0 */
+ && umsdos_real_lookup (pseudo, sbin) == 0
+ && S_ISDIR (sbin->d_inode->i_mode)) {
+
+Printk ((KERN_DEBUG "/%s/sbin is there\n", UMSDOS_PSDROOT_NAME));
+ if (umsdos_real_lookup (pseudo, init) == 0
+ && S_ISREG (init->d_inode->i_mode)) {
+ pseudo_ok = 1;
}
- /* FIXME
- *
- * iput (sbin);
- * iput (etc);
- */
+ /* FIXME !!!
+ * iput (init); */
}
-#endif
- /*iput (pseudo); // iget was removed... so this no longer needed ? */
- }
-#if 1
- #warning UMSDOS: using ugly mount kludge only if necessary (DEBUG)
- if (res->s_root->d_count != 1) { /* if it is not 1, mount will fail with -EBUSY! */
- printk (KERN_ERR "UMSDOS: mount kludge activated: root d_count was %d !\n", res->s_root->d_count);
- res->s_root->d_count = 1;
+ if (pseudo_ok) {
+ umsdos_setup_dir_inode (pseudo);
+Printk ((KERN_INFO "Activating pseudo root /%s\n", UMSDOS_PSDROOT_NAME));
+ pseudo_root = pseudo;
+ inc_count (pseudo);
+ pseudo = NULL;
+ }
+ /* FIXME
+ *
+ * iput (sbin);
+ * iput (etc);
+ */
}
-#endif
- check_dentry_path (res->s_root, "ROOT dentry check");
- Printk ((KERN_DEBUG "umsdos_read_super /mn/: (pseudo=%lu, i_count=%d) returning %p\n", pseudo->i_ino, pseudo->i_count, res));
- return res;
}
-
+#endif
static struct file_system_type umsdos_fs_type =
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov