Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 30470 | Differences between
and this patch

Collapse All | Expand All

(-)kernel/Linux/Makefile.in (-1 / +1 lines)
Lines 150-156 Link Here
150
target_os = @target_os@
150
target_os = @target_os@
151
target_vendor = @target_vendor@
151
target_vendor = @target_vendor@
152
SUBDIRS = @KERNEL_DIR@
152
SUBDIRS = @KERNEL_DIR@
153
DIST_SUBDIRS = 2.4 2.5
153
DIST_SUBDIRS = 2.4 2.5 2.6
154
subdir = kernel/Linux
154
subdir = kernel/Linux
155
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
155
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
156
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
156
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
(-)kernel.orig/Linux/2.6/Makefile.am (+19 lines)
Line 0 Link Here
1
INCLUDES=-I@KERNEL_HDR@ -I@KERNEL_HDR@/asm-i386/mach-default @all_includes@
2
3
LIBS=
4
5
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
6
LDFLAGS=-r
7
8
moduledir=@MODULES_DIR@/kernel/fs/lufs
9
10
module_PROGRAMS=lufs.o
11
12
noinst_HEADERS=lufs.h proc.h
13
lufs_o_SOURCES=proc.c inode.c dir.c file.c symlink.c
14
lufs_o_LDADD=
15
16
install-data-hook:
17
	depmod -aq
18
	if [ "`lsmod | grep lufs`" ]; then rmmod lufs; fi
19
	modprobe lufs
(-)kernel.orig/Linux/2.6/Makefile.in (+480 lines)
Line 0 Link Here
1
# Makefile.in generated by automake 1.7.5 from Makefile.am.
2
# @configure_input@
3
4
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
5
# Free Software Foundation, Inc.
6
# This Makefile.in is free software; the Free Software Foundation
7
# gives unlimited permission to copy and/or distribute it,
8
# with or without modifications, as long as this notice is preserved.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13
# PARTICULAR PURPOSE.
14
15
@SET_MAKE@
16
17
srcdir = @srcdir@
18
top_srcdir = @top_srcdir@
19
VPATH = @srcdir@
20
pkgdatadir = $(datadir)/@PACKAGE@
21
pkglibdir = $(libdir)/@PACKAGE@
22
pkgincludedir = $(includedir)/@PACKAGE@
23
top_builddir = ../../..
24
25
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
26
INSTALL = @INSTALL@
27
install_sh_DATA = $(install_sh) -c -m 644
28
install_sh_PROGRAM = $(install_sh) -c
29
install_sh_SCRIPT = $(install_sh) -c
30
INSTALL_HEADER = $(INSTALL_DATA)
31
transform = $(program_transform_name)
32
NORMAL_INSTALL = :
33
PRE_INSTALL = :
34
POST_INSTALL = :
35
NORMAL_UNINSTALL = :
36
PRE_UNINSTALL = :
37
POST_UNINSTALL = :
38
build_triplet = @build@
39
host_triplet = @host@
40
target_triplet = @target@
41
ACLOCAL = @ACLOCAL@
42
AMDEP_FALSE = @AMDEP_FALSE@
43
AMDEP_TRUE = @AMDEP_TRUE@
44
AMTAR = @AMTAR@
45
AUTOCONF = @AUTOCONF@
46
AUTOFS_INSTALL = @AUTOFS_INSTALL@
47
AUTOHEADER = @AUTOHEADER@
48
AUTOMAKE = @AUTOMAKE@
49
AWK = @AWK@
50
CC = @CC@
51
CCDEPMODE = @CCDEPMODE@
52
53
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
54
CPP = @CPP@
55
CPPFLAGS = @CPPFLAGS@
56
CXX = @CXX@
57
CXXDEPMODE = @CXXDEPMODE@
58
CXXFLAGS = @CXXFLAGS@
59
CYGPATH_W = @CYGPATH_W@
60
DEBUG_FLAGS = @DEBUG_FLAGS@
61
DEFS = @DEFS@
62
DEPDIR = @DEPDIR@
63
ECHO = @ECHO@
64
ECHO_C = @ECHO_C@
65
ECHO_N = @ECHO_N@
66
ECHO_T = @ECHO_T@
67
EGREP = @EGREP@
68
EXEEXT = @EXEEXT@
69
GCONF = @GCONF@
70
GVFSCONF = @GVFSCONF@
71
GVFS_CFLAGS = @GVFS_CFLAGS@
72
GVFS_LDADD = @GVFS_LDADD@
73
INSTALL_DATA = @INSTALL_DATA@
74
INSTALL_PROGRAM = @INSTALL_PROGRAM@
75
INSTALL_SCRIPT = @INSTALL_SCRIPT@
76
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
77
KDEBUG_FLAGS = @KDEBUG_FLAGS@
78
KERNEL_DIR = @KERNEL_DIR@
79
KERNEL_HDR = @KERNEL_HDR@
80
LDFLAGS = -r
81
LIBCHIPCARD_INCLUDES = @LIBCHIPCARD_INCLUDES@
82
LIBCHIPCARD_LIB = @LIBCHIPCARD_LIB@
83
LIBOBJS = @LIBOBJS@
84
85
LIBS = 
86
LIBTOOL = @LIBTOOL@
87
LN_S = @LN_S@
88
LTLIBOBJS = @LTLIBOBJS@
89
LUFS_SUID = @LUFS_SUID@
90
MAKEINFO = @MAKEINFO@
91
MODULES_DIR = @MODULES_DIR@
92
MODV_FLAGS = @MODV_FLAGS@
93
OBJEXT = @OBJEXT@
94
OS_DIR = @OS_DIR@
95
PACKAGE = @PACKAGE@
96
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
97
PACKAGE_NAME = @PACKAGE_NAME@
98
PACKAGE_STRING = @PACKAGE_STRING@
99
PACKAGE_TARNAME = @PACKAGE_TARNAME@
100
PACKAGE_VERSION = @PACKAGE_VERSION@
101
PATH_SEPARATOR = @PATH_SEPARATOR@
102
RANLIB = @RANLIB@
103
SET_MAKE = @SET_MAKE@
104
SHELL = @SHELL@
105
SSHPROG = @SSHPROG@
106
STRIP = @STRIP@
107
VERSION = @VERSION@
108
ac_ct_CC = @ac_ct_CC@
109
ac_ct_CXX = @ac_ct_CXX@
110
ac_ct_RANLIB = @ac_ct_RANLIB@
111
ac_ct_STRIP = @ac_ct_STRIP@
112
all_includes = @all_includes@
113
all_libraries = @all_libraries@
114
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
115
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
116
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
117
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
118
am__include = @am__include@
119
am__leading_dot = @am__leading_dot@
120
am__quote = @am__quote@
121
bindir = @bindir@
122
build = @build@
123
build_alias = @build_alias@
124
build_cpu = @build_cpu@
125
build_os = @build_os@
126
build_vendor = @build_vendor@
127
datadir = @datadir@
128
define_has_libchipcard = @define_has_libchipcard@
129
exec_prefix = @exec_prefix@
130
host = @host@
131
host_alias = @host_alias@
132
host_cpu = @host_cpu@
133
host_os = @host_os@
134
host_vendor = @host_vendor@
135
includedir = @includedir@
136
infodir = @infodir@
137
install_sh = @install_sh@
138
libdir = @libdir@
139
libexecdir = @libexecdir@
140
localstatedir = @localstatedir@
141
mandir = @mandir@
142
oldincludedir = @oldincludedir@
143
opt_fs = @opt_fs@
144
prefix = @prefix@
145
program_transform_name = @program_transform_name@
146
sbindir = @sbindir@
147
sharedstatedir = @sharedstatedir@
148
sysconfdir = @sysconfdir@
149
target = @target@
150
target_alias = @target_alias@
151
target_cpu = @target_cpu@
152
target_os = @target_os@
153
target_vendor = @target_vendor@
154
INCLUDES = -I@KERNEL_HDR@ -I@KERNEL_HDR@/asm-i386/mach-default @all_includes@
155
156
moduledir = @MODULES_DIR@/kernel/fs/lufs
157
158
module_PROGRAMS = lufs.o
159
160
noinst_HEADERS = lufs.h proc.h
161
lufs_o_SOURCES = proc.c inode.c dir.c file.c symlink.c
162
lufs_o_LDADD = 
163
subdir = kernel/Linux/2.5
164
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
165
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
166
CONFIG_HEADER = $(top_builddir)/config.h
167
CONFIG_CLEAN_FILES =
168
module_PROGRAMS = lufs.o$(EXEEXT)
169
PROGRAMS = $(module_PROGRAMS)
170
171
am_lufs_o_OBJECTS = proc.$(OBJEXT) inode.$(OBJEXT) dir.$(OBJEXT) \
172
	file.$(OBJEXT) symlink.$(OBJEXT)
173
lufs_o_OBJECTS = $(am_lufs_o_OBJECTS)
174
lufs_o_DEPENDENCIES =
175
lufs_o_LDFLAGS =
176
177
DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
178
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
179
am__depfiles_maybe = depfiles
180
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dir.Po ./$(DEPDIR)/file.Po \
181
@AMDEP_TRUE@	./$(DEPDIR)/inode.Po ./$(DEPDIR)/proc.Po \
182
@AMDEP_TRUE@	./$(DEPDIR)/symlink.Po
183
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
184
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
185
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
186
	$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
187
CCLD = $(CC)
188
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
189
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
190
DIST_SOURCES = $(lufs_o_SOURCES)
191
HEADERS = $(noinst_HEADERS)
192
193
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
194
SOURCES = $(lufs_o_SOURCES)
195
196
all: all-am
197
198
.SUFFIXES:
199
.SUFFIXES: .c .lo .o .obj
200
$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
201
	cd $(top_srcdir) && \
202
	  $(AUTOMAKE) --gnu  kernel/Linux/2.5/Makefile
203
Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
204
	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
205
modulePROGRAMS_INSTALL = $(INSTALL_PROGRAM)
206
install-modulePROGRAMS: $(module_PROGRAMS)
207
	@$(NORMAL_INSTALL)
208
	$(mkinstalldirs) $(DESTDIR)$(moduledir)
209
	@list='$(module_PROGRAMS)'; for p in $$list; do \
210
	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
211
	  if test -f $$p \
212
	     || test -f $$p1 \
213
	  ; then \
214
	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
215
	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(modulePROGRAMS_INSTALL) $$p $(DESTDIR)$(moduledir)/$$f"; \
216
	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(modulePROGRAMS_INSTALL) $$p $(DESTDIR)$(moduledir)/$$f || exit 1; \
217
	  else :; fi; \
218
	done
219
220
uninstall-modulePROGRAMS:
221
	@$(NORMAL_UNINSTALL)
222
	@list='$(module_PROGRAMS)'; for p in $$list; do \
223
	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
224
	  echo " rm -f $(DESTDIR)$(moduledir)/$$f"; \
225
	  rm -f $(DESTDIR)$(moduledir)/$$f; \
226
	done
227
228
clean-modulePROGRAMS:
229
	@list='$(module_PROGRAMS)'; for p in $$list; do \
230
	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
231
	  echo " rm -f $$p $$f"; \
232
	  rm -f $$p $$f ; \
233
	done
234
lufs.o$(EXEEXT): $(lufs_o_OBJECTS) $(lufs_o_DEPENDENCIES) 
235
	@rm -f lufs.o$(EXEEXT)
236
	$(LINK) $(lufs_o_LDFLAGS) $(lufs_o_OBJECTS) $(lufs_o_LDADD) $(LIBS)
237
238
mostlyclean-compile:
239
	-rm -f *.$(OBJEXT) core *.core
240
241
distclean-compile:
242
	-rm -f *.tab.c
243
244
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Po@am__quote@
245
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@
246
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inode.Po@am__quote@
247
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Po@am__quote@
248
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@
249
250
distclean-depend:
251
	-rm -rf ./$(DEPDIR)
252
253
.c.o:
254
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
255
@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
256
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
257
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
258
@am__fastdepCC_TRUE@	fi
259
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
260
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
261
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
262
@am__fastdepCC_FALSE@	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
263
264
.c.obj:
265
@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
266
@am__fastdepCC_TRUE@	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
267
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
268
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
269
@am__fastdepCC_TRUE@	fi
270
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
271
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
272
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
273
@am__fastdepCC_FALSE@	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
274
275
.c.lo:
276
@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
277
@am__fastdepCC_TRUE@	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
278
@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
279
@am__fastdepCC_TRUE@	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
280
@am__fastdepCC_TRUE@	fi
281
@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
282
@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
283
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
284
@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
285
286
mostlyclean-libtool:
287
	-rm -f *.lo
288
289
clean-libtool:
290
	-rm -rf .libs _libs
291
292
distclean-libtool:
293
	-rm -f libtool
294
uninstall-info-am:
295
296
ETAGS = etags
297
ETAGSFLAGS =
298
299
CTAGS = ctags
300
CTAGSFLAGS =
301
302
tags: TAGS
303
304
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
305
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
306
	unique=`for i in $$list; do \
307
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
308
	  done | \
309
	  $(AWK) '    { files[$$0] = 1; } \
310
	       END { for (i in files) print i; }'`; \
311
	mkid -fID $$unique
312
313
TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
314
		$(TAGS_FILES) $(LISP)
315
	tags=; \
316
	here=`pwd`; \
317
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
318
	unique=`for i in $$list; do \
319
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
320
	  done | \
321
	  $(AWK) '    { files[$$0] = 1; } \
322
	       END { for (i in files) print i; }'`; \
323
	test -z "$(ETAGS_ARGS)$$tags$$unique" \
324
	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
325
	     $$tags $$unique
326
327
ctags: CTAGS
328
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
329
		$(TAGS_FILES) $(LISP)
330
	tags=; \
331
	here=`pwd`; \
332
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
333
	unique=`for i in $$list; do \
334
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
335
	  done | \
336
	  $(AWK) '    { files[$$0] = 1; } \
337
	       END { for (i in files) print i; }'`; \
338
	test -z "$(CTAGS_ARGS)$$tags$$unique" \
339
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
340
	     $$tags $$unique
341
342
GTAGS:
343
	here=`$(am__cd) $(top_builddir) && pwd` \
344
	  && cd $(top_srcdir) \
345
	  && gtags -i $(GTAGS_ARGS) $$here
346
347
distclean-tags:
348
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
349
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
350
351
top_distdir = ../../..
352
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
353
354
distdir: $(DISTFILES)
355
	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
356
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
357
	list='$(DISTFILES)'; for file in $$list; do \
358
	  case $$file in \
359
	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
360
	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
361
	  esac; \
362
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
363
	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
364
	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
365
	    dir="/$$dir"; \
366
	    $(mkinstalldirs) "$(distdir)$$dir"; \
367
	  else \
368
	    dir=''; \
369
	  fi; \
370
	  if test -d $$d/$$file; then \
371
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
372
	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
373
	    fi; \
374
	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
375
	  else \
376
	    test -f $(distdir)/$$file \
377
	    || cp -p $$d/$$file $(distdir)/$$file \
378
	    || exit 1; \
379
	  fi; \
380
	done
381
check-am: all-am
382
check: check-am
383
all-am: Makefile $(PROGRAMS) $(HEADERS)
384
385
installdirs:
386
	$(mkinstalldirs) $(DESTDIR)$(moduledir)
387
install: install-am
388
install-exec: install-exec-am
389
install-data: install-data-am
390
uninstall: uninstall-am
391
392
install-am: all-am
393
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
394
395
installcheck: installcheck-am
396
install-strip:
397
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
398
	  INSTALL_STRIP_FLAG=-s \
399
	  `test -z '$(STRIP)' || \
400
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
401
mostlyclean-generic:
402
403
clean-generic:
404
405
distclean-generic:
406
	-rm -f Makefile $(CONFIG_CLEAN_FILES)
407
408
maintainer-clean-generic:
409
	@echo "This command is intended for maintainers to use"
410
	@echo "it deletes files that may require special tools to rebuild."
411
clean: clean-am
412
413
clean-am: clean-generic clean-libtool clean-modulePROGRAMS \
414
	mostlyclean-am
415
416
distclean: distclean-am
417
418
distclean-am: clean-am distclean-compile distclean-depend \
419
	distclean-generic distclean-libtool distclean-tags
420
421
dvi: dvi-am
422
423
dvi-am:
424
425
info: info-am
426
427
info-am:
428
429
install-data-am: install-modulePROGRAMS
430
	@$(NORMAL_INSTALL)
431
	$(MAKE) $(AM_MAKEFLAGS) 
432
433
install-exec-am:
434
435
install-info: install-info-am
436
437
install-man:
438
439
installcheck-am:
440
441
maintainer-clean: maintainer-clean-am
442
443
maintainer-clean-am: distclean-am maintainer-clean-generic
444
445
mostlyclean: mostlyclean-am
446
447
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
448
	mostlyclean-libtool
449
450
pdf: pdf-am
451
452
pdf-am:
453
454
ps: ps-am
455
456
ps-am:
457
458
uninstall-am: uninstall-info-am uninstall-modulePROGRAMS
459
460
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
461
	clean-libtool clean-modulePROGRAMS ctags distclean \
462
	distclean-compile distclean-depend distclean-generic \
463
	distclean-libtool distclean-tags distdir dvi dvi-am info \
464
	info-am install install-am install-data install-data-am \
465
	install-exec install-exec-am install-info install-info-am \
466
	install-man install-modulePROGRAMS install-strip installcheck \
467
	installcheck-am installdirs maintainer-clean \
468
	maintainer-clean-generic mostlyclean mostlyclean-compile \
469
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
470
	tags uninstall uninstall-am uninstall-info-am \
471
	uninstall-modulePROGRAMS
472
473
474
:
475
	depmod -aq
476
	if [ "`lsmod | grep lufs`" ]; then rmmod lufs; fi
477
	modprobe lufs
478
# Tell versions [3.59,3.63) of GNU make to not export all variables.
479
# Otherwise a system limit (for SysV at least) may be exceeded.
480
.NOEXPORT:
(-)kernel.orig/Linux/2.6/dir.c (+582 lines)
Line 0 Link Here
1
/*
2
 * dir.c
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <linux/version.h>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/fs.h>
27
#include <linux/slab.h>
28
#include <linux/ctype.h>
29
#include <linux/socket.h>
30
31
#include <asm/uaccess.h>
32
#include <asm/system.h>
33
34
#include <linux/smp_lock.h>
35
36
#include "lufs.h"
37
#include "proc.h"
38
39
40
extern struct inode* lu_iget(struct super_block*, struct lufs_fattr*);
41
extern int lufs_notify_change(struct dentry*, struct iattr*);
42
43
static int lu_readdir(struct file*, void*, filldir_t);
44
45
static struct dentry *lu_lookup(struct inode*, struct dentry*);
46
static int lu_mkdir(struct inode*, struct dentry*, int);
47
static int lu_create(struct inode*, struct dentry*, int);
48
static int lu_rmdir(struct inode*, struct dentry*);
49
static int lu_rename(struct inode*, struct dentry*, struct inode*, struct dentry*);
50
static int lu_unlink(struct inode*, struct dentry*);
51
static int lu_link(struct dentry*, struct inode*, struct dentry*);
52
static int lu_symlink(struct inode*, struct dentry*, const char*);
53
54
struct file_operations lu_dir_operations = {
55
    .read	= generic_read_dir,
56
    .readdir	= lu_readdir,
57
};
58
59
struct inode_operations lu_dir_inode_operations = {
60
    .create	= lu_create,
61
    .lookup	= lu_lookup,
62
    .link	= lu_link,
63
    .unlink	= lu_unlink,
64
    .symlink	= lu_symlink,
65
    .mkdir	= lu_mkdir,
66
    .rmdir	= lu_rmdir,
67
    .rename	= lu_rename,
68
    .setattr	= lufs_notify_change,
69
};
70
71
static int lu_lookup_validate(struct dentry *dentry, int flags)
72
{
73
    struct inode *inode = dentry->d_inode;
74
    unsigned long age = jiffies - dentry->d_time;
75
    int res;
76
    
77
    TRACE("in\n");
78
    
79
    res = (age <= LU_MAXAGE);
80
    TRACE("age: %lu, valid: %d\n", age, res);
81
82
    if(!res)
83
	res = (lu_revalidate_inode(dentry) == 0);
84
85
    
86
    if(inode){
87
	lock_kernel();
88
89
	if(is_bad_inode(inode))
90
	    res = 0;
91
	unlock_kernel();
92
    }else
93
	TRACE("no inode?!\n");
94
95
    TRACE("out(res=%d)\n", res);
96
97
    return res;
98
}
99
100
static int lu_delete_dentry(struct dentry *dentry)
101
{
102
    
103
    TRACE("in\n");
104
    if(dentry->d_inode && is_bad_inode(dentry->d_inode)){
105
	WARN("bad inode, unhashing \n");
106
    	return 1;
107
    }
108
109
    TRACE("out\n");
110
    return 0;
111
}
112
113
struct dentry_operations lufs_dentry_operations = {
114
    .d_revalidate	= lu_lookup_validate,
115
    .d_delete		= lu_delete_dentry,
116
};
117
118
static int lu_readdir(struct file *f, void *dirent, filldir_t filldir)
119
{
120
    int res = -1;
121
    char *c;
122
    struct qstr qname;
123
    unsigned long ino;
124
    struct iovec siov[2], riov;
125
    struct server_slot *slot;
126
    unsigned short offset;
127
    
128
    TRACE("in\n");
129
    
130
    if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
131
	return -ERESTARTSYS;
132
133
    if(lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA) < 0){
134
	WARN("lu_getname failed!\n");
135
	goto out;
136
    }
137
138
    TRACE("reading %s, offset %u...\n", slot->s_buf, (unsigned)f->f_pos);
139
    res = 0;
140
    
141
    switch((unsigned int)f->f_pos){
142
143
    case 0:
144
	if(filldir(dirent, ".", 1, 0, f->f_dentry->d_inode->i_ino, DT_DIR) < 0)
145
	    goto out;
146
	f->f_pos++;
147
148
    case 1:
149
	if(filldir(dirent, "..", 2, 1, f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
150
	    goto out;
151
	f->f_pos++;
152
153
    default:
154
	offset = f->f_pos;
155
	siov[0].iov_base = &offset;
156
	siov[0].iov_len = sizeof(unsigned short);
157
	siov[1].iov_base = slot->s_buf;
158
	siov[1].iov_len = strlen(slot->s_buf) + 1;
159
	riov.iov_base = slot->s_buf;
160
	riov.iov_len = LU_MAXDATA;
161
162
	if((res = lu_execute(GET_INFO(f->f_dentry->d_inode->i_sb), slot, PTYPE_READDIR, siov, 2, &riov, 1)) < 0){
163
	    WARN("could not read directory content!\n");
164
	    if(res == -ERESTARTSYS)
165
		res = -EINTR;
166
	    goto out;
167
	}
168
	if(PIS_ERROR(res)){
169
	    WARN("server failure!\n");
170
	    res = PERROR(res);
171
	    goto out;
172
	}
173
	for(qname.name = slot->s_buf, c = strchr(slot->s_buf, '\n'); c != NULL; qname.name = c+1, c = strchr(c+1, '\n')){
174
	    *c = 0;
175
	    TRACE("direntry: %s.\n", qname.name);
176
	    qname.len = strlen(qname.name);
177
	    if((ino = find_inode_number(f->f_dentry, &qname)) == 0)
178
		ino = iunique(f->f_dentry->d_sb, 2);
179
	    if(filldir(dirent, qname.name, qname.len, f->f_pos, ino, DT_UNKNOWN) < 0)
180
		break;
181
	    f->f_pos++;	    
182
	}
183
    }
184
185
    TRACE("out\n");
186
 out:
187
    lu_putslot(slot);
188
    return res;
189
}
190
191
static struct dentry* lu_lookup(struct inode *dir, struct dentry *dentry)
192
{
193
    int res;
194
    struct lufs_fattr fattr;
195
    struct iovec siov, riov;
196
    struct inode *inode;
197
    struct server_slot *slot;
198
199
    TRACE("in\n");
200
201
    if((slot = lu_getslot(GET_INFO(dir->i_sb))) == NULL)
202
	return ERR_PTR(-ERESTARTSYS);
203
    
204
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
205
	WARN("lu_getname failed!\n");
206
	goto out;
207
    }
208
209
    TRACE("looking up %s\n", slot->s_buf);
210
    
211
    siov.iov_base = slot->s_buf;
212
    siov.iov_len = strlen(slot->s_buf) + 1;
213
    riov.iov_base = &fattr;
214
    riov.iov_len = sizeof(struct lufs_fattr);
215
216
    if((res = lu_execute(GET_INFO(dir->i_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
217
	goto out;
218
219
    if(PIS_ERROR(res)){
220
	TRACE("File not found...\n");
221
	dentry->d_op = &lufs_dentry_operations;
222
	dentry->d_time = jiffies;
223
	d_add(dentry, NULL);
224
	lu_putslot(slot);
225
	return NULL;
226
    }
227
228
    lu_fixattrs(GET_INFO(dir->i_sb), &fattr);
229
230
    if(dentry == dentry->d_parent)
231
	fattr.f_ino = 2;
232
    else 
233
	fattr.f_ino = iunique(dentry->d_sb, 2);
234
235
    if((inode = lu_iget(dir->i_sb, &fattr))){
236
	dentry->d_op = &lufs_dentry_operations;
237
	dentry->d_time = jiffies;
238
	d_add(dentry, inode);
239
    }
240
    res = 0;
241
242
 out:
243
    lu_putslot(slot);
244
245
    TRACE("out\n");
246
    return ERR_PTR(res);
247
}
248
249
static int lu_instantiate(struct dentry *dentry, char *name, struct server_slot *slot)
250
{
251
    int res;
252
    struct lufs_fattr fattr;
253
    struct iovec siov, riov;
254
    struct inode *inode;
255
256
    TRACE("in\n");
257
258
    TRACE("instantiating %s\n", name);
259
    
260
    siov.iov_base = name;
261
    siov.iov_len = strlen(name) + 1;
262
    riov.iov_base = &fattr;
263
    riov.iov_len = sizeof(struct lufs_fattr);
264
265
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
266
	goto out;
267
268
    if(PIS_ERROR(res)){
269
	TRACE("File not found...\n");
270
	res = PERROR(res);
271
	goto out;
272
    }
273
274
    lu_fixattrs(GET_INFO(dentry->d_sb), &fattr);
275
276
    fattr.f_ino = iunique(dentry->d_sb, 2);
277
    inode = lu_iget(dentry->d_sb, &fattr);
278
279
    if(!inode){
280
	res = -EACCES;
281
	goto out;
282
    }
283
284
    d_instantiate(dentry, inode);
285
    res = 0;
286
287
  out:
288
    TRACE("out\n");
289
    return res;
290
}
291
292
static int lu_mkdir(struct inode *dir, struct dentry *dentry, int mode)
293
{
294
    int res;
295
    struct server_slot *slot;
296
    struct iovec iov[2];
297
298
    TRACE("in\n");
299
300
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
301
	return -ERESTARTSYS;
302
303
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
304
	WARN("lu_getname failed!\n");
305
	goto out;
306
    }
307
    
308
    iov[0].iov_base = &mode;
309
    iov[0].iov_len = sizeof(mode);
310
    iov[1].iov_base = slot->s_buf;
311
    iov[1].iov_len = strlen(slot->s_buf) + 1;
312
313
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_MKDIR, iov, 2, NULL, 0)) < 0)
314
	goto out;
315
316
    if(PIS_ERROR(res)){
317
	TRACE("Could not create directory.\n");
318
	res = PERROR(res);
319
	goto out;
320
    }
321
322
    res = lu_instantiate(dentry, slot->s_buf, slot);
323
324
  out:
325
    lu_putslot(slot);
326
    
327
    TRACE("out\n");
328
    return res;
329
}
330
331
static int lu_create(struct inode *dir, struct dentry *dentry, int mode)
332
{
333
    int res;
334
    struct server_slot *slot;
335
    struct iovec iov[2];
336
337
    TRACE("in\n");
338
339
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
340
	return -ERESTARTSYS;
341
342
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
343
	WARN("lu_getname failed!\n");
344
	goto out;
345
    }
346
    
347
    iov[0].iov_base = &mode;
348
    iov[0].iov_len = sizeof(mode);
349
    iov[1].iov_base = slot->s_buf;
350
    iov[1].iov_len = strlen(slot->s_buf) + 1;
351
352
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_CREATE, iov, 2, NULL, 0)) < 0)
353
	goto out;
354
355
    if(PIS_ERROR(res)){
356
	TRACE("Could not create file.\n");
357
	res = PERROR(res);
358
	goto out;
359
    }
360
361
    res = lu_instantiate(dentry, slot->s_buf, slot);
362
    
363
  out:
364
    lu_putslot(slot);
365
366
    TRACE("out\n");
367
    return res;
368
}
369
370
static int lu_rmdir(struct inode *dir, struct dentry *dentry)
371
{
372
    int res;
373
    struct server_slot *slot;
374
    struct iovec iov;
375
376
    if(!d_unhashed(dentry))
377
	return -EBUSY;    
378
379
    TRACE("in\n");
380
    
381
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
382
	return -ERESTARTSYS;
383
384
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
385
	WARN("lu_getname failed!");
386
	goto out;
387
    }
388
    
389
    iov.iov_base = slot->s_buf;
390
    iov.iov_len = strlen(slot->s_buf) + 1;
391
392
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_RMDIR, &iov, 1, NULL, 0)) < 0)
393
	goto out;
394
395
    if(PIS_ERROR(res)){
396
	TRACE("rmdir failed!\n");
397
	res = PERROR(res);
398
	goto out;
399
    }
400
    res = 0;
401
402
  out:
403
    lu_putslot(slot);
404
405
    TRACE("out\n");
406
    return res;
407
}
408
409
static int lu_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
410
{
411
    struct server_slot *slot;
412
    int res;
413
    struct iovec iov[2];
414
415
    TRACE("in\n");
416
417
    if((slot = lu_getslot(GET_INFO(old_dentry->d_sb))) == NULL)
418
	return -ERESTARTSYS;
419
420
    if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0 ||
421
       (res = lu_getname(new_dentry, &(slot->s_buf[LU_MAXPATHLEN]), LU_MAXPATHLEN)) < 0){
422
	WARN("lu_getname failed!\n");
423
	goto out;
424
    }
425
426
    iov[0].iov_base = slot->s_buf;
427
    iov[0].iov_len = strlen(slot->s_buf) + 1;
428
    iov[1].iov_base = &(slot->s_buf[LU_MAXPATHLEN]);
429
    iov[1].iov_len = strlen(&(slot->s_buf[LU_MAXPATHLEN])) + 1;
430
431
    if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_RENAME, iov, 2, NULL, 0)) < 0)
432
	goto out;
433
434
    if(PIS_ERROR(res)){
435
	TRACE("rename failed!\n");
436
	res = PERROR(res);
437
	goto out;
438
    }
439
    res = 0;
440
441
  out:
442
    lu_putslot(slot);
443
444
    TRACE("out\n");
445
    return res;
446
}
447
448
static int lu_unlink(struct inode *dir, struct dentry *dentry)
449
{
450
    int res;
451
    struct server_slot *slot;
452
    struct iovec iov;
453
454
    TRACE("in\n");
455
456
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
457
	return -ERESTARTSYS;
458
459
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
460
	WARN("lu_getname failed!");
461
	goto out;
462
    }
463
    
464
    iov.iov_base = slot->s_buf;
465
    iov.iov_len = strlen(slot->s_buf) + 1;
466
467
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_UNLINK, &iov, 1, NULL, 0)) < 0)
468
	goto out;
469
470
    if(PIS_ERROR(res)){
471
	TRACE("unlink failed!\n");
472
	res = PERROR(res);
473
	goto out;
474
    }
475
    res = 0;
476
477
  out:
478
    lu_putslot(slot);
479
480
    TRACE("out\n");
481
    return res;
482
}
483
484
485
static int lu_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
486
{
487
    int res;
488
    struct server_slot *slot;
489
    struct iovec iov[2];
490
491
    TRACE("in\n");
492
493
    if(S_ISDIR(old_dentry->d_inode->i_mode))
494
	return -EPERM;
495
496
    if(!(slot = lu_getslot(GET_INFO(old_dentry->d_sb))))
497
	return -ERESTARTSYS;
498
499
    if((res = lu_getname(old_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
500
	WARN("lu_getname failed!\n");
501
	goto out;
502
    }
503
504
    if((res = lu_getname(dentry, &slot->s_buf[LU_MAXPATHLEN], LU_MAXPATHLEN)) < 0){
505
	WARN("lu_getname failed!\n");
506
	goto out;
507
    }
508
509
    iov[0].iov_base = slot->s_buf;
510
    iov[0].iov_len = strlen(slot->s_buf) + 1;
511
    iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN];
512
    iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1;
513
514
    d_drop(dentry);
515
516
    if((res = lu_execute(GET_INFO(old_dentry->d_sb), slot, PTYPE_LINK, iov, 2, NULL, 0)) < 0)
517
	goto out;
518
519
    if(PIS_ERROR(res)){
520
	TRACE("link failed!\n");
521
	res = PERROR(res);
522
	goto out;
523
    }
524
525
    res = 0;
526
527
  out:
528
    lu_putslot(slot);
529
    TRACE("out\n");
530
    return res;
531
}
532
533
static int lu_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
534
{
535
    int res;
536
    struct server_slot *slot;
537
    struct iovec iov[2];
538
539
    TRACE("in\n");
540
    TRACE("symlink: %s\n", symname);
541
    
542
    if(strlen(symname) > LU_MAXPATHLEN - 1)
543
	return -ENAMETOOLONG;
544
545
    if(!(slot = lu_getslot(GET_INFO(dentry->d_sb))))
546
	return -ERESTARTSYS;
547
548
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
549
	WARN("lu_getname failed!\n");
550
	goto out;
551
    }
552
553
    TRACE("fname: %s\n", slot->s_buf);
554
555
    strcpy(&slot->s_buf[LU_MAXPATHLEN], symname);
556
557
    iov[0].iov_base = slot->s_buf;
558
    iov[0].iov_len = strlen(slot->s_buf) + 1;
559
    iov[1].iov_base = &slot->s_buf[LU_MAXPATHLEN];
560
    iov[1].iov_len = strlen(&slot->s_buf[LU_MAXPATHLEN]) + 1;
561
562
    d_drop(dentry);
563
564
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SYMLINK, iov, 2, NULL, 0)) < 0)
565
	goto out;
566
567
    if(PIS_ERROR(res)){
568
	TRACE("symlink failed!\n");
569
	res = PERROR(res);
570
	goto out;
571
    }
572
573
    res = 0;
574
575
  out:
576
    lu_putslot(slot);
577
    TRACE("out\n");
578
    return res;
579
}
580
581
582
(-)kernel.orig/Linux/2.6/file.c (+321 lines)
Line 0 Link Here
1
/*
2
 * file.c
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <linux/version.h>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/slab.h>
27
#include <linux/pagemap.h>
28
#include <linux/socket.h>
29
30
#include <asm/uaccess.h>
31
#include <asm/system.h>
32
33
#include <linux/smp_lock.h>
34
35
#include "lufs.h"
36
#include "proc.h"
37
38
extern int lufs_notify_change(struct dentry*, struct iattr*);
39
extern int lu_revalidate_inode(struct dentry*);
40
41
static int lu_file_open(struct inode *inode, struct file *file)
42
{
43
    int res, gres;
44
    struct server_slot *slot;
45
    struct iovec iov[2];
46
    unsigned flags;
47
48
    TRACE("in\n");
49
50
    if((gres = generic_file_open(inode, file)) < 0)
51
	return gres;
52
53
    TRACE("f_mode: %u, i_mode: %u\n", file->f_mode, inode->i_mode);
54
    TRACE("f_flags: %u, i_flags: %u\n", file->f_flags, inode->i_flags);
55
56
    if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL)
57
	return gres;
58
59
    if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
60
	WARN("lu_getname failed!\n");
61
	goto out;
62
    }
63
64
    flags = file->f_flags & O_ACCMODE;
65
    iov[0].iov_base = &flags;
66
    iov[0].iov_len = sizeof(flags);
67
    iov[1].iov_base = slot->s_buf;
68
    iov[1].iov_len = strlen(slot->s_buf) + 1;
69
70
    lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_OPEN, iov, 2, NULL, 0);
71
72
out:
73
    lu_putslot(slot);
74
75
    TRACE("out\n");
76
    return gres;
77
}
78
79
static int lu_file_release(struct inode *inode, struct file *file)
80
{
81
    int res;
82
    struct server_slot *slot;
83
    struct iovec iov;
84
85
    TRACE("in\n");
86
87
    if((slot = lu_getslot(GET_INFO(file->f_dentry->d_sb))) == NULL)
88
	return -ERESTARTSYS;
89
90
    if((res = lu_getname(file->f_dentry, slot->s_buf, LU_MAXPATHLEN)) < 0){
91
	WARN("lu_getname failed!\n");
92
	goto out;
93
    }
94
    
95
    iov.iov_base = slot->s_buf;
96
    iov.iov_len = strlen(slot->s_buf) + 1;
97
98
    if((res = lu_execute(GET_INFO(file->f_dentry->d_sb), slot, PTYPE_RELEASE, &iov, 1, NULL, 0)) < 0)
99
	goto out;
100
101
    if(PIS_ERROR(res)){
102
	TRACE("release failed\n");
103
	res = PERROR(res);
104
	goto out;
105
    }
106
    
107
    res = 0;
108
109
out:
110
    lu_putslot(slot);
111
112
    TRACE("out\n");
113
    return res;
114
}
115
116
static int lu_file_readpage(struct file *f, struct page *p)
117
{
118
    int res;
119
    struct iovec siov[3], riov;
120
    long long offset;
121
    unsigned long count;
122
    struct server_slot *slot;
123
124
    TRACE("in\n");
125
126
    if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
127
	return -ERESTARTSYS;
128
129
    get_page(p);
130
131
    if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
132
	WARN("lu_getname failed!\n");
133
	goto out;
134
    }
135
136
    offset = p->index << PAGE_CACHE_SHIFT;
137
    count = PAGE_SIZE;
138
139
    siov[0].iov_base = &offset;
140
    siov[0].iov_len = sizeof(offset);
141
    siov[1].iov_base = &count;
142
    siov[1].iov_len = sizeof(count);
143
    siov[2].iov_base = slot->s_buf;
144
    siov[2].iov_len = strlen(slot->s_buf) + 1;
145
146
    riov.iov_base = page_address(p);
147
    riov.iov_len = count;
148
149
    if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_READ, siov, 3, &riov, 1)) < 0)
150
	goto out;
151
152
    if(PIS_ERROR(res)){
153
	TRACE("read failed\n");
154
	res = PERROR(res);
155
	goto out;
156
    }
157
    
158
    flush_dcache_page(p);
159
    SetPageUptodate(p);
160
    res = 0;
161
    
162
  out:
163
    lu_putslot(slot);
164
    unlock_page(p);
165
    put_page(p);
166
        
167
    TRACE("out\n");
168
    return res;
169
}
170
171
static int lu_file_writepage(struct page *p, struct writeback_control *wbc)
172
{
173
    TRACE("in\n");
174
175
    TRACE("out\n");
176
    return -1;
177
}
178
179
static int lu_file_preparewrite(struct file *f, struct page *p, unsigned offset, unsigned to)
180
{
181
    TRACE("in\n");
182
183
    TRACE("out\n");
184
185
    return 0;
186
}
187
188
static int lu_file_commitwrite(struct file *f, struct page *p, unsigned offset, unsigned to)
189
{
190
    int res;
191
    struct server_slot *slot;
192
    struct iovec iov[4];
193
    char *buf;
194
    long long off;
195
    unsigned long cnt;
196
197
    TRACE("in\n");
198
199
    if((slot = lu_getslot(GET_INFO(f->f_dentry->d_sb))) == NULL)
200
	return -ERESTARTSYS;
201
202
    if((res = lu_getname(f->f_dentry, slot->s_buf, LU_MAXDATA)) < 0){
203
	WARN("lu_getname failed!\n");
204
	goto out2;
205
    }
206
207
    lock_kernel();
208
209
    buf = kmap(p) + offset;
210
    cnt = to - offset;
211
    off = offset + (((long long)p->index) << PAGE_CACHE_SHIFT);
212
213
    iov[0].iov_base = &off;
214
    iov[0].iov_len = sizeof(off);
215
    iov[1].iov_base = &cnt;
216
    iov[1].iov_len = sizeof(cnt);
217
    iov[2].iov_base = slot->s_buf;
218
    iov[2].iov_len = strlen(slot->s_buf) + 1;
219
    iov[3].iov_base = buf;
220
    iov[3].iov_len = cnt;
221
222
    TRACE("write %s, offset %Ld, count %d\n", slot->s_buf, off, (int)cnt);
223
224
    if((res = lu_execute(GET_INFO(f->f_dentry->d_sb), slot, PTYPE_WRITE, iov, 4, NULL, 0)) < 0)
225
	goto out1;
226
227
228
    if(PIS_ERROR(res)){
229
	TRACE("write failed\n");
230
	res = PERROR(res);
231
	goto out1;
232
    }
233
234
    f->f_dentry->d_inode->i_mtime = f->f_dentry->d_inode->i_atime = CURRENT_TIME;
235
    if(off + cnt > f->f_dentry->d_inode->i_size)
236
	f->f_dentry->d_inode->i_size = off + cnt;
237
238
    res = cnt;
239
240
  out1:
241
    kunmap(p);
242
    unlock_kernel();
243
  out2:
244
    lu_putslot(slot);
245
    TRACE("out\n");
246
    return res;
247
}
248
249
static int lu_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
250
{
251
    struct dentry *dentry = filp->f_dentry;
252
    int res;
253
254
    TRACE("in\n");
255
256
    if(!(res = lu_revalidate_inode(dentry)))
257
	res = generic_file_read(filp, buf, count, ppos);
258
259
    TRACE("out\n");
260
    
261
    return res;
262
}
263
264
static int lu_file_mmap(struct file *filp, struct vm_area_struct *vma)
265
{
266
    struct dentry *dentry = filp->f_dentry;
267
    int res;
268
269
    TRACE("in\n");
270
271
    if(!(res = lu_revalidate_inode(dentry)))
272
	res = generic_file_mmap(filp, vma);
273
274
    TRACE("out\n");
275
276
    return res;
277
}
278
279
static ssize_t lu_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
280
{
281
    struct dentry *dentry = filp->f_dentry;
282
    ssize_t res;
283
284
    TRACE("in\n");
285
286
    if(!(res = lu_revalidate_inode(dentry)) && (count > 0))
287
	res = generic_file_write(filp, buf, count, ppos);
288
289
    TRACE("out\n");
290
291
    return res;
292
}
293
294
static int lu_file_fsync(struct file *filp, struct dentry *dentryp, int datasync)
295
{    
296
    return 0;
297
}
298
299
struct file_operations lu_file_operations = {
300
    .llseek	= generic_file_llseek,
301
    .read	= lu_file_read,
302
    .write	= lu_file_write,
303
    .mmap	= lu_file_mmap,
304
    .open	= lu_file_open,
305
    .release	= lu_file_release,
306
    :fsync	= lu_file_fsync,
307
};
308
309
struct inode_operations lu_file_inode_operations = {
310
    .setattr	= lufs_notify_change,
311
};
312
313
struct address_space_operations lu_file_aops = {
314
    .readpage	       	= lu_file_readpage,
315
    .writepage		= lu_file_writepage,
316
    .prepare_write	= lu_file_preparewrite,
317
    .commit_write	= lu_file_commitwrite,
318
};
319
320
321
(-)kernel.orig/Linux/2.6/inode.c (+535 lines)
Line 0 Link Here
1
/*
2
 * inode.c
3
 * Copyright (C) 2002-2003 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <linux/version.h>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/init.h>
27
#include <linux/fs.h>
28
#include <linux/slab.h>
29
#include <linux/list.h>
30
#include <linux/smp_lock.h>
31
#include <linux/signal.h>
32
#include <linux/sched.h>
33
#include <linux/socket.h>
34
#include <linux/string.h>
35
#include <linux/vfs.h>
36
37
#include <asm/system.h>
38
#include <asm/uaccess.h>
39
40
#include "lufs.h"
41
#include "proc.h"
42
43
MODULE_AUTHOR("Florin Malita <mali@go.ro>");
44
MODULE_DESCRIPTION("Linux Userland Filesystem");
45
#ifdef MODULE_LICENSE
46
MODULE_LICENSE("GPL");
47
#endif
48
49
extern struct file_operations lu_dir_operations, lu_file_operations;
50
extern struct inode_operations lu_dir_inode_operations, lu_file_inode_operations, lu_symlink_inode_operations;
51
extern struct address_space_operations lu_file_aops;
52
extern struct dentry_operations lufs_dentry_operations;
53
54
static void lu_delete_inode(struct inode*);
55
static void lu_put_super(struct super_block*);
56
static int  lu_statfs(struct super_block*, struct statfs*);
57
58
static struct super_operations lu_sops = {
59
    .drop_inode		= generic_delete_inode,
60
    .delete_inode	= lu_delete_inode,
61
    .put_super		= lu_put_super,
62
    .statfs		= lu_statfs,
63
};
64
65
66
/*
67
 * Ignore unknown options, they're probably for the userspace daemon.
68
 */
69
static void parse_options(struct lufs_sb_info *server, char *opts)
70
{
71
    char *p, *q;
72
    int len;
73
74
    if(!opts)
75
	return;
76
77
    len = strlen(opts);
78
79
    while((p = strsep(&opts, ","))){
80
	if(strncmp(p, "server_socket=", 14) == 0){
81
	    if(strlen(p+14) > UNIX_PATH_MAX)
82
		goto ugly_opts;
83
	    strcpy(server->server_socket, p+14);
84
	    TRACE("server_socket: %s\n", server->server_socket);
85
	}else 
86
	if(strncmp(p, "uid=", 4) == 0){
87
	    if(current->uid)
88
		ERROR("only root can use uid option!\n");
89
	    else{
90
		if(strlen(p+4) > 5)
91
		    goto ugly_opts;
92
		q = p + 4;
93
		server->config.uid = simple_strtoul(q, &q, 0);
94
		TRACE("uid: %d\n", server->config.uid); 
95
	    }
96
	}else
97
	if(strncmp(p, "gid=", 4) == 0){
98
	    if(current->uid)
99
		ERROR("only root can use gid option!\n");
100
	    else{
101
		if(strlen(p+4) > 5)
102
		    goto ugly_opts;
103
		q = p + 4;
104
		server->config.gid = simple_strtoul(q, &q, 0);
105
		TRACE("gid: %d\n", server->config.gid); 
106
	    }
107
	}else
108
	if(strncmp(p, "fmask=", 6) == 0){
109
	    if(strlen(p + 6) > 3)
110
		goto ugly_opts;
111
	    q = p + 6;
112
	    server->config.fmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO);
113
	    TRACE("fmode: %d\n", server->config.fmode);
114
	}else
115
	if(strncmp(p, "dmask=", 6) == 0){
116
	    if(strlen(p + 6) > 3)
117
		goto ugly_opts;
118
	    q = p + 6;
119
	    server->config.dmode = (((q[0] - '0') << 6) + ((q[1] - '0') << 3) + (q[2] - '0')) & (S_IRWXU | S_IRWXG | S_IRWXO);
120
	    TRACE("dmode: %d\n", server->config.dmode);
121
	}else
122
	if(strncmp(p, "root=", 5) == 0){
123
	    if(strlen(p+5) >= UNIX_PATH_MAX - 1)
124
		goto ugly_opts;
125
	    strcpy(server->root, p+5);
126
	    server->rootlen = strlen(server->root);
127
	    
128
	    if(server->root[server->rootlen - 1] == '/'){
129
		server->root[server->rootlen - 1] = 0;
130
		server->rootlen--;
131
	    }
132
			    
133
	    TRACE("remote root: %s, len: %u\n", server->root, server->rootlen);
134
	}else
135
	if(strncmp(p, "channels=", 9) == 0){
136
	    if(strlen(p+9) > 5)
137
		goto ugly_opts;
138
	    q = p + 9;
139
	    server->config.channels = simple_strtoul(q, &q, 0);
140
	    
141
	    TRACE("channels: %u\n", server->config.channels);
142
	}else
143
	if(strncmp(p, "own_fs", 6) == 0){
144
	    server->config.own_fs = 1;
145
	    TRACE("forcing ownership\n");
146
	}else
147
	if(strncmp(p, "server_pid=", 11) == 0){
148
	    if(strlen(p+11) > 7)
149
		goto ugly_opts;
150
	    q = p + 11;
151
	    server->server_pid = simple_strtoul(q, &q, 0);
152
153
	    TRACE("server_pid: %u\n", server->server_pid);
154
	}
155
    }
156
157
    return;
158
159
  ugly_opts:
160
    WARN("evil options!\n");
161
}
162
163
/*
164
 * Fill in inode attributes. 
165
 * Ivalidate the page_cache pages if the inode has been modified.
166
 */
167
static void set_inode_attr(struct inode *inode, struct lufs_fattr *fattr)
168
{
169
    time_t last_time = inode->i_mtime.tv_sec;
170
    loff_t last_sz = inode->i_size;
171
172
    TRACE("in\n");
173
    
174
    inode->i_mode = fattr->f_mode;
175
    inode->i_nlink = fattr->f_nlink;
176
    inode->i_uid = fattr->f_uid;
177
    inode->i_gid = fattr->f_gid;
178
    inode->i_ctime.tv_sec = fattr->f_ctime;
179
    inode->i_mtime.tv_sec = fattr->f_mtime;
180
    inode->i_atime.tv_sec = fattr->f_atime;
181
    inode->i_blksize = fattr->f_blksize;
182
    inode->i_blocks = fattr->f_blocks;
183
    inode->i_size = fattr->f_size;
184
185
    if(inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz){
186
	TRACE("inode changed...\n");
187
	if(!S_ISDIR(inode->i_mode))
188
	    invalidate_inode_pages(inode->i_mapping);
189
    }
190
191
    TRACE("out\n");
192
}
193
194
static int lu_do_stat(struct dentry *dentry, struct lufs_fattr *fattr)
195
{
196
    struct server_slot *slot;
197
    struct iovec siov, riov;
198
    int res;
199
200
    TRACE("in\n");
201
202
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
203
	return -ERESTARTSYS;
204
205
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
206
	WARN("lu_getname failed!\n");
207
	goto out;
208
    }
209
210
    TRACE("stating %s...\n", slot->s_buf);
211
212
    siov.iov_base = slot->s_buf;
213
    siov.iov_len = strlen(slot->s_buf) + 1;
214
    riov.iov_base = fattr;
215
    riov.iov_len = sizeof(struct lufs_fattr);
216
217
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0)
218
	goto out;
219
220
    if(PIS_ERROR(res)){
221
	WARN("stat failed!\n");
222
	res = PERROR(res);
223
	goto out;
224
    }
225
226
    lu_fixattrs(GET_INFO(dentry->d_sb), fattr);
227
228
    res = 0;
229
230
  out:
231
    TRACE("out\n");
232
    lu_putslot(slot);
233
    return res;
234
}
235
236
/*
237
 * Reload inode attributes.
238
 */
239
static int lu_refresh_inode(struct dentry *dentry)
240
{
241
    struct inode *inode = dentry->d_inode;
242
    struct lufs_fattr fattr;
243
    int res;
244
245
    TRACE("in\n");
246
247
    if((res = lu_do_stat(dentry, &fattr)) < 0)
248
	return res;
249
250
    dentry->d_time = jiffies;
251
252
    if(!inode)
253
	return 0;
254
255
    if((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
256
	set_inode_attr(inode, &fattr);
257
    else{
258
	WARN("inode changed mode, %x to %x\n", inode->i_mode, (unsigned int)fattr.f_mode);
259
	TRACE("oops!\n");
260
	
261
	fattr.f_mode = inode->i_mode;
262
	make_bad_inode(inode);
263
	inode->i_mode = fattr.f_mode;
264
265
	if(!S_ISDIR(inode->i_mode))
266
	    invalidate_inode_pages(inode->i_mapping);
267
	    
268
	return -EIO;
269
    }
270
271
    TRACE("out\n");
272
    return 0;
273
}
274
275
int lu_revalidate_inode(struct dentry *dentry)
276
{
277
    int res = 0;
278
279
    TRACE("in\n");
280
    
281
    lock_kernel();
282
    
283
    if(time_before(jiffies, dentry->d_time + LU_MAXAGE))
284
	goto out;
285
286
    res = lu_refresh_inode(dentry);
287
288
  out:
289
    TRACE("out\n");
290
    unlock_kernel();
291
    return res;
292
}
293
294
int lufs_notify_change(struct dentry *dentry, struct iattr *iattr)
295
{
296
    struct server_slot *slot;
297
    struct iovec iov[2];
298
    struct lufs_fattr fattr;
299
    int res;
300
301
    TRACE("in\n");
302
303
    if((res = lu_do_stat(dentry, &fattr)) < 0)
304
	return res;
305
306
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
307
	return -ERESTARTSYS;
308
309
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
310
	WARN("lu_getname failed!\n");
311
	goto out;
312
    }
313
    
314
    if(iattr->ia_valid & ATTR_MODE)
315
	fattr.f_mode = iattr->ia_mode;
316
    if(iattr->ia_valid & ATTR_UID)
317
	fattr.f_uid  = iattr->ia_uid;
318
    if(iattr->ia_valid & ATTR_GID)
319
	fattr.f_gid  = iattr->ia_gid;
320
    if(iattr->ia_valid & ATTR_SIZE)
321
	fattr.f_size = iattr->ia_size;
322
    if(iattr->ia_valid & ATTR_ATIME)
323
	fattr.f_atime= iattr->ia_atime.tv_sec;
324
    if(iattr->ia_valid & ATTR_MTIME)
325
	fattr.f_mtime= iattr->ia_mtime.tv_sec;
326
    if(iattr->ia_valid & ATTR_CTIME)
327
	fattr.f_ctime= iattr->ia_ctime.tv_sec;
328
329
    iov[0].iov_base = &fattr;
330
    iov[0].iov_len = sizeof(struct lufs_fattr);
331
    iov[1].iov_base = slot->s_buf;
332
    iov[1].iov_len = strlen(slot->s_buf) + 1;
333
334
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_SETATTR, iov, 2, NULL, 0)) < 0)
335
	goto out;
336
337
    if(PIS_ERROR(res)){
338
	WARN("setattr failed!\n");
339
	res = PERROR(res);
340
	goto out;
341
    }
342
343
    res = 0;
344
345
    lu_refresh_inode(dentry);
346
347
  out:
348
    TRACE("out\n");
349
    lu_putslot(slot);
350
    return res;
351
}
352
353
/*
354
 * We always create a new inode here.
355
 */
356
struct inode* lu_iget(struct super_block *sb, struct lufs_fattr *fattr)
357
{
358
    struct inode *res;
359
360
    TRACE("in\n");
361
    
362
    res = new_inode(sb);
363
    if(!res)
364
	return NULL;
365
    res->i_ino = fattr->f_ino;
366
    set_inode_attr(res, fattr);
367
368
    if(S_ISDIR(res->i_mode)){
369
	TRACE("it's a dir.\n");
370
	res->i_op = &lu_dir_inode_operations;
371
	res->i_fop = &lu_dir_operations;
372
    }else if(S_ISLNK(res->i_mode)){
373
	TRACE("it's a link.\n");
374
	res->i_op = &lu_symlink_inode_operations;
375
    }else{
376
	TRACE("it's a file.\n");
377
	res->i_op = &lu_file_inode_operations;
378
	res->i_fop = &lu_file_operations;
379
	res->i_data.a_ops = &lu_file_aops;
380
    }
381
	
382
    insert_inode_hash(res);
383
    return res;
384
}
385
386
static int lu_statfs(struct super_block *sb, struct statfs *attr)
387
{
388
    TRACE("in\n");
389
    
390
    attr->f_type = LU_MAGIC;
391
    attr->f_bsize = LU_BLOCKSIZE;
392
    attr->f_blocks = 0;
393
    attr->f_namelen = LU_MAXPATHLEN;
394
    attr->f_files = -1;
395
    attr->f_bavail = -1;
396
397
    TRACE("out\n");
398
    return 0;
399
}
400
401
static void lu_put_super(struct super_block *sb)
402
{
403
    struct siginfo info;
404
405
    TRACE("in\n");
406
407
    info.si_signo = SIGUSR1;
408
    info.si_errno = 0;
409
    info.si_code = SI_USER;
410
    info.si_pid = current->pid;
411
    info.si_uid = current->uid;
412
    
413
    /* notify the daemon that we're going bye-bye */
414
    kill_proc_info(SIGUSR1, &info, GET_INFO(sb)->server_pid);
415
416
    lu_empty_slots(GET_INFO(sb));
417
    kfree(GET_INFO(sb));
418
    TRACE("out\n");
419
}
420
421
static void lu_delete_inode(struct inode *in)
422
{
423
    TRACE("in\n");
424
    clear_inode(in);
425
    TRACE("out\n");
426
}
427
428
static int lu_fill_super(struct super_block *sb, void *opts, int silent)
429
{
430
    struct lufs_sb_info *info;
431
    struct server_slot *slot;
432
    struct lufs_fattr root_attr;
433
    struct inode *root_inode;
434
435
    int i;
436
437
    TRACE("in\n");
438
    
439
    if(!opts){
440
	ERROR("need some options here!\n");
441
	goto out;
442
    }
443
    
444
    if((info = (struct lufs_sb_info*)kmalloc(sizeof(struct lufs_sb_info), GFP_KERNEL)) == NULL){
445
	ERROR("kmalloc error!\n");
446
	goto out;
447
    }
448
    memset(info, 0, sizeof(struct lufs_sb_info));
449
    info->lock = RW_LOCK_UNLOCKED;
450
    INIT_LIST_HEAD(&info->slots);
451
452
    info->config.uid = current->uid;
453
    info->config.gid = current->gid;    
454
    info->config.channels = LU_NRSLOTS;
455
    
456
    parse_options(info, opts);
457
    
458
    if(!info->server_socket[0]){
459
	ERROR("no server_socket specified!\n");
460
	goto out_info;
461
    }
462
    
463
    for(i = 0; i < info->config.channels; i++){
464
	if((slot = kmalloc(sizeof(struct server_slot), GFP_KERNEL)) == NULL){
465
	    ERROR("kmalloc error!\n");
466
	    goto out_slots;
467
	}
468
	memset(slot, 0, sizeof(struct server_slot));
469
	init_MUTEX(&slot->s_lock);
470
	if((slot->s_buf = kmalloc(LU_MAXDATA, GFP_KERNEL)) == NULL){
471
	    ERROR("kmalloc error!\n");
472
	    goto out_slots;
473
	}
474
	list_add(&slot->s_list, &info->slots);
475
    }
476
477
    sb->s_fs_info = info;
478
    sb->s_blocksize = LU_BLOCKSIZE;
479
    sb->s_blocksize_bits = LU_BLOCKSIZEBITS;
480
    sb->s_magic = LU_MAGIC;
481
    sb->s_op = &lu_sops;
482
    sb->s_flags = 0;
483
    sb->s_maxbytes = ((((long long)1) << 32) << LU_BLOCKSIZEBITS) - 1;
484
    TRACE("sb->s_maxbytes=%Ld\n",sb->s_maxbytes);
485
486
    lu_lookup_root(info, &root_attr);
487
    root_inode = lu_iget(sb, &root_attr);
488
    if(!root_inode)
489
	goto out_slots;
490
    sb->s_root = d_alloc_root(root_inode);
491
    if(!sb->s_root)
492
	goto out_slots;
493
494
    sb->s_root->d_op = &lufs_dentry_operations;
495
    sb->s_root->d_time = jiffies;
496
497
    TRACE("mount succeded: %s\n", info->server_socket);
498
    return 0;
499
500
 out_slots:
501
    lu_empty_slots(info);
502
 out_info:
503
    kfree(info);
504
 out:
505
    ERROR("mount failed!\n");
506
    return -EINVAL;
507
}
508
509
static struct super_block *lu_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data)
510
{
511
    return get_sb_nodev(fs_type, flags, data, lu_fill_super);
512
}
513
514
static struct file_system_type lu_fs_type = {
515
    .owner	= THIS_MODULE,
516
    .name	= "lufs",
517
    .get_sb	= lu_get_sb,
518
    .kill_sb	= kill_anon_super,
519
};
520
521
static int __init lu_init(void)
522
{
523
    VERBOSE("UserLand File System\n");
524
    VERBOSE("Copyright (c) 2002, Florin Malita\n");
525
    return register_filesystem(&lu_fs_type);
526
}
527
528
static void __exit lu_release(void)
529
{
530
    VERBOSE("Unregistering lufs...\n");
531
    unregister_filesystem(&lu_fs_type);
532
}
533
534
module_init(lu_init);
535
module_exit(lu_release);
(-)kernel.orig/Linux/2.6/lufs.h (+87 lines)
Line 0 Link Here
1
/*
2
 * lufs.h
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#ifndef _LUFS_H_
24
#define _LUFS_H_
25
26
#include <linux/list.h>
27
#include <linux/un.h>
28
#include <linux/spinlock.h>
29
30
#include "../../../include/lufs/proto.h"
31
32
#undef TRACE
33
#undef WARN
34
#undef VERBOSE
35
#undef ERROR
36
37
#ifdef LUFS_DEBUG
38
#define TRACE(x...) 	do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0)
39
#define WARN(x...) 	do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0)
40
#else
41
#define TRACE(x...) 	do {} while(0)
42
#define WARN(x...)	do {} while(0)
43
#endif
44
45
#ifdef LUFS_VERBOSE
46
#define VERBOSE(x...) 	do { printk(KERN_INFO "(%s) - ", __func__); printk(x); } while(0)
47
#else
48
#define VERBOSE(x...)	do {} while(0)
49
#endif
50
51
#define ERROR(x...) 	do { printk(KERN_ERR "(%s) - ", __func__); printk(x); } while(0)
52
53
#define GET_INFO(sb)	((struct lufs_sb_info*)sb->s_fs_info)
54
55
#define LU_MAXPATHLEN	1024
56
#define LU_MAXTRIES	10
57
#define LU_MAXIOVEC	5
58
#define LU_NRSLOTS	3
59
#define LU_MAGIC	0xfade
60
#define LU_MAXAGE	HZ*5
61
62
#define LU_DEF_UID	2
63
#define LU_DEF_GID	2
64
65
#define LU_BLOCKSIZE	512
66
#define LU_BLOCKSIZEBITS	9
67
68
struct lufs_config{
69
    __kernel_uid_t 	uid;
70
    __kernel_gid_t	gid;
71
    __kernel_mode_t	fmode;
72
    __kernel_mode_t	dmode;
73
    unsigned 		channels;
74
    int			own_fs;
75
};
76
77
struct lufs_sb_info{
78
    struct list_head	slots;
79
    struct lufs_config	config;
80
    rwlock_t		lock;
81
    char 		server_socket[UNIX_PATH_MAX];
82
    pid_t		server_pid;
83
    char		root[UNIX_PATH_MAX];
84
    unsigned 		rootlen;
85
};
86
87
#endif
(-)kernel.orig/Linux/2.6/proc.c (+505 lines)
Line 0 Link Here
1
/*
2
 * proc.c
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <linux/version.h>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/fs.h>
27
#include <linux/slab.h>
28
#include <linux/socket.h>
29
#include <linux/un.h>
30
#include <linux/types.h>
31
#include <linux/list.h>
32
#include <linux/smp_lock.h>
33
#include <linux/net.h>
34
#include <linux/vfs.h>
35
#include <linux/mount.h>
36
37
#include <asm/system.h>
38
#include <asm/uaccess.h>
39
40
#include "lufs.h"
41
#include "proc.h"
42
43
static int sock_send(struct socket *sock, struct iovec *iov, int len)
44
{
45
    struct msghdr msg = {
46
	.msg_name	= NULL,
47
	.msg_namelen	= 0,
48
	.msg_iov	= iov,
49
	.msg_iovlen	= len,
50
	.msg_control	= NULL,
51
	.msg_controllen	= 0,
52
	.msg_flags	= 0
53
    };
54
    int res, i, size;
55
    mm_segment_t fs;
56
57
    for(i = 0, size = 0; i < len; i++)
58
	size += iov[i].iov_len;
59
    
60
    fs = get_fs();
61
    set_fs(get_ds());
62
    res = sock_sendmsg(sock, &msg, size);
63
    set_fs(fs);
64
65
    return res;
66
}
67
68
static int sock_recv(struct socket *sock, struct iovec *iov, int len, int rsize, unsigned flags)
69
{
70
    struct msghdr msg = {
71
	.msg_flags	= flags,
72
	.msg_name	= NULL,
73
	.msg_namelen	= 0,
74
	.msg_iov	= iov,
75
	.msg_iovlen	= len,
76
	.msg_control	= NULL,
77
	.msg_controllen	= 0
78
    };
79
    mm_segment_t fs;
80
    int res, i, size;
81
82
    for(i = 0, size = 0; i < len; i++)
83
	size += iov[i].iov_len;
84
85
    if(size < rsize){
86
	VERBOSE("Trying to overflow old me?! Truncating...\n");
87
	rsize = size;
88
    }
89
90
    fs = get_fs();
91
    set_fs(get_ds());
92
    res = sock_recvmsg(sock, &msg, rsize, flags);
93
    set_fs(fs);
94
95
    return res;
96
}
97
98
static int sock_connect(char *path, struct socket **s)
99
{
100
    struct sockaddr_un addr;
101
    int res;
102
103
    if(strlen(path) > UNIX_PATH_MAX - 1){
104
	WARN("unix domain path too long: %s", path);
105
	return -1;
106
    }
107
108
    addr.sun_family = AF_UNIX;
109
    strcpy(addr.sun_path, path);
110
111
    if((res = sock_create(PF_UNIX, SOCK_STREAM, 0, s)) < 0){
112
	WARN("failed to create a unix domain socket!\n");
113
	return res;
114
    }
115
116
    if((res = (*s)->ops->connect(*s, (struct sockaddr*)&addr, sizeof(addr), 0)) < 0){
117
	WARN("failed to connect the socket: %d!\n", res);
118
	return res;
119
    }
120
    return 0;
121
}
122
123
static int slot_reconnect(struct lufs_sb_info *info, struct server_slot *slot)
124
{
125
    int res = 0, tries = 0;
126
127
    if(slot->s_sock){
128
	TRACE("closing socket.\n");
129
	sock_release(slot->s_sock);
130
	slot->s_sock = NULL;
131
    }
132
133
    while(tries++ < LU_MAXTRIES && (res = sock_connect(info->server_socket, &slot->s_sock)) < 0){
134
	TRACE("retrying...\n");
135
	sock_release(slot->s_sock);
136
	slot->s_sock = NULL;
137
    }
138
139
    if(res >= 0){
140
	TRACE("successfully reconnected.\n");
141
    }
142
143
    return res;
144
}
145
146
void lu_empty_slots(struct lufs_sb_info *info)
147
{
148
    struct server_slot *slot;
149
150
    while(!list_empty(&info->slots)){
151
	slot = list_entry(info->slots.next, struct server_slot, s_list);
152
	if(slot->s_sock)
153
	    sock_release(slot->s_sock);
154
	list_del(&slot->s_list);
155
	if(slot->s_buf)
156
	    kfree(slot->s_buf);
157
	kfree(slot);
158
    }
159
}
160
161
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)
162
{
163
    struct lu_msg msg;
164
    struct iovec iov;
165
    int res;
166
167
    TRACE("msg_len: %d\n", msglen);
168
    
169
    msg.msg_version = PVERSION;
170
    msg.msg_type = cmd;
171
    msg.msg_datalen = msglen;
172
    msg.msg_pid = current->pid;
173
174
    iov.iov_base = &msg;
175
    iov.iov_len = sizeof(struct lu_msg);
176
177
    if((res = sock_send(sock, &iov, 1)) < 0){
178
	WARN("sock_send failed!\n");
179
	return res;
180
    }
181
    if((res = sock_send(sock, siov, slen)) < 0){
182
	WARN("sock_send failed!\n");
183
	return res;
184
    }
185
186
    iov.iov_base = &msg;
187
    iov.iov_len = sizeof(struct lu_msg);
188
    if((res = sock_recv(sock, &iov, 1, sizeof(struct lu_msg), 0)) < 0){
189
	WARN("sock_recv failed!\n");
190
	return res;
191
    }
192
    if(res != sizeof(struct lu_msg)){
193
	WARN("Ayeeee, didn't read a whole header!\n");
194
	return -EBUSY;
195
    }
196
    
197
    if((msg.msg_datalen == 0))
198
	return msg.msg_type;
199
200
    if(riov == NULL){
201
	WARN("Unexpected data!!! Getting out of sync...\n");
202
	return -1;
203
    }
204
	
205
    if((res = sock_recv(sock, riov, rlen, msg.msg_datalen, 0)) < 0){
206
	WARN("sock_recv failed!\n");
207
	return res;
208
    }
209
210
    return msg.msg_type;
211
}
212
213
struct server_slot* lu_getslot(struct lufs_sb_info *info)
214
{
215
    struct list_head *p, *nd_best = NULL;
216
    struct server_slot *slot;
217
    int gotlock = 0;
218
219
    /* Look for a slot used by this process before */
220
    read_lock(&info->lock);
221
    list_for_each(p, &info->slots)
222
	if(list_entry(p, struct server_slot, s_list)->s_lastpid == current->pid){
223
	    TRACE("found a previous used slot for %u.\n", current->pid);
224
	    if(down_trylock(&list_entry(p, struct server_slot, s_list)->s_lock) == 0){
225
		gotlock = 1;
226
		break;
227
	    }
228
	    TRACE("oops! I still hold the lock! forget this one...\n");
229
	}else 
230
	    if(!nd_best){
231
		nd_best = p;
232
	    }
233
234
    /* if we couldn't find one, take the first not locked by us */	
235
    if(p == &info->slots){
236
	if(!nd_best){
237
	    ERROR("deadlock: all locks owned by us!\n");
238
	    read_unlock(&info->lock);
239
	    return NULL;
240
	}else
241
	    p = nd_best;
242
	
243
    }
244
    read_unlock(&info->lock);
245
246
    slot = list_entry(p, struct server_slot, s_list);
247
    
248
    /* Get the lock on that slot */
249
    if(!gotlock)
250
	if(down_interruptible(&slot->s_lock))
251
	    return NULL;
252
253
    slot->s_lastpid = current->pid;
254
255
    /* Move it to the tail */
256
    write_lock(&info->lock);
257
    list_del(p);
258
    list_add_tail(p, &info->slots);
259
    write_unlock(&info->lock);
260
261
    return slot;
262
}
263
264
void lu_putslot(struct server_slot *slot)
265
{
266
    up(&slot->s_lock);
267
}
268
269
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)
270
{
271
    int res, i, msglen;
272
    struct iovec bkup[LU_MAXIOVEC];
273
274
    for(i = 0, msglen = 0; i < slen; i++){
275
	bkup[i] = siov[i];
276
	msglen += siov[i].iov_len;
277
    }
278
279
    if(slot->s_sock == NULL){
280
	TRACE("slot not connected.\n");
281
	if((res = slot_reconnect(info, slot)) < 0){
282
	    ERROR("failed to connect!\n");
283
	    goto out;
284
	}
285
    }
286
287
    if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){
288
	TRACE("do_execute failed!\n");
289
290
	if(signal_pending(current) && (!sigismember(&current->pending.signal, SIGPIPE))){
291
	    TRACE("interrupted by a signal. disconnecting this slot...\n");
292
	    sock_release(slot->s_sock);
293
	    slot->s_sock = NULL;
294
	    goto out;
295
	}
296
	
297
	if(sigismember(&current->pending.signal, SIGPIPE)){
298
	    TRACE("got a SIGPIPE\n");
299
	    sigdelset(&current->pending.signal, SIGPIPE);
300
	}
301
302
	if((res = slot_reconnect(info, slot)) < 0){
303
	    ERROR("could't reconnect!\n");
304
	    goto out;
305
	}
306
	    
307
	for(i = 0; i < slen; i++)
308
	    siov[i] = bkup[i];
309
	        
310
	if((res = do_execute(slot->s_sock, cmd, msglen, siov, slen, riov, rlen)) < 0){
311
	    ERROR("error executing command!\n");
312
	    goto out;
313
	}
314
    }
315
    
316
 out:
317
    return res;
318
}
319
320
int lu_getname(struct dentry *d, char *name, int max)
321
{
322
    int len = 0;
323
    struct dentry *p;
324
    struct lufs_sb_info *info = GET_INFO(d->d_sb);
325
    
326
    for(p = d; p != p->d_parent; p = p->d_parent)
327
	len += p->d_name.len + 1;
328
329
    TRACE("root: %s, rootlen: %d, namelen: %d\n", info->root, info->rootlen, len);
330
    
331
    if(len + info->rootlen > max)
332
	return -1;
333
334
    strcpy(name, info->root);
335
336
    if(len + info->rootlen == 0){
337
	strcat(name, "/");
338
    	goto out;
339
    }
340
    
341
    len += info->rootlen;
342
343
    name[len] = 0;
344
    for(p = d; p != p->d_parent; p = p->d_parent){
345
	len -= p->d_name.len;
346
	strncpy(&(name[len]), p->d_name.name, p->d_name.len);
347
	name[--len] = '/';
348
    }
349
350
out:
351
    TRACE("name resolved to %s\n", name);
352
    return 0;
353
}
354
355
int lu_getname_dumb(struct dentry *d, char *name, int max)
356
{
357
    int len = 0;
358
    struct dentry *p;
359
360
    for(p = d; p != p->d_parent; p = p->d_parent)
361
	len += p->d_name.len + 1;
362
363
    if(len > max)
364
	return -1;
365
366
    if(len == 0){
367
	name[0] = '/';
368
	name[1] = 0;
369
	goto out;
370
    }
371
372
    name[len] = 0;
373
    for(p = d; p != p->d_parent; p = p->d_parent){
374
	len -= p->d_name.len;
375
	strncpy(&(name[len]), p->d_name.name, p->d_name.len);
376
	name[--len] = '/';
377
    }
378
379
out:
380
    return 0;
381
}
382
383
static void init_root_dirent(struct lufs_sb_info *server, struct lufs_fattr *fattr)
384
{
385
    memset(fattr, 0, sizeof(struct lufs_fattr));
386
    fattr->f_nlink = 1;
387
    fattr->f_uid = server->config.uid;
388
    fattr->f_gid = server->config.gid;
389
    fattr->f_blksize = 512;
390
    fattr->f_ino = 2;
391
    fattr->f_mtime = CURRENT_TIME.tv_sec;
392
    fattr->f_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH | S_IFDIR | server->config.dmode;
393
    fattr->f_size = 512;
394
    fattr->f_blocks = 1;
395
}
396
397
void lu_lookup_root(struct lufs_sb_info *server, struct lufs_fattr *fattr)
398
{
399
    struct server_slot *slot;
400
    struct iovec siov, riov;
401
    int res;
402
403
    TRACE("in\n");
404
405
    if((slot = lu_getslot(server)) == NULL){
406
	init_root_dirent(server, fattr);
407
	return;
408
    }
409
    
410
    if(server->rootlen)
411
	strcpy(slot->s_buf, server->root);
412
    else
413
	strcpy(slot->s_buf, "/");
414
	
415
    TRACE("stating root %s\n", slot->s_buf);
416
417
    siov.iov_base = slot->s_buf;
418
    siov.iov_len = strlen(slot->s_buf) + 1;
419
    riov.iov_base = fattr;
420
    riov.iov_len = sizeof(struct lufs_fattr);
421
422
    if((res = lu_execute(server, slot, PTYPE_STAT, &siov, 1, &riov, 1)) < 0){
423
	init_root_dirent(server, fattr);
424
	goto out;
425
    }
426
427
    if(PIS_ERROR(res)){
428
	WARN("stat failed!\n");
429
	init_root_dirent(server, fattr);
430
	goto out;
431
    }
432
433
    lu_fixattrs(server, fattr);
434
435
    fattr->f_ino = 2;
436
437
  out:
438
    TRACE("out\n");
439
    lu_putslot(slot);
440
}
441
442
void lu_fixattrs(struct lufs_sb_info *info, struct lufs_fattr *fattr)
443
{
444
445
    fattr->f_blksize = LU_BLOCKSIZE;
446
    
447
    if(S_ISREG(fattr->f_mode) || S_ISDIR(fattr->f_mode))
448
	fattr->f_blocks = (fattr->f_size + LU_BLOCKSIZE - 1) / LU_BLOCKSIZE;
449
    else
450
	fattr->f_blocks = 0;
451
452
    if(info->config.own_fs){
453
454
	if(!fattr->f_uid)
455
	    fattr->f_mode = (fattr->f_mode & ~S_IRWXU) | ((fattr->f_mode & S_IRWXO)*(S_IRWXU/S_IRWXO));
456
457
	if(!fattr->f_gid)
458
	    fattr->f_mode = (fattr->f_mode & ~S_IRWXG) | ((fattr->f_mode & S_IRWXO)*(S_IRWXG/S_IRWXO));
459
	
460
	fattr->f_uid = info->config.uid;
461
	fattr->f_gid = info->config.gid;
462
463
    }else{
464
	
465
	if(fattr->f_uid)
466
	    fattr->f_uid = info->config.uid;
467
	else
468
	    fattr->f_uid = LU_DEF_UID;
469
470
	if(fattr->f_gid)
471
	    fattr->f_gid = info->config.gid;
472
	else
473
	    fattr->f_gid = LU_DEF_GID;
474
    }
475
476
    if(fattr->f_mode & S_IFDIR)
477
	fattr->f_mode |= info->config.dmode;
478
    else
479
	fattr->f_mode |= info->config.fmode;
480
}
481
482
void lu_xlate_symlink(char *link, char *target, char *buf)
483
{
484
    int i;
485
    char *c1, *c2 = link;
486
487
    TRACE("translating %s->%s\n", link, target);
488
489
    for(c1 = strchr(link, '/'); c1 && !strncmp(link, target, c1 - link); c2 = c1, c1 = strchr(c1 + 1, '/'));
490
491
    TRACE("disjoint paths: %s, %s\n", c2, target + (c2 - link));
492
493
    for(i = 0, c1 = c2; (c1 = strchr(c1 + 1, '/')); i++);
494
495
    strcpy(buf, "./");
496
    
497
    for(; i > 0; i--)
498
	strcat(buf, "../");
499
500
    strcat(buf, target + (c2 - link) + 1);
501
    
502
    TRACE("absolute link resolved to %s\n", buf);
503
   
504
}
505
(-)kernel.orig/Linux/2.6/proc.h (+51 lines)
Line 0 Link Here
1
/*
2
 * proc.h
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#ifndef _LU_PROC_H_
24
#define _LU_PROC_H_
25
26
#include <linux/types.h>
27
#include <linux/list.h>
28
#include <linux/socket.h>
29
30
struct server_slot{
31
    struct socket	*s_sock;
32
    struct semaphore 	s_lock;
33
    struct list_head 	s_list;
34
    pid_t 		s_lastpid;
35
    char		*s_buf;
36
};
37
38
struct lufs_fattr;
39
40
int lu_execute(struct lufs_sb_info*, struct server_slot*, unsigned short, struct iovec*, unsigned short, struct iovec*, unsigned short);
41
void lu_empty_slots(struct lufs_sb_info*);
42
int lu_getname(struct dentry*, char*, int);
43
int lu_getname_dumb(struct dentry*, char*, int);
44
struct server_slot* lu_getslot(struct lufs_sb_info*);
45
void lu_putslot(struct server_slot*);
46
int lu_revalidate_inode(struct dentry*);
47
void lu_lookup_root(struct lufs_sb_info*, struct lufs_fattr*);
48
void lu_fixattrs(struct lufs_sb_info*, struct lufs_fattr*);
49
void lu_xlate_symlink(char*, char*, char*);
50
51
#endif
(-)kernel.orig/Linux/2.6/symlink.c (+184 lines)
Line 0 Link Here
1
/*
2
 * symlink.c
3
 * Copyright (C) 2002 Florin Malita <mali@go.ro>
4
 *
5
 * This file is part of LUFS, a free userspace filesystem implementation.
6
 * See http://lufs.sourceforge.net/ for updates.
7
 *
8
 * LUFS is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * LUFS is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <linux/version.h>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/slab.h>
27
#include <linux/socket.h>
28
#include <linux/smp_lock.h>
29
#include <linux/fs.h>
30
31
#include <asm/uaccess.h>
32
#include <asm/system.h>
33
34
35
#include "lufs.h"
36
#include "proc.h"
37
38
static char failed_link[] = "invalid";
39
40
static int lu_readlink(struct dentry *dentry, char *buffer, int bufflen)
41
{
42
    struct server_slot *slot;
43
    struct iovec siov, riov;
44
    int res;
45
    char *cc = failed_link;
46
47
    TRACE("in\n");
48
49
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
50
	return vfs_readlink(dentry, buffer, bufflen, cc);
51
52
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
53
	WARN("lu_getname failed!\n");
54
	goto out;
55
    }
56
57
    siov.iov_base = slot->s_buf;
58
    siov.iov_len = strlen(slot->s_buf) + 1;
59
    riov.iov_base = &slot->s_buf[LU_MAXPATHLEN];
60
    riov.iov_len = LU_MAXPATHLEN;
61
62
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0)
63
	goto out;
64
65
    if(PIS_ERROR(res)){
66
	TRACE("read_link failed.\n");
67
	res = PERROR(res);
68
	goto out;
69
    }
70
71
    cc = &slot->s_buf[LU_MAXPATHLEN];
72
    
73
    TRACE("response: %s\n", cc);
74
    
75
    if(*cc == '/'){
76
	if(GET_INFO(dentry->d_sb)->rootlen){
77
	    if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){
78
		WARN("symlink outside mounted root!");
79
		cc = failed_link;
80
		goto out;
81
	    }
82
	    cc += GET_INFO(dentry->d_sb)->rootlen;
83
	}
84
85
	lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf);
86
87
	cc = slot->s_buf;
88
89
    }
90
91
92
93
  out:
94
    res = vfs_readlink(dentry, buffer, bufflen, cc);
95
96
    lu_putslot(slot);
97
98
    TRACE("out\n");
99
    return res;
100
}
101
102
static int lu_followlink(struct dentry *dentry, struct nameidata *nd)
103
{
104
    struct server_slot *slot;
105
    struct iovec siov, riov;
106
    int res;
107
    char *cc = failed_link;
108
    char *tmp;
109
    
110
    TRACE("in\n");
111
112
    if((slot = lu_getslot(GET_INFO(dentry->d_sb))) == NULL)
113
	return vfs_follow_link(nd, cc);
114
115
116
    if((res = lu_getname(dentry, slot->s_buf, LU_MAXDATA)) < 0){
117
	WARN("lu_getname failed!\n");
118
	goto out;
119
    }
120
121
    siov.iov_base = slot->s_buf;
122
    siov.iov_len = strlen(slot->s_buf) + 1;
123
    riov.iov_base = &slot->s_buf[LU_MAXPATHLEN];
124
    riov.iov_len = LU_MAXPATHLEN;
125
126
    if((res = lu_execute(GET_INFO(dentry->d_sb), slot, PTYPE_READLINK, &siov, 1, &riov, 1)) < 0)
127
	goto out;
128
129
    if(PIS_ERROR(res)){
130
	TRACE("read_link failed.\n");
131
	res = PERROR(res);
132
	goto out;
133
    }
134
135
    cc = &slot->s_buf[LU_MAXPATHLEN];
136
137
    if(*cc == '/'){
138
	if(GET_INFO(dentry->d_sb)->rootlen){
139
	    if(strncmp(GET_INFO(dentry->d_sb)->root, cc, GET_INFO(dentry->d_sb)->rootlen)){
140
		WARN("symlink outside mounted root!");
141
		cc = failed_link;
142
		goto out;
143
	    }
144
	    cc += GET_INFO(dentry->d_sb)->rootlen;
145
	}
146
147
	lu_xlate_symlink(slot->s_buf, slot->s_buf + LU_MAXPATHLEN, slot->s_buf);
148
149
	cc = slot->s_buf;
150
151
    }
152
153
  out:
154
155
    /* vfs_follow_link somehow manages to call lookup_validate, so we need to 
156
       release the slot, in case it's the only one, otherwise lu_lookup will 
157
       fail (avoid a deadlock). bad, bad vfs_follow_link! you break the overall
158
       beauty of no kmallocs... */
159
160
    if((tmp = kmalloc(strlen(cc) + 1, GFP_KERNEL)) == NULL){
161
	WARN("out of mem!\n");
162
	tmp = failed_link;
163
    }else    
164
	strcpy(tmp, cc);
165
166
    lu_putslot(slot);
167
    res = vfs_follow_link(nd, tmp);
168
169
    if(tmp != failed_link)
170
	kfree(tmp);
171
    
172
    TRACE("out\n");
173
    return res;
174
}
175
176
struct inode_operations lu_symlink_inode_operations = {
177
    .readlink		= lu_readlink,
178
    .follow_link	= lu_followlink,
179
};
180
181
182
183
184

Return to bug 30470