-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Tuesday 08 October 2002 00:13, you wrote:
> On Monday 07 October 2002 16:01, Alon Barzilai wrote:
> > mount -t iso9660 -o ro 1.iso /mnt/disk1
> > mount -t iso9660 -o ro 2.iso /mnt/disk1
>
> This is called "union mount". Linux does not have this feature (I think BSD
> has it).
Actually, there were some noises made by Al Viro that were implying that this
is something which is in his tree.
Meanwhile - If you are into development then you can use use (file
systems in user space) and the attached file (by yours truly) to get you
started. I haven't tested it well and I *** KNOW *** that it has problems and
just didn't have any time to work on it.... What can you expect out of 25
minutes of coding ?...:)
Have fun
Mark
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQE9ohECxlxDIcceXTgRAg/hAJ43vOxo5r9EdcLYVdV4Qi7EBwnTbwCeI8Vu
718vcwQ8HO8QV7aa/IUEsbk=
=Sf5b
-----END PGP SIGNATURE-----
diff -urN fuse-0.95/example/Makefile.am fuse-0.95-mark/example/Makefile.am
--- fuse-0.95/example/Makefile.am Wed Nov 21 11:52:42 2001
+++ fuse-0.95-mark/example/Makefile.am Thu Jan 10 16:08:26 2002
@@ -1,9 +1,11 @@
## Process this file with automake to produce Makefile.in
-noinst_PROGRAMS = fusexmp null hello
+noinst_PROGRAMS = fusexmp null hello mount union_mount
fusexmp_SOURCES = fusexmp.c
null_SOURCES = null.c
hello_SOURCES = hello.c
+mount_SOURCES = mount.c
+union_mount_SOURCES = union_mount.c
LDADD = ../lib/libfuse.a -lpthread
diff -urN fuse-0.95/example/Makefile.in fuse-0.95-mark/example/Makefile.in
--- fuse-0.95/example/Makefile.in Wed Jan 9 15:51:33 2002
+++ fuse-0.95-mark/example/Makefile.in Thu Jan 10 16:11:27 2002
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -66,11 +66,13 @@
VERSION = @VERSION@
kmoduledir = @kmoduledir@
-noinst_PROGRAMS = fusexmp null hello
+noinst_PROGRAMS = fusexmp null hello mount union_mount
fusexmp_SOURCES = fusexmp.c
null_SOURCES = null.c
hello_SOURCES = hello.c
+mount_SOURCES = mount.c
+union_mount_SOURCES = union_mount.c
LDADD = ../lib/libfuse.a -lpthread
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -95,6 +97,14 @@
hello_LDADD = $(LDADD)
hello_DEPENDENCIES = ../lib/libfuse.a
hello_LDFLAGS =
+mount_OBJECTS = mount.o
+mount_LDADD = $(LDADD)
+mount_DEPENDENCIES = ../lib/libfuse.a
+mount_LDFLAGS =
+union_mount_OBJECTS = union_mount.o
+union_mount_LDADD = $(LDADD)
+union_mount_DEPENDENCIES = ../lib/libfuse.a
+union_mount_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
@@ -104,10 +114,10 @@
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
+TAR = gtar
GZIP_ENV = --best
-SOURCES = $(fusexmp_SOURCES) $(null_SOURCES) $(hello_SOURCES)
-OBJECTS = $(fusexmp_OBJECTS) $(null_OBJECTS) $(hello_OBJECTS)
+SOURCES = $(fusexmp_SOURCES) $(null_SOURCES) $(hello_SOURCES) $(mount_SOURCES) $(union_mount_SOURCES)
+OBJECTS = $(fusexmp_OBJECTS) $(null_OBJECTS) $(hello_OBJECTS) $(mount_OBJECTS) $(union_mount_OBJECTS)
all: all-redirect
.SUFFIXES:
@@ -160,6 +170,14 @@
@rm -f hello
$(LINK) $(hello_LDFLAGS) $(hello_OBJECTS) $(hello_LDADD) $(LIBS)
+mount: $(mount_OBJECTS) $(mount_DEPENDENCIES)
+ @rm -f mount
+ $(LINK) $(mount_LDFLAGS) $(mount_OBJECTS) $(mount_LDADD) $(LIBS)
+
+union_mount: $(union_mount_OBJECTS) $(union_mount_DEPENDENCIES)
+ @rm -f union_mount
+ $(LINK) $(union_mount_LDFLAGS) $(union_mount_OBJECTS) $(union_mount_LDADD) $(LIBS)
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
@@ -204,7 +222,6 @@
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
-
info-am:
info: info-am
dvi-am:
diff -urN fuse-0.95/example/fusexmp.c fuse-0.95-mark/example/fusexmp.c
--- fuse-0.95/example/fusexmp.c Tue Jan 8 11:40:12 2002
+++ fuse-0.95-mark/example/fusexmp.c Thu Jan 10 16:12:06 2002
@@ -18,6 +18,7 @@
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>
+#include <string.h>
static int xmp_getattr(const char *path, struct stat *stbuf)
{
diff -urN fuse-0.95/example/hello.c fuse-0.95-mark/example/hello.c
--- fuse-0.95/example/hello.c Tue Jan 8 11:40:12 2002
+++ fuse-0.95-mark/example/hello.c Thu Jan 10 14:39:15 2002
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <string.h>
static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";
diff -urN fuse-0.95/example/mount.c fuse-0.95-mark/example/mount.c
--- fuse-0.95/example/mount.c Thu Jan 1 02:00:00 1970
+++ fuse-0.95-mark/example/mount.c Thu Jan 10 16:09:02 2002
@@ -0,0 +1,286 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001 Miklos Szeredi ([EMAIL PROTECTED])
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+
+ This example shows mounting of single directory (whatever file system
+ it is originally).
+*/
+
+#ifdef linux
+/* For pread()/pwrite() */
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <fuse.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/statfs.h>
+#include <string.h>
+
+static char* dir="/home/mark/first";
+#define SIZE 1024
+
+static void copy_it(const char* path,char* temp) {
+ *temp='\0';
+ strncat(temp,dir,SIZE);
+ strncat(temp,path,SIZE);
+}
+
+static int xmp_getattr(const char *path, struct stat *stbuf)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res=lstat(temp, stbuf);
+ if(res==-1)
+ return(-errno);
+ return(0);
+}
+
+static int xmp_readlink(const char *path, char *buf, size_t size)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res=readlink(temp,buf,size-1);
+ if(res==-1)
+ return(-errno);
+ buf[res]='\0';
+ return 0;
+}
+
+
+static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
+{
+ DIR *dp;
+ struct dirent *de;
+ int res = 0;
+ char temp[SIZE];
+ copy_it(path,temp);
+ dp=opendir(temp);
+ if(dp==NULL)
+ return(-errno);
+ while((de = readdir(dp)) != NULL) {
+ res = filler(h, de->d_name, de->d_type);
+ if(res != 0)
+ break;
+ }
+ closedir(dp);
+ return(res);
+}
+
+static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res=mknod(temp,mode,rdev);
+ if(res==-1)
+ return(-errno);
+ return(0);
+}
+
+static int xmp_mkdir(const char *path, mode_t mode)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res=mkdir(temp,mode);
+ if(res==-1)
+ return(-errno);
+ return(0);
+}
+
+static int xmp_unlink(const char *path)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = unlink(temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_rmdir(const char *path)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res=rmdir(temp);
+ if(res==-1)
+ return(-errno);
+ return 0;
+}
+
+static int xmp_symlink(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp);
+ copy_it(to,to_temp);
+ res = symlink(from_temp, to_temp);
+ if(res == -1)
+ return(-errno);
+ return 0;
+}
+
+static int xmp_rename(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp);
+ copy_it(to,to_temp);
+ res = rename(from_temp, to_temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_link(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp);
+ copy_it(to,to_temp);
+ res = link(from_temp, to_temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_chmod(const char *path, mode_t mode)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = chmod(temp, mode);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_chown(const char *path, uid_t uid, gid_t gid)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = lchown(temp, uid, gid);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_truncate(const char *path, off_t size)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = truncate(temp, size);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_utime(const char *path, struct utimbuf *buf)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = utime(temp, buf);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+
+static int xmp_open(const char *path, int flags)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ res = open(temp, flags);
+ if(res == -1)
+ return(-errno);
+ close(res);
+ return 0;
+}
+
+static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
+{
+ int fd;
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ fd = open(temp, O_RDONLY);
+ if(fd == -1)
+ return -errno;
+ res = pread(fd, buf, size, offset);
+ if(res == -1)
+ res = -errno;
+ close(fd);
+ return res;
+}
+
+static int xmp_write(const char *path, const char *buf, size_t size,
+ off_t offset)
+{
+ int fd;
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp);
+ fd = open(temp, O_RDONLY);
+ fd = open(temp, O_WRONLY);
+ if(fd == -1)
+ return -errno;
+ res = pwrite(fd, buf, size, offset);
+ if(res == -1)
+ res = -errno;
+ close(fd);
+ return res;
+}
+
+static int xmp_statfs(struct statfs *fst)
+{
+ struct statfs st;
+ int rv = statfs(dir,&st);
+ if(!rv)
+ memcpy(fst,&st,sizeof(st));
+ return rv;
+}
+
+static struct fuse_operations xmp_oper = {
+ getattr: xmp_getattr,
+ readlink: xmp_readlink,
+ getdir: xmp_getdir,
+ mknod: xmp_mknod,
+ mkdir: xmp_mkdir,
+ symlink: xmp_symlink,
+ unlink: xmp_unlink,
+ rmdir: xmp_rmdir,
+ rename: xmp_rename,
+ link: xmp_link,
+ chmod: xmp_chmod,
+ chown: xmp_chown,
+ truncate: xmp_truncate,
+ utime: xmp_utime,
+ open: xmp_open,
+ read: xmp_read,
+ write: xmp_write,
+ statfs: xmp_statfs,
+};
+
+int main(int argc, char *argv[])
+{
+ fuse_main(argc, argv, &xmp_oper);
+ return 0;
+}
diff -urN fuse-0.95/example/null.c fuse-0.95-mark/example/null.c
--- fuse-0.95/example/null.c Tue Jan 8 11:40:12 2002
+++ fuse-0.95-mark/example/null.c Wed Jan 9 19:18:21 2002
@@ -11,6 +11,7 @@
#include <unistd.h>
#include <time.h>
#include <errno.h>
+#include <string.h>
#define UNUSED __attribute__((unused))
diff -urN fuse-0.95/example/union_mount.c fuse-0.95-mark/example/union_mount.c
--- fuse-0.95/example/union_mount.c Thu Jan 1 02:00:00 1970
+++ fuse-0.95-mark/example/union_mount.c Thu Jan 10 16:10:59 2002
@@ -0,0 +1,341 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001 Miklos Szeredi ([EMAIL PROTECTED])
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+
+ This example shows how to union mount two or more directories.
+ It creates a single directory where files in all directories are
+ shown. When writing to the directory, the directory designated by
+ a special number is the only one which gets written to. This
+ could be useful for many things (change a single file on a CDROM
+ without copying it's content to a hard drive ? you get my meaning...).
+*/
+
+#ifdef linux
+/* For pread()/pwrite() */
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <fuse.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/statfs.h>
+#include <string.h>
+
+#define SIZE 1024
+#define NUM 2
+#define NODE 1
+static const char dir[NUM][SIZE]={
+ "/home/mark/test/second",
+ "/home/mark/test/first"
+};
+
+static void copy_it(const char* path,char* temp,const char* dir) {
+ *temp='\0';
+ strncat(temp,dir,SIZE);
+ strncat(temp,path,SIZE);
+}
+
+static int xmp_getattr(const char *path, struct stat *stbuf)
+{
+ int res;
+ int i;
+ int found=0;
+ for(i=0;i<NUM;i++) {
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res=lstat(temp, stbuf);
+ if(res!=-1) {
+ found=1;
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_readlink(const char *path, char *buf, size_t size)
+{
+ int res;
+ int i;
+ for(i=0;i<NUM;i++) {
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res=readlink(temp,buf,size-1);
+ if(res!=-1) {
+ buf[res]='\0';
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+/* FIXME: add hash to avoid duplicates here */
+static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
+{
+ DIR *dp;
+ struct dirent *de;
+ int res = 0;
+ int i;
+ int error=1;
+ for(i=0;i<NUM;i++) {
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ dp=opendir(temp);
+ if(dp==NULL)
+ continue;
+ error=0;
+ while((de = readdir(dp)) != NULL) {
+ res = filler(h, de->d_name, de->d_type);
+ if(res != 0)
+ break;
+ }
+ closedir(dp);
+ }
+ if(error) {
+ return(-1);
+ } else {
+ return(0);
+ }
+}
+
+static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[NODE]);
+ res=mknod(temp,mode,rdev);
+ if(res==-1)
+ return(-errno);
+ return(0);
+}
+
+static int xmp_mkdir(const char *path, mode_t mode)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[NODE]);
+ res=mkdir(temp,mode);
+ if(res==-1)
+ return(-errno);
+ return(0);
+}
+
+static int xmp_unlink(const char *path)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[NODE]);
+ res = unlink(temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_rmdir(const char *path)
+{
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[NODE]);
+ res=rmdir(temp);
+ if(res==-1)
+ return(-errno);
+ return 0;
+}
+
+static int xmp_symlink(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp,dir[NODE]);
+ copy_it(to,to_temp,dir[NODE]);
+ res = symlink(from_temp, to_temp);
+ if(res == -1)
+ return(-errno);
+ return 0;
+}
+
+static int xmp_rename(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp,dir[NODE]);
+ copy_it(to,to_temp,dir[NODE]);
+ res = rename(from_temp, to_temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_link(const char *from, const char *to)
+{
+ int res;
+ char from_temp[SIZE];
+ char to_temp[SIZE];
+ copy_it(from,from_temp,dir[NODE]);
+ copy_it(to,to_temp,dir[NODE]);
+ res = link(from_temp, to_temp);
+ if(res == -1)
+ return -errno;
+ return 0;
+}
+
+static int xmp_chmod(const char *path, mode_t mode)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res = chmod(temp, mode);
+ if(res != -1)
+ return (0);
+ }
+ return(-1);
+}
+
+static int xmp_chown(const char *path, uid_t uid, gid_t gid)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res = lchown(temp, uid, gid);
+ if(res != -1) {
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_truncate(const char *path, off_t size)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res = truncate(temp, size);
+ if(res != -1) {
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_utime(const char *path, struct utimbuf *buf)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res = utime(temp, buf);
+ if(res!=-1) {
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+
+static int xmp_open(const char *path, int flags)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ res = open(temp, flags);
+ if(res!=-1) {
+ close(res);
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int fd;
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ fd = open(temp, O_RDONLY);
+ if(fd==-1)
+ continue;
+ res=pread(fd, buf, size, offset);
+ if(res!=-1) {
+ close(fd);
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_write(const char *path, const char *buf, size_t size,
+ off_t offset)
+{
+ int i;
+ for(i=0;i<NUM;i++) {
+ int fd;
+ int res;
+ char temp[SIZE];
+ copy_it(path,temp,dir[i]);
+ fd = open(temp, O_RDONLY);
+ fd = open(temp, O_WRONLY);
+ if(fd == -1)
+ continue;
+ res = pwrite(fd, buf, size, offset);
+ if(res!=-1) {
+ close(fd);
+ return(0);
+ }
+ }
+ return(-1);
+}
+
+static int xmp_statfs(struct statfs *fst)
+{
+ struct statfs st;
+ int rv = statfs(dir[NODE],&st);
+ if(!rv)
+ memcpy(fst,&st,sizeof(st));
+ return rv;
+}
+
+static struct fuse_operations xmp_oper = {
+ getattr: xmp_getattr,
+ readlink: xmp_readlink,
+ getdir: xmp_getdir,
+ mknod: xmp_mknod,
+ mkdir: xmp_mkdir,
+ symlink: xmp_symlink,
+ unlink: xmp_unlink,
+ rmdir: xmp_rmdir,
+ rename: xmp_rename,
+ link: xmp_link,
+ chmod: xmp_chmod,
+ chown: xmp_chown,
+ truncate: xmp_truncate,
+ utime: xmp_utime,
+ open: xmp_open,
+ read: xmp_read,
+ write: xmp_write,
+ statfs: xmp_statfs,
+};
+
+int main(int argc, char *argv[])
+{
+ fuse_main(argc, argv, &xmp_oper);
+ return 0;
+}