Gnokiifs -------- Copyright (c) Edward Rosten 2005 er258 (at) cam (dot) ac (dot) uk This program talks gnokii on one and coda on the other, allowing you to mount the files on your Nokia phone (tested on the 7600 only). LICENSE ------- See the file LICENSE REQUIREMENTS ------------ Gnokii version 20041221 or greater (I use this one from a CVS snapshot). Linux 2.6 Coda (you only need the kernel side. This does not interact with the userland daemon) Some means of communication with your phone. Check the gnokii docs. USAGE ----- gnokiifs & mount -tcoda /dev/cfs0 /my/mount/point ... do stuff ... umount /my/mount/point fg ^C Note that files are committed to the phone when they are closed, not when the system is unmounted. Also, you can terminate gnokiifs and unmount it in either order. When files are opened non-destructively (i.e. not O_TRUNC), they are copied to the local disk first. This can make opening rather slow, especially if you use a program like xv for viewing images, which opens all of the images before displaying any of them. Make sure you have the coda module loaded/compiled in. Make sure you have read+write access on your coda device (default is /dev/cfs0) If you want to use USB, make sure you have nokia_dku2.ko loaded If the command: gnokii --getfilelist 'A:\*' produces an error, you need to configure gnokii properly. This program relies on a properly configured gnokii. Here is the output of gnokiifs -h: gnokiifs [-f X | -d X | -c X | -t X | -h | -d] -f X = file permission bits (use 0nnn for octal) -d X = directory permission bits -c X = coda device file -t X = Time after which closed files are flushed from the cache in seconds. -D print very verbose debug messages (only if compiled in) -h print this message INSTALL ------- To compile: make This generates an executable called gnokiifs. Copy to wherever you wish. Problems: Look at the makefile and: 1 Make sure the path to the gnokii headers is correct (e.g. /usr/local/include) 2 Make sure the path to the gnokii library is correct (e.g. /usr/local/lib) 3 If you compiled gnokii with bluetooth, you need to link against bluetooth. If you don't have libbluetooth installed, then you don't want to link against it. Check your kernel headers! If you get lots of errors like "struct timespec redefined" then you have bad kernel headers in /usr/include/linux. The problem is that linux/time.h defines the same stuff as time.h without checking. This program needs both of these headers. If you get errors along the lines of: /usr/include/sys/time.h:95: parse error before numeric constant Then it is also a kernel headers problem. linux/time.h #defines the constants ITIMER_REAL, ITIMER_VIRTUAL and ITIMER_PROF, where as sys/time.h makes them in to an enum. You have two options here: 1 Comment out all the definitions causing errors in 2 Get proper sanitized headers from your distro maker. BUGS / ISSUES ------------- So far it works on at least 2 computers. That's all the resources I have time to test it on. It may not work on yours. It doesn't compile or run on Linux 2.4. The Coda interface changed from 2.4 to 2.6. I no longer use any 2.4 machines so I'm not going to port and test it, but I will take patches. Many filesystem features are not implemented. Some because gnokii does not expose them, others because I have had no use for them yet. These will usually return EPERM. If an error occurs internally, the error code seen by the program attempting the operation might not be too sensible. It doesn't work on Solaris. I believe Solaris supports CODA, but I don't have a Sun. Same with Win32. It doesn't work on FreeBSD either. I only have very limited access to a FreeBSD box, so I'm probably not going to do this either. TODO ---- Ioctl for reading the file ID. Add mount points, so the normal files (A:\*) appear in a/*. This allows for other file-systems, (B:\, etc) as well as virtual file-systems, e.g. messages, phone book. Add mappings, so that things like A:\predefgallery appear as A:\Gallery Internationalization of non debugging messages HOW IT WORKS ------------ The Coda kernel module is a fairly generic module for serializing VFS operations. It turns the operations in to a packet of data containing the op-code (to identify the operation), a unique packet identifier (so that the kernel knows which packet you are responding to) and any extra data which it needs to communicate. Replies are structured in a similar fashion, you reply with a packet containing an error code (standard unix ones like ESUCCESS, EIO, etc), the opcode and identifier of the packet you're replying to and any extra data. This program deals with the commands in an entirely serial manner. Therefore an operation which takes a while to complete (such as committing a file to the phone) freezes the filesystem. Communication is done via a device file (usually /dev/cfs0). This works like a packet socket. A read will return a single packet of data, non necessarily a full buffer's worth of data. Writes work in a similar manner. Almost all incoming packets contain the VFid of a file. A VFid is a 128 bit block of data which is opaque to the kernel, but not to you. When Coda is interested in a new file, it performs a LOOKUP operation, giving you the directory and name of the file in which it is interested. You reply to this with a VFid. When the kernel wants to refer to that file in future, it does it by sending you the VFid of the file. Therefore, you need to keep track of which VFid belongs to which file. The VFid size changed from 96 bits to 128 bits during the transition from Linux 2.4 to Linux 2.6 Opening files is performed in a manner which seems rather odd at first glance. When Coda wishes to open a file, you open the file using the normal open() sys call, and respond with the file descriptor of that open file. The kernel module then removes that file from your process and places it in the calling process. All read() and write() operations on that file are dealt with by the kernel, since it is an "ordinary" "local" file. This means that you can't create purely virtual file-systems where read and write are dealt with by you, but it does mean that performance is good. ALTERNATIVE USERLAND FILE-SYSTEMS -------------------------------- There are several approaches to userland file-systems: 1 Shared library hacks. 2 Nonstandard kernel module / userland program pairs 3 Standard kernel module / userland program pairs AVFS ---- This overrides libc calls so that the open/read/write/etc calls can be diverted so that all programs using libc (i.e. all programs) will see a virtual filesystem. It therefore does not require any kernel functionality and can even be used without root being required to set it up. http://www.inf.bme.hu/~mszeredi/avfs/ LUFS ---- This uses a kernel module to serialize all VFS operations and transmit them to a single userland daemon (using message passing, I believe). This userland daemon then deserializes the messages and invokes function calls from shared libraries (dynamically linking them in when new file-systems are mounted). This essentially replicates the kernel VFS system in userland and does all the communications for you. Much like the kernel, new file-systems can be added without restarting the daemon. http://lufs.sourceforge.net/lufs/ PerlFS ------ A system which serializes commands down a character device for use by a userland program (emphasis on Perl). This allows one to write file-systems in any suitable language. http://perlfs.sourceforge.net/ PODFUK ------ POrtable Dodgy Filesystems in Userland (hacK). The first version was a set of patches to an NFS server. The second version was a standalone program (a C and Makefile polyglot, in fact) which used coda. This version served as inspiration and a reference for the early versions of gnokiifs. Others ------ Pretty much any system which has userland file serving daemons, i.e. the real Coda, NFS, etc. Widespread adoption of these keeps well maintained modules in the standard kernel.