timothy murphy 0082a0cb96 imported patch caseless 13 år sedan
..
README 0082a0cb96 imported patch caseless 13 år sedan
caseless-fuse.c 0082a0cb96 imported patch caseless 13 år sedan
debug.h 0082a0cb96 imported patch caseless 13 år sedan
filehandles.c 0082a0cb96 imported patch caseless 13 år sedan
filehandles.h 0082a0cb96 imported patch caseless 13 år sedan
hashtable.c 0082a0cb96 imported patch caseless 13 år sedan
hashtable.h 0082a0cb96 imported patch caseless 13 år sedan
makefile 0082a0cb96 imported patch caseless 13 år sedan
nodes.h 0082a0cb96 imported patch caseless 13 år sedan
open_creat.c 0082a0cb96 imported patch caseless 13 år sedan
pathcache.c 0082a0cb96 imported patch caseless 13 år sedan
pathcache.h 0082a0cb96 imported patch caseless 13 år sedan
perf_results 0082a0cb96 imported patch caseless 13 år sedan
stat_test.c 0082a0cb96 imported patch caseless 13 år sedan
test.sh 0082a0cb96 imported patch caseless 13 år sedan
test_common.sh 0082a0cb96 imported patch caseless 13 år sedan
test_hash.c 0082a0cb96 imported patch caseless 13 år sedan
test_perf_stat.sh 0082a0cb96 imported patch caseless 13 år sedan

README



Caseless Filesystem
---------------------

The caseless filesystem is designed to allow one to access files in a
case insensitive manner on a case-sensitive filesystem. A particular
example of the use of this is in trying to build code that's maintained
on a case insensitive operating system (e.g. windows) on Linux without
having to spend time correcting all the references.

e.g. on the filesystem the file might be "inc/api.h" but c source code
might contain '#include "INC\Api.h"' which is case-inconsistent and will
fail on Linux.

Usage:

caseless-fuse path/to/mountpoint path/to/source

the "source" is the location with the original files. The mountpoint is
the place where the apparently case-insensitive version of those files
will appear to be present.

When you are finished you can unmount the filesystem like so:
fusermount -u path/to/mountpoint

Example:
If there is a file called api.h in "myproject" and you mount "myproject"
onto "uc_myproject" like so:

mkdir uc_myproject
caseless-fuse myproject uc_myproject

...then this command will fail:

cat myproject/API.H
cat: cannot access myproject/API.H: No such file or directory

...but this one will succeed:
cat uc_myproject/API.H
/* api.h */
#ifndef _API_H_
#define _API_H_
....
#endif

Design
------
Caseless has a big hashtable - the key is a lowercased version of a
filename with the full path and the value is the actual filename on the
storage media.

On startup it fills the hashtable with all the files that exist under
the source directory and then as files are created/removed in the course
of running it keeps this hashtable uptodate.

A chained hastable is used with a compile-time constant number of chains.

When some operation is contemplated on a file: if it's an operation
that requires a file to already exist then the fs lowercases the name
the application asked for, uses this as a key to lookup the "real"
filename and opens that instead. If the file is not in the hash table
then it doesn't exist and this is only ok if the operation is "create"
or "open(ccc,"w+").

Lookups on non-existent keys are expensive-ish in dictionaries so we
also remember when a file doesn't exist by storing a null value into
the dictionary for that key. Make does a lot of lookups for non-existant
things, of course.

There is code for handling the file operations (caseless-fuse.c) for
managing the dictionary of lowercase filenames mapping to real names
(pathcache.c) and code for looking after our "own home-grown filehandles"
(filehandles.c). The filename mapping dictionary uses a generic string
key/string value hashtable from hashtable.c.

There are some little test programs (e.g. for the hashtable
implementation) and some test scripts - test.sh is for basic correctness
of operations and test_perf.sh tries to check performance on "stat"
operations which make does a lot of.

Known-Issues
-------------
Memory usage is not bounded in the face of many deletes since the
filesystem tries to remember what files don't exist and has no way of
recovering the storage that this requires. Future versions will.

It's not as fast as direct access to the filesystem.


Building:
-----------
You need to have the fuse libraries installed.

Just type "make" to build.

To debug the filesystem, build with debugging on:
make CFLAGS="-g -DDEBUG"

then run like so:
./caseless-fuse -o debug path/to/mountpoint path/to/source

The filesystem will not become a daemon and will display debugging output
on the console. You can use another terminal window to run whatever
testing you wish while watching this output. Debugging slows the filesystem
down greatly so for real world use run "make clean; make" to rebuild before
using it.