install-sh
mkinstalldirs
missing
-config.log
*.cache
config.*
depcomp
+2004-11-10 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Merge from fuse_2_0_bugfix to fuse_2_0_merge1
+
+2004-11-10 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Separate configure for the kernel directory
+
+2004-11-09 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Fix 'makeconf.sh' to use autoreconf if available
+
2004-11-08 Miklos Szeredi <miklos@szeredi.hu>
* Add ino argument to 'fuse_dirfil_t'. NOTE: This breaks source
## Process this file with automake to produce Makefile.in
-SUBDIRS = @subdirs@
+SUBDIRS = @subdirs@ @subdirs2@
EXTRA_DIST = \
fuse.pc.in \
-AC_INIT(lib/fuse.c)
-AM_INIT_AUTOMAKE(fuse, 1.9)
+AC_INIT(fuse, 2.1-pre0)
+AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(include/config.h)
m4_ifdef([LT_INIT],
[AC_PROG_LIBTOOL])
AC_PROG_CC
-if test -z "$LD"; then
- LD=ld
-fi
-AC_SUBST(LD)
-
# compatibility for automake < 1.8
if test -z "$mkdir_p"; then
mkdir_p="../mkinstalldirs"
CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT"
AC_ARG_ENABLE(kernel-module,
- [ --enable-kernel-module Compile kernel module, requires --with-kernel option ])
+ [ --enable-kernel-module Compile kernel module ])
AC_ARG_ENABLE(lib,
[ --enable-lib Compile with library ])
AC_ARG_ENABLE(util,
AC_ARG_ENABLE(auto-modprobe,
[ --enable-auto-modprobe Automatically insert kernel module])
-subdirs="include patch"
+subdirs2="include"
if test "$enable_kernel_module" != "no"; then
- AC_MSG_CHECKING([kernel source directory])
- kernelsrc=
- AC_ARG_WITH(kernel,
- [ --with-kernel Specify location of kernel source ],
- [kernelsrc="$withval"])
-
- if test -z "$kernelsrc"; then
- buildlink=/lib/modules/`uname -r`/build
- if test -e $buildlink; then
- kernelsrc=`(cd $buildlink; /bin/pwd)`
- else
- AC_MSG_RESULT([Not found])
- AC_MSG_ERROR([
-*** Please specify the location of the kernel source with
-*** the '--with-kernel=SRCDIR' option])
- fi
- fi
- AC_MSG_RESULT([$kernelsrc])
-
- AC_MSG_CHECKING([kernel source version])
- if test -r $kernelsrc/include/linux/version.h; then
- kernsrcver=`(echo "#include <linux/version.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelsrc/include | grep "^kernsrcver=" | cut -d \" -f 2`
- fi
- if test -z "$kernsrcver"; then
- AC_MSG_RESULT([Not found])
- AC_MSG_ERROR([
-*** Cannot determine the version of the linux kernel source. Please
-*** configure the kernel before running this script])
- fi
- AC_MSG_RESULT([$kernsrcver])
- majver=`echo "$kernsrcver" | cut -f-2 -d.`
- kmoduledir=/lib/modules/$kernsrcver
- AC_SUBST(kernelsrc)
- AC_SUBST(majver)
- AC_SUBST(kmoduledir)
- subdirs="$subdirs kernel"
-
- if echo "$kernsrcver" | grep -q "^2.4"; then
- old_cflags="$CFLAGS"
- CFLAGS="-I${kernelsrc}/include -Wall -O2 -fno-strict-aliasing -D__KERNEL__"
- AC_CHECK_DECL(i_size_read,
- AC_DEFINE(HAVE_I_SIZE_FUNC, 1,
- [Kernel has i_size_read() and i_size_write() functions]),,
- [#include <linux/fs.h>])
- CFLAGS="$old_cflags"
- fi
- AC_MSG_CHECKING([if kernel has extended attribute support])
- if test -f $kernelsrc/include/linux/xattr.h; then
- AC_DEFINE(HAVE_KERNEL_XATTR, 1, [Kernel has xattr support],,)
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
-
- isuml=no
- KERNELMAKE_PARAMS=
- KERNELCPPFLAGS=
- AC_MSG_CHECKING([if this is user mode linux])
- if test -f $kernelsrc/include/linux/autoconf.h && grep -q "^#define CONFIG_USERMODE 1" $kernelsrc/include/linux/autoconf.h; then
- isuml=yes
- KERNELMAKE_PARAMS="ARCH=um"
- KERNELCPPFLAGS="-D__arch_um__ -DSUBARCH=\\\"i386\\\" -D_LARGEFILE64_SOURCE -I${kernelsrc}/arch/um/include -Derrno=kernel_errno -I${kernelsrc}/arch/um/kernel/tt/include -I${kernelsrc}/arch/um/kernel/skas/include"
- fi
- AC_MSG_RESULT([$isuml])
- AC_SUBST(KERNELMAKE_PARAMS)
- AC_SUBST(KERNELCPPFLAGS)
+ AC_CONFIG_SUBDIRS(kernel)
fi
if test "$enable_lib" != "no"; then
- subdirs="$subdirs lib";
+ subdirs2="$subdirs2 lib";
fi
if test "$enable_util" != "no"; then
- subdirs="$subdirs util";
+ subdirs2="$subdirs2 util";
fi
if test "$enable_example" != "no"; then
- subdirs="$subdirs example";
+ subdirs2="$subdirs2 example";
fi
if test "$enable_auto_modprobe" = "yes"; then
AC_DEFINE(AUTO_MODPROBE, 1, [Automatically insert kernel module])
AC_CHECK_FUNCS([setxattr])
AC_CHECK_MEMBERS([struct stat.st_atim])
-AC_SUBST(subdirs)
+AC_SUBST(subdirs2)
-AC_CONFIG_FILES([fuse.pc Makefile kernel/Makefile lib/Makefile util/Makefile example/Makefile include/Makefile include/linux/Makefile patch/Makefile])
+AC_CONFIG_FILES([fuse.pc Makefile lib/Makefile util/Makefile example/Makefile include/Makefile include/linux/Makefile])
AC_OUTPUT
Description: Filesystem in Userspace
Version: @VERSION@
Libs: -L${libdir} -lfuse
-Cflags: -I${includedir}/fuse
+Cflags: -I${includedir}
Makefile.in
Makefile
+fuse.h
## Process this file with automake to produce Makefile.in
noinst_HEADERS = fuse.h
+
+all-local: fuse.h
+
+fuse.h:
+ ln -s ../../kernel/linux/fuse.h .
+++ /dev/null
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2004 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
-*/
-
-/* This file defines the kernel interface of FUSE */
-
-/** Version number of this interface */
-#define FUSE_KERNEL_VERSION 4
-
-/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 1
-
-/** The node ID of the root inode */
-#define FUSE_ROOT_ID 1
-
-/** Opening this will yield a new control file */
-#define FUSE_DEV "/proc/fs/fuse/dev"
-
-/** The file containing the version in the form MAJOR.MINOR */
-#define FUSE_VERSION_FILE "/proc/fs/fuse/version"
-
-struct fuse_attr {
- unsigned long ino;
- unsigned int mode;
- unsigned int nlink;
- unsigned int uid;
- unsigned int gid;
- unsigned int rdev;
- unsigned long long size;
- unsigned long blocks;
- unsigned long atime;
- unsigned long atimensec;
- unsigned long mtime;
- unsigned long mtimensec;
- unsigned long ctime;
- unsigned long ctimensec;
-};
-
-struct fuse_kstatfs {
- unsigned int bsize;
- unsigned long long blocks;
- unsigned long long bfree;
- unsigned long long bavail;
- unsigned long long files;
- unsigned long long ffree;
- unsigned int namelen;
-};
-
-#define FATTR_MODE (1 << 0)
-#define FATTR_UID (1 << 1)
-#define FATTR_GID (1 << 2)
-#define FATTR_SIZE (1 << 3)
-#define FATTR_ATIME (1 << 4)
-#define FATTR_MTIME (1 << 5)
-#define FATTR_CTIME (1 << 6)
-
-enum fuse_opcode {
- FUSE_LOOKUP = 1,
- FUSE_FORGET = 2, /* no reply */
- FUSE_GETATTR = 3,
- FUSE_SETATTR = 4,
- FUSE_READLINK = 5,
- FUSE_SYMLINK = 6,
- FUSE_GETDIR = 7,
- FUSE_MKNOD = 8,
- FUSE_MKDIR = 9,
- FUSE_UNLINK = 10,
- FUSE_RMDIR = 11,
- FUSE_RENAME = 12,
- FUSE_LINK = 13,
- FUSE_OPEN = 14,
- FUSE_READ = 15,
- FUSE_WRITE = 16,
- FUSE_STATFS = 17,
- FUSE_RELEASE = 18, /* no reply */
- FUSE_INVALIDATE = 19, /* user initiated */
- FUSE_FSYNC = 20,
- FUSE_SETXATTR = 21,
- FUSE_GETXATTR = 22,
- FUSE_LISTXATTR = 23,
- FUSE_REMOVEXATTR = 24,
- FUSE_FLUSH = 25,
-};
-
-/* Conservative buffer size for the client */
-#define FUSE_MAX_IN 8192
-
-#define FUSE_NAME_MAX 1024
-#define FUSE_SYMLINK_MAX 4096
-#define FUSE_XATTR_SIZE_MAX 4096
-
-struct fuse_entry_out {
- unsigned long nodeid; /* Inode ID */
- unsigned long generation; /* Inode generation: nodeid:gen must
- be unique for the fs's lifetime */
- unsigned long entry_valid; /* Cache timeout for the name */
- unsigned long entry_valid_nsec;
- unsigned long attr_valid; /* Cache timeout for the attributes */
- unsigned long attr_valid_nsec;
- struct fuse_attr attr;
-};
-
-struct fuse_forget_in {
- int version;
-};
-
-struct fuse_attr_out {
- unsigned long attr_valid; /* Cache timeout for the attributes */
- unsigned long attr_valid_nsec;
- struct fuse_attr attr;
-};
-
-struct fuse_getdir_out {
- int fd;
-};
-
-struct fuse_mknod_in {
- unsigned int mode;
- unsigned int rdev;
-};
-
-struct fuse_mkdir_in {
- unsigned int mode;
-};
-
-struct fuse_rename_in {
- unsigned long newdir;
-};
-
-struct fuse_link_in {
- unsigned long newdir;
-};
-
-struct fuse_setattr_in {
- struct fuse_attr attr;
- unsigned int valid;
-};
-
-struct fuse_open_in {
- unsigned int flags;
-};
-
-struct fuse_open_out {
- unsigned long fh;
-};
-
-struct fuse_release_in {
- unsigned long fh;
- unsigned int flags;
-};
-
-struct fuse_flush_in {
- unsigned long fh;
-};
-
-struct fuse_read_in {
- unsigned long fh;
- unsigned long long offset;
- unsigned int size;
-};
-
-struct fuse_write_in {
- int writepage;
- unsigned long fh;
- unsigned long long offset;
- unsigned int size;
-};
-
-struct fuse_write_out {
- unsigned int size;
-};
-
-struct fuse_statfs_out {
- struct fuse_kstatfs st;
-};
-
-struct fuse_fsync_in {
- unsigned long fh;
- int datasync;
-};
-
-struct fuse_setxattr_in {
- unsigned int size;
- unsigned int flags;
-};
-
-struct fuse_getxattr_in {
- unsigned int size;
-};
-
-struct fuse_getxattr_out {
- unsigned int size;
-};
-
-struct fuse_in_header {
- int unique;
- enum fuse_opcode opcode;
- unsigned long nodeid;
- unsigned int uid;
- unsigned int gid;
- unsigned int pid;
-};
-
-struct fuse_out_header {
- int unique;
- int error;
-};
-
-struct fuse_user_header {
- int unique; /* zero */
- enum fuse_opcode opcode;
- unsigned long nodeid;
- unsigned long ino; /* Needed only on 2.4.x where ino is also
- used for inode lookup */
-};
-
-struct fuse_dirent {
- unsigned long ino;
- unsigned short namelen;
- unsigned char type;
- char name[256];
-};
-
-#define FUSE_NAME_OFFSET ((unsigned int) ((struct fuse_dirent *) 0)->name)
-#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(long) - 1) & ~(sizeof(long) - 1))
-#define FUSE_DIRENT_SIZE(d) \
- FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
-
-/*
- * Local Variables:
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
Makefile
+configure
+config.*
+*.cache
.deps
.*.cmd
*.mod.c
SHELL = /bin/sh
INSTALL = @INSTALL@
-mkdir_p = @mkdir_p@
+mkdir_p = mkdir -p
majver = @majver@
+VERSION = @PACKAGE_VERSION@
-DISTFILES = Makefile.in dev.c dir.c file.c inode.c util.c fuse_i.h
+DISTFILES = Makefile.in configure.ac configure config.h.in makeconf.sh \
+ dev.c dir.c file.c inode.c util.c fuse_i.h
COMPATDISTFILES = compat/parser.c compat/parser.h
+LINUXDISTFILES = linux/fuse.h
fusemoduledir = @kmoduledir@/kernel/fs/fuse
distclean: clean
rm -f Makefile
+ rm -f config.h config.log config.status config.cache
+ rm -rf .tmp_versions
maintainer-clean: distclean
-distdir: $(DISTFILES) $(COMPATDISTFILES)
+distdir: $(DISTFILES) $(COMPATDISTFILES) $(LINUXDISTFILES)
cp -p $(DISTFILES) $(distdir)
mkdir $(distdir)/compat
cp -p $(COMPATDISTFILES) $(distdir)/compat
+ mkdir $(distdir)/linux
+ cp -p $(LINUXDISTFILES) $(distdir)/linux
ifeq ($(majver), 2.4)
-CC = @CC@
-LD = @LD@
+CC = gcc
+LD = ld
CFLAGS = -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -pipe
-CPPFLAGS = -I@kernelsrc@/include -I../include -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -DFUSE_VERSION=\"@VERSION@\" @KERNELCPPFLAGS@
+CPPFLAGS = -I@kernelsrc@/include -I. -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -DFUSE_VERSION=\"$(VERSION)\" @KERNELCPPFLAGS@
fuse_objs = dev.o dir.o file.o inode.o util.o compat/parser.o
fuse.o: $(fuse_objs)
$(LD) -r -o fuse.o $(fuse_objs)
-fuse_headers = fuse_i.h ../include/linux/fuse.h
+fuse_headers = fuse_i.h linux/fuse.h
dev.o: $(fuse_headers)
dir.o: $(fuse_headers)
else
-export FUSE_INCLUDE ?= $(shell pwd)/../include
-EXTRA_CFLAGS += -I$(FUSE_INCLUDE) -DFUSE_VERSION=\"@VERSION@\"
+export FUSE_INCLUDE ?= $(shell pwd)
+EXTRA_CFLAGS += -I$(FUSE_INCLUDE) -DFUSE_VERSION=\"$(VERSION)\"
obj-m := fuse.o
fuse-objs := dev.o dir.o file.o inode.o util.o
--- /dev/null
+AC_INIT(fuse-kernel, 2.1-pre0)
+AC_CONFIG_HEADERS([config.h])
+
+AC_MSG_CHECKING([kernel source directory])
+kernelsrc=
+AC_ARG_WITH(kernel,
+ [ --with-kernel=PATH Specify location of kernel source ],
+ [kernelsrc="$withval"])
+
+if test -z "$kernelsrc"; then
+ buildlink=/lib/modules/`uname -r`/build
+ if test -e $buildlink; then
+ kernelsrc=`(cd $buildlink; /bin/pwd)`
+ else
+ AC_MSG_RESULT([Not found])
+ AC_MSG_ERROR([
+*** Please specify the location of the kernel source with
+*** the '--with-kernel=SRCDIR' option])
+ fi
+fi
+AC_MSG_RESULT([$kernelsrc])
+
+AC_MSG_CHECKING([kernel source version])
+if test -r $kernelsrc/include/linux/version.h; then
+ kernsrcver=`(echo "#include <linux/version.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelsrc/include | grep "^kernsrcver=" | cut -d \" -f 2`
+fi
+if test -z "$kernsrcver"; then
+ AC_MSG_RESULT([Not found])
+ AC_MSG_ERROR([
+*** Cannot determine the version of the linux kernel source. Please
+*** configure the kernel before running this script])
+fi
+AC_MSG_RESULT([$kernsrcver])
+majver=`echo "$kernsrcver" | cut -f-2 -d.`
+kmoduledir=/lib/modules/$kernsrcver
+AC_SUBST(kernelsrc)
+AC_SUBST(majver)
+AC_SUBST(kmoduledir)
+subdirs="$subdirs kernel"
+
+if echo "$kernsrcver" | grep -q "^2.4"; then
+ old_cflags="$CFLAGS"
+ CFLAGS="-I${kernelsrc}/include -Wall -O2 -fno-strict-aliasing -D__KERNEL__"
+ AC_CHECK_DECL(i_size_read,
+ AC_DEFINE(HAVE_I_SIZE_FUNC, 1,
+ [Kernel has i_size_read() and i_size_write() functions]),,
+ [#include <linux/fs.h>])
+ CFLAGS="$old_cflags"
+fi
+AC_MSG_CHECKING([if kernel has extended attribute support])
+if test -f $kernelsrc/include/linux/xattr.h; then
+ AC_DEFINE(HAVE_KERNEL_XATTR, 1, [Kernel has xattr support],,)
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+isuml=no
+KERNELMAKE_PARAMS=
+KERNELCPPFLAGS=
+AC_MSG_CHECKING([if this is user mode linux])
+if test -f $kernelsrc/include/linux/autoconf.h && grep -q "^#define CONFIG_USERMODE 1" $kernelsrc/include/linux/autoconf.h; then
+ isuml=yes
+ KERNELMAKE_PARAMS="ARCH=um"
+ KERNELCPPFLAGS="-D__arch_um__ -DSUBARCH=\\\"i386\\\" -D_LARGEFILE64_SOURCE -I${kernelsrc}/arch/um/include -Derrno=kernel_errno -I${kernelsrc}/arch/um/kernel/tt/include -I${kernelsrc}/arch/um/kernel/skas/include"
+fi
+AC_MSG_RESULT([$isuml])
+AC_SUBST(KERNELMAKE_PARAMS)
+AC_SUBST(KERNELCPPFLAGS)
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
#include <config.h>
#ifndef KERNEL_2_6
-#include <linux/config.h>
-#ifdef CONFIG_MODVERSIONS
-#define MODVERSIONS
-#include <linux/modversions.h>
-#endif
-#ifndef HAVE_I_SIZE_FUNC
-#define i_size_read(inode) ((inode)->i_size)
-#define i_size_write(inode, size) do { (inode)->i_size = size; } while(0)
-#endif
+# include <linux/config.h>
+# ifdef CONFIG_MODVERSIONS
+# define MODVERSIONS
+# include <linux/modversions.h>
+# endif
+# ifndef HAVE_I_SIZE_FUNC
+# define i_size_read(inode) ((inode)->i_size)
+# define i_size_write(inode, size) do { (inode)->i_size = size; } while(0)
+# endif
#endif
#include <linux/kernel.h>
#include <linux/module.h>
--- /dev/null
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2004 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+/* This file defines the kernel interface of FUSE */
+
+/** Version number of this interface */
+#define FUSE_KERNEL_VERSION 4
+
+/** Minor version number of this interface */
+#define FUSE_KERNEL_MINOR_VERSION 1
+
+/** The node ID of the root inode */
+#define FUSE_ROOT_ID 1
+
+/** Opening this will yield a new control file */
+#define FUSE_DEV "/proc/fs/fuse/dev"
+
+/** The file containing the version in the form MAJOR.MINOR */
+#define FUSE_VERSION_FILE "/proc/fs/fuse/version"
+
+struct fuse_attr {
+ unsigned long ino;
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int rdev;
+ unsigned long long size;
+ unsigned long blocks;
+ unsigned long atime;
+ unsigned long atimensec;
+ unsigned long mtime;
+ unsigned long mtimensec;
+ unsigned long ctime;
+ unsigned long ctimensec;
+};
+
+struct fuse_kstatfs {
+ unsigned int bsize;
+ unsigned long long blocks;
+ unsigned long long bfree;
+ unsigned long long bavail;
+ unsigned long long files;
+ unsigned long long ffree;
+ unsigned int namelen;
+};
+
+#define FATTR_MODE (1 << 0)
+#define FATTR_UID (1 << 1)
+#define FATTR_GID (1 << 2)
+#define FATTR_SIZE (1 << 3)
+#define FATTR_ATIME (1 << 4)
+#define FATTR_MTIME (1 << 5)
+#define FATTR_CTIME (1 << 6)
+
+enum fuse_opcode {
+ FUSE_LOOKUP = 1,
+ FUSE_FORGET = 2, /* no reply */
+ FUSE_GETATTR = 3,
+ FUSE_SETATTR = 4,
+ FUSE_READLINK = 5,
+ FUSE_SYMLINK = 6,
+ FUSE_GETDIR = 7,
+ FUSE_MKNOD = 8,
+ FUSE_MKDIR = 9,
+ FUSE_UNLINK = 10,
+ FUSE_RMDIR = 11,
+ FUSE_RENAME = 12,
+ FUSE_LINK = 13,
+ FUSE_OPEN = 14,
+ FUSE_READ = 15,
+ FUSE_WRITE = 16,
+ FUSE_STATFS = 17,
+ FUSE_RELEASE = 18, /* no reply */
+ FUSE_INVALIDATE = 19, /* user initiated */
+ FUSE_FSYNC = 20,
+ FUSE_SETXATTR = 21,
+ FUSE_GETXATTR = 22,
+ FUSE_LISTXATTR = 23,
+ FUSE_REMOVEXATTR = 24,
+ FUSE_FLUSH = 25,
+};
+
+/* Conservative buffer size for the client */
+#define FUSE_MAX_IN 8192
+
+#define FUSE_NAME_MAX 1024
+#define FUSE_SYMLINK_MAX 4096
+#define FUSE_XATTR_SIZE_MAX 4096
+
+struct fuse_entry_out {
+ unsigned long nodeid; /* Inode ID */
+ unsigned long generation; /* Inode generation: nodeid:gen must
+ be unique for the fs's lifetime */
+ unsigned long entry_valid; /* Cache timeout for the name */
+ unsigned long entry_valid_nsec;
+ unsigned long attr_valid; /* Cache timeout for the attributes */
+ unsigned long attr_valid_nsec;
+ struct fuse_attr attr;
+};
+
+struct fuse_forget_in {
+ int version;
+};
+
+struct fuse_attr_out {
+ unsigned long attr_valid; /* Cache timeout for the attributes */
+ unsigned long attr_valid_nsec;
+ struct fuse_attr attr;
+};
+
+struct fuse_getdir_out {
+ int fd;
+};
+
+struct fuse_mknod_in {
+ unsigned int mode;
+ unsigned int rdev;
+};
+
+struct fuse_mkdir_in {
+ unsigned int mode;
+};
+
+struct fuse_rename_in {
+ unsigned long newdir;
+};
+
+struct fuse_link_in {
+ unsigned long newdir;
+};
+
+struct fuse_setattr_in {
+ struct fuse_attr attr;
+ unsigned int valid;
+};
+
+struct fuse_open_in {
+ unsigned int flags;
+};
+
+struct fuse_open_out {
+ unsigned long fh;
+};
+
+struct fuse_release_in {
+ unsigned long fh;
+ unsigned int flags;
+};
+
+struct fuse_flush_in {
+ unsigned long fh;
+};
+
+struct fuse_read_in {
+ unsigned long fh;
+ unsigned long long offset;
+ unsigned int size;
+};
+
+struct fuse_write_in {
+ int writepage;
+ unsigned long fh;
+ unsigned long long offset;
+ unsigned int size;
+};
+
+struct fuse_write_out {
+ unsigned int size;
+};
+
+struct fuse_statfs_out {
+ struct fuse_kstatfs st;
+};
+
+struct fuse_fsync_in {
+ unsigned long fh;
+ int datasync;
+};
+
+struct fuse_setxattr_in {
+ unsigned int size;
+ unsigned int flags;
+};
+
+struct fuse_getxattr_in {
+ unsigned int size;
+};
+
+struct fuse_getxattr_out {
+ unsigned int size;
+};
+
+struct fuse_in_header {
+ int unique;
+ enum fuse_opcode opcode;
+ unsigned long nodeid;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int pid;
+};
+
+struct fuse_out_header {
+ int unique;
+ int error;
+};
+
+struct fuse_user_header {
+ int unique; /* zero */
+ enum fuse_opcode opcode;
+ unsigned long nodeid;
+ unsigned long ino; /* Needed only on 2.4.x where ino is also
+ used for inode lookup */
+};
+
+struct fuse_dirent {
+ unsigned long ino;
+ unsigned short namelen;
+ unsigned char type;
+ char name[256];
+};
+
+#define FUSE_NAME_OFFSET ((unsigned int) ((struct fuse_dirent *) 0)->name)
+#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(long) - 1) & ~(sizeof(long) - 1))
+#define FUSE_DIRENT_SIZE(d) \
+ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+/*
+ * Local Variables:
+ * indent-tabs-mode: t
+ * c-basic-offset: 8
+ * End:
+ */
--- /dev/null
+#! /bin/sh
+
+echo Running autoheader...
+autoheader
+echo Running autoconf...
+autoconf
+
+rm -f config.cache config.status
+echo "To compile run './configure', and then 'make'."
#! /bin/sh
-echo "NOTE: this script is obsolete. Use autoreconf instead!"
echo Running libtoolize...
-libtoolize --automake
-echo Running aclocal...
-aclocal
-echo Running autoheader...
-autoheader
-echo Running autoconf...
-autoconf
-echo Running automake...
-automake -a -c
+libtoolize --automake -c
+
+if test ! -z "`which autoreconf`"; then
+ echo Running autoreconf...
+ autoreconf -i
+else
+ echo Running aclocal...
+ aclocal
+ echo Running autoheader...
+ autoheader
+ echo Running autoconf...
+ autoconf
+ echo Running automake...
+ automake -a -c
+fi
+
rm -f config.cache config.status
echo "To compile run './configure', and then 'make'."
+++ /dev/null
-Makefile.in
-Makefile
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = *.patch
+++ /dev/null
-diff -ru linux-2.6.3-rc4.orig/fs/filesystems.c linux-2.6.3-rc4/fs/filesystems.c
---- linux-2.6.3-rc4.orig/fs/filesystems.c 2003-12-18 03:59:18.000000000 +0100
-+++ linux-2.6.3-rc4/fs/filesystems.c 2004-02-17 10:08:04.000000000 +0100
-@@ -222,7 +222,8 @@
- if (fs && !try_module_get(fs->owner))
- fs = NULL;
- read_unlock(&file_systems_lock);
-- if (!fs && (request_module("%s", name) == 0)) {
-+ if (!fs && capable(CAP_SYS_ADMIN) &&
-+ (request_module("%s", name) == 0)) {
- read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
- if (fs && !try_module_get(fs->owner))
-diff -ru linux-2.6.3-rc4.orig/fs/namespace.c linux-2.6.3-rc4/fs/namespace.c
---- linux-2.6.3-rc4.orig/fs/namespace.c 2004-02-17 10:20:40.000000000 +0100
-+++ linux-2.6.3-rc4/fs/namespace.c 2004-02-17 10:08:04.000000000 +0100
-@@ -25,13 +25,16 @@
-
- extern int __init init_rootfs(void);
- extern int __init sysfs_init(void);
-+extern void put_filesystem(struct file_system_type *fs);
-+
-+#define MAX_MOUNTS 256
-
- /* spinlock for vfsmount related operations, inplace of dcache_lock */
- spinlock_t vfsmount_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
- static struct list_head *mount_hashtable;
- static int hash_mask, hash_bits;
- static kmem_cache_t *mnt_cache;
--
-+struct mounts_stat_struct mounts_stat = { .max_mounts = MAX_MOUNTS };
- static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
- {
- unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
-@@ -40,10 +43,38 @@
- return tmp & hash_mask;
- }
-
-+static inline int inc_nr_mounts(void)
-+{
-+ int err = 0;
-+ spin_lock(&vfsmount_lock);
-+ if (capable(CAP_SYS_ADMIN) ||
-+ mounts_stat.nr_mounts < mounts_stat.max_mounts)
-+ mounts_stat.nr_mounts++;
-+ else
-+ err = mounts_stat.max_mounts ? -EMFILE : -EPERM;
-+ spin_unlock(&vfsmount_lock);
-+ return err;
-+}
-+
-+static inline void dec_nr_mounts(void)
-+{
-+ spin_lock(&vfsmount_lock);
-+ mounts_stat.nr_mounts--;
-+ spin_unlock(&vfsmount_lock);
-+}
-+
- struct vfsmount *alloc_vfsmnt(const char *name)
- {
-- struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
-- if (mnt) {
-+ struct vfsmount *mnt;
-+ int err = inc_nr_mounts();
-+ if (err)
-+ return ERR_PTR(err);
-+
-+ mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
-+ if (!mnt) {
-+ dec_nr_mounts();
-+ return ERR_PTR(-ENOMEM);
-+ } else {
- memset(mnt, 0, sizeof(struct vfsmount));
- atomic_set(&mnt->mnt_count,1);
- INIT_LIST_HEAD(&mnt->mnt_hash);
-@@ -66,6 +97,7 @@
- {
- kfree(mnt->mnt_devname);
- kmem_cache_free(mnt_cache, mnt);
-+ dec_nr_mounts();
- }
-
- /*
-@@ -147,13 +179,14 @@
- struct super_block *sb = old->mnt_sb;
- struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
-
-- if (mnt) {
-+ if (!IS_ERR(mnt)) {
- mnt->mnt_flags = old->mnt_flags;
- atomic_inc(&sb->s_active);
- mnt->mnt_sb = sb;
- mnt->mnt_root = dget(root);
- mnt->mnt_mountpoint = mnt->mnt_root;
- mnt->mnt_parent = mnt;
-+ mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
- }
- return mnt;
- }
-@@ -238,6 +271,8 @@
- if (mnt->mnt_flags & fs_infop->flag)
- seq_puts(m, fs_infop->str);
- }
-+ if (mnt->user)
-+ seq_printf(m, ",user=%i", mnt->user);
- if (mnt->mnt_sb->s_op->show_options)
- err = mnt->mnt_sb->s_op->show_options(m, mnt);
- seq_puts(m, " 0 0\n");
-@@ -388,8 +423,10 @@
- goto dput_and_out;
-
- retval = -EPERM;
-- if (!capable(CAP_SYS_ADMIN))
-- goto dput_and_out;
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ if(nd.mnt->user != current->fsuid || (flags & MNT_FORCE))
-+ goto dput_and_out;
-+ }
-
- retval = do_umount(nd.mnt, flags);
- dput_and_out:
-@@ -409,20 +446,15 @@
-
- static int mount_is_safe(struct nameidata *nd)
- {
-- if (capable(CAP_SYS_ADMIN))
-- return 0;
-- return -EPERM;
--#ifdef notyet
-- if (S_ISLNK(nd->dentry->d_inode->i_mode))
-- return -EPERM;
-- if (nd->dentry->d_inode->i_mode & S_ISVTX) {
-- if (current->uid != nd->dentry->d_inode->i_uid)
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ if (!S_ISDIR(nd->dentry->d_inode->i_mode) &&
-+ !S_ISREG(nd->dentry->d_inode->i_mode))
-+ return -EPERM;
-+ if (current->fsuid != nd->dentry->d_inode->i_uid ||
-+ permission(nd->dentry->d_inode, MAY_WRITE, nd))
- return -EPERM;
- }
-- if (permission(nd->dentry->d_inode, MAY_WRITE, nd))
-- return -EPERM;
- return 0;
--#endif
- }
-
- static int
-@@ -444,8 +476,8 @@
- struct nameidata nd;
-
- res = q = clone_mnt(mnt, dentry);
-- if (!q)
-- goto Enomem;
-+ if (IS_ERR(q))
-+ goto out_error;
- q->mnt_mountpoint = mnt->mnt_mountpoint;
-
- p = mnt;
-@@ -463,8 +495,8 @@
- nd.mnt = q;
- nd.dentry = p->mnt_mountpoint;
- q = clone_mnt(p, p->mnt_root);
-- if (!q)
-- goto Enomem;
-+ if (IS_ERR(q))
-+ goto out_error;
- spin_lock(&vfsmount_lock);
- list_add_tail(&q->mnt_list, &res->mnt_list);
- attach_mnt(q, &nd);
-@@ -472,13 +504,13 @@
- }
- }
- return res;
-- Enomem:
-+ out_error:
- if (res) {
- spin_lock(&vfsmount_lock);
- umount_tree(res);
- spin_unlock(&vfsmount_lock);
- }
-- return NULL;
-+ return q;
- }
-
- static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
-@@ -538,11 +570,14 @@
- down_write(¤t->namespace->sem);
- err = -EINVAL;
- if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
-- err = -ENOMEM;
- if (recurse)
- mnt = copy_tree(old_nd.mnt, old_nd.dentry);
- else
- mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
-+ if (IS_ERR(mnt)) {
-+ err = PTR_ERR(mnt);
-+ goto out;
-+ }
- }
-
- if (mnt) {
-@@ -555,6 +590,7 @@
- mntput(mnt);
- }
-
-+ out:
- up_write(¤t->namespace->sem);
- path_release(&old_nd);
- return err;
-@@ -654,14 +690,28 @@
- int mnt_flags, char *name, void *data)
- {
- struct vfsmount *mnt;
-- int err;
-+ int err = mount_is_safe(nd);
-+ if(err)
-+ return err;
-
- if (!type || !memchr(type, 0, PAGE_SIZE))
- return -EINVAL;
-
- /* we need capabilities... */
-- if (!capable(CAP_SYS_ADMIN))
-- return -EPERM;
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ /* but allow "safe" filesystems anyway */
-+ int issafe = 0;
-+ struct file_system_type *t = get_fs_type(type);
-+ if(t) {
-+ issafe = t->fs_flags & FS_SAFE;
-+ put_filesystem(t);
-+ }
-+ if(!issafe)
-+ return -EPERM;
-+
-+ /* users should not have suid or dev files */
-+ mnt_flags |= (MNT_NOSUID | MNT_NODEV);
-+ }
-
- mnt = do_kern_mount(type, flags, name, data);
- err = PTR_ERR(mnt);
-@@ -797,6 +847,7 @@
- struct namespace *new_ns;
- struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
- struct fs_struct *fs = tsk->fs;
-+ int err;
-
- if (!namespace)
- return 0;
-@@ -806,11 +857,7 @@
- if (!(flags & CLONE_NEWNS))
- return 0;
-
-- if (!capable(CAP_SYS_ADMIN)) {
-- put_namespace(namespace);
-- return -EPERM;
-- }
--
-+ err = -ENOMEM;
- new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
- if (!new_ns)
- goto out;
-@@ -822,7 +869,8 @@
- down_write(&tsk->namespace->sem);
- /* First pass: copy the tree topology */
- new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
-- if (!new_ns->root) {
-+ if (IS_ERR(new_ns->root)) {
-+ err = PTR_ERR(new_ns->root);
- up_write(&tsk->namespace->sem);
- kfree(new_ns);
- goto out;
-@@ -872,7 +920,7 @@
-
- out:
- put_namespace(namespace);
-- return -ENOMEM;
-+ return err;
- }
-
- asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
-diff -ru linux-2.6.3-rc4.orig/fs/super.c linux-2.6.3-rc4/fs/super.c
---- linux-2.6.3-rc4.orig/fs/super.c 2004-02-17 10:20:40.000000000 +0100
-+++ linux-2.6.3-rc4/fs/super.c 2004-02-17 10:17:38.000000000 +0100
-@@ -705,7 +705,7 @@
- do_kern_mount(const char *fstype, int flags, const char *name, void *data)
- {
- struct file_system_type *type = get_fs_type(fstype);
-- struct super_block *sb = ERR_PTR(-ENOMEM);
-+ struct super_block *sb;
- struct vfsmount *mnt;
- int error;
- char *secdata = NULL;
-@@ -714,24 +714,23 @@
- return ERR_PTR(-ENODEV);
-
- mnt = alloc_vfsmnt(name);
-- if (!mnt)
-+ error = PTR_ERR(mnt);
-+ if (IS_ERR(mnt))
- goto out;
-
- if (data) {
- secdata = alloc_secdata();
-- if (!secdata) {
-- sb = ERR_PTR(-ENOMEM);
-+ error = -ENOMEM;
-+ if (!secdata)
- goto out_mnt;
-- }
-
- error = security_sb_copy_data(fstype, data, secdata);
-- if (error) {
-- sb = ERR_PTR(error);
-+ if (error)
- goto out_free_secdata;
-- }
- }
-
- sb = type->get_sb(type, flags, name, data);
-+ error = PTR_ERR(sb);
- if (IS_ERR(sb))
- goto out_free_secdata;
- error = security_sb_kern_mount(sb, secdata);
-@@ -741,20 +740,20 @@
- mnt->mnt_root = dget(sb->s_root);
- mnt->mnt_mountpoint = sb->s_root;
- mnt->mnt_parent = mnt;
-+ mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
- up_write(&sb->s_umount);
- put_filesystem(type);
- return mnt;
- out_sb:
- up_write(&sb->s_umount);
- deactivate_super(sb);
-- sb = ERR_PTR(error);
- out_free_secdata:
- free_secdata(secdata);
- out_mnt:
- free_vfsmnt(mnt);
- out:
- put_filesystem(type);
-- return (struct vfsmount *)sb;
-+ return ERR_PTR(error);
- }
-
- struct vfsmount *kern_mount(struct file_system_type *type)
-diff -ru linux-2.6.3-rc4.orig/include/linux/fs.h linux-2.6.3-rc4/include/linux/fs.h
---- linux-2.6.3-rc4.orig/include/linux/fs.h 2004-02-17 10:20:42.000000000 +0100
-+++ linux-2.6.3-rc4/include/linux/fs.h 2004-02-17 10:08:04.000000000 +0100
-@@ -55,6 +55,12 @@
- };
- extern struct files_stat_struct files_stat;
-
-+struct mounts_stat_struct {
-+ int nr_mounts;
-+ int max_mounts;
-+};
-+extern struct mounts_stat_struct mounts_stat;
-+
- struct inodes_stat_t {
- int nr_inodes;
- int nr_unused;
-@@ -89,6 +95,7 @@
-
- /* public flags for file_system_type */
- #define FS_REQUIRES_DEV 1
-+#define FS_SAFE 2 /* Safe to mount by user */
- #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
- #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
- * as nfs_rename() will be cleaned up
-diff -ru linux-2.6.3-rc4.orig/include/linux/mount.h linux-2.6.3-rc4/include/linux/mount.h
---- linux-2.6.3-rc4.orig/include/linux/mount.h 2003-12-18 03:58:08.000000000 +0100
-+++ linux-2.6.3-rc4/include/linux/mount.h 2004-02-17 10:08:04.000000000 +0100
-@@ -30,6 +30,7 @@
- atomic_t mnt_count;
- int mnt_flags;
- char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
-+ uid_t user;
- struct list_head mnt_list;
- };
-
-diff -ru linux-2.6.3-rc4.orig/include/linux/sysctl.h linux-2.6.3-rc4/include/linux/sysctl.h
---- linux-2.6.3-rc4.orig/include/linux/sysctl.h 2004-02-17 10:20:42.000000000 +0100
-+++ linux-2.6.3-rc4/include/linux/sysctl.h 2004-02-17 10:08:04.000000000 +0100
-@@ -608,8 +608,8 @@
- FS_NRFILE=6, /* int:current number of allocated filedescriptors */
- FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */
- FS_DENTRY=8,
-- FS_NRSUPER=9, /* int:current number of allocated super_blocks */
-- FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
-+ FS_NRMOUNT=9, /* int:current number of mounts */
-+ FS_MAXMOUNT=10, /* int:maximum number of mounts allowed */
- FS_OVERFLOWUID=11, /* int: overflow UID */
- FS_OVERFLOWGID=12, /* int: overflow GID */
- FS_LEASES=13, /* int: leases enabled */
-diff -ru linux-2.6.3-rc4.orig/kernel/sysctl.c linux-2.6.3-rc4/kernel/sysctl.c
---- linux-2.6.3-rc4.orig/kernel/sysctl.c 2004-02-17 10:20:43.000000000 +0100
-+++ linux-2.6.3-rc4/kernel/sysctl.c 2004-02-17 10:08:04.000000000 +0100
-@@ -763,6 +763,22 @@
- .proc_handler = &proc_dointvec,
- },
- {
-+ .ctl_name = FS_NRMOUNT,
-+ .procname = "mount-nr",
-+ .data = &mounts_stat.nr_mounts,
-+ .maxlen = sizeof(int),
-+ .mode = 0444,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = FS_MAXMOUNT,
-+ .procname = "mount-max",
-+ .data = &mounts_stat.max_mounts,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
- .ctl_name = FS_OVERFLOWUID,
- .procname = "overflowuid",
- .data = &fs_overflowuid,
+++ /dev/null
-diff -rup linux-2.6.5.orig/fs/filesystems.c linux-2.6.5/fs/filesystems.c
---- linux-2.6.5.orig/fs/filesystems.c 2003-12-18 03:59:18.000000000 +0100
-+++ linux-2.6.5/fs/filesystems.c 2004-04-05 10:54:37.000000000 +0200
-@@ -222,7 +222,8 @@ struct file_system_type *get_fs_type(con
- if (fs && !try_module_get(fs->owner))
- fs = NULL;
- read_unlock(&file_systems_lock);
-- if (!fs && (request_module("%s", name) == 0)) {
-+ if (!fs && capable(CAP_SYS_ADMIN) &&
-+ (request_module("%s", name) == 0)) {
- read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
- if (fs && !try_module_get(fs->owner))
-diff -rup linux-2.6.5.orig/fs/namespace.c linux-2.6.5/fs/namespace.c
---- linux-2.6.5.orig/fs/namespace.c 2004-04-05 10:50:46.000000000 +0200
-+++ linux-2.6.5/fs/namespace.c 2004-04-05 10:54:37.000000000 +0200
-@@ -25,13 +25,16 @@
-
- extern int __init init_rootfs(void);
- extern int __init sysfs_init(void);
-+extern void put_filesystem(struct file_system_type *fs);
-+
-+#define MAX_MOUNTS 256
-
- /* spinlock for vfsmount related operations, inplace of dcache_lock */
- spinlock_t vfsmount_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
- static struct list_head *mount_hashtable;
- static int hash_mask, hash_bits;
- static kmem_cache_t *mnt_cache;
--
-+struct mounts_stat_struct mounts_stat = { .max_mounts = MAX_MOUNTS };
- static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
- {
- unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
-@@ -40,10 +43,38 @@ static inline unsigned long hash(struct
- return tmp & hash_mask;
- }
-
-+static inline int inc_nr_mounts(void)
-+{
-+ int err = 0;
-+ spin_lock(&vfsmount_lock);
-+ if (capable(CAP_SYS_ADMIN) ||
-+ mounts_stat.nr_mounts < mounts_stat.max_mounts)
-+ mounts_stat.nr_mounts++;
-+ else
-+ err = mounts_stat.max_mounts ? -EMFILE : -EPERM;
-+ spin_unlock(&vfsmount_lock);
-+ return err;
-+}
-+
-+static inline void dec_nr_mounts(void)
-+{
-+ spin_lock(&vfsmount_lock);
-+ mounts_stat.nr_mounts--;
-+ spin_unlock(&vfsmount_lock);
-+}
-+
- struct vfsmount *alloc_vfsmnt(const char *name)
- {
-- struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
-- if (mnt) {
-+ struct vfsmount *mnt;
-+ int err = inc_nr_mounts();
-+ if (err)
-+ return ERR_PTR(err);
-+
-+ mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
-+ if (!mnt) {
-+ dec_nr_mounts();
-+ return ERR_PTR(-ENOMEM);
-+ } else {
- memset(mnt, 0, sizeof(struct vfsmount));
- atomic_set(&mnt->mnt_count,1);
- INIT_LIST_HEAD(&mnt->mnt_hash);
-@@ -66,6 +97,7 @@ void free_vfsmnt(struct vfsmount *mnt)
- {
- kfree(mnt->mnt_devname);
- kmem_cache_free(mnt_cache, mnt);
-+ dec_nr_mounts();
- }
-
- /*
-@@ -147,13 +179,14 @@ clone_mnt(struct vfsmount *old, struct d
- struct super_block *sb = old->mnt_sb;
- struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
-
-- if (mnt) {
-+ if (!IS_ERR(mnt)) {
- mnt->mnt_flags = old->mnt_flags;
- atomic_inc(&sb->s_active);
- mnt->mnt_sb = sb;
- mnt->mnt_root = dget(root);
- mnt->mnt_mountpoint = mnt->mnt_root;
- mnt->mnt_parent = mnt;
-+ mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
- }
- return mnt;
- }
-@@ -238,6 +271,8 @@ static int show_vfsmnt(struct seq_file *
- if (mnt->mnt_flags & fs_infop->flag)
- seq_puts(m, fs_infop->str);
- }
-+ if (mnt->user)
-+ seq_printf(m, ",user=%i", mnt->user);
- if (mnt->mnt_sb->s_op->show_options)
- err = mnt->mnt_sb->s_op->show_options(m, mnt);
- seq_puts(m, " 0 0\n");
-@@ -388,8 +423,10 @@ asmlinkage long sys_umount(char __user *
- goto dput_and_out;
-
- retval = -EPERM;
-- if (!capable(CAP_SYS_ADMIN))
-- goto dput_and_out;
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ if(nd.mnt->user != current->fsuid || (flags & MNT_FORCE))
-+ goto dput_and_out;
-+ }
-
- retval = do_umount(nd.mnt, flags);
- dput_and_out:
-@@ -409,20 +446,15 @@ asmlinkage long sys_oldumount(char __use
-
- static int mount_is_safe(struct nameidata *nd)
- {
-- if (capable(CAP_SYS_ADMIN))
-- return 0;
-- return -EPERM;
--#ifdef notyet
-- if (S_ISLNK(nd->dentry->d_inode->i_mode))
-- return -EPERM;
-- if (nd->dentry->d_inode->i_mode & S_ISVTX) {
-- if (current->uid != nd->dentry->d_inode->i_uid)
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ if (!S_ISDIR(nd->dentry->d_inode->i_mode) &&
-+ !S_ISREG(nd->dentry->d_inode->i_mode))
-+ return -EPERM;
-+ if (current->fsuid != nd->dentry->d_inode->i_uid ||
-+ permission(nd->dentry->d_inode, MAY_WRITE, nd))
- return -EPERM;
- }
-- if (permission(nd->dentry->d_inode, MAY_WRITE, nd))
-- return -EPERM;
- return 0;
--#endif
- }
-
- static int
-@@ -444,8 +476,8 @@ static struct vfsmount *copy_tree(struct
- struct nameidata nd;
-
- res = q = clone_mnt(mnt, dentry);
-- if (!q)
-- goto Enomem;
-+ if (IS_ERR(q))
-+ goto out_error;
- q->mnt_mountpoint = mnt->mnt_mountpoint;
-
- p = mnt;
-@@ -463,8 +495,8 @@ static struct vfsmount *copy_tree(struct
- nd.mnt = q;
- nd.dentry = p->mnt_mountpoint;
- q = clone_mnt(p, p->mnt_root);
-- if (!q)
-- goto Enomem;
-+ if (IS_ERR(q))
-+ goto out_error;
- spin_lock(&vfsmount_lock);
- list_add_tail(&q->mnt_list, &res->mnt_list);
- attach_mnt(q, &nd);
-@@ -472,13 +504,13 @@ static struct vfsmount *copy_tree(struct
- }
- }
- return res;
-- Enomem:
-+ out_error:
- if (res) {
- spin_lock(&vfsmount_lock);
- umount_tree(res);
- spin_unlock(&vfsmount_lock);
- }
-- return NULL;
-+ return q;
- }
-
- static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
-@@ -538,11 +570,14 @@ static int do_loopback(struct nameidata
- down_write(¤t->namespace->sem);
- err = -EINVAL;
- if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
-- err = -ENOMEM;
- if (recurse)
- mnt = copy_tree(old_nd.mnt, old_nd.dentry);
- else
- mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
-+ if (IS_ERR(mnt)) {
-+ err = PTR_ERR(mnt);
-+ goto out;
-+ }
- }
-
- if (mnt) {
-@@ -555,6 +590,7 @@ static int do_loopback(struct nameidata
- mntput(mnt);
- }
-
-+ out:
- up_write(¤t->namespace->sem);
- path_release(&old_nd);
- return err;
-@@ -654,14 +690,28 @@ static int do_add_mount(struct nameidata
- int mnt_flags, char *name, void *data)
- {
- struct vfsmount *mnt;
-- int err;
-+ int err = mount_is_safe(nd);
-+ if(err)
-+ return err;
-
- if (!type || !memchr(type, 0, PAGE_SIZE))
- return -EINVAL;
-
- /* we need capabilities... */
-- if (!capable(CAP_SYS_ADMIN))
-- return -EPERM;
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ /* but allow "safe" filesystems anyway */
-+ int issafe = 0;
-+ struct file_system_type *t = get_fs_type(type);
-+ if(t) {
-+ issafe = t->fs_flags & FS_SAFE;
-+ put_filesystem(t);
-+ }
-+ if(!issafe)
-+ return -EPERM;
-+
-+ /* users should not have suid or dev files */
-+ mnt_flags |= (MNT_NOSUID | MNT_NODEV);
-+ }
-
- mnt = do_kern_mount(type, flags, name, data);
- err = PTR_ERR(mnt);
-@@ -801,6 +851,7 @@ int copy_namespace(int flags, struct tas
- struct namespace *new_ns;
- struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
- struct fs_struct *fs = tsk->fs;
-+ int err;
-
- if (!namespace)
- return 0;
-@@ -810,11 +861,7 @@ int copy_namespace(int flags, struct tas
- if (!(flags & CLONE_NEWNS))
- return 0;
-
-- if (!capable(CAP_SYS_ADMIN)) {
-- put_namespace(namespace);
-- return -EPERM;
-- }
--
-+ err = -ENOMEM;
- new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
- if (!new_ns)
- goto out;
-@@ -826,7 +873,8 @@ int copy_namespace(int flags, struct tas
- down_write(&tsk->namespace->sem);
- /* First pass: copy the tree topology */
- new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
-- if (!new_ns->root) {
-+ if (IS_ERR(new_ns->root)) {
-+ err = PTR_ERR(new_ns->root);
- up_write(&tsk->namespace->sem);
- kfree(new_ns);
- goto out;
-@@ -876,7 +924,7 @@ int copy_namespace(int flags, struct tas
-
- out:
- put_namespace(namespace);
-- return -ENOMEM;
-+ return err;
- }
-
- asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
-diff -rup linux-2.6.5.orig/fs/super.c linux-2.6.5/fs/super.c
---- linux-2.6.5.orig/fs/super.c 2004-04-05 10:50:46.000000000 +0200
-+++ linux-2.6.5/fs/super.c 2004-04-05 11:02:10.000000000 +0200
-@@ -726,7 +726,7 @@ struct vfsmount *
- do_kern_mount(const char *fstype, int flags, const char *name, void *data)
- {
- struct file_system_type *type = get_fs_type(fstype);
-- struct super_block *sb = ERR_PTR(-ENOMEM);
-+ struct super_block *sb;
- struct vfsmount *mnt;
- int error;
- char *secdata = NULL;
-@@ -735,24 +735,23 @@ do_kern_mount(const char *fstype, int fl
- return ERR_PTR(-ENODEV);
-
- mnt = alloc_vfsmnt(name);
-- if (!mnt)
-+ error = PTR_ERR(mnt);
-+ if (IS_ERR(mnt))
- goto out;
-
- if (data) {
- secdata = alloc_secdata();
-- if (!secdata) {
-- sb = ERR_PTR(-ENOMEM);
-+ error = -ENOMEM;
-+ if (!secdata)
- goto out_mnt;
-- }
-
- error = security_sb_copy_data(type, data, secdata);
-- if (error) {
-- sb = ERR_PTR(error);
-+ if (error)
- goto out_free_secdata;
-- }
- }
-
- sb = type->get_sb(type, flags, name, data);
-+ error = PTR_ERR(sb);
- if (IS_ERR(sb))
- goto out_free_secdata;
- error = security_sb_kern_mount(sb, secdata);
-@@ -762,20 +761,20 @@ do_kern_mount(const char *fstype, int fl
- mnt->mnt_root = dget(sb->s_root);
- mnt->mnt_mountpoint = sb->s_root;
- mnt->mnt_parent = mnt;
-+ mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
- up_write(&sb->s_umount);
- put_filesystem(type);
- return mnt;
- out_sb:
- up_write(&sb->s_umount);
- deactivate_super(sb);
-- sb = ERR_PTR(error);
- out_free_secdata:
- free_secdata(secdata);
- out_mnt:
- free_vfsmnt(mnt);
- out:
- put_filesystem(type);
-- return (struct vfsmount *)sb;
-+ return ERR_PTR(error);
- }
-
- struct vfsmount *kern_mount(struct file_system_type *type)
-diff -rup linux-2.6.5.orig/include/linux/fs.h linux-2.6.5/include/linux/fs.h
---- linux-2.6.5.orig/include/linux/fs.h 2004-04-05 10:50:50.000000000 +0200
-+++ linux-2.6.5/include/linux/fs.h 2004-04-05 11:03:55.000000000 +0200
-@@ -55,6 +55,12 @@ struct files_stat_struct {
- };
- extern struct files_stat_struct files_stat;
-
-+struct mounts_stat_struct {
-+ int nr_mounts;
-+ int max_mounts;
-+};
-+extern struct mounts_stat_struct mounts_stat;
-+
- struct inodes_stat_t {
- int nr_inodes;
- int nr_unused;
-@@ -90,6 +96,7 @@ extern int leases_enable, dir_notify_ena
- /* public flags for file_system_type */
- #define FS_REQUIRES_DEV 1
- #define FS_BINARY_MOUNTDATA 2
-+#define FS_SAFE 4 /* Safe to mount by user */
- #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
- #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
- * as nfs_rename() will be cleaned up
-diff -rup linux-2.6.5.orig/include/linux/mount.h linux-2.6.5/include/linux/mount.h
---- linux-2.6.5.orig/include/linux/mount.h 2003-12-18 03:58:08.000000000 +0100
-+++ linux-2.6.5/include/linux/mount.h 2004-04-05 10:54:37.000000000 +0200
-@@ -30,6 +30,7 @@ struct vfsmount
- atomic_t mnt_count;
- int mnt_flags;
- char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
-+ uid_t user;
- struct list_head mnt_list;
- };
-
-diff -rup linux-2.6.5.orig/include/linux/sysctl.h linux-2.6.5/include/linux/sysctl.h
---- linux-2.6.5.orig/include/linux/sysctl.h 2004-04-05 10:50:50.000000000 +0200
-+++ linux-2.6.5/include/linux/sysctl.h 2004-04-05 10:54:37.000000000 +0200
-@@ -624,8 +624,8 @@ enum
- FS_NRFILE=6, /* int:current number of allocated filedescriptors */
- FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */
- FS_DENTRY=8,
-- FS_NRSUPER=9, /* int:current number of allocated super_blocks */
-- FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
-+ FS_NRMOUNT=9, /* int:current number of mounts */
-+ FS_MAXMOUNT=10, /* int:maximum number of mounts allowed */
- FS_OVERFLOWUID=11, /* int: overflow UID */
- FS_OVERFLOWGID=12, /* int: overflow GID */
- FS_LEASES=13, /* int: leases enabled */
-diff -rup linux-2.6.5.orig/kernel/sysctl.c linux-2.6.5/kernel/sysctl.c
---- linux-2.6.5.orig/kernel/sysctl.c 2004-04-05 10:50:51.000000000 +0200
-+++ linux-2.6.5/kernel/sysctl.c 2004-04-05 10:54:37.000000000 +0200
-@@ -793,6 +793,22 @@ static ctl_table fs_table[] = {
- .proc_handler = &proc_dointvec,
- },
- {
-+ .ctl_name = FS_NRMOUNT,
-+ .procname = "mount-nr",
-+ .data = &mounts_stat.nr_mounts,
-+ .maxlen = sizeof(int),
-+ .mode = 0444,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .ctl_name = FS_MAXMOUNT,
-+ .procname = "mount-max",
-+ .data = &mounts_stat.max_mounts,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
- .ctl_name = FS_OVERFLOWUID,
- .procname = "overflowuid",
- .data = &fs_overflowuid,