-----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;
+}

Reply via email to