Messages in this thread Patch in this message | | | Date | Thu, 10 Jun 1999 23:10:59 +0200 | From | Pavel Machek <> | Subject | [PATCH] Re: cachefs module for linux? |
| |
Hi!
> > Anyway, going back to CacheFS, obviously some people would like to have such a > > thing, but obviously also, none of them needs it badly enough that she's > > willing to write it... so the discussion is mostly pointless.
Well, I don't think so.
> Usage -- In the generic VFS routines, add a check upon file open() to > see if it is backed by a local CacheFS cache. This could be a flag set > in the superblock.
This means you can not cache parts of files. Which may or may not hurt.
> When each file read occurs, if the cached flag is set on that inode, > then try to read from the local CacheFS. If the read fails, or the file > is not cached, normal file read occurs. > > Adding hooks in the generic VFS should make it possible to cache any > filesystem easily.
Take a look at this patch:
If you mount all your filesystems into /overlay tree, then / tree will serve as cache. This might also work for people wanting to override CDs.
Problem is with writes - how it is done now, they will go into / filesystem so you'll not be able to modify cached fs... Which might be considered feature. (Be sure to define symbol CLEAN.)
Pavel
--- clean//fs/namei.c Tue May 25 00:16:04 1999 +++ linux/fs/namei.c Tue May 18 11:12:41 1999 @@ -10,6 +10,8 @@ /* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname * lookup logic. + * + * 1998-1999 Pavel Machek - /overlay hack (thanks to mikulas for correcting bugs in it) */ #include <linux/mm.h> @@ -27,7 +29,7 @@ /* This can be removed after the beta phase. */ #define CACHE_SUPERVISE /* debug the correctness of dcache entries */ -#undef DEBUG /* some other debugging */ +#define DEBUG /* some other debugging */ #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) @@ -297,6 +299,38 @@ return dentry; } +struct dentry * +no_file( struct dentry *base, int lookup_flags ) +{ + char *tmp = (char *) __get_free_page(GFP_KERNEL); + char *path = d_path(base, tmp, PAGE_SIZE); + struct dentry *res; + char *s = "yalrevo/"; + + if (strlen(path) > PAGE_SIZE-30) { + /*printk( "Namei: path much too long\n" );*/ + res = ERR_PTR(-ENOENT); + goto done; + } + + if (!strncmp( path, "/overlay", 8 )) { + /*printk( "[loop]" );*/ + res = ERR_PTR(-ENOENT); + goto done; + } + + /*printk( "No file %s / ???...", path );*/ + while (*s) *--path = *s++; + /*printk( "looking %s...", path );*/ + + res = lookup_dentry( path, NULL, lookup_flags ); + /*printk( "done (%x)\n", res );*/ + +done: + free_page((unsigned long) tmp); + return res; +} + /* * Name resolution. * @@ -364,6 +398,7 @@ flags |= LOOKUP_CONTINUE; } +//printk( "(L: %s, %d)", this.name, follow ); /* * See if the low-level filesystem might want * to use its own hash.. @@ -374,7 +409,7 @@ if (error < 0) { dentry = ERR_PTR(error); break; - } + } } /* This does the actual lookups.. */ @@ -387,6 +422,58 @@ break; } } +#ifndef CLEAN + if (strchr( this.name, '#' )) +#endif + if (!dentry->d_inode) { + struct dentry *tbase, *tdentry = NULL; + tbase = no_file( base, lookup_flags ); + if (!IS_ERR(tbase) && (tbase->d_inode)) { + /* We need to do lookup once again. */ + + /* FIXME: We should save original hash... + * [what if fs wanted _normal_ hash?] + * See if the low-level filesystem might want + * to use its own hash.. + */ + if (tbase->d_op && tbase->d_op->d_hash) { + int error; + error = tbase->d_op->d_hash(base, &this); + if (error < 0) { + dentry = ERR_PTR(error); + dput(tbase); + break; + } + } + + /* This does the actual lookups.. */ + tdentry = reserved_lookup(tbase, &this); + if (!tdentry) { + tdentry = cached_lookup(tbase, &this, flags); + if (!tdentry) { + tdentry = real_lookup(tbase, &this, flags); + if (IS_ERR(tdentry)) { + dput(dentry); + dentry = tdentry; + dput(tbase); + break; + } + } + } + if (!IS_ERR(tdentry) && (tdentry->d_inode)) { + dput(dentry); + dput(base); + base = tbase; + dentry = tdentry; + } else { + if (!IS_ERR(tdentry)) dput(tdentry); + dput(tbase); + } + } else if (!IS_ERR(tbase)) dput(tbase); + } + + if (IS_ERR(dentry)) + break; /* Check mountpoints.. */ dentry = follow_mount(dentry); @@ -1404,3 +1491,4 @@ unlock_kernel(); return error; } +
-- I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel. Pavel Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |