Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 18851 Details for
Bug 30470
lufs-0.9.6 does not support 2.6 kernels
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch to fix.
lufs-kernel-2.6.patch (text/plain), 73.30 KB, created by
James Harlow (RETIRED)
on 2003-10-06 03:56:06 UTC
(
hide
)
Description:
patch to fix.
Filename:
MIME Type:
Creator:
James Harlow (RETIRED)
Created:
2003-10-06 03:56:06 UTC
Size:
73.30 KB
patch
obsolete
>--- kernel/Linux/Makefile.in 2003-10-06 11:26:34.000000000 +0100 >+++ kernel/Linux/Makefile.in.patched 2003-10-06 11:26:15.000000000 +0100 >@@ -150,7 +150,7 @@ > target_os = @target_os@ > target_vendor = @target_vendor@ > SUBDIRS = @KERNEL_DIR@ >-DIST_SUBDIRS = 2.4 2.5 >+DIST_SUBDIRS = 2.4 2.5 2.6 > subdir = kernel/Linux > ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 > mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs >diff -burN kernel.orig/Linux/2.6/Makefile.am kernel/Linux/2.6/Makefile.am >--- kernel.orig/Linux/2.6/Makefile.am 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/Makefile.am 2003-01-25 22:35:37.000000000 +0000 >@@ -0,0 +1,19 @@ >+INCLUDES=-I@KERNEL_HDR@ -I@KERNEL_HDR@/asm-i386/mach-default @all_includes@ >+ >+LIBS= >+ >+CFLAGS=@MODV_FLAGS@ @KDEBUG_FLAGS@ -DKBUILD_MODNAME=lufs -O2 -pipe -fomit-frame-pointer -fno-strict-aliasing -mpreferred-stack-boundary=2 -Wall -D__KERNEL__ -DMODULE -DLINUX >+LDFLAGS=-r >+ >+moduledir=@MODULES_DIR@/kernel/fs/lufs >+ >+module_PROGRAMS=lufs.o >+ >+noinst_HEADERS=lufs.h proc.h >+lufs_o_SOURCES=proc.c inode.c dir.c file.c symlink.c >+lufs_o_LDADD= >+ >+install-data-hook: >+ depmod -aq >+ if [ "`lsmod | grep lufs`" ]; then rmmod lufs; fi >+ modprobe lufs >diff -burN kernel.orig/Linux/2.6/Makefile.in kernel/Linux/2.6/Makefile.in >--- kernel.orig/Linux/2.6/Makefile.in 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/Makefile.in 2003-10-06 11:18:11.000000000 +0100 >@@ -0,0 +1,480 @@ >+# Makefile.in generated by automake 1.7.5 from Makefile.am. >+# @configure_input@ >+ >+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 >+# 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. >+ >+# This program is distributed in the hope that it will be useful, >+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without >+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A >+# PARTICULAR PURPOSE. >+ >+@SET_MAKE@ >+ >+srcdir = @srcdir@ >+top_srcdir = @top_srcdir@ >+VPATH = @srcdir@ >+pkgdatadir = $(datadir)/@PACKAGE@ >+pkglibdir = $(libdir)/@PACKAGE@ >+pkgincludedir = $(includedir)/@PACKAGE@ >+top_builddir = ../../.. >+ >+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd >+INSTALL = @INSTALL@ >+install_sh_DATA = $(install_sh) -c -m 644 >+install_sh_PROGRAM = $(install_sh) -c >+install_sh_SCRIPT = $(install_sh) -c >+INSTALL_HEADER = $(INSTALL_DATA) >+transform = $(program_transform_name) >+NORMAL_INSTALL = : >+PRE_INSTALL = : >+POST_INSTALL = : >+NORMAL_UNINSTALL = : >+PRE_UNINSTALL = : >+POST_UNINSTALL = : >+build_triplet = @build@ >+host_triplet = @host@ >+target_triplet = @target@ >+ACLOCAL = @ACLOCAL@ >+AMDEP_FALSE = @AMDEP_FALSE@ >+AMDEP_TRUE = @AMDEP_TRUE@ >+AMTAR = @AMTAR@ >+AUTOCONF = @AUTOCONF@ >+AUTOFS_INSTALL = @AUTOFS_INSTALL@ >+AUTOHEADER = @AUTOHEADER@ >+AUTOMAKE = @AUTOMAKE@ >+AWK = @AWK@ >+CC = @CC@ >+CCDEPMODE = @CCDEPMODE@ >+ >+CFLAGS = @MODV_FLAGS@ @KDEBUG_FLAGS@ -DKBUILD_MODNAME=lufs -O2 -pipe -fomit-frame-pointer -fno-strict-aliasing -mpreferred-stack-boundary=2 -Wall -D__KERNEL__ -DMODULE -DLINUX >+CPP = @CPP@ >+CPPFLAGS = @CPPFLAGS@ >+CXX = @CXX@ >+CXXDEPMODE = @CXXDEPMODE@ >+CXXFLAGS = @CXXFLAGS@ >+CYGPATH_W = @CYGPATH_W@ >+DEBUG_FLAGS = @DEBUG_FLAGS@ >+DEFS = @DEFS@ >+DEPDIR = @DEPDIR@ >+ECHO = @ECHO@ >+ECHO_C = @ECHO_C@ >+ECHO_N = @ECHO_N@ >+ECHO_T = @ECHO_T@ >+EGREP = @EGREP@ >+EXEEXT = @EXEEXT@ >+GCONF = @GCONF@ >+GVFSCONF = @GVFSCONF@ >+GVFS_CFLAGS = @GVFS_CFLAGS@ >+GVFS_LDADD = @GVFS_LDADD@ >+INSTALL_DATA = @INSTALL_DATA@ >+INSTALL_PROGRAM = @INSTALL_PROGRAM@ >+INSTALL_SCRIPT = @INSTALL_SCRIPT@ >+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ >+KDEBUG_FLAGS = @KDEBUG_FLAGS@ >+KERNEL_DIR = @KERNEL_DIR@ >+KERNEL_HDR = @KERNEL_HDR@ >+LDFLAGS = -r >+LIBCHIPCARD_INCLUDES = @LIBCHIPCARD_INCLUDES@ >+LIBCHIPCARD_LIB = @LIBCHIPCARD_LIB@ >+LIBOBJS = @LIBOBJS@ >+ >+LIBS = >+LIBTOOL = @LIBTOOL@ >+LN_S = @LN_S@ >+LTLIBOBJS = @LTLIBOBJS@ >+LUFS_SUID = @LUFS_SUID@ >+MAKEINFO = @MAKEINFO@ >+MODULES_DIR = @MODULES_DIR@ >+MODV_FLAGS = @MODV_FLAGS@ >+OBJEXT = @OBJEXT@ >+OS_DIR = @OS_DIR@ >+PACKAGE = @PACKAGE@ >+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ >+PACKAGE_NAME = @PACKAGE_NAME@ >+PACKAGE_STRING = @PACKAGE_STRING@ >+PACKAGE_TARNAME = @PACKAGE_TARNAME@ >+PACKAGE_VERSION = @PACKAGE_VERSION@ >+PATH_SEPARATOR = @PATH_SEPARATOR@ >+RANLIB = @RANLIB@ >+SET_MAKE = @SET_MAKE@ >+SHELL = @SHELL@ >+SSHPROG = @SSHPROG@ >+STRIP = @STRIP@ >+VERSION = @VERSION@ >+ac_ct_CC = @ac_ct_CC@ >+ac_ct_CXX = @ac_ct_CXX@ >+ac_ct_RANLIB = @ac_ct_RANLIB@ >+ac_ct_STRIP = @ac_ct_STRIP@ >+all_includes = @all_includes@ >+all_libraries = @all_libraries@ >+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ >+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ >+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ >+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ >+am__include = @am__include@ >+am__leading_dot = @am__leading_dot@ >+am__quote = @am__quote@ >+bindir = @bindir@ >+build = @build@ >+build_alias = @build_alias@ >+build_cpu = @build_cpu@ >+build_os = @build_os@ >+build_vendor = @build_vendor@ >+datadir = @datadir@ >+define_has_libchipcard = @define_has_libchipcard@ >+exec_prefix = @exec_prefix@ >+host = @host@ >+host_alias = @host_alias@ >+host_cpu = @host_cpu@ >+host_os = @host_os@ >+host_vendor = @host_vendor@ >+includedir = @includedir@ >+infodir = @infodir@ >+install_sh = @install_sh@ >+libdir = @libdir@ >+libexecdir = @libexecdir@ >+localstatedir = @localstatedir@ >+mandir = @mandir@ >+oldincludedir = @oldincludedir@ >+opt_fs = @opt_fs@ >+prefix = @prefix@ >+program_transform_name = @program_transform_name@ >+sbindir = @sbindir@ >+sharedstatedir = @sharedstatedir@ >+sysconfdir = @sysconfdir@ >+target = @target@ >+target_alias = @target_alias@ >+target_cpu = @target_cpu@ >+target_os = @target_os@ >+target_vendor = @target_vendor@ >+INCLUDES = -I@KERNEL_HDR@ -I@KERNEL_HDR@/asm-i386/mach-default @all_includes@ >+ >+moduledir = @MODULES_DIR@/kernel/fs/lufs >+ >+module_PROGRAMS = lufs.o >+ >+noinst_HEADERS = lufs.h proc.h >+lufs_o_SOURCES = proc.c inode.c dir.c file.c symlink.c >+lufs_o_LDADD = >+subdir = kernel/Linux/2.5 >+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 >+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs >+CONFIG_HEADER = $(top_builddir)/config.h >+CONFIG_CLEAN_FILES = >+module_PROGRAMS = lufs.o$(EXEEXT) >+PROGRAMS = $(module_PROGRAMS) >+ >+am_lufs_o_OBJECTS = proc.$(OBJEXT) inode.$(OBJEXT) dir.$(OBJEXT) \ >+ file.$(OBJEXT) symlink.$(OBJEXT) >+lufs_o_OBJECTS = $(am_lufs_o_OBJECTS) >+lufs_o_DEPENDENCIES = >+lufs_o_LDFLAGS = >+ >+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) >+depcomp = $(SHELL) $(top_srcdir)/config/depcomp >+am__depfiles_maybe = depfiles >+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dir.Po ./$(DEPDIR)/file.Po \ >+@AMDEP_TRUE@ ./$(DEPDIR)/inode.Po ./$(DEPDIR)/proc.Po \ >+@AMDEP_TRUE@ ./$(DEPDIR)/symlink.Po >+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ >+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) >+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ >+ $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) >+CCLD = $(CC) >+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ >+ $(AM_LDFLAGS) $(LDFLAGS) -o $@ >+DIST_SOURCES = $(lufs_o_SOURCES) >+HEADERS = $(noinst_HEADERS) >+ >+DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in >+SOURCES = $(lufs_o_SOURCES) >+ >+all: all-am >+ >+.SUFFIXES: >+.SUFFIXES: .c .lo .o .obj >+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) >+ cd $(top_srcdir) && \ >+ $(AUTOMAKE) --gnu kernel/Linux/2.5/Makefile >+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status >+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) >+modulePROGRAMS_INSTALL = $(INSTALL_PROGRAM) >+install-modulePROGRAMS: $(module_PROGRAMS) >+ @$(NORMAL_INSTALL) >+ $(mkinstalldirs) $(DESTDIR)$(moduledir) >+ @list='$(module_PROGRAMS)'; for p in $$list; do \ >+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ >+ if test -f $$p \ >+ || test -f $$p1 \ >+ ; then \ >+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ >+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(modulePROGRAMS_INSTALL) $$p $(DESTDIR)$(moduledir)/$$f"; \ >+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(modulePROGRAMS_INSTALL) $$p $(DESTDIR)$(moduledir)/$$f || exit 1; \ >+ else :; fi; \ >+ done >+ >+uninstall-modulePROGRAMS: >+ @$(NORMAL_UNINSTALL) >+ @list='$(module_PROGRAMS)'; for p in $$list; do \ >+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ >+ echo " rm -f $(DESTDIR)$(moduledir)/$$f"; \ >+ rm -f $(DESTDIR)$(moduledir)/$$f; \ >+ done >+ >+clean-modulePROGRAMS: >+ @list='$(module_PROGRAMS)'; for p in $$list; do \ >+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ >+ echo " rm -f $$p $$f"; \ >+ rm -f $$p $$f ; \ >+ done >+lufs.o$(EXEEXT): $(lufs_o_OBJECTS) $(lufs_o_DEPENDENCIES) >+ @rm -f lufs.o$(EXEEXT) >+ $(LINK) $(lufs_o_LDFLAGS) $(lufs_o_OBJECTS) $(lufs_o_LDADD) $(LIBS) >+ >+mostlyclean-compile: >+ -rm -f *.$(OBJEXT) core *.core >+ >+distclean-compile: >+ -rm -f *.tab.c >+ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Po@am__quote@ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inode.Po@am__quote@ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Po@am__quote@ >+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@ >+ >+distclean-depend: >+ -rm -rf ./$(DEPDIR) >+ >+.c.o: >+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ >+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ >+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ >+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ >+@am__fastdepCC_TRUE@ fi >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ >+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< >+ >+.c.obj: >+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ >+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ >+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ >+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ >+@am__fastdepCC_TRUE@ fi >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ >+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` >+ >+.c.lo: >+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ >+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ >+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ >+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ >+@am__fastdepCC_TRUE@ fi >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ >+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ >+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< >+ >+mostlyclean-libtool: >+ -rm -f *.lo >+ >+clean-libtool: >+ -rm -rf .libs _libs >+ >+distclean-libtool: >+ -rm -f libtool >+uninstall-info-am: >+ >+ETAGS = etags >+ETAGSFLAGS = >+ >+CTAGS = ctags >+CTAGSFLAGS = >+ >+tags: TAGS >+ >+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) >+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ >+ unique=`for i in $$list; do \ >+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ >+ done | \ >+ $(AWK) ' { files[$$0] = 1; } \ >+ END { for (i in files) print i; }'`; \ >+ mkid -fID $$unique >+ >+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ >+ $(TAGS_FILES) $(LISP) >+ tags=; \ >+ here=`pwd`; \ >+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ >+ unique=`for i in $$list; do \ >+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ >+ done | \ >+ $(AWK) ' { files[$$0] = 1; } \ >+ END { for (i in files) print i; }'`; \ >+ test -z "$(ETAGS_ARGS)$$tags$$unique" \ >+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ >+ $$tags $$unique >+ >+ctags: CTAGS >+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ >+ $(TAGS_FILES) $(LISP) >+ tags=; \ >+ here=`pwd`; \ >+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ >+ unique=`for i in $$list; do \ >+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ >+ done | \ >+ $(AWK) ' { files[$$0] = 1; } \ >+ END { for (i in files) print i; }'`; \ >+ test -z "$(CTAGS_ARGS)$$tags$$unique" \ >+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ >+ $$tags $$unique >+ >+GTAGS: >+ here=`$(am__cd) $(top_builddir) && pwd` \ >+ && cd $(top_srcdir) \ >+ && gtags -i $(GTAGS_ARGS) $$here >+ >+distclean-tags: >+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags >+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) >+ >+top_distdir = ../../.. >+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) >+ >+distdir: $(DISTFILES) >+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ >+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ >+ list='$(DISTFILES)'; for file in $$list; do \ >+ case $$file in \ >+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ >+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ >+ esac; \ >+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ >+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ >+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ >+ dir="/$$dir"; \ >+ $(mkinstalldirs) "$(distdir)$$dir"; \ >+ else \ >+ dir=''; \ >+ fi; \ >+ if test -d $$d/$$file; then \ >+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ >+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ >+ fi; \ >+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ >+ else \ >+ test -f $(distdir)/$$file \ >+ || cp -p $$d/$$file $(distdir)/$$file \ >+ || exit 1; \ >+ fi; \ >+ done >+check-am: all-am >+check: check-am >+all-am: Makefile $(PROGRAMS) $(HEADERS) >+ >+installdirs: >+ $(mkinstalldirs) $(DESTDIR)$(moduledir) >+install: install-am >+install-exec: install-exec-am >+install-data: install-data-am >+uninstall: uninstall-am >+ >+install-am: all-am >+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am >+ >+installcheck: installcheck-am >+install-strip: >+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ >+ INSTALL_STRIP_FLAG=-s \ >+ `test -z '$(STRIP)' || \ >+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install >+mostlyclean-generic: >+ >+clean-generic: >+ >+distclean-generic: >+ -rm -f Makefile $(CONFIG_CLEAN_FILES) >+ >+maintainer-clean-generic: >+ @echo "This command is intended for maintainers to use" >+ @echo "it deletes files that may require special tools to rebuild." >+clean: clean-am >+ >+clean-am: clean-generic clean-libtool clean-modulePROGRAMS \ >+ mostlyclean-am >+ >+distclean: distclean-am >+ >+distclean-am: clean-am distclean-compile distclean-depend \ >+ distclean-generic distclean-libtool distclean-tags >+ >+dvi: dvi-am >+ >+dvi-am: >+ >+info: info-am >+ >+info-am: >+ >+install-data-am: install-modulePROGRAMS >+ @$(NORMAL_INSTALL) >+ $(MAKE) $(AM_MAKEFLAGS) >+ >+install-exec-am: >+ >+install-info: install-info-am >+ >+install-man: >+ >+installcheck-am: >+ >+maintainer-clean: maintainer-clean-am >+ >+maintainer-clean-am: distclean-am maintainer-clean-generic >+ >+mostlyclean: mostlyclean-am >+ >+mostlyclean-am: mostlyclean-compile mostlyclean-generic \ >+ mostlyclean-libtool >+ >+pdf: pdf-am >+ >+pdf-am: >+ >+ps: ps-am >+ >+ps-am: >+ >+uninstall-am: uninstall-info-am uninstall-modulePROGRAMS >+ >+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ >+ clean-libtool clean-modulePROGRAMS ctags distclean \ >+ distclean-compile distclean-depend distclean-generic \ >+ distclean-libtool distclean-tags distdir dvi dvi-am info \ >+ info-am install install-am install-data install-data-am \ >+ install-exec install-exec-am install-info install-info-am \ >+ install-man install-modulePROGRAMS install-strip installcheck \ >+ installcheck-am installdirs maintainer-clean \ >+ maintainer-clean-generic mostlyclean mostlyclean-compile \ >+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ >+ tags uninstall uninstall-am uninstall-info-am \ >+ uninstall-modulePROGRAMS >+ >+ >+: >+ depmod -aq >+ if [ "`lsmod | grep lufs`" ]; then rmmod lufs; fi >+ modprobe lufs >+# Tell versions [3.59,3.63) of GNU make to not export all variables. >+# Otherwise a system limit (for SysV at least) may be exceeded. >+.NOEXPORT: >diff -burN kernel.orig/Linux/2.6/dir.c kernel/Linux/2.6/dir.c >--- kernel.orig/Linux/2.6/dir.c 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/dir.c 2003-02-06 14:32:31.000000000 +0000 >@@ -0,0 +1,582 @@ >+/* >+ * dir.c >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/version.h> >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/fs.h> >+#include <linux/slab.h> >+#include <linux/ctype.h> >+#include <linux/socket.h> >+ >+#include <asm/uaccess.h> >+#include <asm/system.h> >+ >+#include <linux/smp_lock.h> >+ >+#include "lufs.h" >+#include "proc.h" >+ >+ >+extern struct inode* lu_iget(struct super_block*, struct lufs_fattr*); >+extern int lufs_notify_change(struct dentry*, struct iattr*); >+ >+static int lu_readdir(struct file*, void*, filldir_t); >+ >+static struct dentry *lu_lookup(struct inode*, struct dentry*); >+static int lu_mkdir(struct inode*, struct dentry*, int); >+static int lu_create(struct inode*, struct dentry*, int); >+static int lu_rmdir(struct inode*, struct dentry*); >+static int lu_rename(struct inode*, struct dentry*, struct inode*, struct dentry*); >+static int lu_unlink(struct inode*, struct dentry*); >+static int lu_link(struct dentry*, struct inode*, struct dentry*); >+static int lu_symlink(struct inode*, struct dentry*, const char*); >+ >+struct file_operations lu_dir_operations = { >+ .read = generic_read_dir, >+ .readdir = lu_readdir, >+}; >+ >+struct inode_operations lu_dir_inode_operations = { >+ .create = lu_create, >+ .lookup = lu_lookup, >+ .link = lu_link, >+ .unlink = lu_unlink, >+ .symlink = lu_symlink, >+ .mkdir = lu_mkdir, >+ .rmdir = lu_rmdir, >+ .rename = lu_rename, >+ .setattr = lufs_notify_change, >+}; >+ >+static int lu_lookup_validate(struct dentry *dentry, int flags) >+{ >+ struct inode *inode = dentry->d_inode; >+ unsigned long age = jiffies - dentry->d_time; >+ int res; >+ >+ TRACE("in\n"); >+ >+ res = (age <= LU_MAXAGE); >+ TRACE("age: %lu, valid: %d\n", age, res); >+ >+ if(!res) >+ res = (lu_revalidate_inode(dentry) == 0); >+ >+ >+ if(inode){ >+ lock_kernel(); >+ >+ if(is_bad_inode(inode)) >+ res = 0; >+ unlock_kernel(); >+ }else >+ TRACE("no inode?!\n"); >+ >+ TRACE("out(res=%d)\n", res); >+ >+ return res; >+} >+ >+static int lu_delete_dentry(struct dentry *dentry) >+{ >+ >+ TRACE("in\n"); >+ if(dentry->d_inode && is_bad_inode(dentry->d_inode)){ >+ WARN("bad inode, unhashing \n"); >+ return 1; >+ } >+ >+ TRACE("out\n"); >+ return 0; >+} >+ >+struct dentry_operations lufs_dentry_operations = { >+ .d_revalidate = lu_lookup_validate, >+ .d_delete = lu_delete_dentry, >+}; >+ >+static int lu_readdir(struct file *f, void *dirent, filldir_t filldir) >+{ >+ int res = -1; >+ char *c; >+ struct qstr qname; >+ unsigned long ino; >+ struct iovec siov[2], riov; >+ struct server_slot *slot; >+ unsigned short offset; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if(lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ TRACE("reading %s, offset %u...\n", slot->s_buf, (unsigned)f->f_pos); >+ res = 0; >+ >+ switch((unsigned int)f->f_pos){ >+ >+ case 0: >+ if(filldir(dirent, ".", 1, 0, f->f_dentry->d_inode->i_ino, DT_DIR) < 0) >+ goto out; >+ f->f_pos++; >+ >+ case 1: >+ if(filldir(dirent, "..", 2, 1, f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) >+ goto out; >+ f->f_pos++; >+ >+ default: >+ offset = f->f_pos; >+ siov[0].iov_base = &offset; >+ siov[0].iov_len = sizeof(unsigned short); >+ siov[1].iov_base = slot->s_buf; >+ siov[1].iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = slot->s_buf; >+ riov.iov_len = LU_MAXDATA; >+ >+ if((res = lu_execute(GET_INFO(f->f_dentry->d_inode->i_sb), slot, PTYPE_READDIR, siov, 2, &riov, 1)) < 0){ >+ WARN("could not read directory content!\n"); >+ if(res == -ERESTARTSYS) >+ res = -EINTR; >+ goto out; >+ } >+ if(PIS_ERROR(res)){ >+ WARN("server failure!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ for(qname.name = slot->s_buf, c = strchr(slot->s_buf, '\n'); c != NULL; qname.name = c+1, c = strchr(c+1, '\n')){ >+ *c = 0; >+ TRACE("direntry: %s.\n", qname.name); >+ qname.len = strlen(qname.name); >+ if((ino = find_inode_number(f->f_dentry, &qname)) == 0) >+ ino = iunique(f->f_dentry->d_sb, 2); >+ if(filldir(dirent, qname.name, qname.len, f->f_pos, ino, DT_UNKNOWN) < 0) >+ break; >+ f->f_pos++; >+ } >+ } >+ >+ TRACE("out\n"); >+ out: >+ lu_putslot(slot); >+ return res; >+} >+ >+static struct dentry* lu_lookup(struct inode *dir, struct dentry *dentry) >+{ >+ int res; >+ struct lufs_fattr fattr; >+ struct iovec siov, riov; >+ struct inode *inode; >+ struct server_slot *slot; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dir->i_sb))) == NULL) >+ return ERR_PTR(-ERESTARTSYS); >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ TRACE("looking up %s\n", slot->s_buf); >+ >+ siov.iov_base = slot->s_buf; >+ siov.iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = &fattr; >+ riov.iov_len = sizeof(struct lufs_fattr); >+ >+ if((res = lu_execute(GET_INFO(dir->i_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("File not found...\n"); >+ dentry->d_op = &lufs_dentry_operations; >+ dentry->d_time = jiffies; >+ d_add(dentry, NULL); >+ lu_putslot(slot); >+ return NULL; >+ } >+ >+ lu_fixattrs(GET_INFO(dir->i_sb), &fattr); >+ >+ if(dentry == dentry->d_parent) >+ fattr.f_ino = 2; >+ else >+ fattr.f_ino = iunique(dentry->d_sb, 2); >+ >+ if((inode = lu_iget(dir->i_sb, &fattr))){ >+ dentry->d_op = &lufs_dentry_operations; >+ dentry->d_time = jiffies; >+ d_add(dentry, inode); >+ } >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return ERR_PTR(res); >+} >+ >+static int lu_instantiate(struct dentry *dentry, char *name, struct server_slot *slot) >+{ >+ int res; >+ struct lufs_fattr fattr; >+ struct iovec siov, riov; >+ struct inode *inode; >+ >+ TRACE("in\n"); >+ >+ TRACE("instantiating %s\n", name); >+ >+ siov.iov_base = name; >+ siov.iov_len = strlen(name) + 1; >+ riov.iov_base = &fattr; >+ riov.iov_len = sizeof(struct lufs_fattr); >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("File not found...\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ lu_fixattrs(GET_INFO(dentry->d_sb), &fattr); >+ >+ fattr.f_ino = iunique(dentry->d_sb, 2); >+ inode = lu_iget(dentry->d_sb, &fattr); >+ >+ if(!inode){ >+ res = -EACCES; >+ goto out; >+ } >+ >+ d_instantiate(dentry, inode); >+ res = 0; >+ >+ out: >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_mkdir(struct inode *dir, struct dentry *dentry, int mode) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ iov[0].iov_base = &mode; >+ iov[0].iov_len = sizeof(mode); >+ iov[1].iov_base = slot->s_buf; >+ iov[1].iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_MKDIR, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("Could not create directory.\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = lu_instantiate(dentry, slot->s_buf, slot); >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_create(struct inode *dir, struct dentry *dentry, int mode) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ iov[0].iov_base = &mode; >+ iov[0].iov_len = sizeof(mode); >+ iov[1].iov_base = slot->s_buf; >+ iov[1].iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_CREATE, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("Could not create file.\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = lu_instantiate(dentry, slot->s_buf, slot); >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_rmdir(struct inode *dir, struct dentry *dentry) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov; >+ >+ if(!d_unhashed(dentry)) >+ return -EBUSY; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!"); >+ goto out; >+ } >+ >+ iov.iov_base = slot->s_buf; >+ iov.iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_RMDIR, &iov, 1, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("rmdir failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) >+{ >+ struct server_slot *slot; >+ int res; >+ struct iovec iov[2]; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(old_dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0 || >+ (res = lu_getname(new_dentry, &(slot->s_buf[LU_MAXPATHLEN]), LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ iov[0].iov_base = slot->s_buf; >+ iov[0].iov_len = strlen(slot->s_buf) + 1; >+ iov[1].iov_base = &(slot->s_buf[LU_MAXPATHLEN]); >+ iov[1].iov_len = strlen(&(slot->s_buf[LU_MAXPATHLEN])) + 1; >+ >+ if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_RENAME, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("rename failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_unlink(struct inode *dir, struct dentry *dentry) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!"); >+ goto out; >+ } >+ >+ iov.iov_base = slot->s_buf; >+ iov.iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_UNLINK, &iov, 1, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("unlink failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+ >+static int lu_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ >+ TRACE("in\n"); >+ >+ if(S_ISDIR(old_dentry->d_inode->i_mode)) >+ return -EPERM; >+ >+ if(!(slot = lu_getslot(GET_INFO(old_dentry->d_sb)))) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ if((res = lu_getname(dentry, &slot->s_buf[LU_MAXPATHLEN], LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ iov[0].iov_base = slot->s_buf; >+ iov[0].iov_len = strlen(slot->s_buf) + 1; >+ iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN]; >+ iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1; >+ >+ d_drop(dentry); >+ >+ if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_LINK, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("link failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_symlink(struct inode *dir, struct dentry *dentry, const char *symname) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ >+ TRACE("in\n"); >+ TRACE("symlink: %s\n", symname); >+ >+ if(strlen(symname) > LU_MAXPATHLEN - 1) >+ return -ENAMETOOLONG; >+ >+ if(!(slot = lu_getslot(GET_INFO(dentry->d_sb)))) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ TRACE("fname: %s\n", slot->s_buf); >+ >+ strcpy(&slot->s_buf[LU_MAXPATHLEN], symname); >+ >+ iov[0].iov_base = slot->s_buf; >+ iov[0].iov_len = strlen(slot->s_buf) + 1; >+ iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN]; >+ iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1; >+ >+ d_drop(dentry); >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SYMLINK, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("symlink failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ TRACE("out\n"); >+ return res; >+} >+ >+ >+ >diff -burN kernel.orig/Linux/2.6/file.c kernel/Linux/2.6/file.c >--- kernel.orig/Linux/2.6/file.c 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/file.c 2003-05-29 01:01:15.000000000 +0100 >@@ -0,0 +1,321 @@ >+/* >+ * file.c >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/version.h> >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/slab.h> >+#include <linux/pagemap.h> >+#include <linux/socket.h> >+ >+#include <asm/uaccess.h> >+#include <asm/system.h> >+ >+#include <linux/smp_lock.h> >+ >+#include "lufs.h" >+#include "proc.h" >+ >+extern int lufs_notify_change(struct dentry*, struct iattr*); >+extern int lu_revalidate_inode(struct dentry*); >+ >+static int lu_file_open(struct inode *inode, struct file *file) >+{ >+ int res, gres; >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ unsigned flags; >+ >+ TRACE("in\n"); >+ >+ if((gres = generic_file_open(inode, file)) < 0) >+ return gres; >+ >+ TRACE("f_mode: %u, i_mode: %u\n", file->f_mode, inode->i_mode); >+ TRACE("f_flags: %u, i_flags: %u\n", file->f_flags, inode->i_flags); >+ >+ if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL) >+ return gres; >+ >+ if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ flags = file->f_flags & O_ACCMODE; >+ iov[0].iov_base = &flags; >+ iov[0].iov_len = sizeof(flags); >+ iov[1].iov_base = slot->s_buf; >+ iov[1].iov_len = strlen(slot->s_buf) + 1; >+ >+ lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_OPEN, iov, 2, NULL, 0); >+ >+out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return gres; >+} >+ >+static int lu_file_release(struct inode *inode, struct file *file) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ iov.iov_base = slot->s_buf; >+ iov.iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_RELEASE, &iov, 1, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("release failed\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = 0; >+ >+out: >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_file_readpage(struct file *f, struct page *p) >+{ >+ int res; >+ struct iovec siov[3], riov; >+ long long offset; >+ unsigned long count; >+ struct server_slot *slot; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ get_page(p); >+ >+ if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ offset = p->index << PAGE_CACHE_SHIFT; >+ count = PAGE_SIZE; >+ >+ siov[0].iov_base = &offset; >+ siov[0].iov_len = sizeof(offset); >+ siov[1].iov_base = &count; >+ siov[1].iov_len = sizeof(count); >+ siov[2].iov_base = slot->s_buf; >+ siov[2].iov_len = strlen(slot->s_buf) + 1; >+ >+ riov.iov_base = page_address(p); >+ riov.iov_len = count; >+ >+ if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_READ, siov, 3, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("read failed\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ flush_dcache_page(p); >+ SetPageUptodate(p); >+ res = 0; >+ >+ out: >+ lu_putslot(slot); >+ unlock_page(p); >+ put_page(p); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_file_writepage(struct page *p, struct writeback_control *wbc) >+{ >+ TRACE("in\n"); >+ >+ TRACE("out\n"); >+ return -1; >+} >+ >+static int lu_file_preparewrite(struct file *f, struct page *p, unsigned offset, unsigned to) >+{ >+ TRACE("in\n"); >+ >+ TRACE("out\n"); >+ >+ return 0; >+} >+ >+static int lu_file_commitwrite(struct file *f, struct page *p, unsigned offset, unsigned to) >+{ >+ int res; >+ struct server_slot *slot; >+ struct iovec iov[4]; >+ char *buf; >+ long long off; >+ unsigned long cnt; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out2; >+ } >+ >+ lock_kernel(); >+ >+ buf = kmap(p) + offset; >+ cnt = to - offset; >+ off = offset + (((long long)p->index) << PAGE_CACHE_SHIFT); >+ >+ iov[0].iov_base = &off; >+ iov[0].iov_len = sizeof(off); >+ iov[1].iov_base = &cnt; >+ iov[1].iov_len = sizeof(cnt); >+ iov[2].iov_base = slot->s_buf; >+ iov[2].iov_len = strlen(slot->s_buf) + 1; >+ iov[3].iov_base = buf; >+ iov[3].iov_len = cnt; >+ >+ TRACE("write %s, offset %Ld, count %d\n", slot->s_buf, off, (int)cnt); >+ >+ if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_WRITE, iov, 4, NULL, 0)) < 0) >+ goto out1; >+ >+ >+ if(PIS_ERROR(res)){ >+ TRACE("write failed\n"); >+ res = PERROR(res); >+ goto out1; >+ } >+ >+ f->f_dentry->d_inode->i_mtime = f->f_dentry->d_inode->i_atime = CURRENT_TIME; >+ if(off + cnt > f->f_dentry->d_inode->i_size) >+ f->f_dentry->d_inode->i_size = off + cnt; >+ >+ res = cnt; >+ >+ out1: >+ kunmap(p); >+ unlock_kernel(); >+ out2: >+ lu_putslot(slot); >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos) >+{ >+ struct dentry *dentry = filp->f_dentry; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if(!(res = lu_revalidate_inode(dentry))) >+ res = generic_file_read(filp, buf, count, ppos); >+ >+ TRACE("out\n"); >+ >+ return res; >+} >+ >+static int lu_file_mmap(struct file *filp, struct vm_area_struct *vma) >+{ >+ struct dentry *dentry = filp->f_dentry; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if(!(res = lu_revalidate_inode(dentry))) >+ res = generic_file_mmap(filp, vma); >+ >+ TRACE("out\n"); >+ >+ return res; >+} >+ >+static ssize_t lu_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) >+{ >+ struct dentry *dentry = filp->f_dentry; >+ ssize_t res; >+ >+ TRACE("in\n"); >+ >+ if(!(res = lu_revalidate_inode(dentry)) && (count > 0)) >+ res = generic_file_write(filp, buf, count, ppos); >+ >+ TRACE("out\n"); >+ >+ return res; >+} >+ >+static int lu_file_fsync(struct file *filp, struct dentry *dentryp, int datasync) >+{ >+ return 0; >+} >+ >+struct file_operations lu_file_operations = { >+ .llseek = generic_file_llseek, >+ .read = lu_file_read, >+ .write = lu_file_write, >+ .mmap = lu_file_mmap, >+ .open = lu_file_open, >+ .release = lu_file_release, >+ :fsync = lu_file_fsync, >+}; >+ >+struct inode_operations lu_file_inode_operations = { >+ .setattr = lufs_notify_change, >+}; >+ >+struct address_space_operations lu_file_aops = { >+ .readpage = lu_file_readpage, >+ .writepage = lu_file_writepage, >+ .prepare_write = lu_file_preparewrite, >+ .commit_write = lu_file_commitwrite, >+}; >+ >+ >+ >diff -burN kernel.orig/Linux/2.6/inode.c kernel/Linux/2.6/inode.c >--- kernel.orig/Linux/2.6/inode.c 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/inode.c 2003-03-08 11:48:16.000000000 +0000 >@@ -0,0 +1,535 @@ >+/* >+ * inode.c >+ * Copyright (C) 2002-2003 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/version.h> >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/init.h> >+#include <linux/fs.h> >+#include <linux/slab.h> >+#include <linux/list.h> >+#include <linux/smp_lock.h> >+#include <linux/signal.h> >+#include <linux/sched.h> >+#include <linux/socket.h> >+#include <linux/string.h> >+#include <linux/vfs.h> >+ >+#include <asm/system.h> >+#include <asm/uaccess.h> >+ >+#include "lufs.h" >+#include "proc.h" >+ >+MODULE_AUTHOR("Florin Malita <mali@go.ro>"); >+MODULE_DESCRIPTION("Linux Userland Filesystem"); >+#ifdef MODULE_LICENSE >+MODULE_LICENSE("GPL"); >+#endif >+ >+extern struct file_operations lu_dir_operations, lu_file_operations; >+extern struct inode_operations lu_dir_inode_operations, lu_file_inode_operations, lu_symlink_inode_operations; >+extern struct address_space_operations lu_file_aops; >+extern struct dentry_operations lufs_dentry_operations; >+ >+static void lu_delete_inode(struct inode*); >+static void lu_put_super(struct super_block*); >+static int lu_statfs(struct super_block*, struct statfs*); >+ >+static struct super_operations lu_sops = { >+ .drop_inode = generic_delete_inode, >+ .delete_inode = lu_delete_inode, >+ .put_super = lu_put_super, >+ .statfs = lu_statfs, >+}; >+ >+ >+/* >+ * Ignore unknown options, they're probably for the userspace daemon. >+ */ >+static void parse_options(struct lufs_sb_info *server, char *opts) >+{ >+ char *p, *q; >+ int len; >+ >+ if(!opts) >+ return; >+ >+ len = strlen(opts); >+ >+ while((p = strsep(&opts, ","))){ >+ if(strncmp(p, "server_socket=", 14) == 0){ >+ if(strlen(p+14) > UNIX_PATH_MAX) >+ goto ugly_opts; >+ strcpy(server->server_socket, p+14); >+ TRACE("server_socket: %s\n", server->server_socket); >+ }else >+ if(strncmp(p, "uid=", 4) == 0){ >+ if(current->uid) >+ ERROR("only root can use uid option!\n"); >+ else{ >+ if(strlen(p+4) > 5) >+ goto ugly_opts; >+ q = p + 4; >+ server->config.uid = simple_strtoul(q, &q, 0); >+ TRACE("uid: %d\n", server->config.uid); >+ } >+ }else >+ if(strncmp(p, "gid=", 4) == 0){ >+ if(current->uid) >+ ERROR("only root can use gid option!\n"); >+ else{ >+ if(strlen(p+4) > 5) >+ goto ugly_opts; >+ q = p + 4; >+ server->config.gid = simple_strtoul(q, &q, 0); >+ TRACE("gid: %d\n", server->config.gid); >+ } >+ }else >+ if(strncmp(p, "fmask=", 6) == 0){ >+ if(strlen(p + 6) > 3) >+ goto ugly_opts; >+ q = p + 6; >+ server->config.fmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO); >+ TRACE("fmode: %d\n", server->config.fmode); >+ }else >+ if(strncmp(p, "dmask=", 6) == 0){ >+ if(strlen(p + 6) > 3) >+ goto ugly_opts; >+ q = p + 6; >+ server->config.dmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO); >+ TRACE("dmode: %d\n", server->config.dmode); >+ }else >+ if(strncmp(p, "root=", 5) == 0){ >+ if(strlen(p+5) >= UNIX_PATH_MAX - 1) >+ goto ugly_opts; >+ strcpy(server->root, p+5); >+ server->rootlen = strlen(server->root); >+ >+ if(server->root[server->rootlen - 1] == '/'){ >+ server->root[server->rootlen - 1] = 0; >+ server->rootlen--; >+ } >+ >+ TRACE("remote root: %s, len: %u\n", server->root, server->rootlen); >+ }else >+ if(strncmp(p, "channels=", 9) == 0){ >+ if(strlen(p+9) > 5) >+ goto ugly_opts; >+ q = p + 9; >+ server->config.channels = simple_strtoul(q, &q, 0); >+ >+ TRACE("channels: %u\n", server->config.channels); >+ }else >+ if(strncmp(p, "own_fs", 6) == 0){ >+ server->config.own_fs = 1; >+ TRACE("forcing ownership\n"); >+ }else >+ if(strncmp(p, "server_pid=", 11) == 0){ >+ if(strlen(p+11) > 7) >+ goto ugly_opts; >+ q = p + 11; >+ server->server_pid = simple_strtoul(q, &q, 0); >+ >+ TRACE("server_pid: %u\n", server->server_pid); >+ } >+ } >+ >+ return; >+ >+ ugly_opts: >+ WARN("evil options!\n"); >+} >+ >+/* >+ * Fill in inode attributes. >+ * Ivalidate the page_cache pages if the inode has been modified. >+ */ >+static void set_inode_attr(struct inode *inode, struct lufs_fattr *fattr) >+{ >+ time_t last_time = inode->i_mtime.tv_sec; >+ loff_t last_sz = inode->i_size; >+ >+ TRACE("in\n"); >+ >+ inode->i_mode = fattr->f_mode; >+ inode->i_nlink = fattr->f_nlink; >+ inode->i_uid = fattr->f_uid; >+ inode->i_gid = fattr->f_gid; >+ inode->i_ctime.tv_sec = fattr->f_ctime; >+ inode->i_mtime.tv_sec = fattr->f_mtime; >+ inode->i_atime.tv_sec = fattr->f_atime; >+ inode->i_blksize = fattr->f_blksize; >+ inode->i_blocks = fattr->f_blocks; >+ inode->i_size = fattr->f_size; >+ >+ if(inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz){ >+ TRACE("inode changed...\n"); >+ if(!S_ISDIR(inode->i_mode)) >+ invalidate_inode_pages(inode->i_mapping); >+ } >+ >+ TRACE("out\n"); >+} >+ >+static int lu_do_stat(struct dentry *dentry, struct lufs_fattr *fattr) >+{ >+ struct server_slot *slot; >+ struct iovec siov, riov; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ TRACE("stating %s...\n", slot->s_buf); >+ >+ siov.iov_base = slot->s_buf; >+ siov.iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = fattr; >+ riov.iov_len = sizeof(struct lufs_fattr); >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ WARN("stat failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ lu_fixattrs(GET_INFO(dentry->d_sb), fattr); >+ >+ res = 0; >+ >+ out: >+ TRACE("out\n"); >+ lu_putslot(slot); >+ return res; >+} >+ >+/* >+ * Reload inode attributes. >+ */ >+static int lu_refresh_inode(struct dentry *dentry) >+{ >+ struct inode *inode = dentry->d_inode; >+ struct lufs_fattr fattr; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if((res = lu_do_stat(dentry, &fattr)) < 0) >+ return res; >+ >+ dentry->d_time = jiffies; >+ >+ if(!inode) >+ return 0; >+ >+ if((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) >+ set_inode_attr(inode, &fattr); >+ else{ >+ WARN("inode changed mode, %x to %x\n", inode->i_mode, (unsigned int)fattr.f_mode); >+ TRACE("oops!\n"); >+ >+ fattr.f_mode = inode->i_mode; >+ make_bad_inode(inode); >+ inode->i_mode = fattr.f_mode; >+ >+ if(!S_ISDIR(inode->i_mode)) >+ invalidate_inode_pages(inode->i_mapping); >+ >+ return -EIO; >+ } >+ >+ TRACE("out\n"); >+ return 0; >+} >+ >+int lu_revalidate_inode(struct dentry *dentry) >+{ >+ int res = 0; >+ >+ TRACE("in\n"); >+ >+ lock_kernel(); >+ >+ if(time_before(jiffies, dentry->d_time + LU_MAXAGE)) >+ goto out; >+ >+ res = lu_refresh_inode(dentry); >+ >+ out: >+ TRACE("out\n"); >+ unlock_kernel(); >+ return res; >+} >+ >+int lufs_notify_change(struct dentry *dentry, struct iattr *iattr) >+{ >+ struct server_slot *slot; >+ struct iovec iov[2]; >+ struct lufs_fattr fattr; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if((res = lu_do_stat(dentry, &fattr)) < 0) >+ return res; >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return -ERESTARTSYS; >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ if(iattr->ia_valid & ATTR_MODE) >+ fattr.f_mode = iattr->ia_mode; >+ if(iattr->ia_valid & ATTR_UID) >+ fattr.f_uid = iattr->ia_uid; >+ if(iattr->ia_valid & ATTR_GID) >+ fattr.f_gid = iattr->ia_gid; >+ if(iattr->ia_valid & ATTR_SIZE) >+ fattr.f_size = iattr->ia_size; >+ if(iattr->ia_valid & ATTR_ATIME) >+ fattr.f_atime= iattr->ia_atime.tv_sec; >+ if(iattr->ia_valid & ATTR_MTIME) >+ fattr.f_mtime= iattr->ia_mtime.tv_sec; >+ if(iattr->ia_valid & ATTR_CTIME) >+ fattr.f_ctime= iattr->ia_ctime.tv_sec; >+ >+ iov[0].iov_base = &fattr; >+ iov[0].iov_len = sizeof(struct lufs_fattr); >+ iov[1].iov_base = slot->s_buf; >+ iov[1].iov_len = strlen(slot->s_buf) + 1; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SETATTR, iov, 2, NULL, 0)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ WARN("setattr failed!\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ res = 0; >+ >+ lu_refresh_inode(dentry); >+ >+ out: >+ TRACE("out\n"); >+ lu_putslot(slot); >+ return res; >+} >+ >+/* >+ * We always create a new inode here. >+ */ >+struct inode* lu_iget(struct super_block *sb, struct lufs_fattr *fattr) >+{ >+ struct inode *res; >+ >+ TRACE("in\n"); >+ >+ res = new_inode(sb); >+ if(!res) >+ return NULL; >+ res->i_ino = fattr->f_ino; >+ set_inode_attr(res, fattr); >+ >+ if(S_ISDIR(res->i_mode)){ >+ TRACE("it's a dir.\n"); >+ res->i_op = &lu_dir_inode_operations; >+ res->i_fop = &lu_dir_operations; >+ }else if(S_ISLNK(res->i_mode)){ >+ TRACE("it's a link.\n"); >+ res->i_op = &lu_symlink_inode_operations; >+ }else{ >+ TRACE("it's a file.\n"); >+ res->i_op = &lu_file_inode_operations; >+ res->i_fop = &lu_file_operations; >+ res->i_data.a_ops = &lu_file_aops; >+ } >+ >+ insert_inode_hash(res); >+ return res; >+} >+ >+static int lu_statfs(struct super_block *sb, struct statfs *attr) >+{ >+ TRACE("in\n"); >+ >+ attr->f_type = LU_MAGIC; >+ attr->f_bsize = LU_BLOCKSIZE; >+ attr->f_blocks = 0; >+ attr->f_namelen = LU_MAXPATHLEN; >+ attr->f_files = -1; >+ attr->f_bavail = -1; >+ >+ TRACE("out\n"); >+ return 0; >+} >+ >+static void lu_put_super(struct super_block *sb) >+{ >+ struct siginfo info; >+ >+ TRACE("in\n"); >+ >+ info.si_signo = SIGUSR1; >+ info.si_errno = 0; >+ info.si_code = SI_USER; >+ info.si_pid = current->pid; >+ info.si_uid = current->uid; >+ >+ /* notify the daemon that we're going bye-bye */ >+ kill_proc_info(SIGUSR1, &info, GET_INFO(sb)->server_pid); >+ >+ lu_empty_slots(GET_INFO(sb)); >+ kfree(GET_INFO(sb)); >+ TRACE("out\n"); >+} >+ >+static void lu_delete_inode(struct inode *in) >+{ >+ TRACE("in\n"); >+ clear_inode(in); >+ TRACE("out\n"); >+} >+ >+static int lu_fill_super(struct super_block *sb, void *opts, int silent) >+{ >+ struct lufs_sb_info *info; >+ struct server_slot *slot; >+ struct lufs_fattr root_attr; >+ struct inode *root_inode; >+ >+ int i; >+ >+ TRACE("in\n"); >+ >+ if(!opts){ >+ ERROR("need some options here!\n"); >+ goto out; >+ } >+ >+ if((info = (struct lufs_sb_info*)kmalloc(sizeof(struct lufs_sb_info), GFP_KERNEL)) == NULL){ >+ ERROR("kmalloc error!\n"); >+ goto out; >+ } >+ memset(info, 0, sizeof(struct lufs_sb_info)); >+ info->lock = RW_LOCK_UNLOCKED; >+ INIT_LIST_HEAD(&info->slots); >+ >+ info->config.uid = current->uid; >+ info->config.gid = current->gid; >+ info->config.channels = LU_NRSLOTS; >+ >+ parse_options(info, opts); >+ >+ if(!info->server_socket[0]){ >+ ERROR("no server_socket specified!\n"); >+ goto out_info; >+ } >+ >+ for(i = 0; i < info->config.channels; i++){ >+ if((slot = kmalloc(sizeof(struct server_slot), GFP_KERNEL)) == NULL){ >+ ERROR("kmalloc error!\n"); >+ goto out_slots; >+ } >+ memset(slot, 0, sizeof(struct server_slot)); >+ init_MUTEX(&slot->s_lock); >+ if((slot->s_buf = kmalloc(LU_MAXDATA, GFP_KERNEL)) == NULL){ >+ ERROR("kmalloc error!\n"); >+ goto out_slots; >+ } >+ list_add(&slot->s_list, &info->slots); >+ } >+ >+ sb->s_fs_info = info; >+ sb->s_blocksize = LU_BLOCKSIZE; >+ sb->s_blocksize_bits = LU_BLOCKSIZEBITS; >+ sb->s_magic = LU_MAGIC; >+ sb->s_op = &lu_sops; >+ sb->s_flags = 0; >+ sb->s_maxbytes = ((((long long)1) << 32) << LU_BLOCKSIZEBITS) - 1; >+ TRACE("sb->s_maxbytes=%Ld\n",sb->s_maxbytes); >+ >+ lu_lookup_root(info, &root_attr); >+ root_inode = lu_iget(sb, &root_attr); >+ if(!root_inode) >+ goto out_slots; >+ sb->s_root = d_alloc_root(root_inode); >+ if(!sb->s_root) >+ goto out_slots; >+ >+ sb->s_root->d_op = &lufs_dentry_operations; >+ sb->s_root->d_time = jiffies; >+ >+ TRACE("mount succeded: %s\n", info->server_socket); >+ return 0; >+ >+ out_slots: >+ lu_empty_slots(info); >+ out_info: >+ kfree(info); >+ out: >+ ERROR("mount failed!\n"); >+ return -EINVAL; >+} >+ >+static struct super_block *lu_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data) >+{ >+ return get_sb_nodev(fs_type, flags, data, lu_fill_super); >+} >+ >+static struct file_system_type lu_fs_type = { >+ .owner = THIS_MODULE, >+ .name = "lufs", >+ .get_sb = lu_get_sb, >+ .kill_sb = kill_anon_super, >+}; >+ >+static int __init lu_init(void) >+{ >+ VERBOSE("UserLand File System\n"); >+ VERBOSE("Copyright (c) 2002, Florin Malita\n"); >+ return register_filesystem(&lu_fs_type); >+} >+ >+static void __exit lu_release(void) >+{ >+ VERBOSE("Unregistering lufs...\n"); >+ unregister_filesystem(&lu_fs_type); >+} >+ >+module_init(lu_init); >+module_exit(lu_release); >diff -burN kernel.orig/Linux/2.6/lufs.h kernel/Linux/2.6/lufs.h >--- kernel.orig/Linux/2.6/lufs.h 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/lufs.h 2003-02-27 08:39:51.000000000 +0000 >@@ -0,0 +1,87 @@ >+/* >+ * lufs.h >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#ifndef _LUFS_H_ >+#define _LUFS_H_ >+ >+#include <linux/list.h> >+#include <linux/un.h> >+#include <linux/spinlock.h> >+ >+#include "../../../include/lufs/proto.h" >+ >+#undef TRACE >+#undef WARN >+#undef VERBOSE >+#undef ERROR >+ >+#ifdef LUFS_DEBUG >+#define TRACE(x...) do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0) >+#define WARN(x...) do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0) >+#else >+#define TRACE(x...) do {} while(0) >+#define WARN(x...) do {} while(0) >+#endif >+ >+#ifdef LUFS_VERBOSE >+#define VERBOSE(x...) do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0) >+#else >+#define VERBOSE(x...) do {} while(0) >+#endif >+ >+#define ERROR(x...) do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0) >+ >+#define GET_INFO(sb) ((struct lufs_sb_info*)sb->s_fs_info) >+ >+#define LU_MAXPATHLEN 1024 >+#define LU_MAXTRIES 10 >+#define LU_MAXIOVEC 5 >+#define LU_NRSLOTS 3 >+#define LU_MAGIC 0xfade >+#define LU_MAXAGE HZ*5 >+ >+#define LU_DEF_UID 2 >+#define LU_DEF_GID 2 >+ >+#define LU_BLOCKSIZE 512 >+#define LU_BLOCKSIZEBITS 9 >+ >+struct lufs_config{ >+ __kernel_uid_t uid; >+ __kernel_gid_t gid; >+ __kernel_mode_t fmode; >+ __kernel_mode_t dmode; >+ unsigned channels; >+ int own_fs; >+}; >+ >+struct lufs_sb_info{ >+ struct list_head slots; >+ struct lufs_config config; >+ rwlock_t lock; >+ char server_socket[UNIX_PATH_MAX]; >+ pid_t server_pid; >+ char root[UNIX_PATH_MAX]; >+ unsigned rootlen; >+}; >+ >+#endif >diff -burN kernel.orig/Linux/2.6/proc.c kernel/Linux/2.6/proc.c >--- kernel.orig/Linux/2.6/proc.c 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/proc.c 2003-04-08 15:36:18.000000000 +0100 >@@ -0,0 +1,505 @@ >+/* >+ * proc.c >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/version.h> >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/fs.h> >+#include <linux/slab.h> >+#include <linux/socket.h> >+#include <linux/un.h> >+#include <linux/types.h> >+#include <linux/list.h> >+#include <linux/smp_lock.h> >+#include <linux/net.h> >+#include <linux/vfs.h> >+#include <linux/mount.h> >+ >+#include <asm/system.h> >+#include <asm/uaccess.h> >+ >+#include "lufs.h" >+#include "proc.h" >+ >+static int sock_send(struct socket *sock, struct iovec *iov, int len) >+{ >+ struct msghdr msg = { >+ .msg_name = NULL, >+ .msg_namelen = 0, >+ .msg_iov = iov, >+ .msg_iovlen = len, >+ .msg_control = NULL, >+ .msg_controllen = 0, >+ .msg_flags = 0 >+ }; >+ int res, i, size; >+ mm_segment_t fs; >+ >+ for(i = 0, size = 0; i < len; i++) >+ size += iov[i].iov_len; >+ >+ fs = get_fs(); >+ set_fs(get_ds()); >+ res = sock_sendmsg(sock, &msg, size); >+ set_fs(fs); >+ >+ return res; >+} >+ >+static int sock_recv(struct socket *sock, struct iovec *iov, int len, int rsize, unsigned flags) >+{ >+ struct msghdr msg = { >+ .msg_flags = flags, >+ .msg_name = NULL, >+ .msg_namelen = 0, >+ .msg_iov = iov, >+ .msg_iovlen = len, >+ .msg_control = NULL, >+ .msg_controllen = 0 >+ }; >+ mm_segment_t fs; >+ int res, i, size; >+ >+ for(i = 0, size = 0; i < len; i++) >+ size += iov[i].iov_len; >+ >+ if(size < rsize){ >+ VERBOSE("Trying to overflow old me?! Truncating...\n"); >+ rsize = size; >+ } >+ >+ fs = get_fs(); >+ set_fs(get_ds()); >+ res = sock_recvmsg(sock, &msg, rsize, flags); >+ set_fs(fs); >+ >+ return res; >+} >+ >+static int sock_connect(char *path, struct socket **s) >+{ >+ struct sockaddr_un addr; >+ int res; >+ >+ if(strlen(path) > UNIX_PATH_MAX - 1){ >+ WARN("unix domain path too long: %s", path); >+ return -1; >+ } >+ >+ addr.sun_family = AF_UNIX; >+ strcpy(addr.sun_path, path); >+ >+ if((res = sock_create(PF_UNIX, SOCK_STREAM, 0, s)) < 0){ >+ WARN("failed to create a unix domain socket!\n"); >+ return res; >+ } >+ >+ if((res = (*s)->ops->connect(*s, (struct sockaddr*)&addr, sizeof(addr), 0)) < 0){ >+ WARN("failed to connect the socket: %d!\n", res); >+ return res; >+ } >+ return 0; >+} >+ >+static int slot_reconnect(struct lufs_sb_info *info, struct server_slot *slot) >+{ >+ int res = 0, tries = 0; >+ >+ if(slot->s_sock){ >+ TRACE("closing socket.\n"); >+ sock_release(slot->s_sock); >+ slot->s_sock = NULL; >+ } >+ >+ while(tries++ < LU_MAXTRIES && (res = sock_connect(info->server_socket, &slot->s_sock)) < 0){ >+ TRACE("retrying...\n"); >+ sock_release(slot->s_sock); >+ slot->s_sock = NULL; >+ } >+ >+ if(res >= 0){ >+ TRACE("successfully reconnected.\n"); >+ } >+ >+ return res; >+} >+ >+void lu_empty_slots(struct lufs_sb_info *info) >+{ >+ struct server_slot *slot; >+ >+ while(!list_empty(&info->slots)){ >+ slot = list_entry(info->slots.next, struct server_slot, s_list); >+ if(slot->s_sock) >+ sock_release(slot->s_sock); >+ list_del(&slot->s_list); >+ if(slot->s_buf) >+ kfree(slot->s_buf); >+ kfree(slot); >+ } >+} >+ >+static int do_execute(struct socket *sock, unsigned short cmd, unsigned short msglen, struct iovec *siov, unsigned short slen, struct iovec *riov, unsigned short rlen) >+{ >+ struct lu_msg msg; >+ struct iovec iov; >+ int res; >+ >+ TRACE("msg_len: %d\n", msglen); >+ >+ msg.msg_version = PVERSION; >+ msg.msg_type = cmd; >+ msg.msg_datalen = msglen; >+ msg.msg_pid = current->pid; >+ >+ iov.iov_base = &msg; >+ iov.iov_len = sizeof(struct lu_msg); >+ >+ if((res = sock_send(sock, &iov, 1)) < 0){ >+ WARN("sock_send failed!\n"); >+ return res; >+ } >+ if((res = sock_send(sock, siov, slen)) < 0){ >+ WARN("sock_send failed!\n"); >+ return res; >+ } >+ >+ iov.iov_base = &msg; >+ iov.iov_len = sizeof(struct lu_msg); >+ if((res = sock_recv(sock, &iov, 1, sizeof(struct lu_msg), 0)) < 0){ >+ WARN("sock_recv failed!\n"); >+ return res; >+ } >+ if(res != sizeof(struct lu_msg)){ >+ WARN("Ayeeee, didn't read a whole header!\n"); >+ return -EBUSY; >+ } >+ >+ if((msg.msg_datalen == 0)) >+ return msg.msg_type; >+ >+ if(riov == NULL){ >+ WARN("Unexpected data!!! Getting out of sync...\n"); >+ return -1; >+ } >+ >+ if((res = sock_recv(sock, riov, rlen, msg.msg_datalen, 0)) < 0){ >+ WARN("sock_recv failed!\n"); >+ return res; >+ } >+ >+ return msg.msg_type; >+} >+ >+struct server_slot* lu_getslot(struct lufs_sb_info *info) >+{ >+ struct list_head *p, *nd_best = NULL; >+ struct server_slot *slot; >+ int gotlock = 0; >+ >+ /* Look for a slot used by this process before */ >+ read_lock(&info->lock); >+ list_for_each(p, &info->slots) >+ if(list_entry(p, struct server_slot, s_list)->s_lastpid == current->pid){ >+ TRACE("found a previous used slot for %u.\n", current->pid); >+ if(down_trylock(&list_entry(p, struct server_slot, s_list)->s_lock) == 0){ >+ gotlock = 1; >+ break; >+ } >+ TRACE("oops! I still hold the lock! forget this one...\n"); >+ }else >+ if(!nd_best){ >+ nd_best = p; >+ } >+ >+ /* if we couldn't find one, take the first not locked by us */ >+ if(p == &info->slots){ >+ if(!nd_best){ >+ ERROR("deadlock: all locks owned by us!\n"); >+ read_unlock(&info->lock); >+ return NULL; >+ }else >+ p = nd_best; >+ >+ } >+ read_unlock(&info->lock); >+ >+ slot = list_entry(p, struct server_slot, s_list); >+ >+ /* Get the lock on that slot */ >+ if(!gotlock) >+ if(down_interruptible(&slot->s_lock)) >+ return NULL; >+ >+ slot->s_lastpid = current->pid; >+ >+ /* Move it to the tail */ >+ write_lock(&info->lock); >+ list_del(p); >+ list_add_tail(p, &info->slots); >+ write_unlock(&info->lock); >+ >+ return slot; >+} >+ >+void lu_putslot(struct server_slot *slot) >+{ >+ up(&slot->s_lock); >+} >+ >+int lu_execute(struct lufs_sb_info *info, struct server_slot *slot, unsigned short cmd, struct iovec *siov, unsigned short slen, struct iovec *riov, unsigned short rlen) >+{ >+ int res, i, msglen; >+ struct iovec bkup[LU_MAXIOVEC]; >+ >+ for(i = 0, msglen = 0; i < slen; i++){ >+ bkup[i] = siov[i]; >+ msglen += siov[i].iov_len; >+ } >+ >+ if(slot->s_sock == NULL){ >+ TRACE("slot not connected.\n"); >+ if((res = slot_reconnect(info, slot)) < 0){ >+ ERROR("failed to connect!\n"); >+ goto out; >+ } >+ } >+ >+ if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){ >+ TRACE("do_execute failed!\n"); >+ >+ if(signal_pending(current) && (!sigismember(¤t->pending.signal, SIGPIPE))){ >+ TRACE("interrupted by a signal. disconnecting this slot...\n"); >+ sock_release(slot->s_sock); >+ slot->s_sock = NULL; >+ goto out; >+ } >+ >+ if(sigismember(¤t->pending.signal, SIGPIPE)){ >+ TRACE("got a SIGPIPE\n"); >+ sigdelset(¤t->pending.signal, SIGPIPE); >+ } >+ >+ if((res = slot_reconnect(info, slot)) < 0){ >+ ERROR("could't reconnect!\n"); >+ goto out; >+ } >+ >+ for(i = 0; i < slen; i++) >+ siov[i] = bkup[i]; >+ >+ if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){ >+ ERROR("error executing command!\n"); >+ goto out; >+ } >+ } >+ >+ out: >+ return res; >+} >+ >+int lu_getname(struct dentry *d, char *name, int max) >+{ >+ int len = 0; >+ struct dentry *p; >+ struct lufs_sb_info *info = GET_INFO(d->d_sb); >+ >+ for(p = d; p != p->d_parent; p = p->d_parent) >+ len += p->d_name.len + 1; >+ >+ TRACE("root: %s, rootlen: %d, namelen: %d\n", info->root, info->rootlen, len); >+ >+ if(len + info->rootlen > max) >+ return -1; >+ >+ strcpy(name, info->root); >+ >+ if(len + info->rootlen == 0){ >+ strcat(name, "/"); >+ goto out; >+ } >+ >+ len += info->rootlen; >+ >+ name[len] = 0; >+ for(p = d; p != p->d_parent; p = p->d_parent){ >+ len -= p->d_name.len; >+ strncpy(&(name[len]), p->d_name.name, p->d_name.len); >+ name[--len] = '/'; >+ } >+ >+out: >+ TRACE("name resolved to %s\n", name); >+ return 0; >+} >+ >+int lu_getname_dumb(struct dentry *d, char *name, int max) >+{ >+ int len = 0; >+ struct dentry *p; >+ >+ for(p = d; p != p->d_parent; p = p->d_parent) >+ len += p->d_name.len + 1; >+ >+ if(len > max) >+ return -1; >+ >+ if(len == 0){ >+ name[0] = '/'; >+ name[1] = 0; >+ goto out; >+ } >+ >+ name[len] = 0; >+ for(p = d; p != p->d_parent; p = p->d_parent){ >+ len -= p->d_name.len; >+ strncpy(&(name[len]), p->d_name.name, p->d_name.len); >+ name[--len] = '/'; >+ } >+ >+out: >+ return 0; >+} >+ >+static void init_root_dirent(struct lufs_sb_info *server, struct lufs_fattr *fattr) >+{ >+ memset(fattr, 0, sizeof(struct lufs_fattr)); >+ fattr->f_nlink = 1; >+ fattr->f_uid = server->config.uid; >+ fattr->f_gid = server->config.gid; >+ fattr->f_blksize = 512; >+ fattr->f_ino = 2; >+ fattr->f_mtime = CURRENT_TIME.tv_sec; >+ fattr->f_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH | S_IFDIR | server->config.dmode; >+ fattr->f_size = 512; >+ fattr->f_blocks = 1; >+} >+ >+void lu_lookup_root(struct lufs_sb_info *server, struct lufs_fattr *fattr) >+{ >+ struct server_slot *slot; >+ struct iovec siov, riov; >+ int res; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(server)) == NULL){ >+ init_root_dirent(server, fattr); >+ return; >+ } >+ >+ if(server->rootlen) >+ strcpy(slot->s_buf, server->root); >+ else >+ strcpy(slot->s_buf, "/"); >+ >+ TRACE("stating root %s\n", slot->s_buf); >+ >+ siov.iov_base = slot->s_buf; >+ siov.iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = fattr; >+ riov.iov_len = sizeof(struct lufs_fattr); >+ >+ if((res = lu_execute(server, slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0){ >+ init_root_dirent(server, fattr); >+ goto out; >+ } >+ >+ if(PIS_ERROR(res)){ >+ WARN("stat failed!\n"); >+ init_root_dirent(server, fattr); >+ goto out; >+ } >+ >+ lu_fixattrs(server, fattr); >+ >+ fattr->f_ino = 2; >+ >+ out: >+ TRACE("out\n"); >+ lu_putslot(slot); >+} >+ >+void lu_fixattrs(struct lufs_sb_info *info, struct lufs_fattr *fattr) >+{ >+ >+ fattr->f_blksize = LU_BLOCKSIZE; >+ >+ if(S_ISREG(fattr->f_mode) || S_ISDIR(fattr->f_mode)) >+ fattr->f_blocks = (fattr->f_size + LU_BLOCKSIZE - 1) / LU_BLOCKSIZE; >+ else >+ fattr->f_blocks = 0; >+ >+ if(info->config.own_fs){ >+ >+ if(!fattr->f_uid) >+ fattr->f_mode = (fattr->f_mode & ~S_IRWXU) | ((fattr->f_mode & S_IRWXO)*(S_IRWXU/S_IRWXO)); >+ >+ if(!fattr->f_gid) >+ fattr->f_mode = (fattr->f_mode & ~S_IRWXG) | ((fattr->f_mode & S_IRWXO)*(S_IRWXG/S_IRWXO)); >+ >+ fattr->f_uid = info->config.uid; >+ fattr->f_gid = info->config.gid; >+ >+ }else{ >+ >+ if(fattr->f_uid) >+ fattr->f_uid = info->config.uid; >+ else >+ fattr->f_uid = LU_DEF_UID; >+ >+ if(fattr->f_gid) >+ fattr->f_gid = info->config.gid; >+ else >+ fattr->f_gid = LU_DEF_GID; >+ } >+ >+ if(fattr->f_mode & S_IFDIR) >+ fattr->f_mode |= info->config.dmode; >+ else >+ fattr->f_mode |= info->config.fmode; >+} >+ >+void lu_xlate_symlink(char *link, char *target, char *buf) >+{ >+ int i; >+ char *c1, *c2 = link; >+ >+ TRACE("translating %s->%s\n", link, target); >+ >+ for(c1 = strchr(link, '/'); c1 && !strncmp(link, target, c1 - link); c2 = c1, c1 = strchr(c1 + 1, '/')); >+ >+ TRACE("disjoint paths: %s, %s\n", c2, target + (c2 - link)); >+ >+ for(i = 0, c1 = c2; (c1 = strchr(c1 + 1, '/')); i++); >+ >+ strcpy(buf, "./"); >+ >+ for(; i > 0; i--) >+ strcat(buf, "../"); >+ >+ strcat(buf, target + (c2 - link) + 1); >+ >+ TRACE("absolute link resolved to %s\n", buf); >+ >+} >+ >diff -burN kernel.orig/Linux/2.6/proc.h kernel/Linux/2.6/proc.h >--- kernel.orig/Linux/2.6/proc.h 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/proc.h 2003-02-06 10:28:51.000000000 +0000 >@@ -0,0 +1,51 @@ >+/* >+ * proc.h >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#ifndef _LU_PROC_H_ >+#define _LU_PROC_H_ >+ >+#include <linux/types.h> >+#include <linux/list.h> >+#include <linux/socket.h> >+ >+struct server_slot{ >+ struct socket *s_sock; >+ struct semaphore s_lock; >+ struct list_head s_list; >+ pid_t s_lastpid; >+ char *s_buf; >+}; >+ >+struct lufs_fattr; >+ >+int lu_execute(struct lufs_sb_info*, struct server_slot*, unsigned short, struct iovec*, unsigned short, struct iovec*, unsigned short); >+void lu_empty_slots(struct lufs_sb_info*); >+int lu_getname(struct dentry*, char*, int); >+int lu_getname_dumb(struct dentry*, char*, int); >+struct server_slot* lu_getslot(struct lufs_sb_info*); >+void lu_putslot(struct server_slot*); >+int lu_revalidate_inode(struct dentry*); >+void lu_lookup_root(struct lufs_sb_info*, struct lufs_fattr*); >+void lu_fixattrs(struct lufs_sb_info*, struct lufs_fattr*); >+void lu_xlate_symlink(char*, char*, char*); >+ >+#endif >diff -burN kernel.orig/Linux/2.6/symlink.c kernel/Linux/2.6/symlink.c >--- kernel.orig/Linux/2.6/symlink.c 1970-01-01 01:00:00.000000000 +0100 >+++ kernel/Linux/2.6/symlink.c 2003-02-06 14:32:52.000000000 +0000 >@@ -0,0 +1,184 @@ >+/* >+ * symlink.c >+ * Copyright (C) 2002 Florin Malita <mali@go.ro> >+ * >+ * This file is part of LUFS, a free userspace filesystem implementation. >+ * See http://lufs.sourceforge.net/ for updates. >+ * >+ * LUFS is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 2 of the License, or >+ * (at your option) any later version. >+ * >+ * LUFS is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/version.h> >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/slab.h> >+#include <linux/socket.h> >+#include <linux/smp_lock.h> >+#include <linux/fs.h> >+ >+#include <asm/uaccess.h> >+#include <asm/system.h> >+ >+ >+#include "lufs.h" >+#include "proc.h" >+ >+static char failed_link[] = "invalid"; >+ >+static int lu_readlink(struct dentry *dentry, char *buffer, int bufflen) >+{ >+ struct server_slot *slot; >+ struct iovec siov, riov; >+ int res; >+ char *cc = failed_link; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return vfs_readlink(dentry, buffer, bufflen, cc); >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ siov.iov_base = slot->s_buf; >+ siov.iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = &slot->s_buf[LU_MAXPATHLEN]; >+ riov.iov_len = LU_MAXPATHLEN; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("read_link failed.\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ cc = &slot->s_buf[LU_MAXPATHLEN]; >+ >+ TRACE("response: %s\n", cc); >+ >+ if(*cc == '/'){ >+ if(GET_INFO(dentry->d_sb)->rootlen){ >+ if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){ >+ WARN("symlink outside mounted root!"); >+ cc = failed_link; >+ goto out; >+ } >+ cc += GET_INFO(dentry->d_sb)->rootlen; >+ } >+ >+ lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf); >+ >+ cc = slot->s_buf; >+ >+ } >+ >+ >+ >+ out: >+ res = vfs_readlink(dentry, buffer, bufflen, cc); >+ >+ lu_putslot(slot); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+static int lu_followlink(struct dentry *dentry, struct nameidata *nd) >+{ >+ struct server_slot *slot; >+ struct iovec siov, riov; >+ int res; >+ char *cc = failed_link; >+ char *tmp; >+ >+ TRACE("in\n"); >+ >+ if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL) >+ return vfs_follow_link(nd, cc); >+ >+ >+ if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){ >+ WARN("lu_getname failed!\n"); >+ goto out; >+ } >+ >+ siov.iov_base = slot->s_buf; >+ siov.iov_len = strlen(slot->s_buf) + 1; >+ riov.iov_base = &slot->s_buf[LU_MAXPATHLEN]; >+ riov.iov_len = LU_MAXPATHLEN; >+ >+ if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0) >+ goto out; >+ >+ if(PIS_ERROR(res)){ >+ TRACE("read_link failed.\n"); >+ res = PERROR(res); >+ goto out; >+ } >+ >+ cc = &slot->s_buf[LU_MAXPATHLEN]; >+ >+ if(*cc == '/'){ >+ if(GET_INFO(dentry->d_sb)->rootlen){ >+ if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){ >+ WARN("symlink outside mounted root!"); >+ cc = failed_link; >+ goto out; >+ } >+ cc += GET_INFO(dentry->d_sb)->rootlen; >+ } >+ >+ lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf); >+ >+ cc = slot->s_buf; >+ >+ } >+ >+ out: >+ >+ /* vfs_follow_link somehow manages to call lookup_validate, so we need to >+ release the slot, in case it's the only one, otherwise lu_lookup will >+ fail (avoid a deadlock). bad, bad vfs_follow_link! you break the overall >+ beauty of no kmallocs... */ >+ >+ if((tmp = kmalloc(strlen(cc) + 1, GFP_KERNEL)) == NULL){ >+ WARN("out of mem!\n"); >+ tmp = failed_link; >+ }else >+ strcpy(tmp, cc); >+ >+ lu_putslot(slot); >+ res = vfs_follow_link(nd, tmp); >+ >+ if(tmp != failed_link) >+ kfree(tmp); >+ >+ TRACE("out\n"); >+ return res; >+} >+ >+struct inode_operations lu_symlink_inode_operations = { >+ .readlink = lu_readlink, >+ .follow_link = lu_followlink, >+}; >+ >+ >+ >+ >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 30470
:
18851
|
19130
|
19131