Hi!

> I've been looking at the possibility of cleanly implementing virtual
> files (podfuk/avfs style) with the multiple mount thing in 2.4
> kernels. Here is how it would work:
> 
> 1) There needs to be a global lookup hook in VFS. If a real lookup
> fails, the global lookup is invoked. The cached lookup path is not
> effected.
> 
> 2) The global lookup checks whether the name refers to a virtual file
> (contains the magic char & exists in /overlay). If it does, then the
> file/dir from overlay is mounted on top of the negative dentry. The
> dentry is not filled in, so the virtual file remains invisible.
> 
> For 1) the VFS needs to be modified, but with infinitesimal
> performance effect. For 2) a kernel module could be used.

Great!

> I've prepared a kernel patch against 2.4.0-test4 (just for comments on
> this, NOT for inclusion in the main kernel), and a kernel module. I've
> tested it with avfs, but it should also work for podfuk.

It looks much cleaner than my previous approaches. There seems to be
something strange with usage counts:

pavel@bug:/tmp/cz1_mbrola.tgz#utar$ ls -al
total 88
drwxr-xr-x   2 pavel    users        3586 Mar 26 18:43 ./
drwxrwxrwt  38 root     root        81920 Jul 24 09:57 ../
drwxr-xr-x 42949 pavel    users           0 Mar 25 11:16 czech/
pavel@bug:/tmp/cz1_mbrola.tgz#utar$

> Problems:
> 
>  - The filesystem will be littered with these loopback mounts. This
>    should be cleared upon unmount, and possibly when the dcache is
>    shrunk. There was a similar requirement for new autofs IIRC.
> 
>  - Creation/removal of virtual files are not handled by this code.
> 
> Comments?

Yes. You seem to have damaged locking:

> @@ -281,12 +285,18 @@
>                       lock_kernel();
>                       result = dir->i_op->lookup(dir, dentry);
>                       unlock_kernel();
> -                     if (result)
> +                     if (result) {
>                               dput(dentry);
> -                     else
> +                                up(&dir->i_sem);
> +                        }
> +                     else {
> +                             up(&dir->i_sem);
>                               result = dentry;
> +                             /* for avfs */
> +                             if (!dentry->d_inode && lookup_global)
> +                                     lookup_global(nd, dentry);
> +                     }
>               }
> -             up(&dir->i_sem);

In case of !dentry, up(&dir->i_sem) is not executed at all.

I have some cleanups to nredir.c module, they are attached (please
apply). Ouch, and there's slight problem with caching:

You access vmlinux#gz, then load nredir module, then access vmlinux#gz
again. But failure is already cached and you are out of luck :-(.

                                                                Pavel
-- 
I'm [EMAIL PROTECTED] "In my country we have almost anarchy and I don't care."
Panos Katsaloulis describing me w.r.t. patents at [EMAIL PROTECTED]
--- /tmp/nredir.c       Mon Jul 24 10:03:48 2000
+++ nredir.c    Mon Jul 24 09:53:05 2000
@@ -1,4 +1,5 @@
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
@@ -7,7 +8,7 @@
 
 #define NREDIR_VERSION "0.1"
 
-#define AVFS_MAGIC_CHAR '@'
+#define AVFS_MAGIC_CHAR '#'
 #define OVERLAY_DIR "/overlay"
 #define OVERLAY_DIR_LEN 8
 
@@ -99,7 +100,7 @@
         return dentry;
 }
 
-int init_module(void)
+static int __init init_nredir(void)
 {
     printk(KERN_INFO "nredir init (version %s)\n", NREDIR_VERSION);
 
@@ -111,11 +112,14 @@
 }
 
 
-void cleanup_module(void)
+static void __exit cleanup_nredir(void)
 {
     printk(KERN_INFO "nredir cleanup\n");
 
-    lookup_global = 0;
+    lookup_global = NULL;
 
     printk("lookup_global: %x\n", (int) lookup_global);
 }
+
+module_init(init_nredir);
+module_exit(cleanup_nredir);

Reply via email to