diff -u --recursive --new-file v2.1.20/linux/CREDITS linux/CREDITS --- v2.1.20/linux/CREDITS Mon Dec 30 15:39:02 1996 +++ linux/CREDITS Tue Jan 14 12:59:10 1997 @@ -194,7 +194,7 @@ N: Remy Card E: Remy.Card@masi.ibp.fr E: Remy.Card@linux.org -D: Extended file system designer and developer +D: Extended file system [defunct] designer and developer D: Second extended file system designer and developer S: Institut Blaise Pascal S: 4 Place Jussieu @@ -394,6 +394,14 @@ D: Debugging: SCSI code; Cyclades serial driver; APM driver D: Debugging: XFree86 Mach 32 server, accelerated server code +N: János Farkas +E: chexum@shadow.banki.hu +D: romfs, various (mostly networking) fixes +P: 1024/F81FB2E1 41 B7 E4 E6 3E D4 A6 71 6D 9C F3 9F F2 BF DF 6E +S: Madarász Viktor utca 25 +S: 1131 Budapest +S: Hungary + N: Jürgen Fischer E: fischer@et-inf.fho-emden.de (=?iso-8859-1?q?J=FCrgen?= Fischer) D: Author of Adaptec AHA-152x scsi driver @@ -1562,7 +1570,7 @@ N: Frank Xia E: qx@math.columbia.edu -D: Xiafs filesystem +D: Xiafs filesystem [defunct] S: 542 West 112th Street, 5N S: New York, New York 10025 S: USA diff -u --recursive --new-file v2.1.20/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.20/linux/Documentation/Changes Sun Dec 22 16:37:16 1996 +++ linux/Documentation/Changes Tue Jan 14 12:51:53 1997 @@ -19,7 +19,7 @@ generated by texinfo so a diff is useless anyway (though I can incorporate one by hand if you insist upon sending it that way ;-). -Last updated: December 13, 1996. +Last updated: January 9, 1997. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Minimal Requirements @@ -28,7 +28,7 @@ Upgrade to at *least* these software revisions before thinking you've encountered a bug! -- Kernel modules 2.1.13 +- Kernel modules modutils-970104 - Gnu C 2.7.2.1 - Binutils 2.7.0.3 - Linux C Library 5.4.17 @@ -36,7 +36,6 @@ - Linux C++ Library 2.7.2.1 - Procps 1.01 - SysVinit 2.69 -- Sysklogd 1.3-3 - Mount 2.5p - Net-tools 1.32-alpha - Kbd 0.91 @@ -75,7 +74,7 @@ Modules ======= - You need to upgrade to modules-2.1.13 for kernels 2.1.8 and later. + You need to upgrade to modutils-970104 for kernels 2.1.8 and later. Gnu C ===== @@ -89,9 +88,20 @@ Networking Changes ================== - Please read Documentation/networking/routing.txt. People wanting to use -all the new routing table features such as OSPF classes should also read -Documentation/networking/policy-routing.txt. + Please read Documentation/networking/routing.txt and +Documentation/networking/policy-routing.txt for more information about +changes in routing code. OSPF classes have been added, and interface +routes are generated automatically. + + If for some reason you need to override this automatic default +routing, you have to specify the complete route specification (netmask, +device, etc.) for the kernel to accept it. Consequently, you need to +either remove interface routes from your init scripts or add missing +information to them if you need to replace the automatic routes. + + Also note that some routes, such as loopback routes, do not show up +in some standard tools. Check in /proc/net/rt_local to verify their +presence. SysVinit ======== @@ -99,6 +109,18 @@ To avoid an oops while shutting down or rebooting the computer, upgrade to SysVinit 2.69. +RPM +=== + + If you run RedHat Linux or any other distribution that uses RPM, you +need to upgrade RPM to version 2.2.7 or later. + +DOSEMU +====== + + A new "stable" version of DOSEMU is available for 2.1.x kernels. +Upgrade to 0.64.2 or later. + How to know the version of the installed programs ************************************************* @@ -109,11 +131,13 @@ Gnu C: gcc -v or gcc --version Libc: ls -l /lib/libc.so.* Libc++: ls -l /usr/lib/libg++.so.* +Ld.so: ldd-v Binutils: ld -v modules: insmod -V procps: ps --version -SysVinit: cat /proc/`cat /var/run/syslog.pid`/environ|strings|awk '$1 ~ +SysVinit: cat /proc/`cat /var/run/klogd.pid`/environ|strings|awk '$1 ~ /INIT_VERSION/ {print}' +RPM: rpm --version Where to get the files ********************** @@ -168,9 +192,8 @@ Modules utilities ================= -The 2.1.13 release: -ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.1/modules-2.1.13.tar.gz -ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modules-2.1.13.tar.gz +The 970104 release: +ftp://ftp.redhat.com/pub/alphabits/modutils-970104.tar.gz Procps utilities ================ @@ -185,6 +208,26 @@ The 2.69 release (when it gets there): ftp://tsx-11.mit.edu/pub/linux/sources/sbin/sysvinit-2.69.tar.gz ftp://sunsite.unc.edu/pub/Linux/system/Daemons/init/sysvinit-2.69.tar.gz + +RPM utilities +============= + +The 2.2.7 release for Intel: +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/i386/rpm-2.2.7-1.i386.rpm +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/i386/rpm-devel-2.2.7-1.i386.rpm +The 2.2.7 release for Alpha: +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/axp/rpm-2.2.7-1.axp.rpm +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/axp/rpm-devel-2.2.7-1.axp.rpm +The 2.2.7 release for SPARC: +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/i386/rpm-2.2.7-1.sparc.rpm +ftp://ftp.redhat.com/pub/redhat/redhat-4.0/updates/i386/rpm-devel-2.2.7-1.sparc.rpm + +DOSEMU +====== + +The 0.64.2 release: +ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu0.64.2.tgz +ftp://sunsite.unc.edu/pub/Linux/system/Emulators/dosemu0.64.2.tgz Other Info ========== diff -u --recursive --new-file v2.1.20/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.20/linux/Documentation/Configure.help Thu Jan 2 15:55:13 1997 +++ linux/Documentation/Configure.help Tue Jan 14 12:59:10 1997 @@ -3108,13 +3108,6 @@ Documentation/modules.txt. Note that the filesystem of your root partition cannot be compiled as a module. -Extended fs support -CONFIG_EXT_FS - This is the old Linux filesystem (= method to organize files on a - harddisk partition or a floppy disk) and not in use anymore. It - enlarges your kernel by about 25 kB. Let's all kill this beast. Say - N. - Second extended fs support CONFIG_EXT2_FS This is the de facto standard Linux filesystem (= method to organize @@ -3138,16 +3131,6 @@ sunsite.unc.edu:/pub/Linux/docs/faqs. This option will enlarge your kernel by about 41 kB. Default is Y. -xiafs filesystem support -CONFIG_XIA_FS - This is an old filesystem (= method to organize files on a harddisk - partition or a floppy disk) and not in use anymore. This option - would enlarge your kernel by about 28 kB. Let's all kill this beast: - say N. If you want to compile this as a module ( = code which can - be inserted in and removed from the running kernel whenever you - want), say M here and read Documentation/modules.txt. Note that the - filesystem of your root partition cannot be compiled as a module. - fat fs support CONFIG_FAT_FS If you want to use one of the FAT-based filesystems (the MS-DOS, @@ -3450,6 +3433,14 @@ module, say M here and read Documentation/modules.txt. If unsure, say N. +ROMFS filesystem support (EXPERIMENTAL) +CONFIG_ROMFS_FS + This is a special file system intended for installation disks or + otherwise prebuilt medias. It has very low overhead and low memory + requirements. However, it's read-only (one particular reason of the + smallness), so you need extra programs to prepare disks in this + format. If you are not sure, just say N, you don't need it. + Standard/generic serial support CONFIG_SERIAL This selects whether you want to include the driver for the standard @@ -4587,7 +4578,7 @@ # LocalWords: TR Sony CDU caddyless cdu Mitsumi MCD cd mcd XA MultiSession CDA # LocalWords: Matsushita Panasonic SBPCD Soundblaster Longshine sbpcd Aztech # LocalWords: Okano Wearnes AZTCD CDD SE aztcd sonycd Goldstar GSCD Philips fs -# LocalWords: LMS OPTCD Sanyo SJCD minix faqs xiafs XIA msdos harddrive mtools +# LocalWords: LMS OPTCD Sanyo SJCD minix faqs msdos harddrive mtools # LocalWords: std softlinks umssync NetworkFileSharing nfsd mountd CDs HPFS TI # LocalWords: hpfs SYSV SCO intel iBCS Wyse WordPerfect tsx mit unixes sysv NR # LocalWords: SMB WfW Cyclades async mux Logitech busmouse MouseSystem aka AST diff -u --recursive --new-file v2.1.20/linux/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX --- v2.1.20/linux/Documentation/filesystems/00-INDEX Thu Jun 6 14:57:43 1996 +++ linux/Documentation/filesystems/00-INDEX Fri Jan 3 13:03:41 1997 @@ -6,6 +6,8 @@ - info and mount options for the OS/2 HPFS. ncpfs.txt - info on Novell Netware(tm) filesystem using NCP protocol. +romfs.txt + - Description of the ROMFS filesystem. smbfs.txt - info on using filesystems with the SMB protocol (Win 3.11, Win NT) sysv-fs.txt diff -u --recursive --new-file v2.1.20/linux/Documentation/filesystems/romfs.txt linux/Documentation/filesystems/romfs.txt --- v2.1.20/linux/Documentation/filesystems/romfs.txt Thu Jan 1 02:00:00 1970 +++ linux/Documentation/filesystems/romfs.txt Fri Jan 3 13:03:41 1997 @@ -0,0 +1,152 @@ + +ROMFS - ROM FILE SYSTEM + +This is a quite dumb, read only filesystem, mainly for initial ram +disks of installation disks. It has grown up by the need of having +modules linked at boot time. Using this filesystem, you get a very +similar feature, and even the possibility of a small kernel, with a +file system which doesn't take up useful memory from the router +functions in the basement of your office. + +For comparison, both the older minix and xiafs filesystems (compiled +as module) need more than 20000 bytes, while romfs is less than a +page, about 4000 bytes (assuming ix86 code). Under the same +conditions, the msdos filesystem would need about 30K (and does not +support device nodes or symlinks), while the nfs module with nfsroot +is about 57K. Furthermore, as a bit unfair comparison, an actual +rescue disk used up 3202 blocks with ext2, while with romfs, it needed +3079 blocks. + +To create such a file system, you'll need a user program named +genromfs. It is (or will be shortly) available via ftp on +sunsite.unc.edu and its mirrors, in the /pub/Linux/system/Filesystems/ +directory. + +As the name suggests, romfs could be also used (space-efficiently) on +various read-only medias, like (E)EPROM disks if someone will have the +motivation.. :) + +However, the main purpose of romfs is to have a very small kernel, +which has only this filesystem linked in, and then can load any module +later, with the current module utilities. It can also be used to run +some program to decide if you need SCSI devices, and even IDE or +floppy drives can be loaded later if you use the "initrd" -- initial +ram disk -- feature of the kernel. This would not be really news +flash, but with romfs, you can even spare off your ext2 or minix or +maybe even affs filesystem until you really know that you need it. + +For example, a distribution boot disk can contain only the cd disk +drivers (and possibly the SCSI drivers), and the ISO filesystem +module. The kernel can be small enough, since it doesn't have other +filesystems, like the quite large ext2fs module, which can then be +loaded off the CD at a later stage of the installation. Another use +would be for a recovery disk, when you are reinstalling a workstation +from the network, and you will have all the tools/modules available +from a nearby server, so you don't want to carry two disks for this +purpose, just because it won't fit into ext2. + +romfs operates on block devices as you can expect, and the underlying +structure is very simple. Every accessible structure begins on 16 +byte boundaries for fast access. The minimum space a file will take +is 32 bytes (this is an empty file, with a less than 16 character +name). The maximum overhead for any non-empty file is the header, and +the 16 byte padding for the name and the contents, also 16+14+15 = 45 +bytes. This is quite rare however, since most file names are longer +than 3 bytes, and shorter than 15 bytes. + +The layout of the filesystem is the following: + +offset content + + +---+---+---+---+ + 0 | - | r | o | m | \ + +---+---+---+---+ The ASCII representation of those bytes + 4 | 1 | f | s | - | / (i.e. "-rom1fs-" + +---+---+---+---+ + 8 | full size | The number of accessible bytes in this fs. + +---+---+---+---+ + 12 | checksum | The checksum of the FIRST 512 BYTES. + +---+---+---+---+ + 16 | volume name | The zero terminated name of the volume, + : : padded to 16 byte boundary. + +---+---+---+---+ + xx | file | + : headers : + +Every multi byte value (32 bit words, I'll use the longwords term from +now on) must be in big endian order. + +The first eight bytes identify the filesystem, even for the casual +reader. After that in the 3rd longword, it contains the number of +bytes accessible from the start of this filesystem. The 4th longword +is the checksum of the first 512 bytes (or the number of bytes +accessible, whichever is smallest). The applied algorithm is the same +as in the AFFS filesystem, namely a simple sum of the longwords +(assuming bigendian quantities again). For details, please consult +the source. This algorithm was chosen because although it's not quite +reliable, it does not require any tables, and it is very simple. + +The following bytes are now part of the file system; each file header +must begin on a 16 byte boundary. + +offset content + + +---+---+---+---+ + 0 | next filehdr|X| The offset of the next file header + +---+---+---+---+ (zero if no more files) + 4 | spec.info | Info for directories/hard links/devices + +---+---+---+---+ + 8 | size | The size of this file in bytes + +---+---+---+---+ + 12 | checksum | Covering the meta data, including the file + +---+---+---+---+ name, and padding + 16 | file name | The zero terminated name of the file, + : : padded to 16 byte boundary. + +---+---+---+---+ + xx | file data | + : : + +Since the file headers begin always at a 16 byte boundary, the lowest +4 bits would be always zero in the next filehdr pointer. These four +bits are used for the mode information. Bits 0..2 specify the type of +the file; while bit 4 shows if the file is executable or not. The +permissions are assumed to be world readable, if this bit is not set, +and world executable if it is; except the character and block devices, +they are readable only for the owner. The owner of every file is user +and group 0, this should never be a problem for the intended use. The +mapping of the 8 possible values to file types is the following: + + mapping spec.info means + 0 hard link link destination [file header] + 1 directory first file's header + 2 regular file unused, must be zero [MBZ] + 3 symbolic link unused, MBZ (file data is the link content) + 4 block device 16/16 bits major/minor number + 5 char device - " - + 6 socket unused, MBZ + 7 fifo unused, MBZ + +Note that hard links are specifically marked in this filesystem, but +they will behave as you can expect (i.e. share the inode number). +Note also that your responsibility to not create hard link loops, and +creating all the . and .. links for directories. This is normally +done correctly by the genromfs program. Please refrain from using the +executable bits on the socket and fifo special files, they may have +other uses in the future. Additionally, please remember that only +regular files, and symlinks are supposed to have a nonzero size field; +they contain the number of bytes available directly after the (padded) +file name. + +Another thing to note is that romfs works on file headers and data +aligned to 16 byte boundaries, but most hardware devices and the block +device drivers are unable to cope with smaller than block-sized data. +To overcome this limitation, the whole size of the file system must be +padded to an 1024 byte boundary. + +If you have any problems or suggestions concerning this file system, +please contact me. However, think twice before wanting me to add +features and code, because the primary advantage of this file system +is the small code. + +Have fun, +Janos Farkas diff -u --recursive --new-file v2.1.20/linux/Documentation/modules.txt linux/Documentation/modules.txt --- v2.1.20/linux/Documentation/modules.txt Sun Dec 22 16:37:20 1996 +++ linux/Documentation/modules.txt Tue Jan 14 12:59:10 1997 @@ -49,7 +49,7 @@ Here is a sample of the available modules included in the kernel sources: - Most filesystems: minix, xiafs, msdos, umsdos, sysv, isofs, hpfs, + Most filesystems: minix, msdos, umsdos, sysv, isofs, hpfs, smbfs, nfs Mid-level SCSI support (required by top and low level scsi drivers). diff -u --recursive --new-file v2.1.20/linux/Makefile linux/Makefile --- v2.1.20/linux/Makefile Thu Jan 2 15:55:14 1997 +++ linux/Makefile Fri Jan 3 11:33:25 1997 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 20 +SUBLEVEL = 21 ARCH = i386 @@ -39,6 +39,7 @@ NM =$(CROSS_COMPILE)nm STRIP =$(CROSS_COMPILE)strip MAKE =make +GENKSYMS=/sbin/genksyms all: do-it-all @@ -87,7 +88,7 @@ # standard CFLAGS # -CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce +CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer ifdef CONFIG_CPP CFLAGS := $(CFLAGS) -x c++ diff -u --recursive --new-file v2.1.20/linux/Rules.make linux/Rules.make --- v2.1.20/linux/Rules.make Thu Dec 12 17:02:39 1996 +++ linux/Rules.make Tue Jan 14 08:47:10 1997 @@ -67,7 +67,7 @@ else $(AR) rcs $@ endif -endif +endif # O_TARGET # # Rule to compile a set of .o files into one .a file @@ -140,56 +140,58 @@ # Separate the object into "normal" objects and "exporting" objects # Exporting objects are: all objects that define symbol tables # -ifdef CONFIG_MODVERSIONS +ifdef CONFIG_MODULES + SYMTAB_OBJS = $(LX_OBJS) $(OX_OBJS) $(MX_OBJS) + +ifdef CONFIG_MODVERSIONS ifneq "$(strip $(SYMTAB_OBJS))" "" MODINCL = $(TOPDIR)/include/linux/modules -# The -w option (enable warnings) for /bin/genksyms will return here in 2.1 +# The -w option (enable warnings) for genksyms will return here in 2.1 $(MODINCL)/%.ver: %.c - @if [ ! -x /sbin/genksyms ]; then echo "Please read: Documentation/modules.txt"; fi - $(CC) $(CFLAGS) -E -D__GENKSYMS__ $< | /sbin/genksyms $(MODINCL) - + $(CC) $(CFLAGS) -E -D__GENKSYMS__ $<\ + | $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp + mv $@.tmp $@ + $(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver)): $(TOPDIR)/include/linux/autoconf.h $(TOPDIR)/include/linux/modversions.h: $(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver)) @echo updating $(TOPDIR)/include/linux/modversions.h - @(echo "#ifdef MODVERSIONS";\ - echo "#undef CONFIG_MODVERSIONS";\ - echo "#define CONFIG_MODVERSIONS";\ - echo "#ifndef _set_ver";\ - echo "#define _set_ver(sym,vers) sym ## _R ## vers";\ - echo "#endif";\ - cd $(TOPDIR)/include/linux/modules; for f in *.ver;\ - do echo "#include "; done; \ - echo "#undef CONFIG_MODVERSIONS";\ - echo "#endif") \ - > $(TOPDIR)/include/linux/modversions.h - -$(MX_OBJS): $(TOPDIR)/include/linux/modversions.h - $(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c) - -$(LX_OBJS) $(OX_OBJS): $(TOPDIR)/include/linux/modversions.h - $(CC) $(CFLAGS) -DMODVERSIONS -DEXPORT_SYMTAB -c $(@:.o=.c) + @(echo "#ifndef _LINUX_MODVERSIONS_H";\ + echo "#define _LINUX_MODVERSIONS_H"; \ + echo "#include "; \ + cd $(TOPDIR)/include/linux/modules; \ + for f in *.ver; do \ + if [ -f $$f ]; then echo "#include "; fi; \ + done; \ + echo "#endif"; \ + ) > $@ dep fastdep: $(TOPDIR)/include/linux/modversions.h -endif +endif # SYMTAB_OBJS + $(M_OBJS): $(TOPDIR)/include/linux/modversions.h ifdef MAKING_MODULES $(O_OBJS) $(L_OBJS): $(TOPDIR)/include/linux/modversions.h endif -# This is needed to ensure proper dependency for multipart modules such as -# fs/ext.o. (Otherwise, not all subobjects will be recompiled when -# version information changes.) else $(TOPDIR)/include/linux/modversions.h: - @touch $(TOPDIR)/include/linux/modversions.h + @echo "#include " > $@ + +endif # CONFIG_MODVERSIONS +ifneq "$(strip $(SYMTAB_OBJS))" "" +$(SYMTAB_OBJS): $(TOPDIR)/include/linux/modversions.h + $(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c) endif + +endif # CONFIG_MODULES + # # include dependency files they exist diff -u --recursive --new-file v2.1.20/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.20/linux/arch/alpha/defconfig Mon Dec 30 15:39:02 1996 +++ linux/arch/alpha/defconfig Tue Jan 14 12:59:10 1997 @@ -183,9 +183,7 @@ # # CONFIG_QUOTA is not set # CONFIG_MINIX_FS is not set -# CONFIG_EXT_FS is not set CONFIG_EXT2_FS=y -# CONFIG_XIA_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_VFAT_FS is not set diff -u --recursive --new-file v2.1.20/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v2.1.20/linux/arch/alpha/kernel/Makefile Tue Jun 4 06:06:37 1996 +++ linux/arch/alpha/kernel/Makefile Fri Jan 3 11:33:25 1997 @@ -16,7 +16,8 @@ O_TARGET := kernel.o O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \ - bios32.o ptrace.o time.o apecs.o lca.o cia.o ksyms.o + bios32.o ptrace.o time.o apecs.o lca.o cia.o +OX_OBJS := alpha_ksyms.o all: kernel.o head.o diff -u --recursive --new-file v2.1.20/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.1.20/linux/arch/alpha/kernel/alpha_ksyms.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/kernel/alpha_ksyms.c Fri Jan 3 11:33:25 1997 @@ -0,0 +1,103 @@ +/* + * linux/arch/alpha/kernel/ksyms.c + * + * Export the alpha-specific functions that are needed for loadable + * modules. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +extern void bcopy (const char *src, char *dst, int len); +extern struct hwrpb_struct *hwrpb; +extern long __kernel_thread(unsigned long, int (*)(void *), void *); +extern void dump_thread(struct pt_regs *, struct user *); +extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); + +/* these are C runtime functions with special calling conventions: */ +extern void __divl (void); +extern void __reml (void); +extern void __divq (void); +extern void __remq (void); +extern void __divlu (void); +extern void __remlu (void); +extern void __divqu (void); +extern void __remqu (void); + + +/* platform dependent support */ +EXPORT_SYMBOL(_inb); +EXPORT_SYMBOL(_inw); +EXPORT_SYMBOL(_inl); +EXPORT_SYMBOL(_outb); +EXPORT_SYMBOL(_outw); +EXPORT_SYMBOL(_outl); +EXPORT_SYMBOL(_readb); +EXPORT_SYMBOL(_readw); +EXPORT_SYMBOL(_readl); +EXPORT_SYMBOL(_writeb); +EXPORT_SYMBOL(_writew); +EXPORT_SYMBOL(_writel); +EXPORT_SYMBOL(insb); +EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(insl); +EXPORT_SYMBOL(outsb); +EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(outsl); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strtok); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(__memcpy); +EXPORT_SYMBOL(__memset); +EXPORT_SYMBOL(__constant_c_memset); + +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(hwrpb); +EXPORT_SYMBOL(wrusp); +EXPORT_SYMBOL(__kernel_thread); + +/* + * The following are specially called from the uaccess assembly stubs. + */ +EXPORT_SYMBOL_NOVERS(__copy_user); +EXPORT_SYMBOL_NOVERS(__clear_user); +EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(__strlen_user); + +/* + * The following are special because they're not called + * explicitly (the C compiler or assembler generates them in + * response to division operations). Fortunately, their + * interface isn't gonna change any time soon now, so it's OK + * to leave it out of version control. + */ +# undef bcopy +# undef memcpy +# undef memset +EXPORT_SYMBOL_NOVERS(__divl); +EXPORT_SYMBOL_NOVERS(__divlu); +EXPORT_SYMBOL_NOVERS(__divq); +EXPORT_SYMBOL_NOVERS(__divqu); +EXPORT_SYMBOL_NOVERS(__reml); +EXPORT_SYMBOL_NOVERS(__remlu); +EXPORT_SYMBOL_NOVERS(__remq); +EXPORT_SYMBOL_NOVERS(__remqu); +EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL_NOVERS(memset); diff -u --recursive --new-file v2.1.20/linux/arch/alpha/kernel/ksyms.c linux/arch/alpha/kernel/ksyms.c --- v2.1.20/linux/arch/alpha/kernel/ksyms.c Mon Dec 30 15:39:02 1996 +++ linux/arch/alpha/kernel/ksyms.c Thu Jan 1 02:00:00 1970 @@ -1,101 +0,0 @@ -/* - * linux/arch/alpha/kernel/ksyms.c - * - * Export the alpha-specific functions that are needed for loadable - * modules. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -extern void bcopy (const char *src, char *dst, int len); -extern struct hwrpb_struct *hwrpb; - -/* these are C runtime functions with special calling conventions: */ -extern void __divl (void); -extern void __reml (void); -extern void __divq (void); -extern void __remq (void); -extern void __divlu (void); -extern void __remlu (void); -extern void __divqu (void); -extern void __remqu (void); - -extern void dump_thread(struct pt_regs *, struct user *); -extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); - - -/* platform dependent support */ -EXPORT_SYMBOL(_inb); -EXPORT_SYMBOL(_inw); -EXPORT_SYMBOL(_inl); -EXPORT_SYMBOL(_outb); -EXPORT_SYMBOL(_outw); -EXPORT_SYMBOL(_outl); -EXPORT_SYMBOL(_readb); -EXPORT_SYMBOL(_readw); -EXPORT_SYMBOL(_readl); -EXPORT_SYMBOL(_writeb); -EXPORT_SYMBOL(_writew); -EXPORT_SYMBOL(_writel); -EXPORT_SYMBOL(insb); -EXPORT_SYMBOL(insw); -EXPORT_SYMBOL(insl); -EXPORT_SYMBOL(outsb); -EXPORT_SYMBOL(outsw); -EXPORT_SYMBOL(outsl); -EXPORT_SYMBOL(strcat); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strcpy); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); -EXPORT_SYMBOL(strnlen); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strtok); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(__memcpy); -EXPORT_SYMBOL(__memset); -EXPORT_SYMBOL(__constant_c_memset); - -EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(hwrpb); -EXPORT_SYMBOL(wrusp); - -/* - * The following are specially called from the uaccess assembly stubs. - */ -EXPORT_SYMBOL_NOVERS(__copy_user); -EXPORT_SYMBOL_NOVERS(__clear_user); -EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(__strlen_user); - -/* - * The following are special because they're not called - * explicitly (the C compiler or assembler generates them in - * response to division operations). Fortunately, their - * interface isn't gonna change any time soon now, so it's OK - * to leave it out of version control. - */ -# undef bcopy -# undef memcpy -# undef memset -EXPORT_SYMBOL_NOVERS(__divl); -EXPORT_SYMBOL_NOVERS(__divlu); -EXPORT_SYMBOL_NOVERS(__divq); -EXPORT_SYMBOL_NOVERS(__divqu); -EXPORT_SYMBOL_NOVERS(__reml); -EXPORT_SYMBOL_NOVERS(__remlu); -EXPORT_SYMBOL_NOVERS(__remq); -EXPORT_SYMBOL_NOVERS(__remqu); -EXPORT_SYMBOL_NOVERS(memcpy); -EXPORT_SYMBOL_NOVERS(memset); diff -u --recursive --new-file v2.1.20/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v2.1.20/linux/arch/alpha/kernel/traps.c Mon Dec 30 15:39:02 1996 +++ linux/arch/alpha/kernel/traps.c Fri Jan 3 18:48:37 1997 @@ -236,7 +236,7 @@ " lda %1,3b-1b(%0)\n" " .gprel32 2b\n" " lda %2,3b-2b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -257,7 +257,7 @@ " lda %1,3b-1b(%0)\n" " .gprel32 2b\n" " lda %2,3b-2b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -277,7 +277,7 @@ " lda %1,3b-1b(%0)\n" " .gprel32 2b\n" " lda %2,3b-2b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -311,7 +311,7 @@ " lda $31,5b-3b(%0)\n" " .gprel32 4b\n" " lda $31,5b-4b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); @@ -342,7 +342,7 @@ " lda $31,5b-3b(%0)\n" " .gprel32 4b\n" " lda $31,5b-4b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); @@ -372,7 +372,7 @@ " lda $31,5b-3b(%0)\n" " .gprel32 4b\n" " lda $31,5b-4b(%0)\n" - ".text" + ".previous" : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); diff -u --recursive --new-file v2.1.20/linux/arch/alpha/lib/clear_user.S linux/arch/alpha/lib/clear_user.S --- v2.1.20/linux/arch/alpha/lib/clear_user.S Fri Nov 1 17:13:14 1996 +++ linux/arch/alpha/lib/clear_user.S Fri Jan 3 18:48:37 1997 @@ -31,7 +31,7 @@ .section __ex_table,"a"; \ .gprel32 99b; \ lda $31, $exception-99b($31); \ - .text + .previous .set noat .set noreorder diff -u --recursive --new-file v2.1.20/linux/arch/alpha/lib/copy_user.S linux/arch/alpha/lib/copy_user.S --- v2.1.20/linux/arch/alpha/lib/copy_user.S Fri Nov 1 17:13:14 1996 +++ linux/arch/alpha/lib/copy_user.S Fri Jan 3 18:48:37 1997 @@ -33,7 +33,7 @@ .section __ex_table,"a"; \ .gprel32 99b; \ lda $31, $exit-99b($31); \ - .text + .previous .set noat .align 3 diff -u --recursive --new-file v2.1.20/linux/arch/alpha/lib/strlen_user.S linux/arch/alpha/lib/strlen_user.S --- v2.1.20/linux/arch/alpha/lib/strlen_user.S Tue Nov 19 15:53:53 1996 +++ linux/arch/alpha/lib/strlen_user.S Fri Jan 3 18:48:37 1997 @@ -14,7 +14,7 @@ .section __ex_table,"a"; \ .gprel32 99b; \ lda v0, $exception-99b(zero); \ - .text + .previous .set noreorder diff -u --recursive --new-file v2.1.20/linux/arch/alpha/lib/strncpy_from_user.S linux/arch/alpha/lib/strncpy_from_user.S --- v2.1.20/linux/arch/alpha/lib/strncpy_from_user.S Mon Dec 30 15:39:02 1996 +++ linux/arch/alpha/lib/strncpy_from_user.S Fri Jan 3 18:48:37 1997 @@ -21,7 +21,7 @@ .section __ex_table,"a"; \ .gprel32 99b; \ lda $31, $exception-99b($0); \ - .text + .previous .set noat diff -u --recursive --new-file v2.1.20/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.1.20/linux/arch/i386/Makefile Thu Sep 26 07:39:10 1996 +++ linux/arch/i386/Makefile Fri Jan 3 11:33:25 1997 @@ -45,7 +45,7 @@ BZLINKFLAGS =-Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS) LINKFLAGS =-Ttext $(IMAGE_OFFSET) $(LDFLAGS) -CFLAGS := $(CFLAGS) -pipe +CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce ifdef CONFIG_M386 CFLAGS := $(CFLAGS) -m386 -DCPU=386 diff -u --recursive --new-file v2.1.20/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.20/linux/arch/i386/defconfig Thu Jan 2 15:55:14 1997 +++ linux/arch/i386/defconfig Tue Jan 14 12:59:10 1997 @@ -136,9 +136,7 @@ # # CONFIG_QUOTA is not set CONFIG_MINIX_FS=y -# CONFIG_EXT_FS is not set CONFIG_EXT2_FS=y -# CONFIG_XIA_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_VFAT_FS is not set @@ -151,6 +149,7 @@ # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_UFS_FS is not set # diff -u --recursive --new-file v2.1.20/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.1.20/linux/arch/i386/kernel/Makefile Wed Dec 18 15:58:34 1996 +++ linux/arch/i386/kernel/Makefile Fri Jan 3 11:33:25 1997 @@ -22,7 +22,8 @@ O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \ - ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o ksyms.o + ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o +OX_OBJS := i386_ksyms.o ifdef CONFIG_MCA O_OBJS += mca.o diff -u --recursive --new-file v2.1.20/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.20/linux/arch/i386/kernel/i386_ksyms.c Thu Jan 1 02:00:00 1970 +++ linux/arch/i386/kernel/i386_ksyms.c Fri Jan 3 11:33:25 1997 @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern void dump_thread(struct pt_regs *, struct user *); +extern int dump_fpu(elf_fpregset_t *); + +/* platform dependent support */ +EXPORT_SYMBOL(EISA_bus); +EXPORT_SYMBOL(MCA_bus); +EXPORT_SYMBOL(wp_works_ok); +EXPORT_SYMBOL(__verify_write); +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(ioremap); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL_NOVERS(__down_failed); +EXPORT_SYMBOL_NOVERS(__up_wakeup); + +#ifdef __SMP__ +EXPORT_SYMBOL(apic_reg); /* Needed internally for the I386 inlines */ +EXPORT_SYMBOL(cpu_data); +EXPORT_SYMBOL(syscall_count); +EXPORT_SYMBOL(kernel_flag); +EXPORT_SYMBOL(kernel_counter); +EXPORT_SYMBOL(active_kernel_processor); +EXPORT_SYMBOL(smp_invalidate_needed); +#endif + +#ifdef CONFIG_MCA +/* Adapter probing and info methods. */ +EXPORT_SYMBOL(mca_write_pos); +EXPORT_SYMBOL(mca_read_pos); +EXPORT_SYMBOL(mca_read_stored_pos); +EXPORT_SYMBOL(mca_set_adapter_name); +EXPORT_SYMBOL(mca_get_adapter_name); +EXPORT_SYMBOL(mca_set_adapter_procfn); +EXPORT_SYMBOL(mca_isenabled); +EXPORT_SYMBOL(mca_isadapter); +#endif diff -u --recursive --new-file v2.1.20/linux/arch/i386/kernel/ksyms.c linux/arch/i386/kernel/ksyms.c --- v2.1.20/linux/arch/i386/kernel/ksyms.c Mon Dec 30 15:39:03 1996 +++ linux/arch/i386/kernel/ksyms.c Thu Jan 1 02:00:00 1970 @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern void dump_thread(struct pt_regs *, struct user *); -extern int dump_fpu(elf_fpregset_t *); - -/* platform dependent support */ -EXPORT_SYMBOL(EISA_bus); -EXPORT_SYMBOL(MCA_bus); -EXPORT_SYMBOL(wp_works_ok); -EXPORT_SYMBOL(__verify_write); -EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(ioremap); -EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL_NOVERS(__down_failed); -EXPORT_SYMBOL_NOVERS(__up_wakeup); - -#ifdef __SMP__ -EXPORT_SYMBOL(apic_reg); /* Needed internally for the I386 inlines */ -EXPORT_SYMBOL(cpu_data); -EXPORT_SYMBOL(syscall_count); -EXPORT_SYMBOL(kernel_flag); -EXPORT_SYMBOL(kernel_counter); -EXPORT_SYMBOL(active_kernel_processor); -EXPORT_SYMBOL(smp_invalidate_needed); -#endif - -#ifdef CONFIG_MCA -/* Adapter probing and info methods. */ -EXPORT_SYMBOL(mca_write_pos); -EXPORT_SYMBOL(mca_read_pos); -EXPORT_SYMBOL(mca_read_stored_pos); -EXPORT_SYMBOL(mca_set_adapter_name); -EXPORT_SYMBOL(mca_get_adapter_name); -EXPORT_SYMBOL(mca_set_adapter_procfn); -EXPORT_SYMBOL(mca_isenabled); -EXPORT_SYMBOL(mca_isadapter); -#endif diff -u --recursive --new-file v2.1.20/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.1.20/linux/arch/i386/kernel/process.c Thu Jan 2 15:55:14 1997 +++ linux/arch/i386/kernel/process.c Fri Jan 3 11:54:16 1997 @@ -284,8 +284,7 @@ if(!reboot_thru_bios) { sti(); /* rebooting needs to touch the page at absolute addr 0 */ - pg0[0] = 7; - *((unsigned short *)0x472) = reboot_mode; + *((unsigned short *)__va(0x472)) = reboot_mode; for (;;) { int i; for (i=0; i<100; i++) { diff -u --recursive --new-file v2.1.20/linux/arch/m68k/amiga/Makefile linux/arch/m68k/amiga/Makefile --- v2.1.20/linux/arch/m68k/amiga/Makefile Wed Sep 25 10:47:37 1996 +++ linux/arch/m68k/amiga/Makefile Fri Jan 3 11:33:25 1997 @@ -9,7 +9,8 @@ O_TARGET := amiga.o O_OBJS := config.o amikeyb.o amiints.o cia.o \ - chipram.o amisound.o amifb.o zorro.o ksyms.o + chipram.o amisound.o amifb.o zorro.o +OX_OBJS := amiga_ksyms.o ifdef CONFIG_FB_CYBER O_OBJS := $(O_OBJS) cyberfb.o diff -u --recursive --new-file v2.1.20/linux/arch/m68k/amiga/amiga_ksyms.c linux/arch/m68k/amiga/amiga_ksyms.c --- v2.1.20/linux/arch/m68k/amiga/amiga_ksyms.c Thu Jan 1 02:00:00 1970 +++ linux/arch/m68k/amiga/amiga_ksyms.c Fri Jan 3 11:33:25 1997 @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +extern volatile u_short amiga_audio_min_period; +extern u_short amiga_audio_period; + +/* + * Add things here when you find the need for it. + */ +EXPORT_SYMBOL(amiga_model); +EXPORT_SYMBOL(amiga_hw_present); +EXPORT_SYMBOL(amiga_eclock); +EXPORT_SYMBOL(amiga_colorclock); +EXPORT_SYMBOL(amiga_chip_alloc); +EXPORT_SYMBOL(amiga_chip_free); +EXPORT_SYMBOL(amiga_chip_avail); +EXPORT_SYMBOL(amiga_audio_period); +EXPORT_SYMBOL(amiga_audio_min_period); + +EXPORT_SYMBOL(zorro_find); +EXPORT_SYMBOL(zorro_get_board); +EXPORT_SYMBOL(zorro_config_board); +EXPORT_SYMBOL(zorro_unconfig_board); +EXPORT_SYMBOL(zorro_unused_z2ram); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/amiga/ksyms.c linux/arch/m68k/amiga/ksyms.c --- v2.1.20/linux/arch/m68k/amiga/ksyms.c Mon Dec 30 15:39:03 1996 +++ linux/arch/m68k/amiga/ksyms.c Thu Jan 1 02:00:00 1970 @@ -1,26 +0,0 @@ -#include -#include -#include -#include - -extern volatile u_short amiga_audio_min_period; -extern u_short amiga_audio_period; - -/* - * Add things here when you find the need for it. - */ -EXPORT_SYMBOL(amiga_model); -EXPORT_SYMBOL(amiga_hw_present); -EXPORT_SYMBOL(amiga_eclock); -EXPORT_SYMBOL(amiga_colorclock); -EXPORT_SYMBOL(amiga_chip_alloc); -EXPORT_SYMBOL(amiga_chip_free); -EXPORT_SYMBOL(amiga_chip_avail); -EXPORT_SYMBOL(amiga_audio_period); -EXPORT_SYMBOL(amiga_audio_min_period); - -EXPORT_SYMBOL(zorro_find); -EXPORT_SYMBOL(zorro_get_board); -EXPORT_SYMBOL(zorro_config_board); -EXPORT_SYMBOL(zorro_unconfig_board); -EXPORT_SYMBOL(zorro_unused_z2ram); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/atari/Makefile linux/arch/m68k/atari/Makefile --- v2.1.20/linux/arch/m68k/atari/Makefile Sun Dec 22 16:37:21 1996 +++ linux/arch/m68k/atari/Makefile Fri Jan 3 11:33:25 1997 @@ -9,6 +9,7 @@ O_TARGET := atari.o O_OBJS := config.o atakeyb.o ataints.o \ - stdma.o atasound.o joystick.o stram.o atafb.o ksyms.o + stdma.o atasound.o joystick.o stram.o atafb.o +OX_OBJS := atari_ksyms.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.20/linux/arch/m68k/atari/atari_ksyms.c linux/arch/m68k/atari/atari_ksyms.c --- v2.1.20/linux/arch/m68k/atari/atari_ksyms.c Thu Jan 1 02:00:00 1970 +++ linux/arch/m68k/atari/atari_ksyms.c Fri Jan 3 11:33:25 1997 @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +extern void atari_microwire_cmd( int cmd ); + + +EXPORT_SYMBOL(atari_mch_cookie); +EXPORT_SYMBOL(atari_hw_present); +EXPORT_SYMBOL(is_medusa); +EXPORT_SYMBOL(atari_register_vme_int); +EXPORT_SYMBOL(atari_unregister_vme_int); +EXPORT_SYMBOL(stdma_lock); +EXPORT_SYMBOL(stdma_release); +EXPORT_SYMBOL(stdma_others_waiting); +EXPORT_SYMBOL(stdma_islocked); + +EXPORT_SYMBOL(atari_mouse_buttons); +EXPORT_SYMBOL(atari_mouse_interrupt_hook); +EXPORT_SYMBOL(atari_MIDI_interrupt_hook); +EXPORT_SYMBOL(atari_mch_cookie); +EXPORT_SYMBOL(ikbd_write); +EXPORT_SYMBOL(ikbd_mouse_y0_top); +EXPORT_SYMBOL(ikbd_mouse_thresh); +EXPORT_SYMBOL(ikbd_mouse_rel_pos); +EXPORT_SYMBOL(ikbd_mouse_disable); + +EXPORT_SYMBOL(atari_microwire_cmd); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/atari/ksyms.c linux/arch/m68k/atari/ksyms.c --- v2.1.20/linux/arch/m68k/atari/ksyms.c Mon Dec 30 15:39:03 1996 +++ linux/arch/m68k/atari/ksyms.c Thu Jan 1 02:00:00 1970 @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -extern void atari_microwire_cmd( int cmd ); - - -EXPORT_SYMBOL(atari_mch_cookie); -EXPORT_SYMBOL(atari_hw_present); -EXPORT_SYMBOL(is_medusa); -EXPORT_SYMBOL(atari_register_vme_int); -EXPORT_SYMBOL(atari_unregister_vme_int); -EXPORT_SYMBOL(stdma_lock); -EXPORT_SYMBOL(stdma_release); -EXPORT_SYMBOL(stdma_others_waiting); -EXPORT_SYMBOL(stdma_islocked); - -EXPORT_SYMBOL(atari_mouse_buttons); -EXPORT_SYMBOL(atari_mouse_interrupt_hook); -EXPORT_SYMBOL(atari_MIDI_interrupt_hook); -EXPORT_SYMBOL(atari_mch_cookie); -EXPORT_SYMBOL(ikbd_write); -EXPORT_SYMBOL(ikbd_mouse_y0_top); -EXPORT_SYMBOL(ikbd_mouse_thresh); -EXPORT_SYMBOL(ikbd_mouse_rel_pos); -EXPORT_SYMBOL(ikbd_mouse_disable); - -EXPORT_SYMBOL(atari_microwire_cmd); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/defconfig linux/arch/m68k/defconfig --- v2.1.20/linux/arch/m68k/defconfig Sun Dec 22 16:37:22 1996 +++ linux/arch/m68k/defconfig Tue Jan 14 12:59:10 1997 @@ -149,9 +149,7 @@ # # CONFIG_QUOTA is not set CONFIG_MINIX_FS=y -# CONFIG_EXT_FS is not set CONFIG_EXT2_FS=y -# CONFIG_XIA_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_VFAT_FS is not set diff -u --recursive --new-file v2.1.20/linux/arch/m68k/kernel/Makefile linux/arch/m68k/kernel/Makefile --- v2.1.20/linux/arch/m68k/kernel/Makefile Wed Sep 25 10:47:39 1996 +++ linux/arch/m68k/kernel/Makefile Fri Jan 3 11:33:25 1997 @@ -13,7 +13,8 @@ all: kernel.o head.o O_TARGET := kernel.o O_OBJS := entry.o process.o traps.o ints.o signal.o ptrace.o \ - setup.o bios32.o sys_m68k.o console.o time.o ksyms.o + setup.o bios32.o sys_m68k.o console.o time.o +OX_OBJS := m68k_ksyms.o head.o: head.S diff -u --recursive --new-file v2.1.20/linux/arch/m68k/kernel/ksyms.c linux/arch/m68k/kernel/ksyms.c --- v2.1.20/linux/arch/m68k/kernel/ksyms.c Mon Dec 30 15:39:03 1996 +++ linux/arch/m68k/kernel/ksyms.c Thu Jan 1 02:00:00 1970 @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -asmlinkage long long __ashrdi3 (long long, int); -extern char m68k_debug_device[]; - -extern void dump_thread(struct pt_regs *, struct user *); -extern int dump_fpu(elf_fpregset_t *); - -/* platform dependent support */ - -EXPORT_SYMBOLS(memcmp); -EXPORT_SYMBOLS(m68k_machtype); -EXPORT_SYMBOLS(m68k_cputype); -EXPORT_SYMBOLS(m68k_is040or060); -EXPORT_SYMBOLS(cache_push); -EXPORT_SYMBOLS(cache_push_v); -EXPORT_SYMBOLS(cache_clear); -EXPORT_SYMBOLS(mm_vtop); -EXPORT_SYMBOLS(mm_ptov); -EXPORT_SYMBOLS(mm_end_of_chunk); -EXPORT_SYMBOLS(m68k_debug_device); -EXPORT_SYMBOLS(request_irq); -EXPORT_SYMBOLS(free_irq); -EXPORT_SYMBOLS(dump_fpu); -EXPORT_SYMBOLS(dump_thread); -EXPORT_SYMBOLS(strnlen); -EXPORT_SYMBOLS(strrchr); -EXPORT_SYMBOLS(strstr); - -/* The following are special because they're not called - explicitly (the C compiler generates them). Fortunately, - their interface isn't gonna change any time soon now, so - it's OK to leave it out of version control. */ -EXPORT_SYMBOLS_NOVERS(__ashrdi3); -EXPORT_SYMBOLS_NOVERS(memcpy); -EXPORT_SYMBOLS_NOVERS(memset); - -EXPORT_SYMBOLS_NOVERS(__down_failed); -EXPORT_SYMBOLS_NOVERS(__up_wakeup); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c --- v2.1.20/linux/arch/m68k/kernel/m68k_ksyms.c Thu Jan 1 02:00:00 1970 +++ linux/arch/m68k/kernel/m68k_ksyms.c Fri Jan 3 11:33:25 1997 @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +asmlinkage long long __ashrdi3 (long long, int); +extern char m68k_debug_device[]; + +extern void dump_thread(struct pt_regs *, struct user *); +extern int dump_fpu(elf_fpregset_t *); + +/* platform dependent support */ + +EXPORT_SYMBOLS(memcmp); +EXPORT_SYMBOLS(m68k_machtype); +EXPORT_SYMBOLS(m68k_cputype); +EXPORT_SYMBOLS(m68k_is040or060); +EXPORT_SYMBOLS(cache_push); +EXPORT_SYMBOLS(cache_push_v); +EXPORT_SYMBOLS(cache_clear); +EXPORT_SYMBOLS(mm_vtop); +EXPORT_SYMBOLS(mm_ptov); +EXPORT_SYMBOLS(mm_end_of_chunk); +EXPORT_SYMBOLS(m68k_debug_device); +EXPORT_SYMBOLS(request_irq); +EXPORT_SYMBOLS(free_irq); +EXPORT_SYMBOLS(dump_fpu); +EXPORT_SYMBOLS(dump_thread); +EXPORT_SYMBOLS(strnlen); +EXPORT_SYMBOLS(strrchr); +EXPORT_SYMBOLS(strstr); + +/* The following are special because they're not called + explicitly (the C compiler generates them). Fortunately, + their interface isn't gonna change any time soon now, so + it's OK to leave it out of version control. */ +EXPORT_SYMBOLS_NOVERS(__ashrdi3); +EXPORT_SYMBOLS_NOVERS(memcpy); +EXPORT_SYMBOLS_NOVERS(memset); + +EXPORT_SYMBOLS_NOVERS(__down_failed); +EXPORT_SYMBOLS_NOVERS(__up_wakeup); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c --- v2.1.20/linux/arch/m68k/kernel/signal.c Sun Dec 22 16:37:22 1996 +++ linux/arch/m68k/kernel/signal.c Fri Jan 3 18:48:37 1997 @@ -174,7 +174,7 @@ if (context.sc_usp != fp+fsize) current->flags &= ~PF_ONSIGSTK; - + /* OK. Make room on the supervisor stack for the extra junk, * if necessary. */ @@ -200,7 +200,7 @@ " .align 4\n" " .long 2b,4b\n" " .long 3b,4b\n" - ".text" + ".previous" : /* no outputs, it doesn't ever return */ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), "n" (frame_offset), "a" (fp) @@ -360,7 +360,7 @@ /* * OK, we're invoking a handler - */ + */ static inline void handle_signal(unsigned long signr, struct sigaction *sa, unsigned long oldmask, struct pt_regs *regs) { @@ -482,7 +482,7 @@ continue; current->state = TASK_STOPPED; current->exit_code = signr; - if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & SA_NOCLDSTOP)) notify_parent(current); schedule(); diff -u --recursive --new-file v2.1.20/linux/arch/m68k/lib/checksum.c linux/arch/m68k/lib/checksum.c --- v2.1.20/linux/arch/m68k/lib/checksum.c Fri Nov 22 18:28:17 1996 +++ linux/arch/m68k/lib/checksum.c Fri Jan 3 18:48:37 1997 @@ -241,7 +241,7 @@ ".long 19b,7b\n" ".long 20b,7b\n" ".long 21b,7b\n" - ".text" + ".previous" : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), "=&d" (tmp1), "=&d" (tmp2) : "0" (sum), "1" (len), "2" (src), "3" (dst) diff -u --recursive --new-file v2.1.20/linux/arch/mips/defconfig linux/arch/mips/defconfig --- v2.1.20/linux/arch/mips/defconfig Thu Feb 8 05:41:50 1996 +++ linux/arch/mips/defconfig Tue Jan 14 12:59:10 1997 @@ -53,9 +53,7 @@ # Filesystems # # CONFIG_MINIX_FS is not set -# CONFIG_EXT_FS is not set CONFIG_EXT2_FS=y -# CONFIG_XIA_FS is not set # CONFIG_MSDOS_FS is not set CONFIG_PROC_FS=y # CONFIG_ISO9660_FS is not set diff -u --recursive --new-file v2.1.20/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.1.20/linux/arch/sparc/defconfig Tue Dec 31 21:40:59 1996 +++ linux/arch/sparc/defconfig Tue Jan 14 12:59:10 1997 @@ -167,9 +167,7 @@ # CONFIG_QUOTA=y CONFIG_MINIX_FS=m -CONFIG_EXT_FS=m CONFIG_EXT2_FS=y -CONFIG_XIA_FS=m CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m diff -u --recursive --new-file v2.1.20/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c --- v2.1.20/linux/arch/sparc/kernel/sparc_ksyms.c Tue Dec 31 21:40:59 1996 +++ linux/arch/sparc/kernel/sparc_ksyms.c Tue Jan 14 08:58:19 1997 @@ -67,10 +67,8 @@ */ #define EXPORT_SYMBOL_DOT(sym) \ -extern int __sparc_dot_ ## sym (int) __asm__("." ## #sym); \ -const struct module_symbol __export_dot_##sym \ -__attribute__((section("__ksymtab"))) = \ -{ (unsigned long) &__sparc_dot_ ## sym, "." ## #sym } +extern int __sparc_dot_ ## sym (int) __asm__("." #sym); \ +__EXPORT_SYMBOL(__sparc_dot_ ## sym, "." #sym) /* used by various drivers */ diff -u --recursive --new-file v2.1.20/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- v2.1.20/linux/arch/sparc/kernel/sys_sunos.c Tue Dec 31 21:41:00 1996 +++ linux/arch/sparc/kernel/sys_sunos.c Tue Jan 14 12:59:10 1997 @@ -779,10 +779,6 @@ dev_fname = (char *) data; } else if(strcmp(type, "minix") == 0) { dev_fname = (char *) data; - } else if(strcmp(type, "ext") == 0) { - dev_fname = (char *) data; - } else if(strcmp(type, "xiafs") == 0) { - dev_fname = (char *) data; } else if(strcmp(type, "nfs") == 0) { return sunos_nfs_mount (dir, flags, data); } else if(strcmp(type, "ufs") == 0) { diff -u --recursive --new-file v2.1.20/linux/arch/sparc/kernel/unaligned.c linux/arch/sparc/kernel/unaligned.c --- v2.1.20/linux/arch/sparc/kernel/unaligned.c Wed Dec 18 15:58:46 1996 +++ linux/arch/sparc/kernel/unaligned.c Fri Jan 3 18:48:37 1997 @@ -202,11 +202,11 @@ ".word 14b, " #errh "\n\t" \ ".word 15b, " #errh "\n\t" \ ".word 16b, " #errh "\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \ : "l1", "l2", "g7", "g1"); \ }) - + #define store_common(dst_addr, size, src_val, errh) ({ \ __asm__ __volatile__ ( \ "ld [%2], %%l1\n" \ @@ -256,7 +256,7 @@ ".word 15b, " #errh "\n\t" \ ".word 16b, " #errh "\n\t" \ ".word 17b, " #errh "\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : : "r" (dst_addr), "r" (size), "r" (src_val) \ : "l1", "l2", "g7", "g1"); \ }) @@ -307,7 +307,7 @@ { unsigned long g2 = regs->u_regs [UREG_G2]; unsigned long fixup = search_exception_table (regs->pc, &g2); - + if (!fixup) { unsigned long address = compute_effective_address(regs, insn); if(address < PAGE_SIZE) { @@ -336,7 +336,7 @@ printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n", regs->pc); unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store."); - + __asm__ __volatile__ ("\n" "kernel_unaligned_trap_fault:\n\t" "mov %0, %%o0\n\t" @@ -344,7 +344,7 @@ " mov %1, %%o1\n\t" : : "r" (regs), "r" (insn) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7"); - + return; } else { unsigned long addr = compute_effective_address(regs, insn); @@ -369,7 +369,7 @@ #if 0 /* unsupported */ case both: do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), - (unsigned long *) addr, + (unsigned long *) addr, kernel_unaligned_trap_fault); break; #endif @@ -477,7 +477,7 @@ " mov %1, %%o1\n\t" : : "r" (regs), "r" (insn) : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7"); - + return; } advance(regs); diff -u --recursive --new-file v2.1.20/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.1.20/linux/arch/sparc64/defconfig Tue Dec 31 21:41:00 1996 +++ linux/arch/sparc64/defconfig Tue Jan 14 12:59:10 1997 @@ -165,9 +165,7 @@ # CONFIG_QUOTA=y CONFIG_MINIX_FS=y -CONFIG_EXT_FS=y CONFIG_EXT2_FS=y -CONFIG_XIA_FS=y CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff -u --recursive --new-file v2.1.20/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.1.20/linux/drivers/block/rd.c Mon Dec 30 15:39:04 1996 +++ linux/drivers/block/rd.c Fri Jan 3 13:03:42 1997 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,7 @@ * We currently check for the following magic numbers: * minix * ext2 + * romfs * gzip */ int @@ -336,6 +338,7 @@ const int size = 512; struct minix_super_block *minixsb; struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; int nblocks = -1; int max_blocks; unsigned char *buf; @@ -346,6 +349,7 @@ minixsb = (struct minix_super_block *) buf; ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; memset(buf, 0xe5, size); /* @@ -368,6 +372,16 @@ goto done; } + /* romfs is at block zero too */ + if (romfsb->word0 == ROMSB_WORD0 && + romfsb->word1 == ROMSB_WORD1) { + printk(KERN_NOTICE + "RAMDISK: Romfs filesystem found at block %d\n", + start_block); + nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + goto done; + } + /* * Read block 1 to test for minix and ext2 superblock */ @@ -396,6 +410,7 @@ nblocks = ext2sb->s_blocks_count; goto done; } + printk(KERN_NOTICE "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n", start_block); diff -u --recursive --new-file v2.1.20/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.1.20/linux/drivers/char/serial.c Mon Dec 30 15:39:08 1996 +++ linux/drivers/char/serial.c Tue Jan 14 12:52:46 1997 @@ -25,6 +25,7 @@ * int rs_open(struct tty_struct * tty, struct file * filp) */ +#include #include #include #include @@ -35,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -2931,6 +2931,11 @@ } state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; + if (state->type == PORT_UNKNOWN) { + restore_flags(flags); + return; + } + request_region(info->port,8,"serial(auto)"); /* @@ -3099,11 +3104,6 @@ state->port = req->port; state->flags = req->flags; - if (check_region(state->port,8)) { - restore_flags(flags); - printk("register_serial(): I/O region in use\n"); - return -1; /* Area in use */ - } autoconfig(state); if (state->type == PORT_UNKNOWN) { restore_flags(flags); diff -u --recursive --new-file v2.1.20/linux/drivers/net/hdlcdrv.c linux/drivers/net/hdlcdrv.c --- v2.1.20/linux/drivers/net/hdlcdrv.c Thu Jan 2 15:55:18 1997 +++ linux/drivers/net/hdlcdrv.c Fri Jan 3 11:33:26 1997 @@ -35,9 +35,8 @@ /*****************************************************************************/ -#include - #include +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.1.20/linux/drivers/net/ppp.c Thu Jan 2 15:55:19 1997 +++ linux/drivers/net/ppp.c Fri Jan 3 11:33:26 1997 @@ -59,6 +59,7 @@ * released under the GNU General Public License Version 2. */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.1.20/linux/drivers/net/smc-ultra.c Tue Dec 31 21:41:06 1996 +++ linux/drivers/net/smc-ultra.c Tue Jan 14 08:58:19 1997 @@ -434,8 +434,8 @@ static int io[MAX_ULTRA_CARDS] = { 0, }; static int irq[MAX_ULTRA_CARDS] = { 0, }; -MODULE_PARM(io, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i"); +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/ChangeLog.ncr53c8xx linux/drivers/scsi/ChangeLog.ncr53c8xx --- v2.1.20/linux/drivers/scsi/ChangeLog.ncr53c8xx Thu Jan 2 15:55:21 1997 +++ linux/drivers/scsi/ChangeLog.ncr53c8xx Tue Jan 14 08:21:41 1997 @@ -1,3 +1,32 @@ +Sun Jan 12 12:00 1997 Gerard Roudier (groudier@club-internet.fr) + * ncr53c8xx.c - revision 1.16e + - Add support of PCI burst length control from boot setup command. + burst:0 disable burst + burst:255 get burst from initial settings (BIOS settings?) + burst:#x set burst transfers to 1<<#x + - Only check xfer direction for common op-codes. + For all device specific / vendor specific opcodes the driver + now uses the xfer direction decided by the target. + +Sun Jan 05 12:00 1997 Gerard Roudier (groudier@club-internet.fr) + * ncr53c8xx.c - revision 1.16d + - The driver is now able to process scsi commands without + knowledge of xfer data direction. + Stefan agreed with this change for Linux. This change is + not needed under FreeBSD since low-level drivers receive + the expected data direction for each scsi request. + - Save ctest5 features bits at start-up and restore them at + module release step. + Avoid side effects when a ncr driver which trusts bios + settings is reloaded (could be the ncr53c8xx itself). + + +Wed Jan 01 23:30 1997 Gerard Roudier (groudier@club-internet.fr) + * ncr53c8xx.c - revision 1.16c + - Bad decision about 20MHz for 13 ns period factor. + Was wrong, so I restore the previous algorithm. + - Burst length 128 not correctly set in dmode. + Thu Dec 26 22:00 1996 Gerard Roudier (groudier@club-internet.fr) * ncr53c8xx.c ncr53c8xx.h README.ncr53c8xx - revision 1.16b - Remove useless code. diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.1.20/linux/drivers/scsi/Config.in Thu Jan 2 15:55:21 1997 +++ linux/drivers/scsi/Config.in Tue Jan 14 12:48:50 1997 @@ -32,6 +32,8 @@ dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI if [ "$CONFIG_SCSI_EATA" != "n" ]; then bool ' enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE + bool ' enable linked commands' CONFIG_SCSI_EATA_LINKED_COMMANDS + int ' maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16 fi dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI @@ -74,6 +76,10 @@ dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI + if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then + bool ' enable linked commands' CONFIG_SCSI_U14_34F_LINKED_COMMANDS + int ' maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8 + fi dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI endmenu diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v2.1.20/linux/drivers/scsi/Makefile Wed Dec 18 15:58:50 1996 +++ linux/drivers/scsi/Makefile Tue Jan 14 08:58:19 1997 @@ -30,11 +30,19 @@ endif ifeq ($(CONFIG_SCSI),y) -L_OBJS += hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o + # We must attach scsi_syms.o to scsi.o, as otherwise there is nothing to + # pull the object file from the archive. + SCSI=scsi.o + ifeq ($(CONFIG_MODULES),y) + O_TARGET := scsi_n_syms.o + O_OBJS := scsi.o + OX_OBJS := scsi_syms.o + SCSI := $(O_TARGET) + endif + L_OBJS += $(SCSI) hosts.o scsi_ioctl.o constants.o scsicam.o ifeq ($(CONFIG_PROC_FS),y) L_OBJS += scsi_proc.o endif -LX_OBJS += scsi_syms.o else ifeq ($(CONFIG_SCSI),m) MX_OBJS += scsi_syms.o diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/README.ncr53c8xx linux/drivers/scsi/README.ncr53c8xx --- v2.1.20/linux/drivers/scsi/README.ncr53c8xx Thu Jan 2 15:55:21 1997 +++ linux/drivers/scsi/README.ncr53c8xx Tue Jan 14 08:21:41 1997 @@ -4,7 +4,7 @@ 21 Rue Carnot 95170 DEUIL LA BARRE - FRANCE -29 December 1996 +12 January 1997 =============================================================================== 1. Introduction @@ -62,6 +62,10 @@ This driver has been tested OK with linux/i386 and Linux/Alpha. +Latest driver version and patches are available at: + + ftp://linux.wauug.org/pub/roudier + I am not a native speaker of English and there are probably lots of mistakes in this README file. Any help will be welcome. @@ -491,8 +495,20 @@ DEBUG_FREEZE 0x800 DEBUG_RESTART 0x1000 -You can play safely with DEBUG_NEGO. However, some of these flags may -generate bunches of syslog messages. + You can play safely with DEBUG_NEGO. However, some of these flags may + generate bunches of syslog messages. + +Burst max + burst:0 burst disabled + burst:255 get burst length from initial IO register settings. + burst:#x burst enabled (1<<#x burst transfers max) + #x is an integer value which is log base 2 of the burst transfers max. + The NCR53C875 and NCR53C825A support up to 128 burst transfers (#x = 7). + Other chips only support up to 16 (#x = 4). + This is a maximum value. The driver set the burst length according to chip + and revision ids. By default the driver uses the maximum value supported + by the chip. + 10.3 Advised boot setup commands @@ -508,7 +524,8 @@ The driver prints its actual setup when verbosity level is 2. You can try "ncr53c8xx=verb:2" to get the "static" setup of the driver, or add "verb:2" -to your boot setup command in order to check the actual setup the drive use. +to your boot setup command in order to check the actual setup the driver is +using. 11. Some constants and flags of the ncr53c8xx.h header file diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v2.1.20/linux/drivers/scsi/eata.c Thu Dec 12 19:37:07 1996 +++ linux/drivers/scsi/eata.c Tue Jan 14 12:48:50 1997 @@ -1,6 +1,10 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. * + * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 + * Added linked command support. + * Improved detection of PCI boards using ISA base addresses. + * * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 * Added support for tagged commands and queue depth adjustment. * @@ -88,7 +92,7 @@ * This driver is based on the CAM (Common Access Method Committee) * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. * - * Copyright (C) 1994, 1995, 1996 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994-1997 Dario Ballabio (dario@milano.europe.dg.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source @@ -124,6 +128,15 @@ * PCI support has been tested using up to 2 DPT PM3224W (DPT SCSI BIOS * v003.D0, firmware v07G.0). * + * DPT SmartRAID boards support "Hardware Array" - a group of disk drives + * which are all members of the same RAID-1 or RAID-5 array implemented + * in host adapter hardware. Hardware Arrays are fully compatible with this + * driver, since they look to it as a single disk drive. + * By contrast RAID-0 are implemented as "Array Group", which does not + * seem to be supported correctly by the actual SCSI subsystem. + * To get RAID-0 functionality, the linux MD driver must be used instead of + * the DPT "Array Group" feature. + * * Multiple ISA, EISA and PCI boards can be configured in the same system. * It is suggested to put all the EISA boards on the same IRQ level, all * the PCI boards on another IRQ level, while ISA boards cannot share @@ -202,6 +215,7 @@ #undef FORCE_CONFIG +#undef DEBUG_LINKED_COMMANDS #undef DEBUG_DETECT #undef DEBUG_INTERRUPT #undef DEBUG_STATISTICS @@ -231,6 +245,8 @@ #define LOCKED 2 #define IN_RESET 3 #define IGNORE 4 +#define READY 5 +#define ABORTING 6 #define NO_DMA 0xff #define MAXLOOP 200000 @@ -245,8 +261,9 @@ #define REG_MID 4 #define REG_MSB 5 #define REGION_SIZE 9 -#define ISA_RANGE 0x0fff -#define EISA_RANGE 0xfc88 +#define MAX_ISA_ADDR 0x03ff +#define MIN_EISA_ADDR 0x1c88 +#define MAX_EISA_ADDR 0xfc88 #define BSY_ASSERTED 0x80 #define DRQ_ASSERTED 0x08 #define ABSY_ASSERTED 0x01 @@ -373,6 +390,7 @@ ulong sp_addr; /* Address where sp is DMA'ed when cp completes */ ulong sense_addr; /* Address where Sense Data is DMA'ed on error */ unsigned int index; /* cp index */ + unsigned int link_id; /* reference cp for linked commands */ struct sg_list *sglist; }; @@ -437,6 +455,18 @@ static int tagged_commands = FALSE; #endif +#if defined (CONFIG_SCSI_EATA_LINKED_COMMANDS) +static int linked_commands = TRUE; +#else +static int linked_commands = FALSE; +#endif + +#if defined CONFIG_SCSI_EATA_MAX_TAGS +static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS; +#else +static int max_queue_depth = MAX_CMD_PER_LUN; +#endif + static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { Scsi_Device *dev; int j, ntag = 0, nuntag = 0, tqd, utqd; @@ -459,7 +489,7 @@ tqd = (host->can_queue - utqd * nuntag) / (ntag + 1); - if (tqd > MAX_TAGGED_CMD_PER_LUN) tqd = MAX_TAGGED_CMD_PER_LUN; + if (tqd > max_queue_depth) tqd = max_queue_depth; if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN; @@ -568,34 +598,59 @@ else protocol_rev = 'C'; - irq = info.irq; - - if (port_base > ISA_RANGE) { - - if (!info.haaval || info.ata || info.drqvld) { - printk("%s: unusable EISA/PCI board found (%d%d%d), detaching.\n", - name, info.haaval, info.ata, info.drqvld); - return FALSE; - } - + if (!setup_done && j > 0 && j <= MAX_PCI) { + bus_type = "PCI"; + subversion = ESA; + } + else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) { + bus_type = "PCI"; + subversion = ESA; + } + else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) { + bus_type = "EISA"; + subversion = ESA; + } + else if (protocol_rev == 'C' && !info.eisa && !info.pci) { + bus_type = "ISA"; + subversion = ISA; + } + else if (port_base > MAX_ISA_ADDR) { + bus_type = "PCI"; subversion = ESA; - dma_channel = NO_DMA; } else { + bus_type = "ISA"; + subversion = ISA; + } - if (!info.haaval || info.ata || !info.drqvld) { - printk("%s: unusable ISA board found (%d%d%d), detaching.\n", - name, info.haaval, info.ata, info.drqvld); - return FALSE; - } + if (!info.haaval || info.ata) { + printk("%s: address 0x%03x, unusable %s board (%d%d), detaching.\n", + name, port_base, bus_type, info.haaval, info.ata); + return FALSE; + } + + if (info.drqvld) { + + if (subversion == ESA) + printk("%s: warning, weird %s board using DMA.\n", name, bus_type); subversion = ISA; dma_channel = dma_channel_table[3 - info.drqx]; } + else { + + if (subversion == ISA) + printk("%s: warning, weird %s board not using DMA.\n", name, bus_type); + + subversion = ESA; + dma_channel = NO_DMA; + } if (!info.dmasup) printk("%s: warning, DMA protocol support not asserted.\n", name); + irq = info.irq; + if (subversion == ESA && !info.irq_tr) printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", name, irq); @@ -707,11 +762,6 @@ sh[j]->max_lun = info.max_lun + 1; } - if (subversion == ESA && protocol_rev == 'C' && info.pci) bus_type = "PCI"; - else if (sh[j]->io_port > EISA_RANGE) bus_type = "PCI"; - else if (subversion == ESA) bus_type = "EISA"; - else bus_type = "ISA"; - if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "NO DMA"); else sprintf(dma_name, "DMA %u", dma_channel); @@ -724,10 +774,15 @@ return FALSE; } - printk("%s: rev. 2.0%c, %s, PORT 0x%03x, IRQ %u, %s, SG %d, "\ - "Mbox %d, TC %d.\n", BN(j), HD(j)->protocol_rev, bus_type, - sh[j]->io_port, sh[j]->irq, dma_name, sh[j]->sg_tablesize, - sh[j]->can_queue, tagged_commands); + if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) + max_queue_depth = MAX_TAGGED_CMD_PER_LUN; + + if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; + + printk("%s: 2.0%c, %s 0x%03x, IRQ %u, %s, SG %d, MB %d, TC %d, LC %d, "\ + "MQ %d.\n", BN(j), HD(j)->protocol_rev, bus_type, sh[j]->io_port, + sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue, + tagged_commands, linked_commands, max_queue_depth); if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", @@ -831,7 +886,7 @@ } if (j > 0) - printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995, 1996 Dario Ballabio.\n"); + printk("EATA/DMA 2.0x: Copyright (C) 1994-1997 Dario Ballabio.\n"); restore_flags(flags); return j; @@ -962,6 +1017,28 @@ memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); + if (linked_commands && SCpnt->device->tagged_supported + && !HD(j)->target_to[SCpnt->target][SCpnt->channel] + && !HD(j)->target_redo[SCpnt->target][SCpnt->channel]) + + for (k = 0; k < sh[j]->can_queue; k++) { + + if (HD(j)->cp_stat[k] != IN_USE) continue; + + if ((&HD(j)->cp[k])->SCpnt->device != SCpnt->device) continue; + + cpp->link_id = k; + HD(j)->cp_stat[i] = READY; + +#if defined (DEBUG_LINKED_COMMANDS) + printk("%s: qcomm, target %d.%d:%d, pid %ld, Mbox %d ready.\n", + BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, + SCpnt->pid, i); +#endif + restore_flags(flags); + return 0; + } + /* Send control packet to the board */ if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) { SCpnt->result = DID_ERROR << 16; @@ -1038,6 +1115,18 @@ restore_flags(flags); return SCSI_ABORT_NOT_RUNNING; } + + if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { + SCarg->result = DID_ABORT << 16; + SCarg->host_scribble = NULL; + HD(j)->cp_stat[i] = FREE; + printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", + BN(j), i, SCarg->pid); + SCarg->scsi_done(SCarg); + restore_flags(flags); + return SCSI_ABORT_SUCCESS; + } + restore_flags(flags); panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); } @@ -1088,14 +1177,21 @@ continue; } - SCpnt = HD(j)->cp[i].SCpnt; - HD(j)->cp_stat[i] = IN_RESET; - printk("%s: reset, mbox %d in reset, pid %ld.\n", - BN(j), i, SCpnt->pid); - - if (SCpnt == NULL) + if (!(SCpnt = HD(j)->cp[i].SCpnt)) panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); + if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { + HD(j)->cp_stat[i] = ABORTING; + printk("%s: reset, mbox %d aborting, pid %ld.\n", + BN(j), i, SCpnt->pid); + } + + else { + HD(j)->cp_stat[i] = IN_RESET; + printk("%s: reset, mbox %d in reset, pid %ld.\n", + BN(j), i, SCpnt->pid); + } + if (SCpnt->host_scribble == NULL) panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); @@ -1129,18 +1225,35 @@ for (i = 0; i < sh[j]->can_queue; i++) { - /* Skip mailboxes already set free by interrupt */ - if (HD(j)->cp_stat[i] != IN_RESET) continue; + if (HD(j)->cp_stat[i] == IN_RESET) { + SCpnt = HD(j)->cp[i].SCpnt; + SCpnt->result = DID_RESET << 16; + SCpnt->host_scribble = NULL; - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; + /* This mailbox is still waiting for its interrupt */ + HD(j)->cp_stat[i] = LOCKED; - /* This mailbox is still waiting for its interrupt */ - HD(j)->cp_stat[i] = LOCKED; + printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", + BN(j), i, SCpnt->pid); + } + + else if (HD(j)->cp_stat[i] == ABORTING) { + SCpnt = HD(j)->cp[i].SCpnt; + SCpnt->result = DID_RESET << 16; + SCpnt->host_scribble = NULL; + + /* This mailbox was never queued to the adapter */ + HD(j)->cp_stat[i] = FREE; + + printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", + BN(j), i, SCpnt->pid); + } + + else + + /* Any other mailbox has already been set free by interrupt */ + continue; - printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); restore_flags(flags); SCpnt->scsi_done(SCpnt); cli(); @@ -1160,6 +1273,42 @@ } } +static inline void process_ready_list(unsigned int i, unsigned int j) { + Scsi_Cmnd *SCpnt; + unsigned int k, n_ready = 0; + struct mscp *cpp; + + for (k = 0; k < sh[j]->can_queue; k++) { + + if (HD(j)->cp_stat[k] != READY) continue; + + cpp = &HD(j)->cp[k]; + + if (cpp->link_id != i) continue; + + SCpnt = cpp->SCpnt; + n_ready++; + + if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) { + printk("%s: ihdlr, target %d.%d:%d, pid %ld, Mbox %d, link_id %d, "\ + "n_ready %d, adapter busy, will abort.\n", BN(j), + SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, + k, i, n_ready); + HD(j)->cp_stat[k] = ABORTING; + continue; + } + + HD(j)->cp_stat[k] = IN_USE; + +#if defined (DEBUG_LINKED_COMMANDS) + printk("%s: ihdlr, target %d.%d:%d, pid %ld, Mbox %d in use, link_id %d," + " n_ready %d.\n", BN(j), SCpnt->channel, SCpnt->target, + SCpnt->lun, SCpnt->pid, k, i, n_ready); +#endif + } + +} + static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) { Scsi_Cmnd *SCpnt; @@ -1207,6 +1356,8 @@ spp->eoc = FALSE; + if (linked_commands) process_ready_list(i, j); + if (HD(j)->cp_stat[i] == IGNORE) { HD(j)->cp_stat[i] = FREE; continue; diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h --- v2.1.20/linux/drivers/scsi/eata.h Thu Dec 12 19:37:07 1996 +++ linux/drivers/scsi/eata.h Tue Jan 14 12:48:50 1997 @@ -12,7 +12,7 @@ int eata2x_abort(Scsi_Cmnd *); int eata2x_reset(Scsi_Cmnd *, unsigned int); -#define EATA_VERSION "2.40.00" +#define EATA_VERSION "2.50.00" #define EATA { \ diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.20/linux/drivers/scsi/ncr53c8xx.c Thu Jan 2 15:55:21 1997 +++ linux/drivers/scsi/ncr53c8xx.c Tue Jan 14 08:21:41 1997 @@ -40,7 +40,7 @@ */ /* -** 26 December 1996, version 1.16b +** 12 January 1997, version 1.16e ** ** Supported SCSI-II features: ** Synchronous negotiation @@ -368,15 +368,17 @@ /* ** Transfer direction ** -** The middle scsi driver of Linux does not provide the transfer -** direction in the command structure. -** FreeBsd ncr driver requires this information. -** -** I spent some hours to read the scsi2 documentation to see if -** it was possible to deduce the direction of transfer from the opcode -** of the command. It seems that it's OK. -** guess_xfer_direction() seems to work. If it's wrong we will -** get a phase mismatch on some opcode. +** Low-level scsi drivers under Linux do not receive the expected +** data transfer direction from upper scsi drivers. +** The driver will only check actual data direction for common +** scsi opcodes. Other ones may cause problem, since they may +** depend on device type or be vendor specific. +** I would prefer to never trust the device for data direction, +** but that is not possible. +** +** The original driver requires the expected direction to be known. +** The Linux version of the driver has been enhanced in order to +** be able to transfer data in the direction choosen by the target. */ #define XferNone 0 @@ -440,6 +442,7 @@ unsigned default_tags; unsigned default_sync; unsigned debug; + unsigned burst_max; } driver_setup = SCSI_NCR_DRIVER_SETUP; /* @@ -656,7 +659,8 @@ #define SIR_REJECT_SENT (10) #define SIR_IGN_RESIDUE (11) #define SIR_MISSING_SAVE (12) -#define SIR_MAX (12) +#define SIR_DATA_IO_IS_OUT (13) +#define SIR_MAX (13) /*========================================================== ** @@ -1254,6 +1258,14 @@ */ u_char tag; + + /* + ** Number of segments of the scatter list. + ** Used for recalculation of savep/goalp/lastp on + ** SIR_DATA_IO_IS_OUT interrupt. + */ + + u_char segments; }; #define CCB_PHYS(cp,lbl) (cp->p_ccb + offsetof(struct ccb, lbl)) @@ -1297,6 +1309,7 @@ u_char sv_dcntl; u_char sv_ctest3; u_char sv_ctest4; + u_char sv_ctest5; u_char rv_dmode; u_char rv_dcntl; @@ -1544,6 +1557,7 @@ ncrcmd resel_tmp [ 5]; ncrcmd resel_lun [ 18]; ncrcmd resel_tag [ 24]; + ncrcmd data_io [ 2]; /* MUST be just before data_in */ ncrcmd data_in [MAX_SCATTER * 4 + 7]; ncrcmd data_out [MAX_SCATTER * 4 + 7]; ncrcmd aborttag [ 4]; @@ -3088,6 +3102,17 @@ SCR_RETURN, 0, +}/*-------------------------< DATA_IO >--------------------*/,{ +/* +** Because Linux does not provide xfer data direction +** to low-level scsi drivers, we must trust the target +** for actual data direction when we cannot guess it. +** The programmed interrupt patches savep, lastp, goalp, +** etc.., and restarts the scsi script at data_out. +*/ + SCR_INT ^ IFTRUE (WHEN (SCR_DATA_OUT)), + SIR_DATA_IO_IS_OUT, + }/*-------------------------< DATA_IN >--------------------*/,{ /* ** Because the size depends on the @@ -4149,8 +4174,14 @@ **---------------------------------------------------- */ + cp->segments = segments; + switch (xfer_direction) { default: + case XferBoth: + cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_io); + cp->phys.header.goalp = cp->phys.header.savep +8 +20 +segments*16; + break; case XferIn: cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_in); cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16; @@ -4470,6 +4501,7 @@ OUTB(nc_dcntl, np->sv_dcntl); OUTB(nc_ctest3, np->sv_ctest3); OUTB(nc_ctest4, np->sv_ctest4); + OUTB(nc_ctest5, np->sv_ctest5); if (np->uf_doubler) { OUTB(nc_stest1, DBLEN); /* Enable clock doubler */ @@ -4883,6 +4915,46 @@ }; } +/*=============================================================== +** +** NCR chips allow burst lengths of 2, 4, 8, 16, 32, 64, 128 +** transfers. 32,64,128 are only supported by 875 chips. +** We use log base 2 (burst length) as internal code, with +** value 0 meaning "burst disabled". +** +**=============================================================== +*/ + +/* + * Burst length from burst code. + */ +#define burst_length(bc) (!(bc))? 0 : 1 << (bc) + +/* + * Burst code from io register bits. + */ +#define burst_code(dmode, ctest4, ctest5) \ + (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1 + +/* + * Set initial io register bits from burst code. + */ +static void ncr_init_burst(ncb_p np, u_char bc) +{ + np->rv_ctest4 &= ~0x80; + np->rv_dmode &= ~(0x3 << 6); + np->rv_ctest5 &= ~0x4; + + if (!bc) { + np->rv_ctest4 |= 0x80; + } + else { + --bc; + np->rv_dmode |= ((bc & 0x3) << 6); + np->rv_ctest5 |= (bc & 0x4); + } +} + /*========================================================== ** ** @@ -4897,6 +4969,7 @@ int i; u_long usrsync; u_char usrwide; + u_char burst_max; /* ** Reset chip. @@ -4938,40 +5011,48 @@ np->rv_dcntl = np->sv_dcntl; np->rv_ctest3 = np->sv_ctest3; np->rv_ctest4 = np->sv_ctest4; + np->rv_ctest5 = np->sv_ctest5; + burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5); #else np->rv_dmode = 0; np->rv_dcntl = 0; np->rv_ctest3 = 0; np->rv_ctest4 = 0; + burst_max = driver_setup.burst_max; + if (burst_max == 255) + burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5); + if (burst_max > 7) + burst_max = 7; /** NCR53C810 **/ if (ChipDevice == PCI_DEVICE_ID_NCR_53C810 && ChipVersion == 0) { - np->rv_dmode = 0x80; /* burst length 8 */ + burst_max = burst_max < 4 ? burst_max : 4; } else /** NCR53C815 **/ if (ChipDevice == PCI_DEVICE_ID_NCR_53C815) { - np->rv_dmode = 0x80; /* burst length 8 */ + burst_max = burst_max < 4 ? burst_max : 4; } else /** NCR53C825 **/ if (ChipDevice == PCI_DEVICE_ID_NCR_53C825 && ChipVersion == 0) { - np->rv_dmode = 0x8a; /* burst length 8, burst opcode fetch */ + burst_max = burst_max < 4 ? burst_max : 4; + np->rv_dmode = 0x0a; /* burst opcode fetch */ } else /** NCR53C810A or NCR53C860 **/ if ((ChipDevice == PCI_DEVICE_ID_NCR_53C810 && ChipVersion >= 0x10) || ChipDevice == PCI_DEVICE_ID_NCR_53C860) { if (!driver_setup.special_features) - np->rv_dmode = 0xc0; /* burst length 16 */ + burst_max = burst_max < 4 ? burst_max : 4; else { - np->rv_dmode = 0xc0 | BOF | ERMP | ERL; + burst_max = burst_max < 4 ? burst_max : 4; + np->rv_dmode = BOF | ERMP | ERL; /* burst op-code fetch, read multiple */ - /* read line, burst 16 */ + /* read line */ np->rv_dcntl = PFEN | CLSE; /* prefetch, cache line size */ np->rv_ctest3 = WRIE; /* write and invalidate */ - np->rv_ctest4 = 0x0; /* burst not disabled */ } } else @@ -4979,30 +5060,43 @@ if ((ChipDevice == PCI_DEVICE_ID_NCR_53C825 && ChipVersion >= 0x10) || ChipDevice == PCI_DEVICE_ID_NCR_53C875) { if (!driver_setup.special_features) - np->rv_dmode = 0xc0; /* burst length 16 */ + burst_max = burst_max < 4 ? burst_max : 4; else { - np->rv_dmode = 0xc0 | BOF | ERMP | ERL; + burst_max = burst_max < 7 ? burst_max : 7; + np->rv_dmode = BOF | ERMP | ERL; /* burst op-code fetch, read multiple */ /* read line, burst 128 (ctest5&4) */ np->rv_dcntl = PFEN | CLSE; /* prefetch, cache line size */ np->rv_ctest3 = WRIE; /* write and invalidate */ - np->rv_ctest4 = 0x0; /* burst not disabled */ - np->rv_ctest5 = 0x24; /* burst 128 (0x04) */ - /* dma fifo 536 (0x20) */ + np->rv_ctest5 = 0x20; /* dma fifo 536 (0x20) */ } } /** OTHERS **/ else { - np->rv_dmode = 0xc0; /* burst length 16 */ + burst_max = burst_max < 4 ? burst_max : 4; } #endif /* SCSI_NCR_TRUST_BIOS_SETTING */ + /* + * Prepare initial io register bits for burst length + */ + ncr_init_burst(np, burst_max); + + if (bootverbose > 1) { + printf ("%s: initial value of dmode/ctest4/ctest5 = 0x%02x/0x%02x/0x%02x\n", + ncr_name(np), np->sv_dmode, np->sv_ctest4, np->sv_ctest5); + } + if (bootverbose) { + printf ("%s: final value of dmode/ctest4/ctest5 = 0x%02x/0x%02x/0x%02x\n", + ncr_name(np), np->rv_dmode, np->rv_ctest4, np->rv_ctest5); + } + #if 0 - printf("%s: bios: dmode=0x%02x, dcntl=0x%02x, ctest3=0x%02x, ctest4=0x%02x\n", - ncr_name(np), np->sv_dmode, np->sv_dcntl, np->sv_ctest3, np->sv_ctest4); - printf("%s: used: dmode=0x%02x, dcntl=0x%02x, ctest3=0x%02x, ctest4=0x%02x\n", - ncr_name(np), np->rv_dmode, np->rv_dcntl, np->rv_ctest3, np->rv_ctest4); + printf("%s: bios: dmode=0x%02x, dcntl=0x%02x, ctest3=0x%02x, ctest4=0x%02x, ctest5=0x%02x\n", + ncr_name(np), np->sv_dmode, np->sv_dcntl, np->sv_ctest3, np->sv_ctest4, np->sv_ctest5); + printf("%s: used: dmode=0x%02x, dcntl=0x%02x, ctest3=0x%02x, ctest4=0x%02x, ctest5=0x%02x\n", + ncr_name(np), np->rv_dmode, np->rv_dcntl, np->rv_ctest3, np->rv_ctest4, np->rv_ctest5); #endif OUTB (nc_istat, 0x00 ); /* Remove Reset, abort ... */ @@ -6268,6 +6362,23 @@ } switch (num) { + case SIR_DATA_IO_IS_OUT: +/* +** We did not guess the direction of transfer. We assumed DATA IN, +** but the the target drove DATA OUT. +** We have to patch the script context with DATA OUT context and +** restart processing at data out script address. +*/ + cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_out); + cp->phys.header.goalp = cp->phys.header.savep +20 +cp->segments*16; + cp->phys.header.lastp = cp->phys.header.savep; + np->header.savep = cp->phys.header.savep; + np->header.goalp = cp->phys.header.goalp; + np->header.lastp = cp->phys.header.lastp; + OUTL (nc_temp, np->header.savep); + OUTL (nc_dsp, np->header.savep); + return; + /* break; */ /*-------------------------------------------------------------------- ** @@ -6492,14 +6603,14 @@ /* ** Check against controller limits. ** -------------------------------- - ** per <= 13 special case, allow fast 20 MHz transfer. - ** per < 25 fast 20 + ** per < 25 fast20 ** per < 50 fast ** per < 100 slow ** Use a value p2 twice the controller limit in order to ** not do wrong integer calculation for 80 MHz clock. ** (12.5x2 = 25ns). - ** Compute scntl3&0xf0 sync clock divisor for 50 ns period. + ** Compute scntl3&0xf0 sync clock divisor for 50 ns period + ** from the async pre-scaler. ** Ajust it according to actual controller sync period. ** - 0x40 divides it by 4 -> 50/4 = 12.5ns ** - 0x20 divides it by 2 -> 50/2 = 25 ns @@ -6513,25 +6624,19 @@ p2 = 100; scntl3 = (np->rv_scntl3 & 0x07) << 4; - if (per <= 13) { - fak = 0; + if (per < 25) { + p2 = 25; scntl3 = (scntl3 - 0x40) | 0x80; } - else { - if (per < 25) { - p2 = 25; - scntl3 = (scntl3 - 0x40) | 0x80; - } - else if (per < 50) { - p2 = 50; - scntl3 = scntl3 - 0x20; - } + else if (per < 50) { + p2 = 50; + scntl3 = scntl3 - 0x20; + } - fak = (8 * per - 1) / p2 - 3; - if (fak > 7) { - chg = 1; - ofs = 0; - } + fak = (8 * per - 1) / p2 - 3; + if (fak > 7) { + chg = 1; + ofs = 0; } } if (ofs == 0) { @@ -7654,22 +7759,27 @@ ** 0x04 enable read multiple ** 0x08 enable read line ** 0xc0 burst length 16/8/2 -** DCNTL 0xa0 +** DCNTL 0xa8 +** 0x08 totem pole irq ** 0x20 enable pre-fetch ** 0x80 enable cache line size ** CTEST3 0x01 ** 0x01 set write and invalidate ** CTEST4 0x80 ** 0x80 burst disabled +** CTEST5 0x24 +** 0x20 dma fifo 536 (875 only) +** 0x04 burst len 32/64/128 (875 only) */ static void ncr_save_bios_setting(ncb_p np) { np->sv_scntl3 = INB(nc_scntl3) & 0x07; np->sv_dmode = INB(nc_dmode) & 0xce; - np->sv_dcntl = INB(nc_dcntl) & 0xa0; + np->sv_dcntl = INB(nc_dcntl) & 0xa8; np->sv_ctest3 = INB(nc_ctest3) & 0x01; np->sv_ctest4 = INB(nc_ctest4) & 0x80; + np->sv_ctest5 = INB(nc_ctest5) & 0x24; } /*===================== LINUX ENTRY POINTS SECTION ==========================*/ @@ -7750,6 +7860,8 @@ driver_setup.verbose = val; else if (!strncmp(cur, "debug:", 6)) driver_setup.debug = val; + else if (!strncmp(cur, "burst:", 6)) + driver_setup.burst_max = val; if ((cur = strchr(cur, ',')) != NULL) ++cur; @@ -7804,12 +7916,13 @@ #define YesNo(y) y ? 'y' : 'n' if (bootverbose >= 2) { - printk("ncr53c8xx: setup=disc:%c,specf:%c,ultra:%c,tags:%d,sync:%d\n", + printk("ncr53c8xx: setup=disc:%c,specf:%c,ultra:%c,tags:%d,sync:%d,burst:%d\n", YesNo(driver_setup.disconnection), YesNo(driver_setup.special_features), YesNo(driver_setup.ultra_scsi), driver_setup.default_tags, - driver_setup.default_sync/1000); + driver_setup.default_sync/1000, + driver_setup.burst_max); printk("ncr53c8xx: setup=mpar:%c,spar:%c,fsn=%c,verb:%d,debug:0x%x\n", YesNo(driver_setup.master_parity), YesNo(driver_setup.scsi_parity), @@ -8173,13 +8286,7 @@ #undef next_wcmd /* -** In order to patch the SCSI script for SAVE/RESTORE DATA POINTER, -** we need the direction of transfer. -** Linux middle-level scsi driver does not provide this information. -** So we have to guess it. -** My documentation about SCSI-II standard is old. Probably some opcode -** are missing. -** If I do'nt know the command code, I assume input transfer direction. +** Returns data transfer direction for common op-codes. */ static int guess_xfer_direction(int opcode) @@ -8187,111 +8294,31 @@ int d; switch(opcode) { - case 0x00: /* TEST UNIT READY 00 */ - case 0x08: /* READ(6) 08 */ case 0x12: /* INQUIRY 12 */ case 0x4D: /* LOG SENSE 4D */ case 0x5A: /* MODE SENSE(10) 5A */ case 0x1A: /* MODE SENSE(6) 1A */ - case 0x28: /* READ(10) 28 */ - case 0xA8: /* READ(12) A8 */ case 0x3C: /* READ BUFFER 3C */ case 0x1C: /* RECEIVE DIAGNOSTIC RESULTS 1C */ - case 0xB7: /* READ DEFECT DATA(12) B7 */ - case 0xB8: /* READ ELEMENT STATUS B8 */ - /* GET WINDOW 25 */ - case 0x25: /* READ CAPACITY 25 */ - case 0x29: /* READ GENERATION 29 */ - case 0x3E: /* READ LONG 3E */ - /* GET DATA BUFFER STATUS 34 */ - /* PRE-FETCH 34 */ - case 0x34: /* READ POSITION 34 */ case 0x03: /* REQUEST SENSE 03 */ - case 0x05: /* READ BLOCK LIMITS 05 */ - case 0x0F: /* READ REVERSE 0F */ - case 0x14: /* RECOVER BUFFERED DATA 14 */ - case 0x2D: /* READ UPDATED BLOCK 2D */ - case 0x37: /* READ DEFECT DATA(10) 37 */ - case 0x42: /* READ SUB-CHANNEL 42 */ - case 0x43: /* READ TOC 43 */ - case 0x44: /* READ HEADER 44 */ - case 0xC7: /* ??? ??? C7 */ d = XferIn; break; case 0x39: /* COMPARE 39 */ case 0x3A: /* COPY AND VERIFY 3A */ - /* PRINT 0A */ - /* SEND MESSAGE(6) 0A */ - case 0x0A: /* WRITE(6) 0A */ case 0x18: /* COPY 18 */ case 0x4C: /* LOG SELECT 4C */ case 0x55: /* MODE SELECT(10) 55 */ case 0x3B: /* WRITE BUFFER 3B */ case 0x1D: /* SEND DIAGNOSTIC 1D */ case 0x40: /* CHANGE DEFINITION 40 */ - /* SEND MESSAGE(12) AA */ - case 0xAA: /* WRITE(12) AA */ - case 0xB6: /* SEND VOLUME TAG B6 */ - case 0x3F: /* WRITE LONG 3F */ - case 0x04: /* FORMAT UNIT 04 */ - /* INITIALIZE ELEMENT STATUS 07 */ - case 0x07: /* REASSIGN BLOCKS 07 */ case 0x15: /* MODE SELECT(6) 15 */ - case 0x24: /* SET WINDOW 24 */ - case 0x2A: /* WRITE(10) 2A */ - case 0x2E: /* WRITE AND VERIFY(10) 2E */ - case 0xAE: /* WRITE AND VERIFY(12) AE */ - case 0xB0: /* SEARCH DATA HIGH(12) B0 */ - case 0xB1: /* SEARCH DATA EQUAL(12) B1 */ - case 0xB2: /* SEARCH DATA LOW(12) B2 */ - /* OBJECT POSITION 31 */ - case 0x30: /* SEARCH DATA HIGH(10) 30 */ - case 0x31: /* SEARCH DATA EQUAL(10) 31 */ - case 0x32: /* SEARCH DATA LOW(10) 32 */ - case 0x38: /* MEDIUM SCAN 38 */ - case 0x3D: /* UPDATE BLOCK 3D */ - case 0x41: /* WRITE SAME 41 */ - /* LOAD UNLOAD 1B */ - /* SCAN 1B */ - case 0x1B: /* START STOP UNIT 1B */ d = XferOut; break; - case 0x01: /* REZERO UNIT 01 */ - /* SEEK(6) 0B */ - case 0x0B: /* SLEW AND PRINT 0B */ - /* SYNCHRONIZE BUFFER 10 */ - case 0x10: /* WRITE FILEMARKS 10 */ - case 0x11: /* SPACE 11 */ - case 0x13: /* VERIFY 13 */ - case 0x16: /* RESERVE UNIT 16 */ - case 0x17: /* RELEASE UNIT 17 */ - case 0x19: /* ERASE 19 */ - /* LOCATE 2B */ - /* POSITION TO ELEMENT 2B */ - case 0x2B: /* SEEK(10) 2B */ - case 0x1E: /* PREVENT ALLOW MEDIUM REMOVAL 1E */ - case 0x2C: /* ERASE(10) 2C */ - case 0xAC: /* ERASE(12) AC */ - case 0x2F: /* VERIFY(10) 2F */ - case 0xAF: /* VERIFY(12) AF */ - case 0x33: /* SET LIMITS(10) 33 */ - case 0xB3: /* SET LIMITS(12) B3 */ - case 0x35: /* SYNCHRONIZE CACHE 35 */ - case 0x36: /* LOCK UNLOCK CACHE 36 */ - case 0x45: /* PLAY AUDIO(10) 45 */ - case 0x47: /* PLAY AUDIO MSF 47 */ - case 0x48: /* PLAY AUDIO TRACK/INDEX 48 */ - case 0x49: /* PLAY TRACK RELATIVE(10) 49 */ - case 0xA9: /* PLAY TRACK RELATIVE(12) A9 */ - case 0x4B: /* PAUSE/RESUME 4B */ - /* MOVE MEDIUM A5 */ - case 0xA5: /* PLAY AUDIO(12) A5 */ - case 0xA6: /* EXCHANGE MEDIUM A6 */ - case 0xB5: /* REQUEST VOLUME ELEMENT ADDRESS B5 */ + case 0x00: /* TEST UNIT READY 00 */ d = XferNone; break; default: - d = XferIn; + d = XferBoth; break; } diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.1.20/linux/drivers/scsi/ncr53c8xx.h Thu Jan 2 15:55:21 1997 +++ linux/drivers/scsi/ncr53c8xx.h Tue Jan 14 08:21:41 1997 @@ -45,7 +45,7 @@ /* ** Name and revision of the driver */ -#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.16b" +#define SCSI_NCR_DRIVER_NAME "ncr53c8xx - revision 1.16e" /* ** If SCSI_NCR_SETUP_SPECIAL_FEATURES is defined, @@ -292,7 +292,8 @@ 1, \ SCSI_NCR_SETUP_DEFAULT_TAGS, \ SCSI_NCR_SETUP_DEFAULT_SYNC, \ - 0x00 \ + 0x00, \ + 7 \ } diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c --- v2.1.20/linux/drivers/scsi/scsi_syms.c Mon Dec 30 15:39:11 1996 +++ linux/drivers/scsi/scsi_syms.c Fri Jan 3 11:33:26 1997 @@ -3,8 +3,8 @@ * a module. */ #define __NO_VERSION__ -#include #include +#include #ifdef CONFIG_MODULES diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/st_options.h linux/drivers/scsi/st_options.h --- v2.1.20/linux/drivers/scsi/st_options.h Sun Dec 17 10:59:24 1995 +++ linux/drivers/scsi/st_options.h Thu Jan 2 20:27:46 1997 @@ -88,4 +88,8 @@ files and the file number status is retained. */ #define ST_FAST_MTEOM 0 +/* If ST_SYSV is non-zero, the tape behaves according to the SYS V semantics. + The default is BSD semantics. */ +#define ST_SYSV 0 + #endif diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v2.1.20/linux/drivers/scsi/u14-34f.c Thu Dec 12 19:37:17 1996 +++ linux/drivers/scsi/u14-34f.c Tue Jan 14 12:48:50 1997 @@ -1,6 +1,9 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 + * Added linked command support. + * * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 * Added queue depth adjustment. * @@ -81,7 +84,7 @@ * * Multiple U14F and/or U34F host adapters are supported. * - * Copyright (C) 1994, 1995, 1996 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994-1997 Dario Ballabio (dario@milano.europe.dg.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source @@ -115,8 +118,8 @@ * * Here a sample configuration using two U14F boards: * - U14F0: PORT 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, Mbox 16, UC 1. - U14F1: PORT 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, Mbox 16, UC 1. + U14F0: ISA 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, MB 16, UC 1, LC 1, MQ 8. + U14F1: ISA 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, MB 16, UC 1, LC 1, MQ 8. * * The boot controller must have its BIOS enabled, while other boards can * have their BIOS disabled, or enabled to an higher address. @@ -197,6 +200,7 @@ #include #include "u14-34f.h" #include +#include struct proc_dir_entry proc_scsi_u14_34f = { PROC_SCSI_U14_34F, 6, "u14_34f", @@ -223,6 +227,7 @@ #define HA_CMD_READ_BUFF 0x3 #define HA_CMD_WRITE_BUFF 0x4 +#undef DEBUG_LINKED_COMMANDS #undef DEBUG_DETECT #undef DEBUG_INTERRUPT #undef DEBUG_STATISTICS @@ -251,6 +256,8 @@ #define LOCKED 2 #define IN_RESET 3 #define IGNORE 4 +#define READY 5 +#define ABORTING 6 #define NO_DMA 0xff #define MAXLOOP 200000 @@ -296,7 +303,7 @@ unsigned int data_address PACKED; /* transfer data pointer */ unsigned int data_len PACKED; /* length in bytes */ unsigned int link_address PACKED; /* for linking command chains */ - unsigned char link_id; /* identifies command in chain */ + unsigned char clink_id; /* identifies command in chain */ unsigned char use_sg; /* (if sg is set) 8 bytes per list */ unsigned char sense_len; unsigned char scsi_cdbs_len; /* 6, 10, or 12 */ @@ -306,6 +313,7 @@ unsigned int sense_addr PACKED; Scsi_Cmnd *SCpnt; unsigned int index; /* cp index */ + unsigned int link_id; /* reference cp for linked commands */ struct sg_list *sglist; }; @@ -365,6 +373,18 @@ static int do_trace = FALSE; static int setup_done = FALSE; +#if defined (CONFIG_SCSI_U14_34F_LINKED_COMMANDS) +static int linked_commands = TRUE; +#else +static int linked_commands = FALSE; +#endif + +#if defined CONFIG_SCSI_U14_34F_MAX_TAGS +static int max_queue_depth = CONFIG_SCSI_U14_34F_MAX_TAGS; +#else +static int max_queue_depth = MAX_CMD_PER_LUN; +#endif + static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { Scsi_Device *dev; int j, ntag = 0, nuntag = 0, tqd, utqd; @@ -387,7 +407,7 @@ tqd = (host->can_queue - utqd * nuntag) / (ntag + 1); - if (tqd > MAX_TAGGED_CMD_PER_LUN) tqd = MAX_TAGGED_CMD_PER_LUN; + if (tqd > max_queue_depth) tqd = max_queue_depth; if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN; @@ -467,7 +487,7 @@ Scsi_Host_Template *tpnt) { unsigned char irq, dma_channel, subversion, i; unsigned char in_byte; - char dma_name[16]; + char *bus_type, dma_name[16]; /* Allowed BIOS base addresses (NULL indicates reserved) */ void *bios_segment_table[8] = { @@ -595,6 +615,7 @@ sh[j]->dma_channel = NO_DMA; sh[j]->unchecked_isa_dma = FALSE; sprintf(BN(j), "U34F%d", j); + bus_type = "VESA"; } else { sh[j]->wish_block = TRUE; @@ -611,6 +632,7 @@ clear_dma_ff(dma_channel); set_dma_mode(dma_channel, DMA_MODE_CASCADE); enable_dma(dma_channel); + bus_type = "ISA"; } sh[j]->max_channel = MAX_CHANNEL - 1; @@ -641,10 +663,15 @@ return FALSE; } - printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, %s, SG %d, "\ - "Mbox %d, UC %d.\n", BN(j), sh[j]->io_port, - (int)sh[j]->base, sh[j]->irq, dma_name, sh[j]->sg_tablesize, - sh[j]->can_queue, sh[j]->hostt->use_clustering); + if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) + max_queue_depth = MAX_TAGGED_CMD_PER_LUN; + + if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; + + printk("%s: %s 0x%03x, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d, UC %d, "\ + "LC %d, MQ %d.\n", BN(j), bus_type, sh[j]->io_port, (int)sh[j]->base, + sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue, + sh[j]->hostt->use_clustering, linked_commands, max_queue_depth); if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", @@ -691,7 +718,7 @@ if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++; if (j > 0) - printk("UltraStor 14F/34F: Copyright (C) 1994, 1995, 1996 Dario Ballabio.\n"); + printk("UltraStor 14F/34F: Copyright (C) 1994-1997 Dario Ballabio.\n"); restore_flags(flags); return j; @@ -803,6 +830,28 @@ cpp->scsi_cdbs_len = SCpnt->cmd_len; memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len); + if (linked_commands && SCpnt->device->tagged_supported + && !HD(j)->target_to[SCpnt->target][SCpnt->channel] + && !HD(j)->target_redo[SCpnt->target][SCpnt->channel]) + + for (k = 0; k < sh[j]->can_queue; k++) { + + if (HD(j)->cp_stat[k] != IN_USE) continue; + + if ((&HD(j)->cp[k])->SCpnt->device != SCpnt->device) continue; + + cpp->link_id = k; + HD(j)->cp_stat[i] = READY; + +#if defined (DEBUG_LINKED_COMMANDS) + printk("%s: qcomm, target %d.%d:%d, pid %ld, Mbox %d ready.\n", + BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, + SCpnt->pid, i); +#endif + restore_flags(flags); + return 0; + } + if (wait_on_busy(sh[j]->io_port)) { SCpnt->result = DID_ERROR << 16; SCpnt->host_scribble = NULL; @@ -884,6 +933,18 @@ restore_flags(flags); return SCSI_ABORT_NOT_RUNNING; } + + if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { + SCarg->result = DID_ABORT << 16; + SCarg->host_scribble = NULL; + HD(j)->cp_stat[i] = FREE; + printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", + BN(j), i, SCarg->pid); + SCarg->scsi_done(SCarg); + restore_flags(flags); + return SCSI_ABORT_SUCCESS; + } + restore_flags(flags); panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); } @@ -934,14 +995,21 @@ continue; } - SCpnt = HD(j)->cp[i].SCpnt; - HD(j)->cp_stat[i] = IN_RESET; - printk("%s: reset, mbox %d in reset, pid %ld.\n", - BN(j), i, SCpnt->pid); - - if (SCpnt == NULL) + if (!(SCpnt = HD(j)->cp[i].SCpnt)) panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); + if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { + HD(j)->cp_stat[i] = ABORTING; + printk("%s: reset, mbox %d aborting, pid %ld.\n", + BN(j), i, SCpnt->pid); + } + + else { + HD(j)->cp_stat[i] = IN_RESET; + printk("%s: reset, mbox %d in reset, pid %ld.\n", + BN(j), i, SCpnt->pid); + } + if (SCpnt->host_scribble == NULL) panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); @@ -976,18 +1044,35 @@ for (i = 0; i < sh[j]->can_queue; i++) { - /* Skip mailboxes already set free by interrupt */ - if (HD(j)->cp_stat[i] != IN_RESET) continue; + if (HD(j)->cp_stat[i] == IN_RESET) { + SCpnt = HD(j)->cp[i].SCpnt; + SCpnt->result = DID_RESET << 16; + SCpnt->host_scribble = NULL; - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; + /* This mailbox is still waiting for its interrupt */ + HD(j)->cp_stat[i] = LOCKED; - /* This mailbox is still waiting for its interrupt */ - HD(j)->cp_stat[i] = LOCKED; + printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", + BN(j), i, SCpnt->pid); + } + + else if (HD(j)->cp_stat[i] == ABORTING) { + SCpnt = HD(j)->cp[i].SCpnt; + SCpnt->result = DID_RESET << 16; + SCpnt->host_scribble = NULL; + + /* This mailbox was never queued to the adapter */ + HD(j)->cp_stat[i] = FREE; + + printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", + BN(j), i, SCpnt->pid); + } + + else + + /* Any other mailbox has already been set free by interrupt */ + continue; - printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); restore_flags(flags); SCpnt->scsi_done(SCpnt); cli(); @@ -1017,11 +1102,49 @@ return FALSE; } +static inline void process_ready_list(unsigned int i, unsigned int j) { + Scsi_Cmnd *SCpnt; + unsigned int k, n_ready = 0; + struct mscp *cpp; + + for (k = 0; k < sh[j]->can_queue; k++) { + + if (HD(j)->cp_stat[k] != READY) continue; + + cpp = &HD(j)->cp[k]; + + if (cpp->link_id != i) continue; + + SCpnt = cpp->SCpnt; + n_ready++; + + if (wait_on_busy(sh[j]->io_port)) { + printk("%s: ihdlr, target %d.%d:%d, pid %ld, Mbox %d, link_id %d, "\ + "n_ready %d, adapter busy, will abort.\n", BN(j), + SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, + k, i, n_ready); + HD(j)->cp_stat[k] = ABORTING; + continue; + } + + outl(V2DEV(cpp), sh[j]->io_port + REG_OGM); + outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); + HD(j)->cp_stat[k] = IN_USE; + +#if defined (DEBUG_LINKED_COMMANDS) + printk("%s: ihdlr, target %d.%d:%d, pid %ld, Mbox %d in use, link_id %d," + " n_ready %d.\n", BN(j), SCpnt->channel, SCpnt->target, + SCpnt->lun, SCpnt->pid, k, i, n_ready); +#endif + } + +} + static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) { Scsi_Cmnd *SCpnt; unsigned long flags; - unsigned int i, j, k, c, status, tstatus, loops, total_loops = 0; + unsigned int i, j, k, c, status, tstatus, loops, total_loops = 0, ret; struct mscp *spp; save_flags(flags); @@ -1051,15 +1174,19 @@ if (do_trace) printk("%s: ihdlr, start service, count %d.\n", BN(j), HD(j)->iocount); - spp = (struct mscp *)DEV2V(inl(sh[j]->io_port + REG_ICM)); + spp = (struct mscp *)DEV2V(ret = inl(sh[j]->io_port + REG_ICM)); /* Clear interrupt pending flag */ outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR); i = spp - HD(j)->cp; - if (i >= sh[j]->can_queue) - panic("%s: ihdlr, invalid mscp address.\n", BN(j)); + if (spp < HD(j)->cp || spp >= HD(j)->cp + sh[j]->can_queue + || i >= sh[j]->can_queue) + panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", + BN(j), (void *)ret, HD(j)->cp); + + if (linked_commands) process_ready_list(i, j); if (HD(j)->cp_stat[i] == IGNORE) { HD(j)->cp_stat[i] = FREE; diff -u --recursive --new-file v2.1.20/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h --- v2.1.20/linux/drivers/scsi/u14-34f.h Thu Dec 12 19:37:17 1996 +++ linux/drivers/scsi/u14-34f.h Tue Jan 14 12:48:50 1997 @@ -11,7 +11,7 @@ int u14_34f_reset(Scsi_Cmnd *, unsigned int); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "2.40.00" +#define U14_34F_VERSION "2.50.00" #define ULTRASTOR_14_34F { \ NULL, /* Ptr for modules */ \ diff -u --recursive --new-file v2.1.20/linux/fs/Config.in linux/fs/Config.in --- v2.1.20/linux/fs/Config.in Thu Dec 12 17:02:45 1996 +++ linux/fs/Config.in Tue Jan 14 12:59:10 1997 @@ -6,9 +6,7 @@ bool 'Quota support' CONFIG_QUOTA tristate 'Minix fs support' CONFIG_MINIX_FS -tristate 'Extended fs support' CONFIG_EXT_FS tristate 'Second extended fs support' CONFIG_EXT2_FS -tristate 'xiafs filesystem support' CONFIG_XIA_FS # msdos filesystems tristate 'DOS FAT fs support' CONFIG_FAT_FS @@ -38,6 +36,7 @@ tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS +tristate 'ROM filesystem support' CONFIG_ROMFS_FS if [ "$CONFIG_AFFS_FS" != "n" ]; then define_bool CONFIG_AMIGA_PARTITION y fi @@ -47,3 +46,4 @@ bool 'SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL fi endmenu + diff -u --recursive --new-file v2.1.20/linux/fs/Makefile linux/fs/Makefile --- v2.1.20/linux/fs/Makefile Sun Dec 22 16:37:38 1996 +++ linux/fs/Makefile Tue Jan 14 13:00:18 1997 @@ -16,8 +16,8 @@ dcache.o $(BINFMTS) MOD_LIST_NAME := FS_MODULES -ALL_SUB_DIRS = minix ext ext2 fat msdos vfat proc isofs nfs xiafs umsdos \ - hpfs sysv smbfs ncpfs ufs affs +ALL_SUB_DIRS = minix ext2 fat msdos vfat proc isofs nfs umsdos \ + hpfs sysv smbfs ncpfs ufs affs romfs ifeq ($(CONFIG_QUOTA),y) O_OBJS += dquot.o @@ -33,14 +33,6 @@ endif endif -ifeq ($(CONFIG_EXT_FS),y) -SUB_DIRS += ext -else - ifeq ($(CONFIG_EXT_FS),m) - MOD_SUB_DIRS += ext - endif -endif - ifeq ($(CONFIG_EXT2_FS),y) SUB_DIRS += ext2 else @@ -97,14 +89,6 @@ endif endif -ifeq ($(CONFIG_XIA_FS),y) -SUB_DIRS += xiafs -else - ifeq ($(CONFIG_XIA_FS),m) - MOD_SUB_DIRS += xiafs - endif -endif - ifeq ($(CONFIG_UMSDOS_FS),y) SUB_DIRS += umsdos else @@ -158,6 +142,14 @@ else ifeq ($(CONFIG_AFFS_FS),m) MOD_SUB_DIRS += affs + endif +endif + +ifeq ($(CONFIG_ROMFS_FS),y) +SUB_DIRS += romfs +else + ifeq ($(CONFIG_ROMFS_FS),m) + MOD_SUB_DIRS += romfs endif endif diff -u --recursive --new-file v2.1.20/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v2.1.20/linux/fs/binfmt_elf.c Mon Dec 30 15:39:13 1996 +++ linux/fs/binfmt_elf.c Thu Jan 2 20:29:00 1997 @@ -1238,9 +1238,9 @@ unsigned long addr = vma->vm_start; unsigned long len = vma->vm_end - vma->vm_start; + i++; if (!maydump(vma)) continue; - i++; #ifdef DEBUG printk("elf_core_dump: writing %08lx %lx\n", addr, len); #endif diff -u --recursive --new-file v2.1.20/linux/fs/devices.c linux/fs/devices.c --- v2.1.20/linux/fs/devices.c Mon May 13 07:36:19 1996 +++ linux/fs/devices.c Tue Jan 14 12:59:10 1997 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/ext/Makefile linux/fs/ext/Makefile --- v2.1.20/linux/fs/ext/Makefile Tue Aug 15 15:07:02 1995 +++ linux/fs/ext/Makefile Thu Jan 1 02:00:00 1970 @@ -1,15 +0,0 @@ -# -# Makefile for the linux ext-filesystem routines. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -O_TARGET := ext.o -O_OBJS := freelists.o truncate.o namei.o inode.o file.o dir.o \ - symlink.o fsync.o -M_OBJS := $(O_TARGET) - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.20/linux/fs/ext/dir.c linux/fs/ext/dir.c --- v2.1.20/linux/fs/ext/dir.c Tue Oct 29 19:58:20 1996 +++ linux/fs/ext/dir.c Thu Jan 1 02:00:00 1970 @@ -1,122 +0,0 @@ -/* - * linux/fs/ext/dir.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/dir.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext directory handling functions - */ - -#include - -#include -#include -#include -#include -#include - -static long ext_dir_read(struct inode * inode, struct file * filp, - char * buf, unsigned long count) -{ - return -EISDIR; -} - -static int ext_readdir(struct inode *, struct file *, void *, filldir_t); - -static struct file_operations ext_dir_operations = { - NULL, /* lseek - default */ - ext_dir_read, /* read */ - NULL, /* write - bad */ - ext_readdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - file_fsync /* fsync */ -}; - -/* - * directories can handle most operations... - */ -struct inode_operations ext_dir_inode_operations = { - &ext_dir_operations, /* default directory file-ops */ - ext_create, /* create */ - ext_lookup, /* lookup */ - ext_link, /* link */ - ext_unlink, /* unlink */ - ext_symlink, /* symlink */ - ext_mkdir, /* mkdir */ - ext_rmdir, /* rmdir */ - ext_mknod, /* mknod */ - ext_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - ext_truncate, /* truncate */ - NULL /* permission */ -}; - -static int ext_readdir(struct inode * inode, struct file * filp, - void * dirent, filldir_t filldir) -{ - int error; - unsigned int i; - off_t offset; - struct buffer_head * bh; - struct ext_dir_entry * de; - - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; - if ((filp->f_pos & 7) != 0) - return -EBADF; - error = 0; - while (!error && filp->f_pos < inode->i_size) { - offset = filp->f_pos & 1023; - bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0); - if (!bh) { - filp->f_pos += 1024-offset; - continue; - } - for (i = 0; i < 1024 && i < offset; ) { - de = (struct ext_dir_entry *) (bh->b_data + i); - if (!de->rec_len) - break; - i += de->rec_len; - } - offset = i; - de = (struct ext_dir_entry *) (offset + bh->b_data); - while (offset < 1024 && filp->f_pos < inode->i_size) { - if (de->rec_len < 8 || de->rec_len % 8 != 0 || - de->rec_len < de->name_len + 8 || - (de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) { - printk ("ext_readdir: bad dir entry, skipping\n"); - printk ("dev=%s, dir=%ld, " - "offset=%ld, rec_len=%d, name_len=%d\n", - kdevname(inode->i_dev), inode->i_ino, - offset, de->rec_len, de->name_len); - filp->f_pos += 1024-offset; - if (filp->f_pos > inode->i_size) - filp->f_pos = inode->i_size; - continue; - } - if (de->inode) { - error = filldir(dirent, de->name, de->name_len, filp->f_pos, de->inode); - if (error) - break; - } - offset += de->rec_len; - filp->f_pos += de->rec_len; - ((char *) de) += de->rec_len; - } - brelse(bh); - } - return 0; -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/file.c linux/fs/ext/file.c --- v2.1.20/linux/fs/ext/file.c Tue Oct 29 19:58:20 1996 +++ linux/fs/ext/file.c Thu Jan 1 02:00:00 1970 @@ -1,264 +0,0 @@ -/* - * linux/fs/ext/file.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/file.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext regular file handling primitives - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define NBUF 32 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -#include -#include - -static long ext_file_read(struct inode *, struct file *, char *, unsigned long); -static long ext_file_write(struct inode *, struct file *, const char *, unsigned long); - -/* - * We have mostly NULL's here: the current defaults are ok for - * the ext filesystem. - */ -static struct file_operations ext_file_operations = { - NULL, /* lseek - default */ - ext_file_read, /* read */ - ext_file_write, /* write */ - NULL, /* readdir - bad */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - generic_file_mmap, /* mmap */ - NULL, /* no special open is needed */ - NULL, /* release */ - ext_sync_file /* fsync */ -}; - -struct inode_operations ext_file_inode_operations = { - &ext_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - generic_readpage, /* readpage */ - NULL, /* writepage */ - ext_bmap, /* bmap */ - ext_truncate, /* truncate */ - NULL /* permission */ -}; - -static long ext_file_read(struct inode * inode, struct file * filp, - char * buf, unsigned long count) -{ - int read,left,chars; - int block, blocks, offset; - int bhrequest, uptodate; - struct buffer_head ** bhb, ** bhe; - struct buffer_head * bhreq[NBUF]; - struct buffer_head * buflist[NBUF]; - unsigned int size; - - if (!inode) { - printk("ext_file_read: inode = NULL\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("ext_file_read: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - offset = filp->f_pos; - size = inode->i_size; - if (offset > size) - left = 0; - else - left = size - offset; - if (left > count) - left = count; - if (left <= 0) - return 0; - read = 0; - block = offset >> BLOCK_SIZE_BITS; - offset &= BLOCK_SIZE-1; - size = (size + (BLOCK_SIZE-1)) >> BLOCK_SIZE_BITS; - blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; - bhb = bhe = buflist; - if (filp->f_reada) { - if(blocks < read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9)) - blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9); - if (block + blocks > size) - blocks = size - block; - } - - /* We do this in a two stage process. We first try to request - as many blocks as we can, then we wait for the first one to - complete, and then we try to wrap up as many as are actually - done. This routine is rather generic, in that it can be used - in a filesystem by substituting the appropriate function in - for getblk. - - This routine is optimized to make maximum use of the various - buffers and caches. */ - - do { - bhrequest = 0; - uptodate = 1; - while (blocks) { - --blocks; - *bhb = ext_getblk(inode, block++, 0); - if (*bhb && !buffer_uptodate(*bhb)) { - uptodate = 0; - bhreq[bhrequest++] = *bhb; - } - - if (++bhb == &buflist[NBUF]) - bhb = buflist; - - /* If the block we have on hand is uptodate, go ahead - and complete processing. */ - if (uptodate) - break; - if (bhb == bhe) - break; - } - - /* Now request them all */ - if (bhrequest) - ll_rw_block(READ, bhrequest, bhreq); - - do { /* Finish off all I/O that has actually completed */ - if (*bhe) { - wait_on_buffer(*bhe); - if (!buffer_uptodate(*bhe)) { /* read error? */ - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - left = 0; - break; - } - } - if (left < BLOCK_SIZE - offset) - chars = left; - else - chars = BLOCK_SIZE - offset; - filp->f_pos += chars; - left -= chars; - read += chars; - if (*bhe) { - copy_to_user(buf,offset+(*bhe)->b_data,chars); - brelse(*bhe); - buf += chars; - } else { - while (chars-->0) - put_user(0,buf++); - } - offset = 0; - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe))); - } while (left > 0); - -/* Release the read-ahead blocks */ - while (bhe != bhb) { - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - }; - if (!read) - return -EIO; - filp->f_reada = 1; - if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - return read; -} - -static long ext_file_write(struct inode * inode, struct file * filp, - const char * buf, unsigned long count) -{ - off_t pos; - int written,c; - struct buffer_head * bh; - char * p; - - if (!inode) { - printk("ext_file_write: inode = NULL\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("ext_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ - if (filp->f_flags & O_APPEND) - pos = inode->i_size; - else - pos = filp->f_pos; - written = 0; - while (written count-written) - c = count-written; - if (c != BLOCK_SIZE && !buffer_uptodate(bh)) { - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - if (!written) - written = -EIO; - break; - } - } - p = (pos % BLOCK_SIZE) + bh->b_data; - copy_from_user(p,buf,c); - update_vm_cache(inode, pos, p, c); - pos += c; - if (pos > inode->i_size) { - inode->i_size = pos; - inode->i_dirt = 1; - } - written += c; - buf += c; - mark_buffer_uptodate(bh, 1); - mark_buffer_dirty(bh, 0); - brelse(bh); - } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - filp->f_pos = pos; - inode->i_dirt = 1; - return written; -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/freelists.c linux/fs/ext/freelists.c --- v2.1.20/linux/fs/ext/freelists.c Sun Nov 26 19:23:10 1995 +++ linux/fs/ext/freelists.c Thu Jan 1 02:00:00 1970 @@ -1,341 +0,0 @@ -/* - * linux/fs/ext/freelists.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - */ - -/* freelists.c contains the code that handles the inode and block free lists */ - - -/* - - The free blocks are managed by a linked list. The super block contains the - number of the first free block. This block contains 254 numbers of other - free blocks and the number of the next block in the list. - - When an ext fs is mounted, the number of the first free block is stored - in s->u.ext_sb.s_firstfreeblocknumber and the block header is stored in - s->u.ext_sb.s_firstfreeblock. u.ext_sb.s_freeblockscount contains the count - of free blocks. - - The free inodes are also managed by a linked list in a similar way. The - super block contains the number of the first free inode. This inode contains - 14 numbers of other free inodes and the number of the next inode in the list. - - The number of the first free inode is stored in - s->u.ext_sb.s_firstfreeinodenumber and the header of the block containing - the inode is stored in s->u.ext_sb.s_firstfreeinodeblock. - u.ext_sb.s_freeinodescount contains the count of free inodes. - -*/ - -#include -#include -#include -#include -#include -#include - -void ext_free_block(struct super_block * sb, int block) -{ - struct buffer_head * bh; - struct ext_free_block * efb; - - if (!sb) { - printk("trying to free block on non-existent device\n"); - return; - } - lock_super (sb); - if (block < sb->u.ext_sb.s_firstdatazone || - block >= sb->u.ext_sb.s_nzones) { - printk("trying to free block not in datazone\n"); - return; - } - bh = get_hash_table(sb->s_dev, block, sb->s_blocksize); - if (bh) - mark_buffer_clean(bh); - brelse(bh); - if (sb->u.ext_sb.s_firstfreeblock) - efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data; - if (!sb->u.ext_sb.s_firstfreeblock || efb->count == 254) { -#ifdef EXTFS_DEBUG -printk("ext_free_block: block full, skipping to %d\n", block); -#endif - if (sb->u.ext_sb.s_firstfreeblock) - brelse (sb->u.ext_sb.s_firstfreeblock); - if (!(sb->u.ext_sb.s_firstfreeblock = bread (sb->s_dev, - block, sb->s_blocksize))) - panic ("ext_free_block: unable to read block to free\n"); - efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data; - efb->next = sb->u.ext_sb.s_firstfreeblocknumber; - efb->count = 0; - sb->u.ext_sb.s_firstfreeblocknumber = block; - } else { - efb->free[efb->count++] = block; - } - sb->u.ext_sb.s_freeblockscount ++; - sb->s_dirt = 1; - mark_buffer_dirty(sb->u.ext_sb.s_firstfreeblock, 1); - unlock_super (sb); - return; -} - -int ext_new_block(struct super_block * sb) -{ - struct buffer_head * bh; - struct ext_free_block * efb; - int j; - - if (!sb) { - printk("trying to get new block from non-existent device\n"); - return 0; - } - if (!sb->u.ext_sb.s_firstfreeblock) - return 0; - lock_super (sb); - efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data; - if (efb->count) { - j = efb->free[--efb->count]; - mark_buffer_dirty(sb->u.ext_sb.s_firstfreeblock, 1); - } else { -#ifdef EXTFS_DEBUG -printk("ext_new_block: block empty, skipping to %d\n", efb->next); -#endif - j = sb->u.ext_sb.s_firstfreeblocknumber; - sb->u.ext_sb.s_firstfreeblocknumber = efb->next; - brelse (sb->u.ext_sb.s_firstfreeblock); - if (!sb->u.ext_sb.s_firstfreeblocknumber) { - sb->u.ext_sb.s_firstfreeblock = NULL; - } else { - if (!(sb->u.ext_sb.s_firstfreeblock = bread (sb->s_dev, - sb->u.ext_sb.s_firstfreeblocknumber, - sb->s_blocksize))) - panic ("ext_new_block: unable to read next free block\n"); - } - } - if (j < sb->u.ext_sb.s_firstdatazone || j > sb->u.ext_sb.s_nzones) { - printk ("ext_new_block: blk = %d\n", j); - printk("allocating block not in data zone\n"); - return 0; - } - sb->u.ext_sb.s_freeblockscount --; - sb->s_dirt = 1; - - if (!(bh=getblk(sb->s_dev, j, sb->s_blocksize))) { - printk("new_block: cannot get block"); - return 0; - } - memset(bh->b_data, 0, BLOCK_SIZE); - mark_buffer_uptodate(bh, 1); - mark_buffer_dirty(bh, 1); - brelse(bh); -#ifdef EXTFS_DEBUG -printk("ext_new_block: allocating block %d\n", j); -#endif - unlock_super (sb); - return j; -} - -unsigned long ext_count_free_blocks(struct super_block *sb) -{ -#ifdef EXTFS_DEBUG - struct buffer_head * bh; - struct ext_free_block * efb; - unsigned long count, block; - - lock_super (sb); - if (!sb->u.ext_sb.s_firstfreeblock) - count = 0; - else { - efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data; - count = efb->count + 1; - block = efb->next; - while (block) { - if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) { - printk ("ext_count_free: error while reading free blocks list\n"); - block = 0; - } else { - efb = (struct ext_free_block *) bh->b_data; - count += efb->count + 1; - block = efb->next; - brelse (bh); - } - } - } -printk("ext_count_free_blocks: stored = %d, computed = %d\n", - sb->u.ext_sb.s_freeblockscount, count); - unlock_super (sb); - return count; -#else - return sb->u.ext_sb.s_freeblockscount; -#endif -} - -void ext_free_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_free_inode * efi; - struct super_block * sb; - unsigned long block; - unsigned long ino; - kdev_t dev; - - if (!inode) - return; - if (!inode->i_dev) { - printk("free_inode: inode has no device\n"); - return; - } - if (inode->i_count != 1) { - printk("free_inode: inode has count=%d\n",inode->i_count); - return; - } - if (inode->i_nlink) { - printk("free_inode: inode has nlink=%d\n",inode->i_nlink); - return; - } - if (!inode->i_sb) { - printk("free_inode: inode on non-existent device\n"); - return; - } - sb = inode->i_sb; - ino = inode->i_ino; - dev = inode->i_dev; - clear_inode(inode); - lock_super (sb); - if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) { - printk("free_inode: inode 0 or non-existent inode\n"); - unlock_super (sb); - return; - } - if (sb->u.ext_sb.s_firstfreeinodeblock) - efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) + - (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK; - if (!sb->u.ext_sb.s_firstfreeinodeblock || efi->count == 14) { -#ifdef EXTFS_DEBUG -printk("ext_free_inode: inode full, skipping to %d\n", ino); -#endif - if (sb->u.ext_sb.s_firstfreeinodeblock) - brelse (sb->u.ext_sb.s_firstfreeinodeblock); - block = 2 + (ino - 1) / EXT_INODES_PER_BLOCK; - if (!(bh = bread(dev, block, sb->s_blocksize))) - panic("ext_free_inode: unable to read inode block\n"); - efi = ((struct ext_free_inode *) bh->b_data) + - (ino - 1) % EXT_INODES_PER_BLOCK; - efi->next = sb->u.ext_sb.s_firstfreeinodenumber; - efi->count = 0; - sb->u.ext_sb.s_firstfreeinodenumber = ino; - sb->u.ext_sb.s_firstfreeinodeblock = bh; - } else { - efi->free[efi->count++] = ino; - } - sb->u.ext_sb.s_freeinodescount ++; - sb->s_dirt = 1; - mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1); - unlock_super (sb); -} - -struct inode * ext_new_inode(const struct inode * dir) -{ - struct super_block * sb; - struct inode * inode; - struct ext_free_inode * efi; - unsigned long block; - int j; - - if (!dir || !(inode=get_empty_inode())) - return NULL; - sb = dir->i_sb; - inode->i_sb = sb; - inode->i_flags = sb->s_flags; - if (!sb->u.ext_sb.s_firstfreeinodeblock) - return 0; - lock_super (sb); - efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) + - (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK; - if (efi->count) { - j = efi->free[--efi->count]; - mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1); - } else { -#ifdef EXTFS_DEBUG -printk("ext_free_inode: inode empty, skipping to %d\n", efi->next); -#endif - j = sb->u.ext_sb.s_firstfreeinodenumber; - if (efi->next > sb->u.ext_sb.s_ninodes) { - printk ("efi->next = %ld\n", efi->next); - panic ("ext_new_inode: bad inode number in free list\n"); - } - sb->u.ext_sb.s_firstfreeinodenumber = efi->next; - block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK; - brelse (sb->u.ext_sb.s_firstfreeinodeblock); - if (!sb->u.ext_sb.s_firstfreeinodenumber) { - sb->u.ext_sb.s_firstfreeinodeblock = NULL; - } else { - if (!(sb->u.ext_sb.s_firstfreeinodeblock = - bread(sb->s_dev, block, sb->s_blocksize))) - panic ("ext_new_inode: unable to read next free inode block\n"); - } - } - sb->u.ext_sb.s_freeinodescount --; - sb->s_dirt = 1; - inode->i_count = 1; - inode->i_nlink = 1; - inode->i_dev = sb->s_dev; - inode->i_uid = current->fsuid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - inode->i_dirt = 1; - inode->i_ino = j; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = NULL; - inode->i_blocks = inode->i_blksize = 0; - insert_inode_hash(inode); -#ifdef EXTFS_DEBUG -printk("ext_new_inode : allocating inode %d\n", inode->i_ino); -#endif - unlock_super (sb); - return inode; -} - -unsigned long ext_count_free_inodes(struct super_block *sb) -{ -#ifdef EXTFS_DEBUG - struct buffer_head * bh; - struct ext_free_inode * efi; - unsigned long count, block, ino; - - lock_super (sb); - if (!sb->u.ext_sb.s_firstfreeinodeblock) - count = 0; - else { - efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) + - ((sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK); - count = efi->count + 1; - ino = efi->next; - while (ino) { - if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) { - printk ("u.ext_sb.s_firstfreeinodenumber = %d, ino = %d\n", - (int) sb->u.ext_sb.s_firstfreeinodenumber,ino); - panic ("ext_count_fre_inodes: bad inode number in free list\n"); - } - block = 2 + ((ino - 1) / EXT_INODES_PER_BLOCK); - if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) { - printk ("ext_count_free_inodes: error while reading free inodes list\n"); - block = 0; - } else { - efi = ((struct ext_free_inode *) bh->b_data) + - ((ino - 1) % EXT_INODES_PER_BLOCK); - count += efi->count + 1; - ino = efi->next; - brelse (bh); - } - } - } -printk("ext_count_free_inodes: stored = %d, computed = %d\n", - sb->u.ext_sb.s_freeinodescount, count); - unlock_super (sb); - return count; -#else - return sb->u.ext_sb.s_freeinodescount; -#endif -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/fsync.c linux/fs/ext/fsync.c --- v2.1.20/linux/fs/ext/fsync.c Tue Oct 29 19:58:20 1996 +++ linux/fs/ext/fsync.c Thu Jan 1 02:00:00 1970 @@ -1,185 +0,0 @@ - -/* - * linux/fs/ext/fsync.c - * - * Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk) - * from - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * from - * linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds - * - * extfs fsync primitive - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - - -#define blocksize BLOCK_SIZE -#define addr_per_block 256 - -static int sync_block (struct inode * inode, unsigned long * block, int wait) -{ - struct buffer_head * bh; - int tmp; - - if (!*block) - return 0; - tmp = *block; - bh = get_hash_table(inode->i_dev, *block, blocksize); - if (!bh) - return 0; - if (*block != tmp) { - brelse (bh); - return 1; - } - if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse(bh); - return -1; - } - if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) - { - brelse(bh); - return 0; - } - ll_rw_block(WRITE, 1, &bh); - bh->b_count--; - return 0; -} - -static int sync_iblock (struct inode * inode, unsigned long * iblock, - struct buffer_head **bh, int wait) -{ - int rc, tmp; - - *bh = NULL; - tmp = *iblock; - if (!tmp) - return 0; - rc = sync_block (inode, iblock, wait); - if (rc) - return rc; - *bh = bread(inode->i_dev, tmp, blocksize); - if (tmp != *iblock) { - brelse(*bh); - *bh = NULL; - return 1; - } - if (!*bh) - return -1; - return 0; -} - - -static int sync_direct(struct inode *inode, int wait) -{ - int i; - int rc, err = 0; - - for (i = 0; i < 9; i++) { - rc = sync_block (inode, inode->u.ext_i.i_data + i, wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - return err; -} - -static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait) -{ - int i; - struct buffer_head * ind_bh; - int rc, err = 0; - - rc = sync_iblock (inode, iblock, &ind_bh, wait); - if (rc || !ind_bh) - return rc; - - for (i = 0; i < addr_per_block; i++) { - rc = sync_block (inode, - ((unsigned long *) ind_bh->b_data) + i, - wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - brelse(ind_bh); - return err; -} - -static int sync_dindirect(struct inode *inode, unsigned long *diblock, - int wait) -{ - int i; - struct buffer_head * dind_bh; - int rc, err = 0; - - rc = sync_iblock (inode, diblock, &dind_bh, wait); - if (rc || !dind_bh) - return rc; - - for (i = 0; i < addr_per_block; i++) { - rc = sync_indirect (inode, - ((unsigned long *) dind_bh->b_data) + i, - wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - brelse(dind_bh); - return err; -} - -static int sync_tindirect(struct inode *inode, unsigned long *tiblock, - int wait) -{ - int i; - struct buffer_head * tind_bh; - int rc, err = 0; - - rc = sync_iblock (inode, tiblock, &tind_bh, wait); - if (rc || !tind_bh) - return rc; - - for (i = 0; i < addr_per_block; i++) { - rc = sync_dindirect (inode, - ((unsigned long *) tind_bh->b_data) + i, - wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - brelse(tind_bh); - return err; -} - -int ext_sync_file(struct inode * inode, struct file *file) -{ - int wait, err = 0; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return -EINVAL; - for (wait=0; wait<=1; wait++) - { - err |= sync_direct(inode, wait); - err |= sync_indirect(inode, inode->u.ext_i.i_data+9, wait); - err |= sync_dindirect(inode, inode->u.ext_i.i_data+10, wait); - err |= sync_tindirect(inode, inode->u.ext_i.i_data+11, wait); - } - err |= ext_sync_inode (inode); - return (err < 0) ? -EIO : 0; -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/inode.c linux/fs/ext/inode.c --- v2.1.20/linux/fs/ext/inode.c Mon Dec 30 15:39:13 1996 +++ linux/fs/ext/inode.c Thu Jan 1 02:00:00 1970 @@ -1,477 +0,0 @@ -/* - * linux/fs/ext/inode.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/inode.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -void ext_put_inode(struct inode *inode) -{ - if (inode->i_nlink) - return; - inode->i_size = 0; - ext_truncate(inode); - ext_free_inode(inode); -} - -void ext_put_super(struct super_block *sb) -{ - - lock_super(sb); - sb->s_dev = 0; - if (sb->u.ext_sb.s_firstfreeinodeblock) - brelse (sb->u.ext_sb.s_firstfreeinodeblock); - if (sb->u.ext_sb.s_firstfreeblock) - brelse (sb->u.ext_sb.s_firstfreeblock); - unlock_super(sb); - MOD_DEC_USE_COUNT; - return; -} - -static struct super_operations ext_sops = { - ext_read_inode, - NULL, - ext_write_inode, - ext_put_inode, - ext_put_super, - ext_write_super, - ext_statfs, - NULL -}; - -struct super_block *ext_read_super(struct super_block *s,void *data, - int silent) -{ - struct buffer_head *bh; - struct ext_super_block *es; - kdev_t dev = s->s_dev; - int block; - - MOD_INC_USE_COUNT; - lock_super(s); - set_blocksize(dev, BLOCK_SIZE); - if (!(bh = bread(dev, 1, BLOCK_SIZE))) { - s->s_dev = 0; - unlock_super(s); - printk("EXT-fs: unable to read superblock\n"); - MOD_DEC_USE_COUNT; - return NULL; - } - es = (struct ext_super_block *) bh->b_data; - s->s_blocksize = 1024; - s->s_blocksize_bits = 10; - s->u.ext_sb.s_ninodes = es->s_ninodes; - s->u.ext_sb.s_nzones = es->s_nzones; - s->u.ext_sb.s_firstdatazone = es->s_firstdatazone; - s->u.ext_sb.s_log_zone_size = es->s_log_zone_size; - s->u.ext_sb.s_max_size = es->s_max_size; - s->s_magic = es->s_magic; - s->u.ext_sb.s_firstfreeblocknumber = es->s_firstfreeblock; - s->u.ext_sb.s_freeblockscount = es->s_freeblockscount; - s->u.ext_sb.s_firstfreeinodenumber = es->s_firstfreeinode; - s->u.ext_sb.s_freeinodescount = es->s_freeinodescount; - brelse(bh); - if (s->s_magic != EXT_SUPER_MAGIC) { - s->s_dev = 0; - unlock_super(s); - if (!silent) - printk("VFS: Can't find an extfs filesystem on dev " - "%s.\n", kdevname(dev)); - MOD_DEC_USE_COUNT; - return NULL; - } - if (!s->u.ext_sb.s_firstfreeblocknumber) - s->u.ext_sb.s_firstfreeblock = NULL; - else - if (!(s->u.ext_sb.s_firstfreeblock = bread(dev, - s->u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE))) { - printk("ext_read_super: unable to read first free block\n"); - s->s_dev = 0; - unlock_super(s); - MOD_DEC_USE_COUNT; - return NULL; - } - if (!s->u.ext_sb.s_firstfreeinodenumber) - s->u.ext_sb.s_firstfreeinodeblock = NULL; - else { - block = 2 + (s->u.ext_sb.s_firstfreeinodenumber - 1) / EXT_INODES_PER_BLOCK; - if (!(s->u.ext_sb.s_firstfreeinodeblock = bread(dev, block, BLOCK_SIZE))) { - printk("ext_read_super: unable to read first free inode block\n"); - brelse(s->u.ext_sb.s_firstfreeblock); - s->s_dev = 0; - unlock_super (s); - MOD_DEC_USE_COUNT; - return NULL; - } - } - unlock_super(s); - /* set up enough so that it can read an inode */ - s->s_dev = dev; - s->s_op = &ext_sops; - if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) { - s->s_dev = 0; - printk("EXT-fs: get root inode failed\n"); - MOD_DEC_USE_COUNT; - return NULL; - } - return s; -} - -void ext_write_super (struct super_block *sb) -{ - struct buffer_head * bh; - struct ext_super_block * es; - - if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) { - printk ("ext_write_super: bread failed\n"); - return; - } - es = (struct ext_super_block *) bh->b_data; - es->s_firstfreeblock = sb->u.ext_sb.s_firstfreeblocknumber; - es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount; - es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber; - es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount; - mark_buffer_dirty(bh, 1); - brelse (bh); - sb->s_dirt = 0; -} - -void ext_statfs (struct super_block *sb, struct statfs *buf, int bufsiz) -{ - struct statfs tmp; - - tmp.f_type = EXT_SUPER_MAGIC; - tmp.f_bsize = 1024; - tmp.f_blocks = sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size; - tmp.f_bfree = ext_count_free_blocks(sb); - tmp.f_bavail = tmp.f_bfree; - tmp.f_files = sb->u.ext_sb.s_ninodes; - tmp.f_ffree = ext_count_free_inodes(sb); - tmp.f_namelen = EXT_NAME_LEN; - copy_to_user(buf, &tmp, bufsiz); -} - -#define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)]) - -static inline int block_bmap(struct buffer_head * bh, int nr) -{ - int tmp; - - if (!bh) - return 0; - tmp = ((unsigned long *) bh->b_data)[nr]; - brelse(bh); - return tmp; -} - -int ext_bmap(struct inode * inode,int block) -{ - int i; - - if (block<0) { - printk("ext_bmap: block<0"); - return 0; - } - if (block >= 9+256+256*256+256*256*256) { - printk("ext_bmap: block>big"); - return 0; - } - if (block<9) - return inode_bmap(inode,block); - block -= 9; - if (block<256) { - i = inode_bmap(inode,9); - if (!i) - return 0; - return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block); - } - block -= 256; - if (block<256*256) { - i = inode_bmap(inode,10); - if (!i) - return 0; - i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8); - if (!i) - return 0; - return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255); - } - block -= 256*256; - i = inode_bmap(inode,11); - if (!i) - return 0; - i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16); - if (!i) - return 0; - i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255); - if (!i) - return 0; - return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255); -} - -static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create) -{ - int tmp; - unsigned long * p; - struct buffer_head * result; - - p = inode->u.ext_i.i_data + nr; -repeat: - tmp = *p; - if (tmp) { - result = getblk(inode->i_dev, tmp, BLOCK_SIZE); - if (tmp == *p) - return result; - brelse(result); - goto repeat; - } - if (!create) - return NULL; - tmp = ext_new_block(inode->i_sb); - if (!tmp) - return NULL; - result = getblk(inode->i_dev, tmp, BLOCK_SIZE); - if (*p) { - ext_free_block(inode->i_sb,tmp); - brelse(result); - goto repeat; - } - *p = tmp; - inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; - return result; -} - -static struct buffer_head * block_getblk(struct inode * inode, - struct buffer_head * bh, int nr, int create) -{ - int tmp; - unsigned long * p; - struct buffer_head * result; - - if (!bh) - return NULL; - if (!buffer_uptodate(bh)) { - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - return NULL; - } - } - p = nr + (unsigned long *) bh->b_data; -repeat: - tmp = *p; - if (tmp) { - result = getblk(bh->b_dev, tmp, BLOCK_SIZE); - if (tmp == *p) { - brelse(bh); - return result; - } - brelse(result); - goto repeat; - } - if (!create) { - brelse(bh); - return NULL; - } - tmp = ext_new_block(inode->i_sb); - if (!tmp) { - brelse(bh); - return NULL; - } - result = getblk(bh->b_dev, tmp, BLOCK_SIZE); - if (*p) { - ext_free_block(inode->i_sb,tmp); - brelse(result); - goto repeat; - } - *p = tmp; - mark_buffer_dirty(bh, 1); - brelse(bh); - return result; -} - -struct buffer_head * ext_getblk(struct inode * inode, int block, int create) -{ - struct buffer_head * bh; - - if (block<0) { - printk("ext_getblk: block<0\n"); - return NULL; - } - if (block >= 9+256+256*256+256*256*256) { - printk("ext_getblk: block>big\n"); - return NULL; - } - if (block<9) - return inode_getblk(inode,block,create); - block -= 9; - if (block<256) { - bh = inode_getblk(inode,9,create); - return block_getblk(inode,bh,block,create); - } - block -= 256; - if (block<256*256) { - bh = inode_getblk(inode,10,create); - bh = block_getblk(inode,bh,block>>8,create); - return block_getblk(inode,bh,block & 255,create); - } - block -= 256*256; - bh = inode_getblk(inode,11,create); - bh = block_getblk(inode,bh,block>>16,create); - bh = block_getblk(inode,bh,(block>>8) & 255,create); - return block_getblk(inode,bh,block & 255,create); -} - -struct buffer_head * ext_bread(struct inode * inode, int block, int create) -{ - struct buffer_head * bh; - - bh = ext_getblk(inode,block,create); - if (!bh || buffer_uptodate(bh)) - return bh; - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return bh; - brelse(bh); - return NULL; -} - -void ext_read_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_inode * raw_inode; - int block; - - block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; - if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) - panic("unable to read i-node block"); - raw_inode = ((struct ext_inode *) bh->b_data) + - (inode->i_ino-1)%EXT_INODES_PER_BLOCK; - inode->i_mode = raw_inode->i_mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; - inode->i_nlink = raw_inode->i_nlinks; - inode->i_size = raw_inode->i_size; - inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; - inode->i_blocks = inode->i_blksize = 0; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]); - else for (block = 0; block < 12; block++) - inode->u.ext_i.i_data[block] = raw_inode->i_zone[block]; - brelse(bh); - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &ext_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &ext_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &ext_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) - init_fifo(inode); -} - -static struct buffer_head * ext_update_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_inode * raw_inode; - int block; - - block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; - if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) - panic("unable to read i-node block"); - raw_inode = ((struct ext_inode *)bh->b_data) + - (inode->i_ino-1)%EXT_INODES_PER_BLOCK; - raw_inode->i_mode = inode->i_mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; - raw_inode->i_nlinks = inode->i_nlink; - raw_inode->i_size = inode->i_size; - raw_inode->i_time = inode->i_mtime; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); - else for (block = 0; block < 12; block++) - raw_inode->i_zone[block] = inode->u.ext_i.i_data[block]; - mark_buffer_dirty(bh, 1); - inode->i_dirt=0; - return bh; -} - -void ext_write_inode(struct inode * inode) -{ - struct buffer_head *bh; - bh = ext_update_inode (inode); - brelse(bh); -} - -int ext_sync_inode (struct inode *inode) -{ - int err = 0; - struct buffer_head *bh; - - bh = ext_update_inode(inode); - if (bh && buffer_dirty(bh)) - { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - { - printk ("IO error syncing ext inode [" - "%s:%08lx]\n", - kdevname(inode->i_dev), inode->i_ino); - err = -1; - } - } - else if (!bh) - err = -1; - brelse (bh); - return err; -} - - -static struct file_system_type ext_fs_type = { - ext_read_super, "ext", 1, NULL -}; - -int init_ext_fs(void) -{ - return register_filesystem(&ext_fs_type); -} - -#ifdef MODULE -EXPORT_NO_SYMBOLS; - -int init_module(void) -{ - return init_ext_fs(); -} - -void cleanup_module(void) -{ - unregister_filesystem(&ext_fs_type); -} - -#endif diff -u --recursive --new-file v2.1.20/linux/fs/ext/namei.c linux/fs/ext/namei.c --- v2.1.20/linux/fs/ext/namei.c Tue Oct 29 19:58:20 1996 +++ linux/fs/ext/namei.c Thu Jan 1 02:00:00 1970 @@ -1,903 +0,0 @@ -/* - * linux/fs/ext/namei.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/namei.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * comment out this line if you want names > EXT_NAME_LEN chars to be - * truncated. Else they will be disallowed. - */ -/* #define NO_TRUNCATE */ - -/* - * EXT_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a power of 2 and must be greater or equal than 8 - * because a directory entry needs 8 bytes for its fixed part - * (4 bytes for the inode, 2 bytes for the entry length and 2 bytes - * for the name length) - */ -#define EXT_DIR_PAD 8 - -/* - * - * EXT_DIR_MIN_SIZE is the minimal size of a directory entry - * - * During allocations, a directory entry is split into 2 ones - * *ONLY* if the size of the unused part is greater than or - * equal to EXT_DIR_MIN_SIZE - */ -#define EXT_DIR_MIN_SIZE 12 - -/* - * ok, we cannot use strncmp, as the name is not in our data space. - * Thus we'll have to use ext_match. No big problem. Match also makes - * some sanity tests. - * - * NOTE! unlike strncmp, ext_match returns 1 for success, 0 for failure. - */ -static int ext_match(int len,const char * name,struct ext_dir_entry * de) -{ - if (!de || !de->inode || len > EXT_NAME_LEN) - return 0; - /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ - if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) - return 1; - if (len != de->name_len) - return 0; - return !memcmp(name, de->name, len); -} - -/* - * ext_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the cache buffer in which the entry was found, and the entry - * itself (as a parameter - res_dir). It does NOT read the inode of the - * entry - you'll have to do that yourself if you want to. - * - * addition for the ext file system : this function returns the previous - * and next directory entries in the parameters prev_dir and next_dir - */ -static struct buffer_head * ext_find_entry(struct inode * dir, - const char * name, int namelen, struct ext_dir_entry ** res_dir, - struct ext_dir_entry ** prev_dir, struct ext_dir_entry ** next_dir) -{ - long offset; - struct buffer_head * bh; - struct ext_dir_entry * de; - - *res_dir = NULL; - if (!dir) - return NULL; -#ifdef NO_TRUNCATE - if (namelen > EXT_NAME_LEN) - return NULL; -#else - if (namelen > EXT_NAME_LEN) - namelen = EXT_NAME_LEN; -#endif - bh = ext_bread(dir,0,0); - if (!bh) - return NULL; - if (prev_dir) - *prev_dir = NULL; - if (next_dir) - *next_dir = NULL; - offset = 0; - de = (struct ext_dir_entry *) bh->b_data; - while (offset < dir->i_size) { - if ((char *)de >= BLOCK_SIZE+bh->b_data) { - brelse(bh); - bh = NULL; - bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,0); - if (!bh) - continue; - de = (struct ext_dir_entry *) bh->b_data; - if (prev_dir) - *prev_dir = NULL; - } - if (de->rec_len < 8 || de->rec_len % 8 != 0 || - de->rec_len < de->name_len + 8 || - (((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) { - printk ("ext_find_entry: bad dir entry\n"); - printk ("dev=%s, dir=%ld, offset=%ld, " - "rec_len=%d, name_len=%d\n", - kdevname(dir->i_dev), dir->i_ino, offset, - de->rec_len, de->name_len); - de = (struct ext_dir_entry *) (bh->b_data+BLOCK_SIZE); - offset = ((offset / BLOCK_SIZE) + 1) * BLOCK_SIZE; - continue; -/* brelse (bh); - return NULL; */ - } - if (ext_match(namelen,name,de)) { - *res_dir = de; - if (next_dir) - if (offset + de->rec_len < dir->i_size && - ((char *)de) + de->rec_len < BLOCK_SIZE+bh->b_data) - *next_dir = (struct ext_dir_entry *) - ((char *) de + de->rec_len); - else - *next_dir = NULL; - return bh; - } - offset += de->rec_len; - if (prev_dir) - *prev_dir = de; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - return NULL; -} - -int ext_lookup(struct inode * dir,const char * name, int len, - struct inode ** result) -{ - int ino; - struct ext_dir_entry * de; - struct buffer_head * bh; - - *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - if (!(bh = ext_find_entry(dir,name,len,&de,NULL,NULL))) { - iput(dir); - return -ENOENT; - } - ino = de->inode; - brelse(bh); - if (!(*result = iget(dir->i_sb,ino))) { - iput(dir); - return -EACCES; - } - iput(dir); - return 0; -} - -/* - * ext_add_entry() - * - * adds a file entry to the specified directory, using the same - * semantics as ext_find_entry(). It returns NULL if it failed. - * - * NOTE!! The inode part of 'de' is left at 0 - which means you - * may not sleep between calling this and putting something into - * the entry, as someone else might have used it while you slept. - */ -static struct buffer_head * ext_add_entry(struct inode * dir, - const char * name, int namelen, struct ext_dir_entry ** res_dir) -{ - int i; - long offset; - unsigned short rec_len; - struct buffer_head * bh; - struct ext_dir_entry * de, * de1; - - *res_dir = NULL; - if (!dir) - return NULL; -#ifdef NO_TRUNCATE - if (namelen > EXT_NAME_LEN) - return NULL; -#else - if (namelen > EXT_NAME_LEN) - namelen = EXT_NAME_LEN; -#endif - if (!namelen) - return NULL; - bh = ext_bread(dir,0,0); - if (!bh) - return NULL; - rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD; - offset = 0; - de = (struct ext_dir_entry *) bh->b_data; - while (1) { - if ((char *)de >= BLOCK_SIZE+bh->b_data && offset < dir->i_size) { -#ifdef EXTFS_DEBUG -printk ("ext_add_entry: skipping to next block\n"); -#endif - brelse(bh); - bh = NULL; - bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,0); - if (!bh) - return NULL; - de = (struct ext_dir_entry *) bh->b_data; - } - if (offset >= dir->i_size) { - /* Check that the directory entry fits in the block */ - if (offset % BLOCK_SIZE == 0 || - (BLOCK_SIZE - (offset % BLOCK_SIZE)) < rec_len) { - if ((offset % BLOCK_SIZE) != 0) { - /* If the entry does not fit in the - block, the remainder of the block - becomes an unused entry */ - de->inode = 0; - de->rec_len = BLOCK_SIZE - - (offset & (BLOCK_SIZE - 1)); - de->name_len = 0; - offset += de->rec_len; - dir->i_size += de->rec_len; - dir->i_dirt = 1; -#if 0 - dir->i_ctime = CURRENT_TIME; -#endif - mark_buffer_dirty(bh, 1); - } - brelse (bh); - bh = NULL; -#ifdef EXTFS_DEBUG -printk ("ext_add_entry : creating next block\n"); -#endif - bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,1); - if (!bh) - return NULL; /* Other thing to do ??? */ - de = (struct ext_dir_entry *) bh->b_data; - } - /* Allocate the entry */ - de->inode=0; - de->rec_len = rec_len; - dir->i_size += de->rec_len; - dir->i_dirt = 1; -#if 0 - dir->i_ctime = CURRENT_TIME; -#endif - } - if (de->rec_len < 8 || de->rec_len % 4 != 0 || - de->rec_len < de->name_len + 8 || - (((char *) de) + de->rec_len-1 >= BLOCK_SIZE+bh->b_data)) { - printk ("ext_addr_entry: bad dir entry\n"); - printk ("dev=%s, dir=%ld, offset=%ld, " - "rec_len=%d, name_len=%d\n", - kdevname(dir->i_dev), dir->i_ino, offset, - de->rec_len, de->name_len); - brelse (bh); - return NULL; - } - if (!de->inode && de->rec_len >= rec_len) { - if (de->rec_len > rec_len - && de->rec_len - rec_len >= EXT_DIR_MIN_SIZE) { - /* The found entry is too big : it is split - into 2 ones : - - the 1st one will be used to hold the name, - - the 2nd one is unused */ - de1 = (struct ext_dir_entry *) ((char *) de + rec_len); - de1->inode = 0; - de1->rec_len = de->rec_len - rec_len; - de1->name_len = 0; - de->rec_len = rec_len; - } - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - dir->i_dirt = 1; - de->name_len = namelen; - for (i=0; i < namelen ; i++) - de->name[i] = name[i]; - mark_buffer_dirty(bh, 1); - *res_dir = de; - return bh; - } - offset += de->rec_len; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - return NULL; -} - -int ext_create(struct inode * dir,const char * name, int len, int mode, - struct inode ** result) -{ - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de; - - *result = NULL; - if (!dir) - return -ENOENT; - inode = ext_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &ext_file_inode_operations; - inode->i_mode = mode; - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - *result = inode; - return 0; -} - -int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev) -{ - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de; - - if (!dir) - return -ENOENT; - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - inode = ext_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_uid = current->fsuid; - inode->i_mode = mode; - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &ext_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ext_dir_inode_operations; - if (dir->i_mode & S_ISGID) - inode->i_mode |= S_ISGID; - } - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &ext_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) - init_fifo(inode); - if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = to_kdev_t(rdev); -#if 0 - inode->i_mtime = inode->i_atime = CURRENT_TIME; -#endif - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int ext_mkdir(struct inode * dir, const char * name, int len, int mode) -{ - struct inode * inode; - struct buffer_head * bh, *dir_block; - struct ext_dir_entry * de; - - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - inode = ext_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &ext_dir_inode_operations; - inode->i_size = 2 * 16; /* Each entry is coded on 16 bytes for "." and ".." - - 4 bytes for the inode number, - - 2 bytes for the record length - - 2 bytes for the name length - - 8 bytes for the name */ -#if 0 - inode->i_mtime = inode->i_atime = CURRENT_TIME; -#endif - dir_block = ext_bread(inode,0,1); - if (!dir_block) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - de = (struct ext_dir_entry *) dir_block->b_data; - de->inode=inode->i_ino; - de->rec_len=16; - de->name_len=1; - strcpy(de->name,"."); - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - de->inode = dir->i_ino; - de->rec_len=16; - de->name_len=2; - strcpy(de->name,".."); - inode->i_nlink = 2; - mark_buffer_dirty(dir_block, 1); - brelse(dir_block); - inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask); - if (dir->i_mode & S_ISGID) - inode->i_mode |= S_ISGID; - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - iput(dir); - inode->i_nlink=0; - iput(inode); - return -ENOSPC; - } - de->inode = inode->i_ino; - mark_buffer_dirty(bh, 1); - dir->i_nlink++; - dir->i_dirt = 1; - iput(dir); - iput(inode); - brelse(bh); - return 0; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -static int empty_dir(struct inode * inode) -{ - unsigned long offset; - struct buffer_head * bh; - struct ext_dir_entry * de, * de1; - - if (inode->i_size < 2 * 12 || !(bh = ext_bread(inode,0,0))) { - printk("warning - bad directory on dev %s\n", - kdevname(inode->i_dev)); - return 1; - } - de = (struct ext_dir_entry *) bh->b_data; - de1 = (struct ext_dir_entry *) ((char *) de + de->rec_len); - if (de->inode != inode->i_ino || !de1->inode || - strcmp(".",de->name) || strcmp("..",de1->name)) { - printk("warning - bad directory on dev %s\n", - kdevname(inode->i_dev)); - return 1; - } - offset = de->rec_len + de1->rec_len; - de = (struct ext_dir_entry *) ((char *) de1 + de1->rec_len); - while (offset < inode->i_size ) { - if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) { - brelse(bh); - bh = ext_bread(inode, offset >> BLOCK_SIZE_BITS,1); - if (!bh) { - offset += BLOCK_SIZE; - continue; - } - de = (struct ext_dir_entry *) bh->b_data; - } - if (de->rec_len < 8 || de->rec_len %4 != 0 || - de->rec_len < de->name_len + 8) { - printk ("empty_dir: bad dir entry\n"); - printk ("dev=%s, dir=%ld, offset=%ld, " - "rec_len=%d, name_len=%d\n", - kdevname(inode->i_dev), inode->i_ino, - offset, de->rec_len, de->name_len); - brelse (bh); - return 1; - } - if (de->inode) { - brelse(bh); - return 0; - } - offset += de->rec_len; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - return 1; -} - -static inline void ext_merge_entries (struct ext_dir_entry * de, - struct ext_dir_entry * pde, struct ext_dir_entry * nde) -{ - if (nde && !nde->inode) - de->rec_len += nde->rec_len; - if (pde && !pde->inode) - pde->rec_len += de->rec_len; -} - -int ext_rmdir(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de, * pde, * nde; - - inode = NULL; - bh = ext_find_entry(dir,name,len,&de,&pde,&nde); - retval = -ENOENT; - if (!bh) - goto end_rmdir; - retval = -EPERM; - if (!(inode = iget(dir->i_sb, de->inode))) - goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !fsuser() && - current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) - goto end_rmdir; - if (inode->i_dev != dir->i_dev) - goto end_rmdir; - if (inode == dir) /* we may not delete ".", but "../dir" is ok */ - goto end_rmdir; - if (!S_ISDIR(inode->i_mode)) { - retval = -ENOTDIR; - goto end_rmdir; - } - if (!empty_dir(inode)) { - retval = -ENOTEMPTY; - goto end_rmdir; - } - if (inode->i_count > 1) { - retval = -EBUSY; - goto end_rmdir; - } - if (inode->i_nlink != 2) - printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink); - de->inode = 0; - de->name_len = 0; - ext_merge_entries (de, pde, nde); - mark_buffer_dirty(bh, 1); - inode->i_nlink=0; - inode->i_dirt=1; - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - dir->i_dirt=1; - retval = 0; -end_rmdir: - iput(dir); - iput(inode); - brelse(bh); - return retval; -} - -int ext_unlink(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de, * pde, * nde; - - retval = -ENOENT; - inode = NULL; - bh = ext_find_entry(dir,name,len,&de,&pde,&nde); - if (!bh) - goto end_unlink; - if (!(inode = iget(dir->i_sb, de->inode))) - goto end_unlink; - retval = -EPERM; - if ((dir->i_mode & S_ISVTX) && !fsuser() && - current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) - goto end_unlink; - if (S_ISDIR(inode->i_mode)) - goto end_unlink; - if (!inode->i_nlink) { - printk("Deleting nonexistent file (%s:%ld), %d\n", - kdevname(inode->i_dev), inode->i_ino, - inode->i_nlink); - inode->i_nlink=1; - } - de->inode = 0; - de->name_len = 0; - ext_merge_entries (de, pde, nde); - mark_buffer_dirty(bh, 1); - inode->i_nlink--; - inode->i_dirt = 1; - inode->i_ctime = CURRENT_TIME; - dir->i_ctime = dir->i_mtime = inode->i_ctime; - dir->i_dirt = 1; - retval = 0; -end_unlink: - brelse(bh); - iput(inode); - iput(dir); - return retval; -} - -int ext_symlink(struct inode * dir, const char * name, int len, const char * symname) -{ - struct ext_dir_entry * de; - struct inode * inode = NULL; - struct buffer_head * bh = NULL, * name_block = NULL; - int i; - char c; - - if (!(inode = ext_new_inode(dir))) { - iput(dir); - return -ENOSPC; - } - inode->i_mode = S_IFLNK | 0777; - inode->i_op = &ext_symlink_inode_operations; - name_block = ext_bread(inode,0,1); - if (!name_block) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - i = 0; - while (i < 1023 && (c = *(symname++))) - name_block->b_data[i++] = c; - name_block->b_data[i] = 0; - mark_buffer_dirty(name_block, 1); - brelse(name_block); - inode->i_size = i; - inode->i_dirt = 1; - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - brelse(bh); - iput(dir); - return -EEXIST; - } - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len) -{ - struct ext_dir_entry * de; - struct buffer_head * bh; - - if (S_ISDIR(oldinode->i_mode)) { - iput(oldinode); - iput(dir); - return -EPERM; - } - if (oldinode->i_nlink > 32000) { - iput(oldinode); - iput(dir); - return -EMLINK; - } - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - iput(oldinode); - return -EEXIST; - } - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - iput(dir); - iput(oldinode); - return -ENOSPC; - } - de->inode = oldinode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - oldinode->i_nlink++; - oldinode->i_ctime = CURRENT_TIME; - oldinode->i_dirt = 1; - iput(oldinode); - return 0; -} - -static int subdir(struct inode * new_inode, struct inode * old_inode) -{ - int ino; - int result; - - new_inode->i_count++; - result = 0; - for (;;) { - if (new_inode == old_inode) { - result = 1; - break; - } - if (new_inode->i_dev != old_inode->i_dev) - break; - ino = new_inode->i_ino; - if (ext_lookup(new_inode,"..",2,&new_inode)) - break; - if (new_inode->i_ino == ino) - break; - } - iput(new_inode); - return result; -} - -#define PARENT_INO(buffer) \ -((struct ext_dir_entry *) ((char *) buffer + \ -((struct ext_dir_entry *) buffer)->rec_len))->inode - -#define PARENT_NAME(buffer) \ -((struct ext_dir_entry *) ((char *) buffer + \ -((struct ext_dir_entry *) buffer)->rec_len))->name - -/* - * rename uses retrying to avoid race-conditions: at least they should be minimal. - * it tries to allocate all the blocks, then sanity-checks, and if the sanity- - * checks fail, it tries to restart itself again. Very practical - no changes - * are done until we know everything works ok.. and then all the changes can be - * done in one fell swoop when we have claimed all the buffers needed. - * - * Anybody can rename anything with this: the permission checks are left to the - * higher-level routines. - */ -static int do_ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len) -{ - struct inode * old_inode, * new_inode; - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext_dir_entry * old_de, * new_de, * pde, * nde; - int retval; - - goto start_up; -try_again: - brelse(old_bh); - brelse(new_bh); - brelse(dir_bh); - iput(old_inode); - iput(new_inode); - current->counter = 0; - schedule(); -start_up: - old_inode = new_inode = NULL; - old_bh = new_bh = dir_bh = NULL; - old_bh = ext_find_entry(old_dir,old_name,old_len,&old_de,&pde,&nde); - retval = -ENOENT; - if (!old_bh) - goto end_rename; - old_inode = __iget(old_dir->i_sb, old_de->inode,0); /* don't cross mnt-points */ - if (!old_inode) - goto end_rename; - retval = -EPERM; - if ((old_dir->i_mode & S_ISVTX) && - current->fsuid != old_inode->i_uid && - current->fsuid != old_dir->i_uid && !fsuser()) - goto end_rename; - new_bh = ext_find_entry(new_dir,new_name,new_len,&new_de,NULL,NULL); - if (new_bh) { - new_inode = __iget(new_dir->i_sb, new_de->inode,0); /* don't cross mnt-points */ - if (!new_inode) { - brelse(new_bh); - new_bh = NULL; - } - } - if (new_inode == old_inode) { - retval = 0; - goto end_rename; - } - if (new_inode && S_ISDIR(new_inode->i_mode)) { - retval = -EEXIST; - goto end_rename; - } - retval = -EPERM; - if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->fsuid != new_inode->i_uid && - current->fsuid != new_dir->i_uid && !fsuser()) - goto end_rename; - if (S_ISDIR(old_inode->i_mode)) { - retval = -EEXIST; - if (new_bh) - goto end_rename; - if ((retval = permission(old_inode, MAY_WRITE)) != 0) - goto end_rename; - retval = -EINVAL; - if (subdir(new_dir, old_inode)) - goto end_rename; - retval = -EIO; - dir_bh = ext_bread(old_inode,0,0); - if (!dir_bh) - goto end_rename; - if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino) - goto end_rename; - } - if (!new_bh) - new_bh = ext_add_entry(new_dir,new_name,new_len,&new_de); - retval = -ENOSPC; - if (!new_bh) - goto end_rename; -/* sanity checking before doing the rename - avoid races */ - if (new_inode && (new_de->inode != new_inode->i_ino)) - goto try_again; - if (new_de->inode && !new_inode) - goto try_again; - if (old_de->inode != old_inode->i_ino) - goto try_again; -/* ok, that's it */ - old_de->inode = 0; - old_de->name_len = 0; - new_de->inode = old_inode->i_ino; - ext_merge_entries (old_de, pde, nde); - if (new_inode) { - new_inode->i_nlink--; - new_inode->i_dirt = 1; - } - mark_buffer_dirty(old_bh, 1); - mark_buffer_dirty(new_bh, 1); - if (dir_bh) { - PARENT_INO(dir_bh->b_data) = new_dir->i_ino; - mark_buffer_dirty(dir_bh, 1); - old_dir->i_nlink--; - new_dir->i_nlink++; - old_dir->i_dirt = 1; - new_dir->i_dirt = 1; - } - retval = 0; -end_rename: - brelse(dir_bh); - brelse(old_bh); - brelse(new_bh); - iput(old_inode); - iput(new_inode); - iput(old_dir); - iput(new_dir); - return retval; -} - -/* - * Ok, rename also locks out other renames, as they can change the parent of - * a directory, and we don't want any races. Other races are checked for by - * "do_rename()", which restarts if there are inconsistencies. - * - * Note that there is no race between different filesystems: it's only within - * the same device that races occur: many renames can happen at once, as long - * as they are on different partitions. - */ -int ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len, - int must_be_dir) -{ - static struct wait_queue * wait = NULL; - static int lock = 0; - int result; - - while (lock) - sleep_on(&wait); - lock = 1; - result = do_ext_rename(old_dir, old_name, old_len, - new_dir, new_name, new_len); - lock = 0; - wake_up(&wait); - return result; -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/symlink.c linux/fs/ext/symlink.c --- v2.1.20/linux/fs/ext/symlink.c Tue Oct 29 19:58:42 1996 +++ linux/fs/ext/symlink.c Thu Jan 1 02:00:00 1970 @@ -1,110 +0,0 @@ -/* - * linux/fs/ext/symlink.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/symlink.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext symlink handling code - */ - -#include - -#include -#include -#include -#include -#include - -static int ext_readlink(struct inode *, char *, int); -static int ext_follow_link(struct inode *, struct inode *, int, int, struct inode **); - -/* - * symlinks can't do much... - */ -struct inode_operations ext_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - ext_readlink, /* readlink */ - ext_follow_link, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ -}; - -static int ext_follow_link(struct inode * dir, struct inode * inode, - int flag, int mode, struct inode ** res_inode) -{ - int error; - struct buffer_head * bh; - - *res_inode = NULL; - if (!dir) { - dir = current->fs->root; - dir->i_count++; - } - if (!inode) { - iput(dir); - return -ENOENT; - } - if (!S_ISLNK(inode->i_mode)) { - iput(dir); - *res_inode = inode; - return 0; - } - if (current->link_count > 5) { - iput(dir); - iput(inode); - return -ELOOP; - } - if (!(bh = ext_bread(inode, 0, 0))) { - iput(inode); - iput(dir); - return -EIO; - } - iput(inode); - current->link_count++; - error = open_namei(bh->b_data,flag,mode,res_inode,dir); - current->link_count--; - brelse(bh); - return error; -} - -static int ext_readlink(struct inode * inode, char * buffer, int buflen) -{ - struct buffer_head * bh; - int i; - char c; - - if (!S_ISLNK(inode->i_mode)) { - iput(inode); - return -EINVAL; - } - if (buflen > 1023) - buflen = 1023; - bh = ext_bread(inode, 0, 0); - iput(inode); - if (!bh) - return 0; - i = 0; - while (ib_data[i])) { - i++; - put_user(c,buffer++); - } - brelse(bh); - return i; -} diff -u --recursive --new-file v2.1.20/linux/fs/ext/truncate.c linux/fs/ext/truncate.c --- v2.1.20/linux/fs/ext/truncate.c Wed Oct 9 08:55:22 1996 +++ linux/fs/ext/truncate.c Thu Jan 1 02:00:00 1970 @@ -1,252 +0,0 @@ -/* - * linux/fs/ext/truncate.c - * - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/truncate.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -/* - * Truncate has the most races in the whole filesystem: coding it is - * a pain in the a**. Especially as I don't do any locking... - * - * The code may look a bit weird, but that's just because I've tried to - * handle things like file-size changes in a somewhat graceful manner. - * Anyway, truncating a file at the same time somebody else writes to it - * is likely to result in pretty weird behaviour... - * - * The new code handles normal truncates (size = 0) as well as the more - * general case (size = XXX). I hope. - */ - -static int trunc_direct(struct inode * inode) -{ - int i, tmp; - unsigned long * p; - struct buffer_head * bh; - int retry = 0; -#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10) - -repeat: - for (i = DIRECT_BLOCK ; i < 9 ; i++) { - p = inode->u.ext_i.i_data+i; - if (!(tmp = *p)) - continue; - bh = getblk(inode->i_dev,tmp,BLOCK_SIZE); - if (i < DIRECT_BLOCK) { - brelse(bh); - goto repeat; - } - if ((bh && bh->b_count != 1) || tmp != *p) { - retry = 1; - brelse(bh); - continue; - } - *p = 0; - inode->i_dirt = 1; - brelse(bh); - ext_free_block(inode->i_sb,tmp); - } - return retry; -} - -static int trunc_indirect(struct inode * inode, int offset, unsigned long * p) -{ - int i, tmp; - struct buffer_head * bh; - struct buffer_head * ind_bh; - unsigned long * ind; - int retry = 0; -#define INDIRECT_BLOCK (DIRECT_BLOCK-offset) - - tmp = *p; - if (!tmp) - return 0; - ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE); - if (tmp != *p) { - brelse(ind_bh); - return 1; - } - if (!ind_bh) { - *p = 0; - return 0; - } -repeat: - for (i = INDIRECT_BLOCK ; i < 256 ; i++) { - if (i < 0) - i = 0; - if (i < INDIRECT_BLOCK) - goto repeat; - ind = i+(unsigned long *) ind_bh->b_data; - tmp = *ind; - if (!tmp) - continue; - bh = getblk(inode->i_dev,tmp,BLOCK_SIZE); - if (i < INDIRECT_BLOCK) { - brelse(bh); - goto repeat; - } - if ((bh && bh->b_count != 1) || tmp != *ind) { - retry = 1; - brelse(bh); - continue; - } - *ind = 0; - mark_buffer_dirty(ind_bh, 1); - brelse(bh); - ext_free_block(inode->i_sb,tmp); - } - ind = (unsigned long *) ind_bh->b_data; - for (i = 0; i < 256; i++) - if (*(ind++)) - break; - if (i >= 256) - if (ind_bh->b_count != 1) - retry = 1; - else { - tmp = *p; - *p = 0; - inode->i_dirt = 1; - ext_free_block(inode->i_sb,tmp); - } - brelse(ind_bh); - return retry; -} - -static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p) -{ - int i,tmp; - struct buffer_head * dind_bh; - unsigned long * dind; - int retry = 0; -#define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8) - - tmp = *p; - if (!tmp) - return 0; - dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE); - if (tmp != *p) { - brelse(dind_bh); - return 1; - } - if (!dind_bh) { - *p = 0; - return 0; - } -repeat: - for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) { - if (i < 0) - i = 0; - if (i < DINDIRECT_BLOCK) - goto repeat; - dind = i+(unsigned long *) dind_bh->b_data; - tmp = *dind; - if (!tmp) - continue; - retry |= trunc_indirect(inode,offset+(i<<8),dind); - mark_buffer_dirty(dind_bh, 1); - } - dind = (unsigned long *) dind_bh->b_data; - for (i = 0; i < 256; i++) - if (*(dind++)) - break; - if (i >= 256) - if (dind_bh->b_count != 1) - retry = 1; - else { - tmp = *p; - *p = 0; - inode->i_dirt = 1; - ext_free_block(inode->i_sb,tmp); - } - brelse(dind_bh); - return retry; -} - -static int trunc_tindirect(struct inode * inode) -{ - int i,tmp; - struct buffer_head * tind_bh; - unsigned long * tind, * p; - int retry = 0; -#define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16) - - p = inode->u.ext_i.i_data+11; - if (!(tmp = *p)) - return 0; - tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE); - if (tmp != *p) { - brelse(tind_bh); - return 1; - } - if (!tind_bh) { - *p = 0; - return 0; - } -repeat: - for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) { - if (i < 0) - i = 0; - if (i < TINDIRECT_BLOCK) - goto repeat; - tind = i+(unsigned long *) tind_bh->b_data; - retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind); - mark_buffer_dirty(tind_bh, 1); - } - tind = (unsigned long *) tind_bh->b_data; - for (i = 0; i < 256; i++) - if (*(tind++)) - break; - if (i >= 256) - if (tind_bh->b_count != 1) - retry = 1; - else { - tmp = *p; - *p = 0; - inode->i_dirt = 1; - ext_free_block(inode->i_sb,tmp); - } - brelse(tind_bh); - return retry; -} - -void ext_truncate(struct inode * inode) -{ - int retry; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; - while (1) { - retry = trunc_direct(inode); - retry |= trunc_indirect(inode,9,inode->u.ext_i.i_data+9); - retry |= trunc_dindirect(inode,9+256,inode->u.ext_i.i_data+10); - retry |= trunc_tindirect(inode); - if (!retry) - break; - current->counter = 0; - schedule(); - } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; -} - -/* - * Called when an inode is released. Note that this is different - * from ext_open: open gets called at every open, but release - * gets called only when /all/ the files are closed. - */ -void ext_release(struct inode * inode, struct file * filp) -{ - printk("ext_release not implemented\n"); -} diff -u --recursive --new-file v2.1.20/linux/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c --- v2.1.20/linux/fs/fat/fatfs_syms.c Mon Dec 30 15:39:13 1996 +++ linux/fs/fat/fatfs_syms.c Fri Jan 3 11:33:26 1997 @@ -4,6 +4,7 @@ * Exported kernel symbols for the low-level FAT-based fs support. * */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/filesystems.c linux/fs/filesystems.c --- v2.1.20/linux/fs/filesystems.c Thu Apr 25 12:32:39 1996 +++ linux/fs/filesystems.c Tue Jan 14 12:59:10 1997 @@ -10,9 +10,7 @@ #include #include -#include #include -#include #include #include #include @@ -24,6 +22,7 @@ #include #include #include +#include #include extern void device_setup(void); @@ -42,18 +41,10 @@ binfmt_setup(); -#ifdef CONFIG_EXT_FS - init_ext_fs(); -#endif - #ifdef CONFIG_EXT2_FS init_ext2_fs(); #endif -#ifdef CONFIG_XIA_FS - init_xiafs_fs(); -#endif - #ifdef CONFIG_MINIX_FS init_minix_fs(); #endif @@ -110,6 +101,11 @@ init_ufs_fs(); #endif +#ifdef CONFIG_ROMFS_FS + init_romfs_fs(); +#endif + mount_root(); return 0; } + diff -u --recursive --new-file v2.1.20/linux/fs/isofs/inode.c linux/fs/isofs/inode.c --- v2.1.20/linux/fs/isofs/inode.c Thu Jan 2 15:55:23 1997 +++ linux/fs/isofs/inode.c Fri Jan 3 11:33:26 1997 @@ -8,6 +8,7 @@ * */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/msdos/msdosfs_syms.c linux/fs/msdos/msdosfs_syms.c --- v2.1.20/linux/fs/msdos/msdosfs_syms.c Mon Dec 30 15:39:13 1996 +++ linux/fs/msdos/msdosfs_syms.c Fri Jan 3 11:33:26 1997 @@ -5,6 +5,7 @@ * These symbols are used by umsdos. */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.20/linux/fs/ncpfs/inode.c Tue Dec 31 21:41:08 1996 +++ linux/fs/ncpfs/inode.c Fri Jan 3 11:33:26 1997 @@ -6,8 +6,8 @@ * */ -#include #include +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v2.1.20/linux/fs/nfs/inode.c Mon Dec 30 15:39:14 1996 +++ linux/fs/nfs/inode.c Fri Jan 3 11:33:26 1997 @@ -13,6 +13,7 @@ * */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c --- v2.1.20/linux/fs/proc/procfs_syms.c Mon Dec 30 15:39:14 1996 +++ linux/fs/proc/procfs_syms.c Fri Jan 3 11:33:26 1997 @@ -1,5 +1,5 @@ -#include #include +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/romfs/Makefile linux/fs/romfs/Makefile --- v2.1.20/linux/fs/romfs/Makefile Thu Jan 1 02:00:00 1970 +++ linux/fs/romfs/Makefile Fri Jan 3 13:03:42 1997 @@ -0,0 +1,14 @@ +# +# Makefile for the linux romfs-filesystem routines. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := romfs.o +O_OBJS := inode.o +M_OBJS := $(O_TARGET) + +include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.20/linux/fs/romfs/inode.c linux/fs/romfs/inode.c --- v2.1.20/linux/fs/romfs/inode.c Thu Jan 1 02:00:00 1970 +++ linux/fs/romfs/inode.c Tue Jan 14 12:51:18 1997 @@ -0,0 +1,666 @@ +/* + * ROMFS file system, Linux implementation + * + * Copyright (C) 1997 Janos Farkas + * + * Using parts of the minix filesystem + * Copyright (C) 1991, 1992 Linus Torvalds + * + * and parts of the affs filesystem additionally + * Copyright (C) 1993 Ray Burr + * Copyright (C) 1996 Hans-Joachim Widmaier + * + * This program 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. + * + * Changes + * Changed for 2.1.19 modules + * Jan 1997 Initial release + */ + +/* todo: + * use malloced memory for file names? + * considering write access... + * network (tftp) files? + */ + +/* + * Sorry about some optimizations and for some goto's. I just wanted + * to squeeze some more bytes out of this code.. :) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int inline min(int a, int b) +{ + return a>=2; + while (size>0) { + sum += ntohl(*ptr++); + size--; + } + return sum; +} + +static struct super_operations romfs_ops; + +static struct super_block * +romfs_read_super(struct super_block *s, void *data, int silent) +{ + struct buffer_head *bh; + kdev_t dev = s->s_dev; + struct romfs_super_block *rsb; + int sz; + + MOD_INC_USE_COUNT; + + /* I would parse the options, but there are none.. :) */ + + lock_super(s); + set_blocksize(dev, ROMBSIZE); + s->s_blocksize = ROMBSIZE; + s->s_blocksize_bits = ROMBSBITS; + bh = bread(dev, 0, ROMBSIZE); + if (!bh) { + printk ("romfs: unable to read superblock\n"); + goto outnobh; + } + + rsb = (struct romfs_super_block *)bh->b_data; + sz = ntohl(rsb->size); + if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 + || sz < ROMFH_SIZE) { + if (!silent) + printk ("VFS: Can't find a romfs filesystem on dev " + "%s.\n", kdevname(dev)); + goto out; + } + if (romfs_checksum(rsb, min(sz,512))) { + printk ("romfs: bad initial checksum on dev " + "%s.\n", kdevname(dev)); + } + + s->s_magic = ROMFS_MAGIC; + s->u.romfs_sb.s_maxsize = sz; + + s->s_flags |= MS_RDONLY; + + /* Find the start of the fs */ + sz = (ROMFH_SIZE + + strnlen(rsb->name, ROMFS_MAXFN) + 1 + ROMFH_PAD) + & ROMFH_MASK; + + brelse(bh); + + s->s_op = &romfs_ops; + + unlock_super(s); + + if (!(s->s_mounted = iget(s, sz))) + goto outnobh; + + /* Ehrhm; sorry.. :) And thanks to Hans-Joachim Widmaier :) */ + if (0) { +out: + brelse(bh); +outnobh: + s->s_dev = 0; + unlock_super(s); + MOD_DEC_USE_COUNT; + s = NULL; + } + + return s; +} + +/* Nothing to do.. */ + +static void +romfs_put_super(struct super_block *sb) +{ + lock_super(sb); + sb->s_dev = 0; + unlock_super(sb); + MOD_DEC_USE_COUNT; + return; +} + + +/* That's simple too. */ + +static void +romfs_statfs(struct super_block *sb, struct statfs *buf, int bufsize) +{ + struct statfs tmp; + + memset(&tmp, 0, sizeof(tmp)); + tmp.f_type = ROMFS_MAGIC; + tmp.f_bsize = ROMBSIZE; + tmp.f_blocks = (sb->u.romfs_sb.s_maxsize+ROMBSIZE-1)>>ROMBSBITS; + copy_to_user(buf, &tmp, bufsize); +} + +static int +romfs_strnlen(struct inode *i, unsigned long offset, unsigned long count) +{ + struct buffer_head *bh; + unsigned long avail, maxsize, res; + + maxsize = i->i_sb->u.romfs_sb.s_maxsize; + if (offset >= maxsize) + return -1; + + /* strnlen is almost always valid */ + if (count > maxsize || offset+count > maxsize) + count = maxsize-offset; + + bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + if (!bh) + return -1; /* error */ + + avail = ROMBSIZE - (offset & ROMBMASK); + maxsize = min(count, avail); + res = strnlen(((char *)bh->b_data)+(offset&ROMBMASK), maxsize); + brelse(bh); + + if (res < maxsize) + return res; /* found all of it */ + + while (res < count) { + offset += maxsize; + + bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + if (!bh) + return -1; + maxsize = min(count-res, ROMBSIZE); + avail = strnlen(bh->b_data, maxsize); + res += avail; + brelse(bh); + if (avail < maxsize) + return res; + } + return res; +} + +static int +romfs_copyfrom(struct inode *i, void *dest, unsigned long offset, unsigned long count) +{ + struct buffer_head *bh; + unsigned long avail, maxsize, res; + + maxsize = i->i_sb->u.romfs_sb.s_maxsize; + if (offset >= maxsize || count > maxsize || offset+count>maxsize) + return -1; + + bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + if (!bh) + return -1; /* error */ + + avail = ROMBSIZE - (offset & ROMBMASK); + maxsize = min(count, avail); + memcpy(dest, ((char *)bh->b_data) + (offset & ROMBMASK), maxsize); + brelse(bh); + + res = maxsize; /* all of it */ + + while (res < count) { + offset += maxsize; + dest += maxsize; + + bh = bread(i->i_dev, offset>>ROMBSBITS, ROMBSIZE); + if (!bh) + return -1; + maxsize = min(count-res, ROMBSIZE); + memcpy(dest, bh->b_data, maxsize); + brelse(bh); + res += maxsize; + } + return res; +} + +/* Directory operations */ + +static int +romfs_readdir(struct inode *i, struct file *filp, void *dirent, filldir_t filldir) +{ + struct romfs_inode ri; + unsigned long offset, maxoff; + int j, ino, nextfh; + int stored = 0; + char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ + + if (!i || !S_ISDIR(i->i_mode)) + return -EBADF; + + maxoff = i->i_sb->u.romfs_sb.s_maxsize; + + offset = filp->f_pos; + if (!offset) { + offset = i->i_ino & ROMFH_MASK; + if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0) + return stored; + offset = ntohl(ri.spec) & ROMFH_MASK; + } + + /* Not really failsafe, but we are read-only... */ + for(;;) { + if (!offset || offset >= maxoff) { + offset = 0xffffffff; + filp->f_pos = offset; + return stored; + } + filp->f_pos = offset; + + /* Fetch inode info */ + if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0) + return stored; + + j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1); + if (j < 0) + return stored; + + fsname[j]=0; + romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j); + + ino = offset; + nextfh = ntohl(ri.next); + if ((nextfh & ROMFH_TYPE) == ROMFH_HRD) + ino = ntohl(ri.spec); + if (filldir(dirent, fsname, j, offset, ino) < 0) { + return stored; + } + stored++; + offset = nextfh & ROMFH_MASK; + } +} + +static int +romfs_lookup(struct inode *dir, const char *name, int len, struct inode **result) +{ + unsigned long offset, maxoff; + int fslen, res; + char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ + struct romfs_inode ri; + + *result = NULL; + if (!dir || !S_ISDIR(dir->i_mode)) { + res = -EBADF; + goto out; + } + + offset = dir->i_ino & ROMFH_MASK; + if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) { + res = -ENOENT; + goto out; + } + + maxoff = dir->i_sb->u.romfs_sb.s_maxsize; + offset = ntohl(ri.spec) & ROMFH_MASK; + + for(;;) { + if (!offset || offset >= maxoff + || romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) { + res = -ENOENT; + goto out; + } + + /* try to match the first 16 bytes of name */ + fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE); + if (len < ROMFH_SIZE) { + if (len == fslen) { + /* both are shorter, and same size */ + romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1); + if (strncmp (name, fsname, len) == 0) + break; + } + } else if (fslen >= ROMFH_SIZE) { + /* both are longer; XXX optimize max size */ + fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, sizeof(fsname)-1); + if (len == fslen) { + romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1); + if (strncmp(name, fsname, len) == 0) + break; + } + } + /* next entry */ + offset = ntohl(ri.next) & ROMFH_MASK; + } + + /* Hard link handling */ + if ((ntohl(ri.next) & ROMFH_TYPE) == ROMFH_HRD) + offset = ntohl(ri.spec) & ROMFH_MASK; + + res = 0; + if (!(*result = iget(dir->i_sb, offset))) + res = -EACCES; + +out: + iput(dir); + return res; +} + +/* + * Ok, we do readpage, to be able to execute programs. Unfortunately, + * bmap is not applicable, since we have looser alignments. + * + * XXX I'm not quite sure that I need to muck around the PG_xx bits.. + */ + +static int +romfs_readpage(struct inode * inode, struct page * page) +{ + unsigned long buf; + unsigned long offset, avail, readlen; + int result = -EIO; + + buf = page_address(page); + page->count++; + offset = page->offset; + if (offset < inode->i_size) { + avail = inode->i_size-offset; + readlen = min(avail, PAGE_SIZE); + if (romfs_copyfrom(inode, (void *)buf, inode->u.romfs_i.i_dataoffset+offset, readlen) == readlen) { + if (readlen < PAGE_SIZE) { + memset((void *)(buf+readlen),0,PAGE_SIZE-readlen); + } + result = 0; + set_bit(PG_uptodate, &page->flags); + } else { + memset((void *)buf, 0, PAGE_SIZE); + } + } + free_page(buf); + return result; +} + +static int +romfs_readlink(struct inode *inode, char *buffer, int len) +{ + int mylen; + char buf[ROMFS_MAXFN]; /* XXX dynamic */ + + if (!inode || !S_ISLNK(inode->i_mode)) { + mylen = -EBADF; + goto out; + } + + mylen = min(sizeof(buf), inode->i_size); + + if (romfs_copyfrom(inode, buf, inode->u.romfs_i.i_dataoffset, mylen) <= 0) { + mylen = -EIO; + goto out; + } + copy_to_user(buffer, buf, mylen); + +out: + iput(inode); + return mylen; +} + +static int +romfs_follow_link(struct inode *dir, struct inode *inode, + int flag, int mode, struct inode **res_inode) +{ + int error, len; + char *buf; + + *res_inode = NULL; + if (!dir) { + dir = current->fs->root; + dir->i_count++; + } + + if (!inode) { + iput(dir); + return -ENOENT; + } + if (!S_ISLNK(inode->i_mode)) { + *res_inode = inode; + iput(dir); + return 0; + } + if (current->link_count > 5) { + iput(inode); + iput(dir); + return -ELOOP; + } + + /* Eek. Short enough. */ + len = inode->i_size; + if (!(buf = kmalloc(len+1, GFP_KERNEL))) { + iput(inode); + iput(dir); + /* correct? spin? */ + return -EAGAIN; + } + error = romfs_copyfrom(inode, buf, inode->u.romfs_i.i_dataoffset, len); + if (error != len) { + iput(inode); + iput(dir); + error = -EIO; + } else { + iput(inode); + buf[len] = 0; + current->link_count++; + error = open_namei(buf, flag, mode, res_inode, dir); + current->link_count--; + } + + kfree(buf); + return error; +} + +/* Mapping from our types to the kernel */ + +static struct file_operations romfs_file_operations = { + NULL, /* lseek - default */ + generic_file_read, /* read */ + NULL, /* write - bad */ + NULL, /* readdir */ + NULL, /* select - default */ + NULL, /* ioctl */ + generic_file_mmap, /* mmap */ + NULL, /* open */ + NULL, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL /* revalidate */ +}; + +static struct inode_operations romfs_file_inode_operations = { + &romfs_file_operations, + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + romfs_readpage, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap -- not really */ + NULL, /* truncate */ + NULL, /* permission */ + NULL, /* smap */ +}; + +static struct file_operations romfs_dir_operations = { + NULL, /* lseek - default */ + NULL, /* read */ + NULL, /* write - bad */ + romfs_readdir, /* readdir */ + NULL, /* select - default */ + NULL, /* ioctl */ + NULL, /* mmap */ + NULL, /* open */ + NULL, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL /* revalidate */ +}; + +/* Merged dir/symlink op table. readdir/lookup/readlink/follow_link + * will protect from type mismatch. + */ + +static struct inode_operations romfs_dirlink_inode_operations = { + &romfs_dir_operations, + NULL, /* create */ + romfs_lookup, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + romfs_readlink, /* readlink */ + romfs_follow_link, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL, /* permission */ + NULL, /* smap */ +}; + +static mode_t romfs_modemap[] = +{ + 0, S_IFDIR, S_IFREG, S_IFLNK+0777, + S_IFBLK, S_IFCHR, S_IFSOCK, S_IFIFO +}; + +static struct inode_operations *romfs_inoops[] = +{ + NULL, /* hardlink, handled elsewhere */ + &romfs_dirlink_inode_operations, + &romfs_file_inode_operations, + &romfs_dirlink_inode_operations, + &blkdev_inode_operations, /* standard handlers */ + &chrdev_inode_operations, + NULL, /* socket */ + NULL, /* fifo */ +}; + +static void +romfs_read_inode(struct inode *i) +{ + int nextfh, ino; + struct romfs_inode ri; + + i->i_op = NULL; + + ino = i->i_ino & ROMFH_MASK; + + /* Loop for finding the real hard link */ + for(;;) { + if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) { + printk("romfs: read error for inode 0x%x\n", ino); + return; + } + nextfh = ntohl(ri.next); + if ((nextfh & ROMFH_TYPE) != ROMFH_HRD) + break; + + ino = ntohl(ri.spec) & ROMFH_MASK; + } + + i->i_nlink = 1; /* Hard to decide.. */ + i->i_size = ntohl(ri.size); + i->i_mtime = i->i_atime = i->i_ctime = 0; + i->i_uid = i->i_gid = 0; + + i->i_op = romfs_inoops[nextfh & ROMFH_TYPE]; + + /* Precalculate the data offset */ + ino = romfs_strnlen(i, ino+ROMFH_SIZE, ROMFS_MAXFN); + if (ino >= 0) + ino = ((ROMFH_SIZE+ino+1+ROMFH_PAD)&ROMFH_MASK); + else + ino = 0; + i->u.romfs_i.i_metasize = ino; + i->u.romfs_i.i_dataoffset = ino+(i->i_ino&ROMFH_MASK); + + /* Compute permissions */ + ino = S_IRUGO|S_IWUSR; + ino |= romfs_modemap[nextfh & ROMFH_TYPE]; + if (nextfh & ROMFH_EXEC) { + ino |= S_IXUGO; + } + i->i_mode = ino; + + if (S_ISFIFO(ino)) + init_fifo(i); + else if (S_ISDIR(ino)) + i->i_size = i->u.romfs_i.i_metasize; + else if (S_ISBLK(ino) || S_ISCHR(ino)) { + i->i_mode &= ~(S_IRWXG|S_IRWXO); + ino = ntohl(ri.spec); + i->i_rdev = MKDEV(ino>>16,ino&0xffff); + } +} + +static struct super_operations romfs_ops = { + romfs_read_inode, /* read inode */ + NULL, /* notify change */ + NULL, /* write inode */ + NULL, /* put inode */ + romfs_put_super, /* put super */ + NULL, /* write super */ + romfs_statfs, /* statfs */ + NULL /* remount */ +}; + +static struct file_system_type romfs_fs_type = { + romfs_read_super, "romfs", 1, NULL +}; + +int +init_romfs_fs(void) +{ + return register_filesystem(&romfs_fs_type); +} + +#ifdef MODULE + +/* Yes, works even as a module... :) */ + +EXPORT_NO_SYMBOLS; + +int +init_module(void) +{ + return init_romfs_fs(); +} + +void +cleanup_module(void) +{ + unregister_filesystem(&romfs_fs_type); +} +#endif diff -u --recursive --new-file v2.1.20/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.20/linux/fs/smbfs/inode.c Mon Dec 30 15:39:14 1996 +++ linux/fs/smbfs/inode.c Fri Jan 3 11:33:26 1997 @@ -5,6 +5,7 @@ * */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/sysv/inode.c linux/fs/sysv/inode.c --- v2.1.20/linux/fs/sysv/inode.c Mon Dec 30 15:39:14 1996 +++ linux/fs/sysv/inode.c Fri Jan 3 11:33:26 1997 @@ -20,6 +20,7 @@ * the superblock. */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/ufs/ufs_super.c linux/fs/ufs/ufs_super.c --- v2.1.20/linux/fs/ufs/ufs_super.c Tue Dec 31 21:41:08 1996 +++ linux/fs/ufs/ufs_super.c Fri Jan 3 11:33:26 1997 @@ -20,6 +20,7 @@ * Gertjan van Wingerde */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.20/linux/fs/vfat/namei.c Mon Dec 30 15:39:14 1996 +++ linux/fs/vfat/namei.c Fri Jan 3 11:33:26 1997 @@ -10,6 +10,7 @@ * the problem, send a script that demonstrates it. */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/Makefile linux/fs/xiafs/Makefile --- v2.1.20/linux/fs/xiafs/Makefile Tue Aug 15 15:07:02 1995 +++ linux/fs/xiafs/Makefile Thu Jan 1 02:00:00 1970 @@ -1,14 +0,0 @@ -# -# Makefile for the XIAFS filesystem routines. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -O_TARGET := xiafs.o -O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o -M_OBJS := $(O_TARGET) - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/bitmap.c linux/fs/xiafs/bitmap.c --- v2.1.20/linux/fs/xiafs/bitmap.c Sun Nov 26 19:23:10 1995 +++ linux/fs/xiafs/bitmap.c Thu Jan 1 02:00:00 1970 @@ -1,389 +0,0 @@ -/* - * linux/fs/xiafs/bitmap.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/bitmap.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -/* bitmap.c contains the code that handles the inode and block bitmaps */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "xiafs_mac.h" - - -char internal_error_message[]="XIA-FS: internal error %s %d\n"; - -static int find_first_zero(struct buffer_head *bh, int start_bit, int end_bit) -{ - /* This routine searches first 0 bit from (start_bit) to (end_bit-1). - * If found the bit is set to 1 and the bit # is returned, otherwise, - * -1 is returned. Race condition is avoid by using "btsl" and - * "goto repeat". ---Frank. - */ - - int end, i, j, tmp; - u_long *bmap; - - bmap=(u_long *)bh->b_data; - end = end_bit >> 5; - -repeat: - i=start_bit >> 5; - if ( (tmp=(~bmap[i]) & (0xffffffff << (start_bit & 31))) ) - goto zone_found; - while (++i < end) - if (~bmap[i]) { - tmp=~bmap[i]; - goto zone_found; - } - if ( !(tmp=~bmap[i] & ((1 << (end_bit & 31)) -1)) ) - return -1; -zone_found: - for (j=0; j < 32; j++) - if (tmp & (1 << j)) - break; - if (set_bit(j,bmap+i)) { - start_bit=j + (i << 5) + 1; - goto repeat; - } - mark_buffer_dirty(bh, 1); - return j + (i << 5); -} - -static void clear_buf(struct buffer_head * bh) -{ - register int i; - register long * lp; - - lp=(long *)bh->b_data; - for (i= bh->b_size >> 2; i-- > 0; ) - *lp++=0; -} - -static void que(struct buffer_head * bmap[], int bznr[], int pos) -{ - struct buffer_head * tbh; - int tmp; - int i; - - tbh=bmap[pos]; - tmp=bznr[pos]; - for (i=pos; i > 0; i--) { - bmap[i]=bmap[i-1]; - bznr[i]=bznr[i-1]; - } - bmap[0]=tbh; - bznr[0]=tmp; -} - -#define get_imap_zone(sb, bit_nr, not_que) \ - get__map_zone((sb), (sb)->u.xiafs_sb.s_imap_buf, \ - (sb)->u.xiafs_sb.s_imap_iznr, \ - (sb)->u.xiafs_sb.s_imap_cached, 1, \ - (sb)->u.xiafs_sb.s_imap_zones, _XIAFS_IMAP_SLOTS, \ - bit_nr, not_que) - -#define get_zmap_zone(sb, bit_nr, not_que) \ - get__map_zone((sb), (sb)->u.xiafs_sb.s_zmap_buf, \ - (sb)->u.xiafs_sb.s_zmap_zznr, \ - (sb)->u.xiafs_sb.s_zmap_cached, \ - 1+(sb)->u.xiafs_sb.s_imap_zones, \ - (sb)->u.xiafs_sb.s_zmap_zones, _XIAFS_ZMAP_SLOTS, \ - bit_nr, not_que) - -static struct buffer_head * -get__map_zone(struct super_block *sb, struct buffer_head * bmap_buf[], - int bznr[], u_char cache, int first_zone, - int bmap_zones, int slots, u_long bit_nr, int * not_que) -{ - struct buffer_head * tmp_bh; - int z_nr, i; - - z_nr = bit_nr >> XIAFS_BITS_PER_Z_BITS(sb); - if (z_nr >= bmap_zones) { - printk("XIA-FS: bad inode/zone number (%s %d)\n", WHERE_ERR); - return NULL; - } - if (!cache) - return bmap_buf[z_nr]; - lock_super(sb); - for (i=0; i < slots; i++) - if (bznr[i]==z_nr) - break; - if (i < slots) { /* cache hit */ - if (not_que) { - *not_que=i; - return bmap_buf[i]; - } else { - que(bmap_buf, bznr, i); - return bmap_buf[0]; - } - } - tmp_bh=bread(sb->s_dev, z_nr+first_zone, XIAFS_ZSIZE(sb)); /* cache not hit */ - if (!tmp_bh) { - printk("XIA-FS: read bitmap failed (%s %d)\n", WHERE_ERR); - unlock_super(sb); - return NULL; - } - brelse(bmap_buf[slots-1]); - bmap_buf[slots-1]=tmp_bh; - bznr[slots-1]=z_nr; - if (not_que) - *not_que=slots-1; - else - que(bmap_buf, bznr, slots-1); - return tmp_bh; -} - -#define xiafs_unlock_super(sb, cache) if (cache) unlock_super(sb); - -#define get_free_ibit(sb, prev_bit) \ - get_free__bit(sb, sb->u.xiafs_sb.s_imap_buf, \ - sb->u.xiafs_sb.s_imap_iznr, \ - sb->u.xiafs_sb.s_imap_cached, \ - 1, sb->u.xiafs_sb.s_imap_zones, \ - _XIAFS_IMAP_SLOTS, prev_bit); - -#define get_free_zbit(sb, prev_bit) \ - get_free__bit(sb, sb->u.xiafs_sb.s_zmap_buf, \ - sb->u.xiafs_sb.s_zmap_zznr, \ - sb->u.xiafs_sb.s_zmap_cached, \ - 1 + sb->u.xiafs_sb.s_imap_zones, \ - sb->u.xiafs_sb.s_zmap_zones, \ - _XIAFS_ZMAP_SLOTS, prev_bit); - -static u_long -get_free__bit(struct super_block *sb, struct buffer_head * bmap_buf[], - int bznr[], u_char cache, int first_zone, int bmap_zones, - int slots, u_long prev_bit) -{ - struct buffer_head * bh; - int not_done=0; - u_long pos, start_bit, end_bit, total_bits; - int z_nr, tmp; - - total_bits=bmap_zones << XIAFS_BITS_PER_Z_BITS(sb); - if (prev_bit >= total_bits) - prev_bit=0; - pos=prev_bit+1; - end_bit=XIAFS_BITS_PER_Z(sb); - - do { - if (pos >= total_bits) - pos=0; - if (!not_done) { /* first time */ - not_done=1; - start_bit= pos & (end_bit-1); - } else - start_bit=0; - if ( pos < prev_bit && pos+end_bit >= prev_bit) { /* last time */ - not_done=0; - end_bit=prev_bit & (end_bit-1); /* only here end_bit modified */ - } - bh = get__map_zone(sb, bmap_buf, bznr, cache, first_zone, - bmap_zones, slots, pos, &z_nr); - if (!bh) - return 0; - tmp=find_first_zero(bh, start_bit, end_bit); - if (tmp >= 0) - break; - xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached); - pos=(pos & ~(end_bit-1))+end_bit; - } while (not_done); - - if (tmp < 0) - return 0; - if (cache) - que(bmap_buf, bznr, z_nr); - xiafs_unlock_super(sb, cache); - return (pos & ~(XIAFS_BITS_PER_Z(sb)-1))+tmp; -} - -void xiafs_free_zone(struct super_block * sb, int d_addr) -{ - struct buffer_head * bh; - unsigned int bit, offset; - - if (!sb) { - printk(INTERN_ERR); - return; - } - if (d_addr < sb->u.xiafs_sb.s_firstdatazone || - d_addr >= sb->u.xiafs_sb.s_nzones) { - printk("XIA-FS: bad zone number (%s %d)\n", WHERE_ERR); - return; - } - bh = get_hash_table(sb->s_dev, d_addr, XIAFS_ZSIZE(sb)); - if (bh) - mark_buffer_clean(bh); - brelse(bh); - bit=d_addr - sb->u.xiafs_sb.s_firstdatazone + 1; - bh = get_zmap_zone(sb, bit, NULL); - if (!bh) - return; - offset = bit & (XIAFS_BITS_PER_Z(sb) -1); - if (!clear_bit(offset, bh->b_data)) - printk("XIA-FS: dev %s" - " block bit %u (0x%x) already cleared (%s %d)\n", - kdevname(sb->s_dev), bit, bit, WHERE_ERR); - mark_buffer_dirty(bh, 1); - xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached); -} - -int xiafs_new_zone(struct super_block * sb, u_long prev_addr) -{ - struct buffer_head * bh; - int prev_znr, tmp; - - if (!sb) { - printk(INTERN_ERR); - return 0; - } - if (prev_addr < sb->u.xiafs_sb.s_firstdatazone || - prev_addr >= sb->u.xiafs_sb.s_nzones) { - prev_addr=sb->u.xiafs_sb.s_firstdatazone; - } - prev_znr=prev_addr-sb->u.xiafs_sb.s_firstdatazone+1; - tmp=get_free_zbit(sb, prev_znr); - if (!tmp) - return 0; - tmp += sb->u.xiafs_sb.s_firstdatazone -1; - if (!(bh = getblk(sb->s_dev, tmp, XIAFS_ZSIZE(sb)))) { - printk("XIA-FS: I/O error (%s %d)\n", WHERE_ERR); - return 0; - } - if (bh->b_count != 1) { - printk(INTERN_ERR); - return 0; - } - clear_buf(bh); - mark_buffer_uptodate(bh, 1); - mark_buffer_dirty(bh, 1); - brelse(bh); - return tmp; -} - -void xiafs_free_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct super_block * sb; - unsigned long ino; - - if (!inode) - return; - if (!inode->i_dev || inode->i_count!=1 - || inode->i_nlink || !inode->i_sb || inode->i_ino < 3 - || inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) { - printk("XIA-FS: bad inode (%s %d)\n", WHERE_ERR); - return; - } - sb = inode->i_sb; - ino = inode->i_ino; - bh = get_imap_zone(sb, ino, NULL); - if (!bh) - return; - clear_inode(inode); - if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data)) - printk("XIA-FS: dev %s" - "inode bit %ld (0x%lx) already cleared (%s %d)\n", - kdevname(inode->i_dev), ino, ino, WHERE_ERR); - mark_buffer_dirty(bh, 1); - xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached); -} - -struct inode * xiafs_new_inode(struct inode * dir) -{ - struct super_block * sb; - struct inode * inode; - ino_t tmp; - - sb = dir->i_sb; - if (!dir || !(inode = get_empty_inode())) - return NULL; - inode->i_sb = sb; - inode->i_flags = inode->i_sb->s_flags; - - tmp=get_free_ibit(sb, dir->i_ino); - if (!tmp) { - iput(inode); - return NULL; - } - inode->i_count = 1; - inode->i_nlink = 1; - inode->i_dev = sb->s_dev; - inode->i_uid = current->fsuid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - inode->i_dirt = 1; - inode->i_ino = tmp; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = NULL; - inode->i_blocks = 0; - inode->i_blksize = XIAFS_ZSIZE(inode->i_sb); - insert_inode_hash(inode); - return inode; -} - -static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; - -static u_long count_zone(struct buffer_head * bh) -{ - int i, tmp; - u_long sum; - - sum=0; - for (i=bh->b_size; i-- > 0; ) { - tmp=bh->b_data[i]; - sum += nibblemap[tmp & 0xf] + nibblemap[(tmp & 0xff) >> 4]; - } - return sum; -} - -unsigned long xiafs_count_free_inodes(struct super_block *sb) -{ - struct buffer_head * bh; - int izones, i, not_que; - u_long sum; - - sum=0; - izones=sb->u.xiafs_sb.s_imap_zones; - for (i=0; i < izones; i++) { - bh=get_imap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), ¬_que); - if (bh) { - sum += count_zone(bh); - xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached); - } - } - i=izones << XIAFS_BITS_PER_Z_BITS(sb); - return i - sum; -} - -unsigned long xiafs_count_free_zones(struct super_block *sb) -{ - struct buffer_head * bh; - int zzones, i, not_que; - u_long sum; - - sum=0; - zzones=sb->u.xiafs_sb.s_zmap_zones; - for (i=0; i < zzones; i++) { - bh=get_zmap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), ¬_que); - if (bh) { - sum += count_zone(bh); - xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached); - } - } - i=zzones << XIAFS_BITS_PER_Z_BITS(sb); - return i - sum; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/dir.c linux/fs/xiafs/dir.c --- v2.1.20/linux/fs/xiafs/dir.c Tue Oct 29 19:58:46 1996 +++ linux/fs/xiafs/dir.c Thu Jan 1 02:00:00 1970 @@ -1,131 +0,0 @@ -/* - * linux/fs/xiafs/dir.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/dir.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "xiafs_mac.h" - -static long xiafs_dir_read(struct inode *, struct file *, char *, unsigned long); -static int xiafs_readdir(struct inode *, struct file *, void *, filldir_t); - -static struct file_operations xiafs_dir_operations = { - NULL, /* lseek - default */ - xiafs_dir_read, /* read */ - NULL, /* write - bad */ - xiafs_readdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - file_fsync /* default fsync */ -}; - -/* - * directories can handle most operations... - */ -struct inode_operations xiafs_dir_inode_operations = { - &xiafs_dir_operations, /* default directory file-ops */ - xiafs_create, /* create */ - xiafs_lookup, /* lookup */ - xiafs_link, /* link */ - xiafs_unlink, /* unlink */ - xiafs_symlink, /* symlink */ - xiafs_mkdir, /* mkdir */ - xiafs_rmdir, /* rmdir */ - xiafs_mknod, /* mknod */ - xiafs_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - xiafs_truncate, /* truncate */ - NULL /* permission */ -}; - -static long xiafs_dir_read(struct inode * inode, struct file * filp, - char * buf, unsigned long count) -{ - return -EISDIR; -} - -static int xiafs_readdir(struct inode * inode, struct file * filp, - void * dirent, filldir_t filldir) -{ - u_int offset, i; - struct buffer_head * bh; - struct xiafs_direct * de; - - if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) - return -EBADF; - if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1) ) - return -EBADF; - while (filp->f_pos < inode->i_size) { - offset = filp->f_pos & (XIAFS_ZSIZE(inode->i_sb) - 1); - bh = xiafs_bread(inode, filp->f_pos >> XIAFS_ZSIZE_BITS(inode->i_sb),0); - if (!bh) { - filp->f_pos += XIAFS_ZSIZE(inode->i_sb)-offset; - continue; - } - for (i = 0; i < XIAFS_ZSIZE(inode->i_sb) && i < offset; ) { - de = (struct xiafs_direct *) (bh->b_data + i); - if (!de->d_rec_len) - break; - i += de->d_rec_len; - } - offset = i; - de = (struct xiafs_direct *) (offset + bh->b_data); - - while (offset < XIAFS_ZSIZE(inode->i_sb) && filp->f_pos < inode->i_size) { - if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes || - de->d_rec_len < 12 || - (char *)de+de->d_rec_len > XIAFS_ZSIZE(inode->i_sb)+bh->b_data || - de->d_name_len < 1 || de->d_name_len + 8 > de->d_rec_len || - de->d_name_len > _XIAFS_NAME_LEN || - de->d_name[de->d_name_len] ) { - printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR); - brelse(bh); - return 0; - } - if (de->d_ino) { - if (!IS_RDONLY (inode)) { - inode->i_atime=CURRENT_TIME; - inode->i_dirt=1; - } - if (filldir(dirent, de->d_name, de->d_name_len, filp->f_pos, de->d_ino) < 0) { - brelse(bh); - return 0; - } - } - offset += de->d_rec_len; - filp->f_pos += de->d_rec_len; - de = (struct xiafs_direct *) (offset + bh->b_data); - } - brelse(bh); - if (offset > XIAFS_ZSIZE(inode->i_sb)) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - return 0; - } - } - if (!IS_RDONLY (inode)) { - inode->i_atime=CURRENT_TIME; - inode->i_dirt=1; - } - return 0; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/file.c linux/fs/xiafs/file.c --- v2.1.20/linux/fs/xiafs/file.c Tue Oct 29 19:58:46 1996 +++ linux/fs/xiafs/file.c Thu Jan 1 02:00:00 1970 @@ -1,256 +0,0 @@ -/* - * linux/fs/xiafs/file.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/file.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "xiafs_mac.h" - -#define NBUF 32 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -static long xiafs_file_read(struct inode *, struct file *, char *, unsigned long); -static long xiafs_file_write(struct inode *, struct file *, const char *, unsigned long); - -/* - * We have mostly NULL's here: the current defaults are ok for - * the xiafs filesystem. - */ -static struct file_operations xiafs_file_operations = { - NULL, /* lseek - default */ - xiafs_file_read, /* read */ - xiafs_file_write, /* write */ - NULL, /* readdir - bad */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - generic_file_mmap, /* mmap */ - NULL, /* no special open is needed */ - NULL, /* release */ - xiafs_sync_file /* fsync */ -}; - -struct inode_operations xiafs_file_inode_operations = { - &xiafs_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - generic_readpage, /* readpage */ - NULL, /* writepage */ - xiafs_bmap, /* bmap */ - xiafs_truncate, /* truncate */ - NULL /* permission */ -}; - -static long -xiafs_file_read(struct inode * inode, struct file * filp, char * buf, unsigned long count) -{ - int read, left, chars; - int zone_nr, zones, f_zones, offset; - int bhrequest, uptodate; - struct buffer_head ** bhb, ** bhe; - struct buffer_head * bhreq[NBUF]; - struct buffer_head * buflist[NBUF]; - - if (!inode) { - printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR); - return -EINVAL; - } - offset = filp->f_pos; - left = inode->i_size - offset; - if (left > count) - left = count; - if (left <= 0) - return 0; - read = 0; - zone_nr = offset >> XIAFS_ZSIZE_BITS(inode->i_sb); - offset &= XIAFS_ZSIZE(inode->i_sb) -1 ; - f_zones =(inode->i_size+XIAFS_ZSIZE(inode->i_sb)-1)>>XIAFS_ZSIZE_BITS(inode->i_sb); - zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb); - bhb = bhe = buflist; - if (filp->f_reada) { - if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb))) - zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)); - if (zone_nr + zones > f_zones) - zones = f_zones - zone_nr; - } - - /* We do this in a two stage process. We first try to request - as many blocks as we can, then we wait for the first one to - complete, and then we try to wrap up as many as are actually - done. This routine is rather generic, in that it can be used - in a filesystem by substituting the appropriate function in - for getblk. - - This routine is optimized to make maximum use of the various - buffers and caches. */ - - do { - bhrequest = 0; - uptodate = 1; - while (zones--) { - *bhb = xiafs_getblk(inode, zone_nr++, 0); - if (*bhb && !buffer_uptodate(*bhb)) { - uptodate = 0; - bhreq[bhrequest++] = *bhb; - } - - if (++bhb == &buflist[NBUF]) - bhb = buflist; - - /* If the block we have on hand is uptodate, go ahead - and complete processing. */ - if (uptodate) - break; - if (bhb == bhe) - break; - } - - /* Now request them all */ - if (bhrequest) - ll_rw_block(READ, bhrequest, bhreq); - - do { /* Finish off all I/O that has actually completed */ - if (*bhe) { - wait_on_buffer(*bhe); - if (!buffer_uptodate(*bhe)) { /* read error? */ - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - left = 0; - break; - } - } - if (left < XIAFS_ZSIZE(inode->i_sb) - offset) - chars = left; - else - chars = XIAFS_ZSIZE(inode->i_sb) - offset; - filp->f_pos += chars; - left -= chars; - read += chars; - if (*bhe) { - copy_to_user(buf,offset+(*bhe)->b_data,chars); - brelse(*bhe); - buf += chars; - } else { - while (chars-->0) - put_user(0,buf++); - } - offset = 0; - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe))); - } while (left > 0); - -/* Release the read-ahead blocks */ - while (bhe != bhb) { - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - }; - if (!read) - return -EIO; - filp->f_reada = 1; - if (!IS_RDONLY (inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - return read; -} - -static long -xiafs_file_write(struct inode * inode, struct file * filp, const char * buf, unsigned long count) -{ - off_t pos; - int written, c; - struct buffer_head * bh; - char * cp; - - if (!inode) { - printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR); - return -EINVAL; - } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ - if (filp->f_flags & O_APPEND) - pos = inode->i_size; - else - pos = filp->f_pos; - written = 0; - while (written < count) { - bh = xiafs_getblk(inode, pos >> XIAFS_ZSIZE_BITS(inode->i_sb), 1); - if (!bh) { - if (!written) - written = -ENOSPC; - break; - } - c = XIAFS_ZSIZE(inode->i_sb) - (pos & (XIAFS_ZSIZE(inode->i_sb) - 1)); - if (c > count-written) - c = count-written; - if (c != XIAFS_ZSIZE(inode->i_sb) && !buffer_uptodate(bh)) { - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - if (!written) - written = -EIO; - break; - } - } - cp = (pos & (XIAFS_ZSIZE(inode->i_sb)-1)) + bh->b_data; - copy_from_user(cp,buf,c); - update_vm_cache(inode,pos,cp,c); - pos += c; - if (pos > inode->i_size) { - inode->i_size = pos; - inode->i_dirt = 1; - } - written += c; - buf += c; - mark_buffer_uptodate(bh, 1); - mark_buffer_dirty(bh, 0); - brelse(bh); - } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - filp->f_pos = pos; - inode->i_dirt = 1; - - return written; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/fsync.c linux/fs/xiafs/fsync.c --- v2.1.20/linux/fs/xiafs/fsync.c Tue Oct 29 19:58:47 1996 +++ linux/fs/xiafs/fsync.c Thu Jan 1 02:00:00 1970 @@ -1,159 +0,0 @@ -/* - * linux/fs/xiafs/fsync.c - * - * Changes Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk) - * from - * Copyright (C) 1991, 1992 Linus Torvalds - * - * xiafs fsync primitive - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "xiafs_mac.h" - - -#define blocksize (XIAFS_ZSIZE(inode->i_sb)) -#define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb)) - -static int sync_block (struct inode * inode, unsigned long * block, int wait) -{ - struct buffer_head * bh; - int tmp; - - if (!*block) - return 0; - tmp = *block; - bh = get_hash_table(inode->i_dev, *block, blocksize); - if (!bh) - return 0; - if (*block != tmp) { - brelse (bh); - return 1; - } - if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse(bh); - return -1; - } - if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) - { - brelse(bh); - return 0; - } - ll_rw_block(WRITE, 1, &bh); - bh->b_count--; - return 0; -} - -static int sync_iblock (struct inode * inode, unsigned long * iblock, - struct buffer_head **bh, int wait) -{ - int rc, tmp; - - *bh = NULL; - tmp = *iblock; - if (!tmp) - return 0; - rc = sync_block (inode, iblock, wait); - if (rc) - return rc; - *bh = bread(inode->i_dev, tmp, blocksize); - if (tmp != *iblock) { - brelse(*bh); - *bh = NULL; - return 1; - } - if (!*bh) - return -1; - return 0; -} - - -static int sync_direct(struct inode *inode, int wait) -{ - int i; - int rc, err = 0; - - for (i = 0; i < 8; i++) { - rc = sync_block (inode, inode->u.ext_i.i_data + i, wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - return err; -} - -static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait) -{ - int i; - struct buffer_head * ind_bh; - int rc, err = 0; - - rc = sync_iblock (inode, iblock, &ind_bh, wait); - if (rc || !ind_bh) - return rc; - - for (i = 0; i < addr_per_block; i++) { - rc = sync_block (inode, - ((unsigned long *) ind_bh->b_data) + i, - wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - brelse(ind_bh); - return err; -} - -static int sync_dindirect(struct inode *inode, unsigned long *diblock, - int wait) -{ - int i; - struct buffer_head * dind_bh; - int rc, err = 0; - - rc = sync_iblock (inode, diblock, &dind_bh, wait); - if (rc || !dind_bh) - return rc; - - for (i = 0; i < addr_per_block; i++) { - rc = sync_indirect (inode, - ((unsigned long *) dind_bh->b_data) + i, - wait); - if (rc > 0) - break; - if (rc) - err = rc; - } - brelse(dind_bh); - return err; -} - -int xiafs_sync_file(struct inode * inode, struct file * file) -{ - int wait, err = 0; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return -EINVAL; - for (wait=0; wait<=1; wait++) - { - err |= sync_direct(inode, wait); - err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait); - err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait); - } - err |= xiafs_sync_inode (inode); - return (err < 0) ? -EIO : 0; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/inode.c linux/fs/xiafs/inode.c --- v2.1.20/linux/fs/xiafs/inode.c Mon Dec 30 15:39:14 1996 +++ linux/fs/xiafs/inode.c Thu Jan 1 02:00:00 1970 @@ -1,538 +0,0 @@ -/* - * linux/fs/xiafs/inode.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/inode.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xiafs_mac.h" - -static u_long random_nr; - -void xiafs_put_inode(struct inode *inode) -{ - if (inode->i_nlink) - return; - inode->i_size = 0; - xiafs_truncate(inode); - xiafs_free_inode(inode); -} - -void xiafs_put_super(struct super_block *sb) -{ - int i; - - lock_super(sb); - sb->s_dev = 0; - for(i = 0 ; i < _XIAFS_IMAP_SLOTS ; i++) - brelse(sb->u.xiafs_sb.s_imap_buf[i]); - for(i = 0 ; i < _XIAFS_ZMAP_SLOTS ; i++) - brelse(sb->u.xiafs_sb.s_zmap_buf[i]); - unlock_super(sb); - MOD_DEC_USE_COUNT; -} - -static struct super_operations xiafs_sops = { - xiafs_read_inode, - NULL, - xiafs_write_inode, - xiafs_put_inode, - xiafs_put_super, - NULL, - xiafs_statfs, - NULL -}; - -struct super_block *xiafs_read_super(struct super_block *s, void *data, - int silent) -{ - struct buffer_head *bh; - struct xiafs_super_block *sp; - int i, z; - kdev_t dev; - - MOD_INC_USE_COUNT; - dev = s->s_dev; - lock_super(s); - - set_blocksize(dev, BLOCK_SIZE); - - if (!(bh = bread(dev, 0, BLOCK_SIZE))) { - s->s_dev = 0; - unlock_super(s); - printk("XIA-FS: read super_block failed (%s %d)\n", WHERE_ERR); - MOD_DEC_USE_COUNT; - return NULL; - } - sp = (struct xiafs_super_block *) bh->b_data; - s->s_magic = sp->s_magic; - if (s->s_magic != _XIAFS_SUPER_MAGIC) { - s->s_dev = 0; - unlock_super(s); - brelse(bh); - if (!silent) - printk("VFS: Can't find a xiafs filesystem on dev " - "%s.\n", kdevname(dev)); - MOD_DEC_USE_COUNT; - return NULL; - } - s->s_blocksize = sp->s_zone_size; - s->s_blocksize_bits = 10 + sp->s_zone_shift; - if (s->s_blocksize != BLOCK_SIZE && - (s->s_blocksize == 1024 || s->s_blocksize == 2048 || - s->s_blocksize == 4096)) { - brelse(bh); - set_blocksize(dev, s->s_blocksize); - bh = bread (dev, 0, s->s_blocksize); - if(!bh) { - MOD_DEC_USE_COUNT; - return NULL; - } - sp = (struct xiafs_super_block *) (((char *)bh->b_data) + BLOCK_SIZE) ; - }; - s->u.xiafs_sb.s_nzones = sp->s_nzones; - s->u.xiafs_sb.s_ninodes = sp->s_ninodes; - s->u.xiafs_sb.s_ndatazones = sp->s_ndatazones; - s->u.xiafs_sb.s_imap_zones = sp->s_imap_zones; - s->u.xiafs_sb.s_zmap_zones = sp->s_zmap_zones; - s->u.xiafs_sb.s_firstdatazone = sp->s_firstdatazone; - s->u.xiafs_sb.s_zone_shift = sp->s_zone_shift; - s->u.xiafs_sb.s_max_size = sp->s_max_size; - brelse(bh); - for (i=0;i < _XIAFS_IMAP_SLOTS;i++) { - s->u.xiafs_sb.s_imap_buf[i] = NULL; - s->u.xiafs_sb.s_imap_iznr[i] = -1; - } - for (i=0;i < _XIAFS_ZMAP_SLOTS;i++) { - s->u.xiafs_sb.s_zmap_buf[i] = NULL; - s->u.xiafs_sb.s_zmap_zznr[i] = -1; - } - z=1; - if ( s->u.xiafs_sb.s_imap_zones > _XIAFS_IMAP_SLOTS ) - s->u.xiafs_sb.s_imap_cached=1; - else { - s->u.xiafs_sb.s_imap_cached=0; - for (i=0 ; i < s->u.xiafs_sb.s_imap_zones ; i++) { - if (!(s->u.xiafs_sb.s_imap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s)))) - goto xiafs_read_super_fail; - s->u.xiafs_sb.s_imap_iznr[i]=i; - } - } - if ( s->u.xiafs_sb.s_zmap_zones > _XIAFS_ZMAP_SLOTS ) - s->u.xiafs_sb.s_zmap_cached=1; - else { - s->u.xiafs_sb.s_zmap_cached=0; - for (i=0 ; i < s->u.xiafs_sb.s_zmap_zones ; i++) { - if (!(s->u.xiafs_sb.s_zmap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s)))) - goto xiafs_read_super_fail; - s->u.xiafs_sb.s_zmap_zznr[i]=i; - } - } - /* set up enough so that it can read an inode */ - s->s_dev = dev; - s->s_op = &xiafs_sops; - s->s_mounted = iget(s, _XIAFS_ROOT_INO); - if (!s->s_mounted) - goto xiafs_read_super_fail; - unlock_super(s); - random_nr=CURRENT_TIME; - return s; - -xiafs_read_super_fail: - for(i=0; i < _XIAFS_IMAP_SLOTS; i++) - brelse(s->u.xiafs_sb.s_imap_buf[i]); - for(i=0; i < _XIAFS_ZMAP_SLOTS; i++) - brelse(s->u.xiafs_sb.s_zmap_buf[i]); - s->s_dev = 0; - unlock_super(s); - printk("XIA-FS: read bitmaps failed (%s %d)\n", WHERE_ERR); - MOD_DEC_USE_COUNT; - return NULL; -} - -void xiafs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) -{ - struct statfs tmp; - - tmp.f_type = _XIAFS_SUPER_MAGIC; - tmp.f_bsize = XIAFS_ZSIZE(sb); - tmp.f_blocks = sb->u.xiafs_sb.s_ndatazones; - tmp.f_bfree = xiafs_count_free_zones(sb); - tmp.f_bavail = tmp.f_bfree; - tmp.f_files = sb->u.xiafs_sb.s_ninodes; - tmp.f_ffree = xiafs_count_free_inodes(sb); - tmp.f_namelen = _XIAFS_NAME_LEN; - copy_to_user(buf, &tmp, bufsiz); -} - -static int zone_bmap(struct buffer_head * bh, int nr) -{ - int tmp; - - if (!bh) - return 0; - tmp = ((u_long *) bh->b_data)[nr]; - brelse(bh); - return tmp; -} - -int xiafs_bmap(struct inode * inode,int zone) -{ - int i; - - if (zone < 0) { - printk("XIA-FS: block < 0 (%s %d)\n", WHERE_ERR); - return 0; - } - if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) { - printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR); - return 0; - } - if (!IS_RDONLY (inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - if (zone < 8) - return inode->u.xiafs_i.i_zone[zone]; - zone -= 8; - if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) { - i = inode->u.xiafs_i.i_ind_zone; - if (i) - i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), zone); - return i; - } - zone -= XIAFS_ADDRS_PER_Z(inode->i_sb); - i = inode->u.xiafs_i.i_dind_zone; - if (i) - i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), - zone >> XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)); - if (i) - i= zone_bmap(bread(inode->i_dev,i, XIAFS_ZSIZE(inode->i_sb)), - zone & (XIAFS_ADDRS_PER_Z(inode->i_sb)-1)); - return i; -} - -static u_long get_prev_addr(struct inode * inode, int zone) -{ - u_long tmp; - - if (zone > 0) - while (--zone >= 0) /* only files with holes suffer */ - if ((tmp=xiafs_bmap(inode, zone))) - return tmp; - random_nr=(random_nr+23)%inode->i_sb->u.xiafs_sb.s_ndatazones; - return random_nr + inode->i_sb->u.xiafs_sb.s_firstdatazone; -} - -static struct buffer_head * -dt_getblk(struct inode * inode, u_long *lp, int create, u_long prev_addr) -{ - int tmp; - struct buffer_head * result; - -repeat: - if ((tmp=*lp)) { - result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (tmp == *lp) - return result; - brelse(result); - goto repeat; - } - if (!create) - return NULL; - tmp = xiafs_new_zone(inode->i_sb, prev_addr); - if (!tmp) - return NULL; - result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (*lp) { - xiafs_free_zone(inode->i_sb, tmp); - brelse(result); - goto repeat; - } - *lp = tmp; - inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb); - return result; -} - -static struct buffer_head * -indt_getblk(struct inode * inode, struct buffer_head * bh, - int nr, int create, u_long prev_addr) -{ - int tmp; - u_long *lp; - struct buffer_head * result; - - if (!bh) - return NULL; - if (!buffer_uptodate(bh)) { - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - brelse(bh); - return NULL; - } - } - lp = nr + (u_long *) bh->b_data; -repeat: - if ((tmp=*lp)) { - result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (tmp == *lp) { - brelse(bh); - return result; - } - brelse(result); - goto repeat; - } - if (!create) { - brelse(bh); - return NULL; - } - tmp = xiafs_new_zone(inode->i_sb, prev_addr); - if (!tmp) { - brelse(bh); - return NULL; - } - result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (*lp) { - xiafs_free_zone(inode->i_sb, tmp); - brelse(result); - goto repeat; - } - *lp = tmp; - inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb); - mark_buffer_dirty(bh, 1); - brelse(bh); - return result; -} - -struct buffer_head * xiafs_getblk(struct inode * inode, int zone, int create) -{ - struct buffer_head * bh; - u_long prev_addr=0; - - if (zone<0) { - printk("XIA-FS: zone < 0 (%s %d)\n", WHERE_ERR); - return NULL; - } - if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) { - if (!create) - printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR); - return NULL; - } - if (create) - prev_addr=get_prev_addr(inode, zone); - if (zone < 8) - return dt_getblk(inode, zone+inode->u.xiafs_i.i_zone, create, prev_addr); - zone -= 8; - if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) { - bh = dt_getblk(inode, &(inode->u.xiafs_i.i_ind_zone), create, prev_addr); - bh = indt_getblk(inode, bh, zone, create, prev_addr); - return bh; - } - zone -= XIAFS_ADDRS_PER_Z(inode->i_sb); - bh = dt_getblk(inode, &(inode->u.xiafs_i.i_dind_zone), create, prev_addr); - bh = indt_getblk(inode, bh, zone>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb), - create, prev_addr); - bh = indt_getblk(inode, bh, zone&(XIAFS_ADDRS_PER_Z(inode->i_sb)-1), - create, prev_addr); - return bh; -} - -struct buffer_head * xiafs_bread(struct inode * inode, int zone, int create) -{ - struct buffer_head * bh; - - bh = xiafs_getblk(inode, zone, create); - if (!bh || buffer_uptodate(bh)) - return bh; - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return bh; - brelse(bh); - return NULL; -} - -void xiafs_read_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct xiafs_inode * raw_inode; - int zone; - ino_t ino; - - ino = inode->i_ino; - inode->i_op = NULL; - inode->i_mode=0; - if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) { - printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR); - return; - } - zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones + - inode->i_sb->u.xiafs_sb.s_zmap_zones + - (ino-1)/ XIAFS_INODES_PER_Z(inode->i_sb); - if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) { - printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR); - return; - } - raw_inode = ((struct xiafs_inode *) bh->b_data) + - ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) - 1)); - inode->i_mode = raw_inode->i_mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; - inode->i_nlink = raw_inode->i_nlinks; - inode->i_size = raw_inode->i_size; - inode->i_mtime = raw_inode->i_mtime; - inode->i_atime = raw_inode->i_atime; - inode->i_ctime = raw_inode->i_ctime; - inode->i_blksize = XIAFS_ZSIZE(inode->i_sb); - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - inode->i_blocks=0; - inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]); - } else { - XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks); - for (zone = 0; zone < 8; zone++) - inode->u.xiafs_i.i_zone[zone] = raw_inode->i_zone[zone] & 0xffffff; - inode->u.xiafs_i.i_ind_zone = raw_inode->i_ind_zone & 0xffffff; - inode->u.xiafs_i.i_dind_zone = raw_inode->i_dind_zone & 0xffffff; - } - brelse(bh); - if (S_ISREG(inode->i_mode)) - inode->i_op = &xiafs_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &xiafs_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &xiafs_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) - init_fifo(inode); -} - -static struct buffer_head * xiafs_update_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct xiafs_inode * raw_inode; - int zone; - ino_t ino; - - if (IS_RDONLY (inode)) { - printk("XIA-FS: write_inode on a read-only filesystem (%s %d)\n", WHERE_ERR); - inode->i_dirt = 0; - return 0; - } - - ino = inode->i_ino; - if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) { - printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR); - inode->i_dirt=0; - return 0; - } - zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones + - inode->i_sb->u.xiafs_sb.s_zmap_zones + - (ino-1) / XIAFS_INODES_PER_Z(inode->i_sb); - if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) { - printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR); - inode->i_dirt=0; - return 0; - } - raw_inode = ((struct xiafs_inode *)bh->b_data) + - ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) -1)); - raw_inode->i_mode = inode->i_mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; - raw_inode->i_nlinks = inode->i_nlink; - raw_inode->i_size = inode->i_size; - raw_inode->i_atime = inode->i_atime; - raw_inode->i_ctime = inode->i_ctime; - raw_inode->i_mtime = inode->i_mtime; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev); - else { - XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks); - for (zone = 0; zone < 8; zone++) - raw_inode->i_zone[zone] = (raw_inode->i_zone[zone] & 0xff000000) - | (inode->u.xiafs_i.i_zone[zone] & 0xffffff); - raw_inode->i_ind_zone = (raw_inode->i_ind_zone & 0xff000000) - | (inode->u.xiafs_i.i_ind_zone & 0xffffff); - raw_inode->i_dind_zone = (raw_inode->i_dind_zone & 0xff000000) - | (inode->u.xiafs_i.i_dind_zone & 0xffffff); - } - inode->i_dirt=0; - mark_buffer_dirty(bh, 1); - return bh; -} - - -void xiafs_write_inode(struct inode * inode) -{ - struct buffer_head * bh; - bh = xiafs_update_inode(inode); - brelse (bh); -} - -int xiafs_sync_inode (struct inode *inode) -{ - int err = 0; - struct buffer_head *bh; - - bh = xiafs_update_inode(inode); - if (bh && buffer_dirty(bh)) - { - ll_rw_block(WRITE, 1, &bh); - wait_on_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - { - printk ("IO error syncing xiafs inode [%s:%lu]\n", - kdevname(inode->i_dev), inode->i_ino); - err = -1; - } - } - else if (!bh) - err = -1; - brelse (bh); - return err; -} - -/* Every kernel module contains stuff like this. */ - -static struct file_system_type xiafs_fs_type = { - xiafs_read_super, "xiafs", 1, NULL -}; - -int init_xiafs_fs(void) -{ - return register_filesystem(&xiafs_fs_type); -} - -#ifdef MODULE -EXPORT_NO_SYMBOLS; - -int init_module(void) -{ - return init_xiafs_fs(); -} - -void cleanup_module(void) -{ - unregister_filesystem(&xiafs_fs_type); -} - -#endif diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/namei.c linux/fs/xiafs/namei.c --- v2.1.20/linux/fs/xiafs/namei.c Tue Oct 29 19:58:47 1996 +++ linux/fs/xiafs/namei.c Thu Jan 1 02:00:00 1970 @@ -1,854 +0,0 @@ -/* - * Linux/fs/xiafs/namei.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/namei.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "xiafs_mac.h" - -#define RNDUP4(x) ((3+(u_long)(x)) & ~3) -/* - * ok, we cannot use strncmp, as the name is not in our data space. - * Thus we'll have to use xiafs_match. No big problem. Match also makes - * some sanity tests. - * - * NOTE! unlike strncmp, xiafs_match returns 1 for success, 0 for failure. - */ -static int xiafs_match(int len, const char * name, struct xiafs_direct * dep) -{ - int i; - - if (!dep || !dep->d_ino || len > _XIAFS_NAME_LEN) - return 0; - /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ - if (!len && (dep->d_name[0]=='.') && (dep->d_name[1]=='\0')) - return 1; - if (len != dep->d_name_len) - return 0; - for (i=0; i < len; i++) - if (*name++ != dep->d_name[i]) - return 0; - return 1; -} - -/* - * xiafs_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the cache buffer in which the entry was found, and the entry - * itself (as a parameter - res_dir). It does NOT read the inode of the - * entry - you'll have to do that yourself if you want to. - */ -static struct buffer_head * -xiafs_find_entry(struct inode * inode, const char * name, int namelen, - struct xiafs_direct ** res_dir, struct xiafs_direct ** res_pre) -{ - int i, zones, pos; - struct buffer_head * bh; - struct xiafs_direct * dep, * dep_pre; - - *res_dir = NULL; - if (!inode) - return NULL; - if (namelen > _XIAFS_NAME_LEN) - return NULL; - - if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1)) { - printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR); - return NULL; - } - zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb); - for (i=0; i < zones; i++ ) { - bh = xiafs_bread(inode, i, 0); - if (!bh) - continue; - dep_pre=dep=(struct xiafs_direct *)bh->b_data; - if (!i && (dep->d_rec_len != 12 || !dep->d_ino || - dep->d_name_len != 1 || strcmp(dep->d_name, "."))) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - brelse(bh); - return NULL; - } - pos = 0; - while ( pos < XIAFS_ZSIZE(inode->i_sb) ) { - if (dep->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes || - dep->d_rec_len < 12 || - dep->d_rec_len+(char *)dep > bh->b_data+XIAFS_ZSIZE(inode->i_sb) || - dep->d_name_len + 8 > dep->d_rec_len || dep->d_name_len <= 0 || - dep->d_name[dep->d_name_len] ) { - brelse(bh); - return NULL; - } - if (xiafs_match(namelen, name, dep)) { - *res_dir=dep; - if (res_pre) - *res_pre=dep_pre; - return bh; - } - pos += dep->d_rec_len; - dep_pre=dep; - dep=(struct xiafs_direct *)(bh->b_data + pos); - } - brelse(bh); - if (pos > XIAFS_ZSIZE(inode->i_sb)) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - return NULL; - } - } - return NULL; -} - -int xiafs_lookup(struct inode * dir, const char * name, int len, - struct inode ** result) -{ - int ino; - struct xiafs_direct * dep; - struct buffer_head * bh; - - *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - if (!(bh = xiafs_find_entry(dir, name, len, &dep, NULL))) { - iput(dir); - return -ENOENT; - } - ino = dep->d_ino; - brelse(bh); - if (!(*result = iget(dir->i_sb, ino))) { - iput(dir); - return -EACCES; - } - iput(dir); - return 0; -} - -/* - * xiafs_add_entry() - * - * adds a file entry to the specified directory, using the same - * semantics as xiafs_find_entry(). It returns NULL if it failed. - * - * NOTE!! The inode part of 'de' is left at 0 - which means you - * may not sleep between calling this and putting something into - * the entry, as someone else might have used it while you slept. - */ -static struct buffer_head * xiafs_add_entry(struct inode * dir, - const char * name, int namelen, struct xiafs_direct ** res_dir, - struct xiafs_direct ** res_pre) -{ - int i, pos, offset; - struct buffer_head * bh; - struct xiafs_direct * de, * de_pre; - - *res_dir = NULL; - if (!dir || !namelen || namelen > _XIAFS_NAME_LEN) - return NULL; - - if (dir->i_size & (XIAFS_ZSIZE(dir->i_sb) - 1)) { - printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR); - return NULL; - } - pos=0; - for ( ; ; ) { - bh = xiafs_bread(dir, pos >> XIAFS_ZSIZE_BITS(dir->i_sb), pos ? 1:0); - if (!bh) - return NULL; - de_pre=de=(struct xiafs_direct *)bh->b_data; - if (!pos) { - if (de->d_rec_len != 12 || !de->d_ino || de->d_name_len != 1 || - strcmp(de->d_name, ".")) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - brelse(bh); - return NULL; - } - offset = 12; - de_pre=de=(struct xiafs_direct *)(bh->b_data+12); - } else - offset = 0; - while (offset < XIAFS_ZSIZE(dir->i_sb)) { - if (pos >= dir->i_size) { - de->d_ino=0; - de->d_name_len=0; - de->d_name[0]=0; - de->d_rec_len=XIAFS_ZSIZE(dir->i_sb); - dir->i_size += XIAFS_ZSIZE(dir->i_sb); - dir->i_dirt = 1; - } else { - if (de->d_ino > dir->i_sb->u.xiafs_sb.s_ninodes || - de->d_rec_len < 12 || - (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(dir->i_sb) || - de->d_name_len + 8 > de->d_rec_len || - de->d_name[de->d_name_len]) { - printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR); - brelse(bh); - return NULL; - } - if (de->d_ino && - RNDUP4(de->d_name_len)+RNDUP4(namelen)+16<=de->d_rec_len) { - i=RNDUP4(de->d_name_len)+8; - de_pre=de; - de=(struct xiafs_direct *)(i+(u_char *)de_pre); - de->d_ino=0; - de->d_rec_len=de_pre->d_rec_len-i; - de_pre->d_rec_len=i; - } - } - if (!de->d_ino && RNDUP4(namelen)+8 <= de->d_rec_len) { - /* - * XXX all times should be set by caller upon successful - * completion. - */ - dir->i_ctime = dir->i_mtime = CURRENT_TIME; - dir->i_dirt = 1; - memcpy(de->d_name, name, namelen); - de->d_name[namelen]=0; - de->d_name_len=namelen; - mark_buffer_dirty(bh, 1); - *res_dir = de; - if (res_pre) - *res_pre = de_pre; - return bh; - } - offset+=de->d_rec_len; - de_pre=de; - de=(struct xiafs_direct *)(bh->b_data+offset); - } - brelse(bh); - if (offset > XIAFS_ZSIZE(dir->i_sb)) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - return NULL; - } - pos+=XIAFS_ZSIZE(dir->i_sb); - } - return NULL; -} - -int xiafs_create(struct inode * dir, const char * name, int len, int mode, - struct inode ** result) -{ - struct inode * inode; - struct buffer_head * bh; - struct xiafs_direct * de; - - *result = NULL; - if (!dir) - return -ENOENT; - inode = xiafs_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &xiafs_file_inode_operations; - inode->i_mode = mode; - inode->i_dirt = 1; - bh = xiafs_add_entry(dir, name, len, &de, NULL); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->d_ino = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - *result = inode; - return 0; -} - -int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev) -{ - struct inode * inode; - struct buffer_head * bh; - struct xiafs_direct * de; - - if (!dir) - return -ENOENT; - bh = xiafs_find_entry(dir,name,len,&de, NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - inode = xiafs_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_uid = current->fsuid; - inode->i_mode = mode; - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &xiafs_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &xiafs_dir_inode_operations; - if (dir->i_mode & S_ISGID) - inode->i_mode |= S_ISGID; - } - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &xiafs_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) - init_fifo(inode); - if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = to_kdev_t(rdev); - inode->i_atime = inode->i_ctime = inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - bh = xiafs_add_entry(dir, name, len, &de, NULL); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->d_ino = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode) -{ - struct inode * inode; - struct buffer_head * bh, *dir_block; - struct xiafs_direct * de; - - bh = xiafs_find_entry(dir,name,len,&de, NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - if (dir->i_nlink > 64000) { - iput(dir); - return -EMLINK; - } - inode = xiafs_new_inode(dir); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &xiafs_dir_inode_operations; - inode->i_size = XIAFS_ZSIZE(dir->i_sb); - inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; - inode->i_dirt = 1; - dir_block = xiafs_bread(inode,0,1); - if (!dir_block) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - de = (struct xiafs_direct *) dir_block->b_data; - de->d_ino=inode->i_ino; - strcpy(de->d_name,"."); - de->d_name_len=1; - de->d_rec_len=12; - de =(struct xiafs_direct *)(12 + dir_block->b_data); - de->d_ino = dir->i_ino; - strcpy(de->d_name,".."); - de->d_name_len=2; - de->d_rec_len=XIAFS_ZSIZE(dir->i_sb)-12; - inode->i_nlink = 2; - mark_buffer_dirty(dir_block, 1); - brelse(dir_block); - inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask); - if (dir->i_mode & S_ISGID) - inode->i_mode |= S_ISGID; - inode->i_dirt = 1; - bh = xiafs_add_entry(dir, name, len, &de, NULL); - if (!bh) { - iput(dir); - inode->i_nlink=0; - iput(inode); - return -ENOSPC; - } - de->d_ino = inode->i_ino; - mark_buffer_dirty(bh, 1); - dir->i_nlink++; - dir->i_dirt = 1; - iput(dir); - iput(inode); - brelse(bh); - return 0; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -static int empty_dir(struct inode * inode) -{ - int i, zones, offset; - struct buffer_head * bh; - struct xiafs_direct * de; - - if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb)-1) ) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - return 1; - } - - zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb); - for (i=0; i < zones; i++) { - bh = xiafs_bread(inode, i, 0); - if (!i) { - if (!bh) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - return 1; - } - de=(struct xiafs_direct *)bh->b_data; - if (de->d_ino != inode->i_ino || strcmp(".", de->d_name) || - de->d_rec_len != 12 ) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - brelse(bh); - return 1; - } - de=(struct xiafs_direct *)(12 + bh->b_data); - if (!de->d_ino || strcmp("..", de->d_name)) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - brelse(bh); - return 1; - } - offset=de->d_rec_len+12; - } - else - offset = 0; - if (!bh) - continue; - while (offset < XIAFS_ZSIZE(inode->i_sb)) { - de=(struct xiafs_direct *)(bh->b_data+offset); - if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes || - de->d_rec_len < 12 || - (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(inode->i_sb) || - de->d_name_len + 8 > de->d_rec_len || - de->d_name[de->d_name_len]) { - printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR); - brelse(bh); - return 1; - } - if (de->d_ino) { - brelse(bh); - return 0; - } - offset+=de->d_rec_len; - } - brelse(bh); - } - return 1; -} - -static void xiafs_rm_entry(struct xiafs_direct *de, struct xiafs_direct * de_pre) -{ - if (de==de_pre) { - de->d_ino=0; - return; - } - while (de_pre->d_rec_len+(u_char *)de_pre < (u_char *)de) { - if (de_pre->d_rec_len < 12) { - printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR); - return; - } - de_pre=(struct xiafs_direct *)(de_pre->d_rec_len+(u_char *)de_pre); - } - if (de_pre->d_rec_len+(u_char *)de_pre > (u_char *)de) { - printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR); - return; - } - de_pre->d_rec_len+=de->d_rec_len; -} - -int xiafs_rmdir(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct xiafs_direct * de, * de_pre; - - inode = NULL; - bh = xiafs_find_entry(dir, name, len, &de, &de_pre); - retval = -ENOENT; - if (!bh) - goto end_rmdir; - retval = -EPERM; - if (!(inode = iget(dir->i_sb, de->d_ino))) - goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && !fsuser() && - current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) - goto end_rmdir; - if (inode->i_dev != dir->i_dev) - goto end_rmdir; - if (inode == dir) /* we may not delete ".", but "../dir" is ok */ - goto end_rmdir; - if (!S_ISDIR(inode->i_mode)) { - retval = -ENOTDIR; - goto end_rmdir; - } - if (!empty_dir(inode)) { - retval = -ENOTEMPTY; - goto end_rmdir; - } - if (inode->i_count > 1) { - retval = -EBUSY; - goto end_rmdir; - } - if (inode->i_nlink != 2) - printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR); - xiafs_rm_entry(de, de_pre); - mark_buffer_dirty(bh, 1); - inode->i_nlink=0; - inode->i_dirt=1; - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - dir->i_dirt=1; - retval = 0; -end_rmdir: - iput(dir); - iput(inode); - brelse(bh); - return retval; -} - -int xiafs_unlink(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct xiafs_direct * de, * de_pre; - -repeat: - retval = -ENOENT; - inode = NULL; - bh = xiafs_find_entry(dir, name, len, &de, &de_pre); - if (!bh) - goto end_unlink; - if (!(inode = iget(dir->i_sb, de->d_ino))) - goto end_unlink; - retval = -EPERM; - if (S_ISDIR(inode->i_mode)) - goto end_unlink; - if (de->d_ino != inode->i_ino) { - iput(inode); - brelse(bh); - current->counter = 0; - schedule(); - goto repeat; - } - if ((dir->i_mode & S_ISVTX) && !fsuser() && - current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) - goto end_unlink; - if (!inode->i_nlink) { - printk("XIA-FS: Deleting nonexistent file (%s %d)\n", WHERE_ERR); - inode->i_nlink=1; - } - xiafs_rm_entry(de, de_pre); - mark_buffer_dirty(bh, 1); - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - dir->i_dirt = 1; - inode->i_nlink--; - inode->i_dirt = 1; - retval = 0; -end_unlink: - brelse(bh); - iput(inode); - iput(dir); - return retval; -} - -int xiafs_symlink(struct inode * dir, const char * name, - int len, const char * symname) -{ - struct xiafs_direct * de; - struct inode * inode = NULL; - struct buffer_head * bh = NULL, * name_block = NULL; - int i; - char c; - - bh = xiafs_find_entry(dir,name,len, &de, NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - if (!(inode = xiafs_new_inode(dir))) { - iput(dir); - return -ENOSPC; - } - inode->i_mode = S_IFLNK | S_IRWXUGO; - inode->i_op = &xiafs_symlink_inode_operations; - name_block = xiafs_bread(inode,0,1); - if (!name_block) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - for (i = 0; i < BLOCK_SIZE-1 && (c=*symname++); i++) - name_block->b_data[i] = c; - name_block->b_data[i] = 0; - mark_buffer_dirty(name_block, 1); - brelse(name_block); - inode->i_size = i; - inode->i_dirt = 1; - bh = xiafs_add_entry(dir, name, len, &de, NULL); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->d_ino = inode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int xiafs_link(struct inode * oldinode, struct inode * dir, - const char * name, int len) -{ - struct xiafs_direct * de; - struct buffer_head * bh; - - if (S_ISDIR(oldinode->i_mode)) { - iput(oldinode); - iput(dir); - return -EPERM; - } - if (oldinode->i_nlink > 64000) { - iput(oldinode); - iput(dir); - return -EMLINK; - } - bh = xiafs_find_entry(dir, name, len, &de, NULL); - if (bh) { - brelse(bh); - iput(dir); - iput(oldinode); - return -EEXIST; - } - bh = xiafs_add_entry(dir, name, len, &de, NULL); - if (!bh) { - iput(dir); - iput(oldinode); - return -ENOSPC; - } - de->d_ino = oldinode->i_ino; - mark_buffer_dirty(bh, 1); - brelse(bh); - iput(dir); - oldinode->i_nlink++; - oldinode->i_ctime = CURRENT_TIME; - oldinode->i_dirt = 1; - iput(oldinode); - return 0; -} - -static int subdir(struct inode * new_inode, struct inode * old_inode) -{ - int ino; - int result; - - new_inode->i_count++; - result = 0; - for (;;) { - if (new_inode == old_inode) { - result = 1; - break; - } - if (new_inode->i_dev != old_inode->i_dev) - break; - ino = new_inode->i_ino; - if (xiafs_lookup(new_inode,"..",2,&new_inode)) - break; - if (new_inode->i_ino == ino) - break; - } - iput(new_inode); - return result; -} - -#define PARENT_INO(buffer) \ - (((struct xiafs_direct *) ((u_char *)(buffer) + 12))->d_ino) - -/* - * rename uses retry to avoid race-conditions: at least they should be minimal. - * it tries to allocate all the blocks, then sanity-checks, and if the sanity- - * checks fail, it tries to restart itself again. Very practical - no changes - * are done until we know everything works ok.. and then all the changes can be - * done in one fell swoop when we have claimed all the buffers needed. - * - * Anybody can rename anything with this: the permission checks are left to the - * higher-level routines. - */ -static int do_xiafs_rename(struct inode * old_dir, const char * old_name, - int old_len, struct inode * new_dir, - const char * new_name, int new_len, - int must_be_dir) -{ - struct inode * old_inode, * new_inode; - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct xiafs_direct * old_de, * old_de_pre, * new_de, * new_de_pre; - int retval; - -try_again: - old_inode = new_inode = NULL; - old_bh = new_bh = dir_bh = NULL; - old_bh = xiafs_find_entry(old_dir, old_name, old_len, &old_de, &old_de_pre); - retval = -ENOENT; - if (!old_bh) - goto end_rename; - old_inode = __iget(old_dir->i_sb, old_de->d_ino, 0); /* don't cross mnt-points */ - if (!old_inode) - goto end_rename; - if (must_be_dir && !S_ISDIR(old_inode->i_mode)) - goto end_rename; - retval = -EPERM; - if ((old_dir->i_mode & S_ISVTX) && - current->fsuid != old_inode->i_uid && - current->fsuid != old_dir->i_uid && !fsuser()) - goto end_rename; - new_bh = xiafs_find_entry(new_dir, new_name, new_len, &new_de, NULL); - if (new_bh) { - new_inode = __iget(new_dir->i_sb, new_de->d_ino, 0); - if (!new_inode) { - brelse(new_bh); - new_bh = NULL; - } - } - if (new_inode == old_inode) { - retval = 0; - goto end_rename; - } - if (new_inode && S_ISDIR(new_inode->i_mode)) { - retval = -EEXIST; - goto end_rename; - } - retval = -EPERM; - if (new_inode && (new_dir->i_mode & S_ISVTX) && - current->fsuid != new_inode->i_uid && - current->fsuid != new_dir->i_uid && !fsuser()) - goto end_rename; - if (S_ISDIR(old_inode->i_mode)) { - retval = -EEXIST; - if (new_bh) - goto end_rename; - if ((retval = permission(old_inode, MAY_WRITE)) != 0) - goto end_rename; - retval = -EINVAL; - if (subdir(new_dir, old_inode)) - goto end_rename; - retval = -EIO; - dir_bh = xiafs_bread(old_inode,0,0); - if (!dir_bh) - goto end_rename; - if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino) - goto end_rename; - retval = -EMLINK; - if (new_dir->i_nlink > 64000) - goto end_rename; - } - if (!new_bh) - new_bh = xiafs_add_entry(new_dir, new_name, new_len, &new_de, &new_de_pre); - retval = -ENOSPC; - if (!new_bh) - goto end_rename; - /* sanity checking */ - if ( (new_inode && (new_de->d_ino != new_inode->i_ino)) - || (new_de->d_ino && !new_inode) - || (old_de->d_ino != old_inode->i_ino)) { - xiafs_rm_entry(new_de, new_de_pre); - brelse(old_bh); - brelse(new_bh); - brelse(dir_bh); - iput(old_inode); - iput(new_inode); - current->counter=0; - schedule(); - goto try_again; - } - xiafs_rm_entry(old_de, old_de_pre); - new_de->d_ino = old_inode->i_ino; - if (new_inode) { - new_inode->i_nlink--; - new_inode->i_dirt = 1; - } - mark_buffer_dirty(old_bh, 1); - mark_buffer_dirty(new_bh, 1); - if (dir_bh) { - PARENT_INO(dir_bh->b_data) = new_dir->i_ino; - mark_buffer_dirty(dir_bh, 1); - old_dir->i_nlink--; - new_dir->i_nlink++; - old_dir->i_dirt = 1; - new_dir->i_dirt = 1; - } - retval = 0; -end_rename: - brelse(dir_bh); - brelse(old_bh); - brelse(new_bh); - iput(old_inode); - iput(new_inode); - iput(old_dir); - iput(new_dir); - return retval; -} - -/* - * Ok, rename also locks out other renames, as they can change the parent of - * a directory, and we don't want any races. Other races are checked for by - * "do_rename()", which restarts if there are inconsistencies. - * - * Note that there is no race between different filesystems: it's only within - * the same device that races occur: many renames can happen at once, as long - * as they are on different partitions. - */ -int xiafs_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len, - int must_be_dir) -{ - static struct wait_queue * wait = NULL; - static int lock = 0; - int result; - - while (lock) - sleep_on(&wait); - lock = 1; - result = do_xiafs_rename(old_dir, old_name, old_len, - new_dir, new_name, new_len, - must_be_dir); - lock = 0; - wake_up(&wait); - return result; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/symlink.c linux/fs/xiafs/symlink.c --- v2.1.20/linux/fs/xiafs/symlink.c Tue Oct 29 19:58:47 1996 +++ linux/fs/xiafs/symlink.c Thu Jan 1 02:00:00 1970 @@ -1,120 +0,0 @@ -/* - * linux/fs/xiafs/symlink.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/symlink.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include -#include -#include -#include -#include - -#include - -static int -xiafs_readlink(struct inode *, char *, int); - -static int -xiafs_follow_link(struct inode *, struct inode *, int, int, struct inode **); - -/* - * symlinks can't do much... - */ -struct inode_operations xiafs_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - xiafs_readlink, /* readlink */ - xiafs_follow_link, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ -}; - -static int xiafs_readlink(struct inode * inode, char * buffer, int buflen) -{ - struct buffer_head * bh; - int i; - char c; - - if (!S_ISLNK(inode->i_mode)) { - iput(inode); - return -EINVAL; - } - if (buflen > BLOCK_SIZE) - buflen = BLOCK_SIZE; - bh = xiafs_bread(inode, 0, 0); - if (!IS_RDONLY (inode)) { - inode->i_atime=CURRENT_TIME; - inode->i_dirt=1; - } - iput(inode); - if (!bh) - return 0; - for (i=0; i < buflen && (c=bh->b_data[i]); i++) - put_user(c, buffer++); - if (i < buflen-1) - put_user('\0', buffer); - brelse(bh); - return i; -} - -static int xiafs_follow_link(struct inode * dir, struct inode * inode, - int flag, int mode, struct inode ** res_inode) -{ - int error; - struct buffer_head * bh; - - *res_inode = NULL; - if (!dir) { - dir = current->fs->root; - dir->i_count++; - } - if (!inode) { - iput(dir); - return -ENOENT; - } - if (!S_ISLNK(inode->i_mode)) { - iput(dir); - *res_inode = inode; - return 0; - } - if (!IS_RDONLY (inode)) { - inode->i_atime=CURRENT_TIME; - inode->i_dirt=1; - } - if (current->link_count > 5) { - iput(inode); - iput(dir); - return -ELOOP; - } - if (!(bh = xiafs_bread(inode, 0, 0))) { - iput(inode); - iput(dir); - return -EIO; - } - iput(inode); - current->link_count++; - error = open_namei(bh->b_data,flag,mode,res_inode,dir); - current->link_count--; - brelse(bh); - return error; -} - - - diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/truncate.c linux/fs/xiafs/truncate.c --- v2.1.20/linux/fs/xiafs/truncate.c Wed Nov 8 12:30:22 1995 +++ linux/fs/xiafs/truncate.c Thu Jan 1 02:00:00 1970 @@ -1,197 +0,0 @@ -/* - * linux/fs/xiafs/truncate.c - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix/truncate.c - * Copyright (C) Linus Torvalds, 1991, 1992. - * - * This software may be redistributed per Linux Copyright. - */ - -#include -#include -#include -#include -#include - -#include "xiafs_mac.h" - -/* - * Linus' comment: - * - * Truncate has the most races in the whole filesystem: coding it is - * a pain in the a**. Especially as I don't do any locking... - * - * The code may look a bit weird, but that's just because I've tried to - * handle things like file-size changes in a somewhat graceful manner. - * Anyway, truncating a file at the same time somebody else writes to it - * is likely to result in pretty weird behaviour... - * - * The new code handles normal truncates (size = 0) as well as the more - * general case (size = XXX). I hope. - */ - -#define DT_ZONE ((inode->i_size + XIAFS_ZSIZE(inode->i_sb) - 1) \ - >> XIAFS_ZSIZE_BITS(inode->i_sb) ) - -static int trunc_direct(struct inode * inode) -{ - u_long * lp; - struct buffer_head * bh; - int i, tmp; - int retry = 0; - -repeat: - for (i = DT_ZONE ; i < 8 ; i++) { - if (i < DT_ZONE) - goto repeat; - lp=i + inode->u.xiafs_i.i_zone; - if (!(tmp = *lp)) - continue; - bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (i < DT_ZONE) { - brelse(bh); - goto repeat; - } - if ((bh && bh->b_count != 1) || tmp != *lp) - retry = 1; - else { - *lp = 0; - inode->i_dirt = 1; - inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb); - xiafs_free_zone(inode->i_sb, tmp); - } - brelse(bh); - } - return retry; -} - -static int trunc_indirect(struct inode * inode, int addr_off, u_long * lp) -{ - -#define INDT_ZONE (DT_ZONE - addr_off) - - struct buffer_head * bh, * ind_bh; - int i, tmp; - u_long * indp; - int retry = 0; - - if ( !(tmp=*lp) ) - return 0; - ind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (tmp != *lp) { - brelse(ind_bh); - return 1; - } - if (!ind_bh) { - *lp = 0; - return 0; - } -repeat: - for (i = INDT_ZONE<0?0:INDT_ZONE; i < XIAFS_ADDRS_PER_Z(inode->i_sb); i++) { - if (i < INDT_ZONE) - goto repeat; - indp = i+(u_long *) ind_bh->b_data; - if (!(tmp=*indp)) - continue; - bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (i < INDT_ZONE) { - brelse(bh); - goto repeat; - } - if ((bh && bh->b_count != 1) || tmp != *indp) - retry = 1; - else { - *indp = 0; - mark_buffer_dirty(ind_bh, 1); - inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb); - xiafs_free_zone(inode->i_sb, tmp); - } - brelse(bh); - } - indp = (u_long *) ind_bh->b_data; - for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*indp++); i++) ; - if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) { - if (ind_bh->b_count != 1) - retry = 1; - else { - tmp = *lp; - *lp = 0; - inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb); - xiafs_free_zone(inode->i_sb, tmp); - } - } - brelse(ind_bh); - return retry; -} - -static int trunc_dindirect(struct inode * inode) -{ - -#define DINDT_ZONE \ - ((DT_ZONE-XIAFS_ADDRS_PER_Z(inode->i_sb)-8)>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)) - - int i, tmp; - struct buffer_head * dind_bh; - u_long * dindp, * lp; - int retry = 0; - - lp = &(inode->u.xiafs_i.i_dind_zone); - if (!(tmp = *lp)) - return 0; - dind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb)); - if (tmp != *lp) { - brelse(dind_bh); - return 1; - } - if (!dind_bh) { - *lp = 0; - return 0; - } -repeat: - for (i=DINDT_ZONE<0?0:DINDT_ZONE ; i < XIAFS_ADDRS_PER_Z(inode->i_sb) ; i ++) { - if (i < DINDT_ZONE) - goto repeat; - dindp = i+(u_long *) dind_bh->b_data; - retry |= trunc_indirect(inode, - 8+((1+i)<i_sb)), - dindp); - mark_buffer_dirty(dind_bh, 1); - } - dindp = (u_long *) dind_bh->b_data; - for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*dindp++); i++); - if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) { - if (dind_bh->b_count != 1) - retry = 1; - else { - tmp = *lp; - *lp = 0; - inode->i_dirt = 1; - inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb); - xiafs_free_zone(inode->i_sb, tmp); - } - } - brelse(dind_bh); - return retry; -} - -void xiafs_truncate(struct inode * inode) -{ - int retry; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; - while (1) { - retry = trunc_direct(inode); - retry |= trunc_indirect(inode, 8, &(inode->u.xiafs_i.i_ind_zone)); - retry |= trunc_dindirect(inode); - if (!retry) - break; - current->counter = 0; - schedule(); - } - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - inode->i_dirt = 1; -} diff -u --recursive --new-file v2.1.20/linux/fs/xiafs/xiafs_mac.h linux/fs/xiafs/xiafs_mac.h --- v2.1.20/linux/fs/xiafs/xiafs_mac.h Wed Aug 10 19:26:28 1994 +++ linux/fs/xiafs/xiafs_mac.h Thu Jan 1 02:00:00 1970 @@ -1,32 +0,0 @@ -/* - * linux/fs/xiafs/xiafs_mac.h - * - * Copyright (C) Q. Frank Xia, 1993. - */ - -extern char internal_error_message[]; -#define INTERN_ERR internal_error_message, __FILE__, __LINE__ -#define WHERE_ERR __FILE__, __LINE__ - -#define XIAFS_ZSHIFT(sp) ((sp)->u.xiafs_sb.s_zone_shift) -#define XIAFS_ZSIZE(sp) (BLOCK_SIZE << XIAFS_ZSHIFT(sp)) -#define XIAFS_ZSIZE_BITS(sp) (BLOCK_SIZE_BITS + XIAFS_ZSHIFT(sp)) -#define XIAFS_ADDRS_PER_Z(sp) (BLOCK_SIZE >> (2 - XIAFS_ZSHIFT(sp))) -#define XIAFS_ADDRS_PER_Z_BITS(sp) (BLOCK_SIZE_BITS - 2 + XIAFS_ZSHIFT(sp)) -#define XIAFS_BITS_PER_Z(sp) (BLOCK_SIZE << (3 + XIAFS_ZSHIFT(sp))) -#define XIAFS_BITS_PER_Z_BITS(sp) (BLOCK_SIZE_BITS + 3 + XIAFS_ZSHIFT(sp)) -#define XIAFS_INODES_PER_Z(sp) (_XIAFS_INODES_PER_BLOCK << XIAFS_ZSHIFT(sp)) - -/* Use the most significant bytes of zone pointers to store block counter. */ -/* This is ugly, but it works. Note, We have another 7 bytes for "expansion". */ - -#define XIAFS_GET_BLOCKS(row_ip, blocks) \ - blocks=((((row_ip)->i_zone[0] >> 24) & 0xff )|\ - (((row_ip)->i_zone[1] >> 16) & 0xff00 )|\ - (((row_ip)->i_zone[2] >> 8) & 0xff0000 ) ) - -/* XIAFS_PUT_BLOCKS should be called before saving zone pointers */ -#define XIAFS_PUT_BLOCKS(row_ip, blocks) \ - (row_ip)->i_zone[2]=((blocks)<< 8) & 0xff000000;\ - (row_ip)->i_zone[1]=((blocks)<<16) & 0xff000000;\ - (row_ip)->i_zone[0]=((blocks)<<24) & 0xff000000 diff -u --recursive --new-file v2.1.20/linux/include/asm-alpha/uaccess.h linux/include/asm-alpha/uaccess.h --- v2.1.20/linux/include/asm-alpha/uaccess.h Tue Nov 19 15:53:56 1996 +++ linux/include/asm-alpha/uaccess.h Fri Jan 3 18:48:36 1997 @@ -122,7 +122,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda %0, 2b-1b(%1)\n" \ - ".text" \ + ".previous" \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) @@ -132,7 +132,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda %0, 2b-1b(%1)\n" \ - ".text" \ + ".previous" \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) @@ -145,7 +145,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda %0, 2b-1b(%1)\n" \ - ".text" \ + ".previous" \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) @@ -155,7 +155,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda %0, 2b-1b(%1)\n" \ - ".text" \ + ".previous" \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) #else @@ -176,7 +176,7 @@ " lda %0, 3b-1b(%2)\n" \ " .gprel32 2b\n" \ " lda %0, 2b-1b(%2)\n" \ - ".text" \ + ".previous" \ : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \ : "r"(addr), "2"(__gu_err)); \ } @@ -188,7 +188,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda %0, 2b-1b(%1)\n" \ - ".text" \ + ".previous" \ : "=&r"(__gu_val), "=r"(__gu_err) \ : "r"(addr), "1"(__gu_err)) #endif @@ -236,7 +236,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda $31,2b-1b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err) \ : "m" (__m(addr)), "rJ" (x), "0"(__pu_err)) @@ -246,7 +246,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda $31,2b-1b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) @@ -259,7 +259,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda $31,2b-1b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) @@ -269,7 +269,7 @@ ".section __ex_table,\"a\"\n" \ " .gprel32 1b\n" \ " lda $31,2b-1b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) #else @@ -300,7 +300,7 @@ " lda $31, 5b-3b(%0)\n" \ " .gprel32 4b\n" \ " lda $31, 5b-4b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err), "=&r"(__pu_tmp1), \ "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \ "=&r"(__pu_tmp4) \ @@ -322,7 +322,7 @@ " lda $31, 3b-1b(%0)\n" \ " .gprel32 2b\n" \ " lda $31, 3b-2b(%0)\n" \ - ".text" \ + ".previous" \ : "=r"(__pu_err), \ "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \ : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \ diff -u --recursive --new-file v2.1.20/linux/include/asm-i386/uaccess.h linux/include/asm-i386/uaccess.h --- v2.1.20/linux/include/asm-i386/uaccess.h Thu Jan 2 15:55:24 1997 +++ linux/include/asm-i386/uaccess.h Tue Jan 14 13:40:10 1997 @@ -153,10 +153,11 @@ ".section .fixup,\"ax\"\n" \ "3: movl %3,%0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 1b,3b\n" \ - ".text" \ + ".previous" \ : "=r"(err) \ : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err)) @@ -200,10 +201,11 @@ "3: movl %3,%0\n" \ " xor"itype" %"rtype"1,%"rtype"1\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 1b,3b\n" \ - ".text" \ + ".previous" \ : "=r"(err), ltype (x) \ : "m"(__m(addr)), "i"(-EFAULT), "0"(err)) @@ -222,11 +224,12 @@ ".section .fixup,\"ax\"\n" \ "3: lea 0(%1,%0,4),%0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ " .long 1b,2b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from) \ : "di", "si", "memory") @@ -242,10 +245,11 @@ ".section .fixup,\"ax\"\n" \ "2: shl $2,%0\n" \ " jmp 1b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,2b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "S"(from), "D"(to), "0"(size/4) \ : "di", "si", "memory"); \ @@ -259,11 +263,12 @@ "3: shl $2,%0\n" \ "4: incl %0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ " .long 1b,4b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "S"(from), "D"(to), "0"(size/4) \ : "di", "si", "memory"); \ @@ -277,11 +282,12 @@ "3: shl $2,%0\n" \ "4: addl $2,%0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ " .long 1b,4b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "S"(from), "D"(to), "0"(size/4) \ : "di", "si", "memory"); \ @@ -297,12 +303,13 @@ "5: addl $2,%0\n" \ "6: incl %0\n" \ " jmp 3b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,4b\n" \ " .long 1b,5b\n" \ " .long 2b,6b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "S"(from), "D"(to), "0"(size/4) \ : "di", "si", "memory"); \ @@ -405,11 +412,12 @@ ".section .fixup,\"ax\"\n" \ "3: lea 0(%1,%0,4),%0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ " .long 1b,2b\n" \ - ".text" \ + ".previous" \ : "=c"(size) \ : "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0) \ : "di") @@ -449,10 +457,11 @@ ".section .fixup,\"ax\"\n" \ "3: movl %2,%0\n" \ " jmp 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ - ".text" \ + ".previous" \ : "=d"(res), "=c"(count) \ : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \ : "si", "di", "ax", "memory") @@ -491,10 +500,11 @@ ".section .fixup,\"ax\"\n" "2: xorl %0,%0\n" " jmp 1b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" - ".text" + ".previous" :"=c" (res), "=D" (s) :"1" (s), "a" (0), "0" (-__addr_ok(s))); return res & -__addr_ok(s); diff -u --recursive --new-file v2.1.20/linux/include/asm-m68k/uaccess.h linux/include/asm-m68k/uaccess.h --- v2.1.20/linux/include/asm-m68k/uaccess.h Sun Dec 22 16:37:40 1996 +++ linux/include/asm-m68k/uaccess.h Fri Jan 3 18:48:37 1997 @@ -82,11 +82,12 @@ " .even\n" \ "2: movel %3,%0\n" \ " jra 1b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 21b,2b\n" \ " .long 1b,2b\n" \ - ".text" \ + ".previous" \ : "=d"(err) \ : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0)) @@ -125,10 +126,11 @@ "3: movel %3,%0\n" \ " sub" #bwl " %1,%1\n" \ " jra 2b\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 1b,3b\n" \ - ".text" \ + ".previous" \ : "=d"(err), reg(x) \ : "m"(*(ptr)), "i" (-EFAULT), "0"(0)) @@ -162,12 +164,13 @@ " jra 6b\n" "9: addql #1,%2\n" " jra 6b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,7b\n" " .long 3b,8b\n" " .long 5b,9b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) : "r"(n & 3), "0"(to), "1"(from), "2"(n/4) : "d0", "memory"); @@ -204,6 +207,7 @@ " jra 5b\n" "8: addql #1,%2\n" " jra 5b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 22b,6b\n" @@ -212,7 +216,7 @@ " .long 4b,7b\n" " .long 25b,8b\n" " .long 5b,8b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)); return n; @@ -229,12 +233,12 @@ "11: lsll #2,%2\n" \ fixup "\n" \ " jra 12f\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 10b,11b\n" \ - ".text\n" \ + ".previous\n" \ copy "\n" \ - ".text\n" \ "12:" \ : "=a"(to), "=a"(from), "=d"(n) \ : "0"(to), "1"(from), "2"(n/4) \ @@ -255,10 +259,11 @@ " .even\n" "3: addql #1,%2\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -272,10 +277,11 @@ " .even\n" "3: addql #2,%2\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -292,11 +298,12 @@ "4: addql #2,%2\n" "5: addql #1,%2\n" " jra 3b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,4b\n" " .long 2b,5b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -310,10 +317,11 @@ " .even\n" "3: addql #4,%2\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -330,11 +338,12 @@ "4: addql #4,%2\n" "5: addql #4,%2\n" " jra 3b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,4b\n" " .long 2b,5b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -354,12 +363,13 @@ "6: addql #4,%2\n" "7: addql #4,%2\n" " jra 4b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,5b\n" " .long 2b,6b\n" " .long 3b,7b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -382,13 +392,14 @@ "8: addql #4,%2\n" "9: addql #4,%2\n" " jra 5b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,6b\n" " .long 2b,7b\n" " .long 3b,8b\n" " .long 4b,9b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -406,7 +417,8 @@ "2: movesb (%1)+,%%d0\n" " moveb %%d0,(%0)+\n" ".section __ex_table,\"a\"\n" - " .long 2b,1b"); + " .long 2b,1b\n" + ".previous"); break; case 2: __copy_from_user_big(to, from, n, @@ -416,7 +428,8 @@ "2: movesw (%1)+,%%d0\n" " movew %%d0,(%0)+\n" ".section __ex_table,\"a\"\n" - " .long 2b,1b"); + " .long 2b,1b\n" + ".previous"); break; case 3: __copy_from_user_big(to, from, n, @@ -430,7 +443,8 @@ " moveb %%d0,(%0)+\n" ".section __ex_table,\"a\"\n" " .long 3b,1b\n" - " .long 4b,2b"); + " .long 4b,2b\n" + ".previous"); break; } break; @@ -449,13 +463,13 @@ "12: lsll #2,%2\n" \ fixup "\n" \ " jra 13f\n" \ + ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 31b,12b\n" \ " .long 11b,12b\n" \ - ".text\n" \ + ".previous\n" \ copy "\n" \ - ".text\n" \ "13:" \ : "=a"(to), "=a"(from), "=d"(n) \ : "0"(to), "1"(from), "2"(n/4) \ @@ -476,11 +490,12 @@ " .even\n" "2: addql #1,%2\n" " jra 1b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n " " .long 21b,2b\n" " .long 1b,2b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -494,11 +509,12 @@ " .even\n" "2: addql #2,%2\n" " jra 1b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,2b\n" " .long 1b,2b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -515,13 +531,14 @@ "3: addql #2,%2\n" "4: addql #1,%2\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,3b\n" " .long 1b,3b\n" " .long 22b,4b\n" " .long 2b,4b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -535,11 +552,12 @@ " .even\n" "2: addql #4,%2\n" " jra 1b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,2b\n" " .long 1b,2b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -556,13 +574,14 @@ "3: addql #4,%2\n" "4: addql #4,%2\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,3b\n" " .long 1b,3b\n" " .long 22b,4b\n" " .long 2b,4b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -582,6 +601,7 @@ "5: addql #4,%2\n" "6: addql #4,%2\n" " jra 3b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,4b\n" @@ -590,7 +610,7 @@ " .long 2b,5b\n" " .long 23b,6b\n" " .long 3b,6b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -613,6 +633,7 @@ "7: addql #4,%2\n" "8: addql #4,%2\n" " jra 4b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 21b,5b\n" @@ -623,7 +644,7 @@ " .long 3b,7b\n" " .long 24b,8b\n" " .long 4b,8b\n" - ".text" + ".previous" : "=a"(to), "=a"(from), "=d"(n) : "0"(to), "1"(from), "2"(0) : "d0", "memory"); @@ -643,7 +664,8 @@ "2:" ".section __ex_table,\"a\"\n" " .long 22b,1b\n" - " .long 2b,1b"); + " .long 2b,1b\n" + ".previous"); break; case 2: __copy_to_user_big(to, from, n, @@ -655,7 +677,8 @@ "2:" ".section __ex_table,\"a\"\n" " .long 22b,1b\n" - " .long 2b,1b"); + " .long 2b,1b\n" + ".previous"); break; case 3: __copy_to_user_big(to, from, n, @@ -672,7 +695,8 @@ " .long 23b,1b\n" " .long 3b,1b\n" " .long 24b,2b\n" - " .long 4b,2b"); + " .long 4b,2b\n" + ".previous"); break; } break; @@ -711,11 +735,12 @@ " .even\n" "4: movel %4,%0\n" " jra 3b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,4b\n" " .long 12b,4b\n" - ".text" + ".previous" : "=d"(res), "=a"(dst), "=a"(src), "=d"(count) : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count) : "d0", "memory"); @@ -740,11 +765,12 @@ " .even\n" "3: moveq %2,%0\n" " jra 2b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" " .long 12b,3b\n" - ".text" + ".previous" : "=d"(res), "=a"(src) : "i"(0), "0"(res), "1"(src) : "d0"); @@ -781,6 +807,7 @@ " jra 5b\n" "8: addql #1,%1\n" " jra 5b\n" + ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,6b\n" @@ -789,7 +816,7 @@ " .long 4b,7b\n" " .long 25b,8b\n" " .long 5b,8b\n" - ".text" + ".previous" : "=a"(to), "=d"(n) : "r"(n & 3), "r"(0), "0"(to), "1"(n/4)); return n; diff -u --recursive --new-file v2.1.20/linux/include/asm-sparc/uaccess.h linux/include/asm-sparc/uaccess.h --- v2.1.20/linux/include/asm-sparc/uaccess.h Wed Dec 18 15:59:02 1996 +++ linux/include/asm-sparc/uaccess.h Fri Jan 3 18:48:37 1997 @@ -59,7 +59,7 @@ * * There is a special way how to put a range of potentially faulting * insns (like twenty ldd/std's with now intervening other instructions) - * You specify address of first in insn and 0 in fixup and in the next + * You specify address of first in insn and 0 in fixup and in the next * exception_table_entry you specify last potentially faulting insn + 1 * and in fixup the routine which should handle the fault. * That fixup code will get @@ -163,11 +163,12 @@ ".align 4\n" \ "3:\n\t" \ "b 2b\n\t" \ - " mov %3, %0\n\n\t" \ + " mov %3, %0\n\t" \ + ".previous\n\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=&r" (ret) : "r" (x), "r" (__m(addr)), \ "i" (-EFAULT)) @@ -179,7 +180,7 @@ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, __ret_efault\n\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=r" (foo) : "r" (x), "r" (__m(addr))); \ else \ __asm__ __volatile( \ @@ -189,11 +190,12 @@ ".align 4\n" \ "3:\n\t" \ "ret\n\t" \ - " restore %%g0, %3, %%o0\n\n\t" \ + " restore %%g0, %3, %%o0\n\t" \ + ".previous\n\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=r" (foo) : "r" (x), "r" (__m(addr)), "i" (ret)) extern int __put_user_bad(void); @@ -250,10 +252,11 @@ "clr %1\n\t" \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \ "i" (-EFAULT)) @@ -265,7 +268,7 @@ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b,__ret_efault\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (x) : "r" (__m(addr))); \ else \ __asm__ __volatile__( \ @@ -276,10 +279,11 @@ "3:\n\t" \ "ret\n\t" \ " restore %%g0, %2, %%o0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (x) : "r" (__m(addr)), "i" (retval)) extern int __get_user_bad(void); diff -u --recursive --new-file v2.1.20/linux/include/asm-sparc64/uaccess.h linux/include/asm-sparc64/uaccess.h --- v2.1.20/linux/include/asm-sparc64/uaccess.h Tue Dec 31 21:41:11 1996 +++ linux/include/asm-sparc64/uaccess.h Fri Jan 3 18:48:37 1997 @@ -58,7 +58,7 @@ * * There is a special way how to put a range of potentially faulting * insns (like twenty ldd/std's with now intervening other instructions) - * You specify address of first in insn and 0 in fixup and in the next + * You specify address of first in insn and 0 in fixup and in the next * exception_table_entry you specify last potentially faulting insn + 1 * and in fixup the routine which should handle the fault. * That fixup code will get @@ -167,10 +167,11 @@ "3:\n\t" \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=&r" (ret) : "r" (x), "r" (__m(addr)), \ "i" (-EFAULT)) @@ -182,7 +183,7 @@ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, __ret_efault\n\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=r" (foo) : "r" (x), "r" (__m(addr))); \ else \ __asm__ __volatile( \ @@ -193,10 +194,11 @@ "3:\n\t" \ "ret\n\t" \ " restore %%g0, %3, %%o0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\n\t" \ + ".previous\n\n\t" \ : "=r" (foo) : "r" (x), "r" (__m(addr)), "i" (ret)) extern int __put_user_bad(void); @@ -257,10 +259,11 @@ "clr %1\n\t" \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (ret), "=&r" (x) : "r" (__m(addr)), \ "i" (-EFAULT)) @@ -272,7 +275,7 @@ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b,__ret_efault\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (x) : "r" (__m(addr))); \ else \ __asm__ __volatile__( \ @@ -283,10 +286,11 @@ "3:\n\t" \ "ret\n\t" \ " restore %%g0, %2, %%o0\n\n\t" \ + ".previous\n\t" \ ".section __ex_table,#alloc\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ - ".text\n\t" \ + ".previous\n\t" \ : "=&r" (x) : "r" (__m(addr)), "i" (retval)) extern int __get_user_bad(void); diff -u --recursive --new-file v2.1.20/linux/include/linux/ext_fs.h linux/include/linux/ext_fs.h --- v2.1.20/linux/include/linux/ext_fs.h Wed Jul 3 11:53:06 1996 +++ linux/include/linux/ext_fs.h Thu Jan 1 02:00:00 1970 @@ -1,111 +0,0 @@ -#ifndef _LINUX_EXT_FS_H -#define _LINUX_EXT_FS_H - -/* - * The ext filesystem constants/structures - */ - -#define EXT_NAME_LEN 255 -#define EXT_ROOT_INO 1 - -#define EXT_SUPER_MAGIC 0x137D - -#define EXT_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_inode))) - -struct ext_inode { - unsigned short i_mode; - unsigned short i_uid; - unsigned long i_size; - unsigned long i_time; - unsigned short i_gid; - unsigned short i_nlinks; - unsigned long i_zone[12]; -}; - -struct ext_free_inode { - unsigned long count; - unsigned long free[14]; - unsigned long next; -}; - -struct ext_free_block { - unsigned long count; - unsigned long free[254]; - unsigned long next; -}; - -struct ext_super_block { - unsigned long s_ninodes; - unsigned long s_nzones; - unsigned long s_firstfreeblock; - unsigned long s_freeblockscount; - unsigned long s_firstfreeinode; - unsigned long s_freeinodescount; - unsigned long s_firstdatazone; - unsigned long s_log_zone_size; - unsigned long s_max_size; - unsigned long s_reserved1; - unsigned long s_reserved2; - unsigned long s_reserved3; - unsigned long s_reserved4; - unsigned long s_reserved5; - unsigned short s_magic; -}; - -struct ext_dir_entry { - unsigned long inode; - unsigned short rec_len; - unsigned short name_len; - char name[EXT_NAME_LEN]; -}; - -#ifdef __KERNEL__ -extern int ext_open(struct inode * inode, struct file * filp); -extern void ext_release(struct inode * inode, struct file * filp); -extern int ext_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); -extern int ext_create(struct inode * dir,const char * name, int len, int mode, - struct inode ** result); -extern int ext_mkdir(struct inode * dir, const char * name, int len, int mode); -extern int ext_rmdir(struct inode * dir, const char * name, int len); -extern int ext_unlink(struct inode * dir, const char * name, int len); -extern int ext_symlink(struct inode * inode, const char * name, int len, - const char * symname); -extern int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len); -extern int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); -extern int ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len, int must_be_dir); -extern struct inode * ext_new_inode(const struct inode * dir); -extern void ext_free_inode(struct inode * inode); -extern unsigned long ext_count_free_inodes(struct super_block *sb); -extern int ext_new_block(struct super_block * sb); -extern void ext_free_block(struct super_block * sb, int block); -extern unsigned long ext_count_free_blocks(struct super_block *sb); - -extern int ext_bmap(struct inode *,int); - -extern struct buffer_head * ext_getblk(struct inode *, int, int); -extern struct buffer_head * ext_bread(struct inode *, int, int); - -extern void ext_truncate(struct inode *); -extern void ext_put_super(struct super_block *); -extern void ext_write_super(struct super_block *); -extern struct super_block *ext_read_super(struct super_block *,void *,int); -extern int init_ext_fs(void); -extern void ext_read_inode(struct inode *); -extern void ext_write_inode(struct inode *); -extern void ext_put_inode(struct inode *); -extern void ext_statfs(struct super_block *, struct statfs *, int); -extern int ext_sync_inode(struct inode *); -extern int ext_sync_file(struct inode *, struct file *); - -extern int ext_lseek(struct inode *, struct file *, off_t, int); -extern int ext_read(struct inode *, struct file *, char *, int); -extern int ext_write(struct inode *, struct file *, char *, int); - -extern struct inode_operations ext_file_inode_operations; -extern struct inode_operations ext_dir_inode_operations; -extern struct inode_operations ext_symlink_inode_operations; - -#endif /*__KERNEL__ */ -#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/ext_fs_i.h linux/include/linux/ext_fs_i.h --- v2.1.20/linux/include/linux/ext_fs_i.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/ext_fs_i.h Thu Jan 1 02:00:00 1970 @@ -1,11 +0,0 @@ -#ifndef _EXT_FS_I -#define _EXT_FS_I - -/* - * extended file system inode data in memory - */ -struct ext_inode_info { - unsigned long i_data[16]; -}; - -#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/ext_fs_sb.h linux/include/linux/ext_fs_sb.h --- v2.1.20/linux/include/linux/ext_fs_sb.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/ext_fs_sb.h Thu Jan 1 02:00:00 1970 @@ -1,21 +0,0 @@ -#ifndef _EXT_FS_SB -#define _EXT_FS_SB - -/* - * extended-fs super-block data in memory - */ -struct ext_sb_info { - unsigned long s_ninodes; - unsigned long s_nzones; - unsigned long s_firstdatazone; - unsigned long s_log_zone_size; - unsigned long s_max_size; - unsigned long s_firstfreeblocknumber; - unsigned long s_freeblockscount; - struct buffer_head * s_firstfreeblock; - unsigned long s_firstfreeinodenumber; - unsigned long s_freeinodescount; - struct buffer_head * s_firstfreeinodeblock; -}; - -#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.20/linux/include/linux/fs.h Mon Dec 30 15:39:15 1996 +++ linux/include/linux/fs.h Tue Jan 14 13:39:58 1997 @@ -221,17 +221,16 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include #include +#include /* * Attribute flags. These should be or-ed together to figure out what @@ -310,17 +309,16 @@ union { struct pipe_inode_info pipe_i; struct minix_inode_info minix_i; - struct ext_inode_info ext_i; struct ext2_inode_info ext2_i; struct hpfs_inode_info hpfs_i; struct msdos_inode_info msdos_i; struct umsdos_inode_info umsdos_i; struct iso_inode_info isofs_i; struct nfs_inode_info nfs_i; - struct xiafs_inode_info xiafs_i; struct sysv_inode_info sysv_i; struct affs_inode_info affs_i; struct ufs_inode_info ufs_i; + struct romfs_inode_info romfs_i; struct socket socket_i; void * generic_ip; } u; @@ -411,16 +409,15 @@ extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **); #include -#include #include #include #include #include #include -#include #include #include #include +#include struct super_block { kdev_t s_dev; @@ -440,16 +437,15 @@ struct wait_queue * s_wait; union { struct minix_sb_info minix_sb; - struct ext_sb_info ext_sb; struct ext2_sb_info ext2_sb; struct hpfs_sb_info hpfs_sb; struct msdos_sb_info msdos_sb; struct isofs_sb_info isofs_sb; struct nfs_sb_info nfs_sb; - struct xiafs_sb_info xiafs_sb; struct sysv_sb_info sysv_sb; struct affs_sb_info affs_sb; struct ufs_sb_info ufs_sb; + struct romfs_sb_info romfs_sb; void *generic_sbp; } u; }; diff -u --recursive --new-file v2.1.20/linux/include/linux/in6.h linux/include/linux/in6.h --- v2.1.20/linux/include/linux/in6.h Thu Dec 12 17:02:46 1996 +++ linux/include/linux/in6.h Tue Jan 14 08:16:49 1997 @@ -96,6 +96,7 @@ #define IPV6_RXSRCRT 5 #define IPV6_PKTOPTIONS 6 #define IPV6_CHECKSUM 7 +#define IPV6_HOPLIMIT 8 /* * Alternative names diff -u --recursive --new-file v2.1.20/linux/include/linux/modsetver.h linux/include/linux/modsetver.h --- v2.1.20/linux/include/linux/modsetver.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/modsetver.h Fri Jan 3 11:33:26 1997 @@ -0,0 +1,10 @@ +/* Symbol versioning nastiness. */ + +#define __SYMBOL_VERSION(x) __ver_ ## x +#define __VERSIONED_SYMBOL2(x,v) x ## _R ## v +#define __VERSIONED_SYMBOL1(x,v) __VERSIONED_SYMBOL2(x,v) +#define __VERSIONED_SYMBOL(x) __VERSIONED_SYMBOL1(x,__SYMBOL_VERSION(x)) + +#ifndef _set_ver +#define _set_ver(x) __VERSIONED_SYMBOL(x) +#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/module.h linux/include/linux/module.h --- v2.1.20/linux/include/linux/module.h Mon Dec 30 15:39:15 1996 +++ linux/include/linux/module.h Tue Jan 14 13:40:08 1997 @@ -8,14 +8,17 @@ #define _LINUX_MODULE_H #ifdef __GENKSYMS__ -# undef MODVERSIONS -# define MODVERSIONS +# define _set_ver(sym) sym +# undef MODVERSIONS +# define MODVERSIONS #else /* ! __GENKSYMS__ */ -# if defined(MODVERSIONS) && !defined(MODULE) && defined(EXPORT_SYMTAB) +# if !defined(MODVERSIONS) && defined(EXPORT_SYMTAB) +# define _set_ver(sym) sym # include # endif #endif /* __GENKSYMS__ */ + /* Don't need to bring in all of uaccess.h just for this decl. */ struct exception_table_entry; @@ -39,6 +42,9 @@ struct module_ref *next_ref; }; +/* TBD */ +struct module_persist; + struct module { unsigned long size_of_struct; /* == sizeof(module) */ @@ -62,6 +68,11 @@ #ifdef __alpha__ unsigned long gp; #endif + /* Members past this point are extensions to the basic + module support and are optional. Use mod_opt_member() + to examine them. */ + const struct module_persist *persist_start; + const struct module_persist *persist_end; }; struct module_info @@ -78,6 +89,7 @@ #define MOD_DELETED 2 #define MOD_AUTOCLEAN 4 #define MOD_VISITED 8 +#define MOD_USED_ONCE 16 /* Values for query_module's which. */ @@ -91,12 +103,23 @@ #define GET_USE_COUNT(module) ((module)->usecount) +/* When the struct module is extended, new values must be examined using + this macro. It returns a pointer to the member if available, NULL + otherwise. */ + +#define mod_opt_member(mod,member) \ + ({ struct module *_mod = (mod); \ + __typeof__(_mod->member) *_mem = &_mod->member; \ + ((char *)(_mem+1) > (char *)_mod + _mod->size_of_struct \ + ? (__typeof__(_mod->member) *)NULL : _mem); \ + }) + /* Indirect stringification. */ #define __MODULE_STRING_1(x) #x #define __MODULE_STRING(x) __MODULE_STRING_1(x) -#ifdef MODULE +#if defined(MODULE) && !defined(__GENKSYMS__) /* Embedded module documentation macros. */ @@ -106,6 +129,10 @@ const char __module_author[] __attribute__((section(".modinfo"))) = \ "author=" name +#define MODULE_DESCRIPTION(desc) \ +const char __module_description[] __attribute__((section(".modinfo"))) = \ +"description=" desc + /* Could potentially be used by kerneld... */ #define MODULE_SUPPORTED_DEVICE(dev) \ @@ -130,27 +157,32 @@ __attribute__((section(".modinfo"))) = \ "parm_" __MODULE_STRING(var) "=" type +#define MODULE_PARM_DESC(var,desc) \ +const char __module_parm_desc_##var[] \ +__attribute__((section(".modinfo"))) = \ +"parm_desc_" __MODULE_STRING(var) "=" desc + /* The attributes of a section are set the first time the section is - seen; we want .modinfo to not be allocated. This header should be - included before any functions or variables are defined. */ + seen; we want .modinfo to not be allocated. */ -__asm__(".section .modinfo\n\t.text"); +__asm__(".section .modinfo\n\t.previous"); /* Define the module variable, and usage macros. */ extern struct module __this_module; -#define MOD_INC_USE_COUNT \ - (__this_module.usecount++, __this_module.flags |= MOD_VISITED) -#define MOD_DEC_USE_COUNT \ +#define MOD_INC_USE_COUNT \ + (__this_module.usecount++, \ + __this_module.flags |= MOD_VISITED|MOD_USED_ONCE) +#define MOD_DEC_USE_COUNT \ (__this_module.usecount--, __this_module.flags |= MOD_VISITED) -#define MOD_IN_USE \ +#define MOD_IN_USE \ (__this_module.usecount != 0) #ifndef __NO_VERSION__ #include const char __module_kernel_version[] __attribute__((section(".modinfo"))) = "kernel_version=" UTS_RELEASE; -#if defined(MODVERSIONS) && !defined(__GENKSYMS__) +#ifdef MODVERSIONS const char __module_using_checksums[] __attribute__((section(".modinfo"))) = "using_checksums=1"; #endif @@ -159,8 +191,12 @@ #else /* MODULE */ #define MODULE_AUTHOR(name) +#define MODULE_DESCRIPTION(desc) #define MODULE_SUPPORTED_DEVICE(name) #define MODULE_PARM(var,type) +#define MODULE_PARM_DESC(var,desc) + +#ifndef __GENKSYMS__ #define MOD_INC_USE_COUNT do { } while (0) #define MOD_DEC_USE_COUNT do { } while (0) @@ -168,6 +204,8 @@ extern struct module *module_list; +#endif /* !__GENKSYMS__ */ + #endif /* MODULE */ /* Export a symbol either from the kernel or a module. @@ -183,30 +221,48 @@ /* We want the EXPORT_SYMBOL tag left intact for recognition. */ +#elif !defined(EXPORT_SYMTAB) + +#define __EXPORT_SYMBOL(sym,str) error EXPORT_SYMTAB_not_defined +#define EXPORT_SYMBOL(var) error EXPORT_SYMTAB_not_defined +#define EXPORT_SYMBOL_NOVERS(var) error EXPORT_SYMTAB_not_defined + +#elif !defined(AUTOCONF_INCLUDED) + +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module + #elif !defined(CONFIG_MODULES) +#define __EXPORT_SYMBOL(sym,str) #define EXPORT_SYMBOL(var) #define EXPORT_SYMBOL_NOVERS(var) -#define EXPORT_NO_SYMBOLS #else -#define EXPORT_SYMBOL(var) \ -const struct module_symbol __export_##var \ -__attribute__((section("__ksymtab"))) = { \ - (unsigned long)&var, __MODULE_STRING(var) \ -} \ +#define __EXPORT_SYMBOL(sym, str) \ +const char __kstrtab_##sym[] \ +__attribute__((section(".kstrtab"))) = str; \ +const struct module_symbol __ksymtab_##sym \ +__attribute__((section("__ksymtab"))) = \ +{ (unsigned long)&sym, __kstrtab_##sym } + +#if defined(MODVERSIONS) || !defined(CONFIG_MODVERSIONS) +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) +#else +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) +#endif + +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) -#define EXPORT_SYMBOL_NOVERS(var) EXPORT_SYMBOL(var) +#endif /* __GENKSYMS__ */ #ifdef MODULE /* Force a module to export no symbols. */ -#define EXPORT_NO_SYMBOLS \ -__asm__(".section __ksymtab\n.text") +#define EXPORT_NO_SYMBOLS __asm__(".section __ksymtab\n.previous") #else #define EXPORT_NO_SYMBOLS #endif /* MODULE */ - -#endif #endif /* _LINUX_MODULE_H */ diff -u --recursive --new-file v2.1.20/linux/include/linux/romfs_fs.h linux/include/linux/romfs_fs.h --- v2.1.20/linux/include/linux/romfs_fs.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/romfs_fs.h Tue Jan 14 12:51:18 1997 @@ -0,0 +1,62 @@ +#ifndef __LINUX_ROMFS_FS_H +#define __LINUX_ROMFS_FS_H + +/* The basic structures of the romfs filesystem */ + +#define ROMBSIZE BLOCK_SIZE +#define ROMBSBITS BLOCK_SIZE_BITS +#define ROMBMASK (ROMBSIZE-1) +#define ROMFS_MAGIC 0x7275 + +#define ROMFS_MAXFN 128 + +#define __mkw(h,l) (((h)&0x00ff)<< 8|((l)&0x00ff)) +#define __mkl(h,l) (((h)&0xffff)<<16|((l)&0xffff)) +#define __mk4(a,b,c,d) htonl(__mkl(__mkw(a,b),__mkw(c,d))) +#define ROMSB_WORD0 __mk4('-','r','o','m') +#define ROMSB_WORD1 __mk4('1','f','s','-') + +/* On-disk "super block" */ + +struct romfs_super_block { + __u32 word0; + __u32 word1; + __u32 size; + __u32 checksum; + char name[0]; /* volume name */ +}; + +/* On disk inode */ + +struct romfs_inode { + __u32 next; /* low 4 bits see ROMFH_ */ + __u32 spec; + __u32 size; + __u32 checksum; + char name[0]; +}; + +#define ROMFH_TYPE 7 +#define ROMFH_HRD 0 +#define ROMFH_DIR 1 +#define ROMFH_REG 2 +#define ROMFH_SYM 3 +#define ROMFH_BLK 4 +#define ROMFH_CHR 5 +#define ROMFH_SCK 6 +#define ROMFH_FIF 7 +#define ROMFH_EXEC 8 + +/* Alignment */ + +#define ROMFH_SIZE 16 +#define ROMFH_PAD (ROMFH_SIZE-1) +#define ROMFH_MASK (~ROMFH_PAD) + +#ifdef __KERNEL__ + +/* Not much now */ +extern int init_romfs_fs(void); + +#endif /* __KERNEL__ */ +#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/romfs_fs_i.h linux/include/linux/romfs_fs_i.h --- v2.1.20/linux/include/linux/romfs_fs_i.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/romfs_fs_i.h Fri Jan 3 13:03:42 1997 @@ -0,0 +1,11 @@ +#ifndef __ROMFS_FS_I +#define __ROMFS_FS_I + +/* inode in-kernel data */ + +struct romfs_inode_info { + unsigned long i_metasize; /* size of non-data area */ + unsigned long i_dataoffset; /* from the start of fs */ +}; + +#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/romfs_fs_sb.h linux/include/linux/romfs_fs_sb.h --- v2.1.20/linux/include/linux/romfs_fs_sb.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/romfs_fs_sb.h Fri Jan 3 13:03:42 1997 @@ -0,0 +1,10 @@ +#ifndef __ROMFS_FS_SB +#define __ROMFS_FS_SB + +/* romfs superblock in-core data */ + +struct romfs_sb_info { + unsigned long s_maxsize; +}; + +#endif diff -u --recursive --new-file v2.1.20/linux/include/linux/xia_fs.h linux/include/linux/xia_fs.h --- v2.1.20/linux/include/linux/xia_fs.h Wed Jul 3 11:53:06 1996 +++ linux/include/linux/xia_fs.h Thu Jan 1 02:00:00 1970 @@ -1,121 +0,0 @@ -#ifndef _XIA_FS_H -#define _XIA_FS_H - -/* - * include/linux/xia_fs.h - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix_fs.h. - * Copyright (C) Linus Torvalds, 1991, 1992. - */ - -#define _XIAFS_SUPER_MAGIC 0x012FD16D -#define _XIAFS_ROOT_INO 1 -#define _XIAFS_BAD_INO 2 - -#define _XIAFS_NAME_LEN 248 - -#define _XIAFS_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof(struct xiafs_inode))) - -struct xiafs_inode { /* 64 bytes */ - mode_t i_mode; - nlink_t i_nlinks; - uid_t i_uid; - gid_t i_gid; - size_t i_size; /* 8 */ - time_t i_ctime; - time_t i_atime; - time_t i_mtime; - daddr_t i_zone[8]; - daddr_t i_ind_zone; - daddr_t i_dind_zone; -}; - -/* - * linux super-block data on disk - */ -struct xiafs_super_block { - u_char s_boot_segment[512]; /* 1st sector reserved for boot */ - u_long s_zone_size; /* 0: the name says it */ - u_long s_nzones; /* 1: volume size, zone aligned */ - u_long s_ninodes; /* 2: # of inodes */ - u_long s_ndatazones; /* 3: # of data zones */ - u_long s_imap_zones; /* 4: # of imap zones */ - u_long s_zmap_zones; /* 5: # of zmap zones */ - u_long s_firstdatazone; /* 6: first data zone */ - u_long s_zone_shift; /* 7: z size = 1KB << z shift */ - u_long s_max_size; /* 8: max size of a single file */ - u_long s_reserved0; /* 9: reserved */ - u_long s_reserved1; /* 10: */ - u_long s_reserved2; /* 11: */ - u_long s_reserved3; /* 12: */ - u_long s_firstkernzone; /* 13: first kernel zone */ - u_long s_kernzones; /* 14: kernel size in zones */ - u_long s_magic; /* 15: magic number for xiafs */ -}; - -struct xiafs_direct { - ino_t d_ino; - u_short d_rec_len; - u_char d_name_len; - char d_name[_XIAFS_NAME_LEN+1]; -}; - -#ifdef __KERNEL__ - -extern int xiafs_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); -extern int xiafs_create(struct inode * dir,const char * name, int len, int mode, - struct inode ** result); -extern int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode); -extern int xiafs_rmdir(struct inode * dir, const char * name, int len); -extern int xiafs_unlink(struct inode * dir, const char * name, int len); -extern int xiafs_symlink(struct inode * inode, const char * name, int len, - const char * symname); -extern int xiafs_link(struct inode * oldinode, struct inode * dir, - const char * name, int len); -extern int xiafs_mknod(struct inode * dir, const char * name, int len, - int mode, int rdev); -extern int xiafs_rename(struct inode * old_dir, const char * old_name, - int old_len, struct inode * new_dir, - const char * new_name, int new_len, - int must_be_dir); -extern struct inode * xiafs_new_inode(struct inode * dir); -extern void xiafs_free_inode(struct inode * inode); -extern unsigned long xiafs_count_free_inodes(struct super_block *sb); -extern int xiafs_new_zone(struct super_block * sb, u_long prev_addr); -extern void xiafs_free_zone(struct super_block * sb, int block); -extern unsigned long xiafs_count_free_zones(struct super_block *sb); - -extern int xiafs_bmap(struct inode *,int); - -extern struct buffer_head * xiafs_getblk(struct inode *, int, int); -extern struct buffer_head * xiafs_bread(struct inode *, int, int); - -extern void xiafs_truncate(struct inode *); -extern void xiafs_put_super(struct super_block *); -extern struct super_block *xiafs_read_super(struct super_block *,void *,int); -extern int init_xiafs_fs(void); -extern void xiafs_read_inode(struct inode *); -extern void xiafs_write_inode(struct inode *); -extern void xiafs_put_inode(struct inode *); -extern void xiafs_statfs(struct super_block *, struct statfs *, int); -extern int xiafs_sync_inode(struct inode *); -extern int xiafs_sync_file(struct inode *, struct file *); - -extern struct inode_operations xiafs_file_inode_operations; -extern struct inode_operations xiafs_dir_inode_operations; -extern struct inode_operations xiafs_symlink_inode_operations; - -#endif /* __KERNEL__ */ - -#endif /* _XIA_FS_H */ - - - - - - - - diff -u --recursive --new-file v2.1.20/linux/include/linux/xia_fs_i.h linux/include/linux/xia_fs_i.h --- v2.1.20/linux/include/linux/xia_fs_i.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/xia_fs_i.h Thu Jan 1 02:00:00 1970 @@ -1,19 +0,0 @@ -#ifndef _XIA_FS_I_H -#define _XIA_FS_I_H - -/* - * include/linux/xia_fs_i.h - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix_fs_i.h. - * Copyright (C) Linus Torvalds, 1991, 1992. - */ - -struct xiafs_inode_info { /* for data zone pointers */ - unsigned long i_zone[8]; - unsigned long i_ind_zone; - unsigned long i_dind_zone; -}; - -#endif /* _XIA_FS_I_H */ diff -u --recursive --new-file v2.1.20/linux/include/linux/xia_fs_sb.h linux/include/linux/xia_fs_sb.h --- v2.1.20/linux/include/linux/xia_fs_sb.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/xia_fs_sb.h Thu Jan 1 02:00:00 1970 @@ -1,36 +0,0 @@ -#ifndef _XIA_FS_SB_H -#define _XIA_FS_SB_H - -/* - * include/linux/xia_fs_sb.h - * - * Copyright (C) Q. Frank Xia, 1993. - * - * Based on Linus' minix_fs_sb.h. - * Copyright (C) Linus Torvalds, 1991, 1992. - */ - -#define _XIAFS_IMAP_SLOTS 8 -#define _XIAFS_ZMAP_SLOTS 32 - -struct xiafs_sb_info { - u_long s_nzones; - u_long s_ninodes; - u_long s_ndatazones; - u_long s_imap_zones; - u_long s_zmap_zones; - u_long s_firstdatazone; - u_long s_zone_shift; - u_long s_max_size; /* 32 bytes */ - struct buffer_head * s_imap_buf[_XIAFS_IMAP_SLOTS]; /* 32 bytes */ - struct buffer_head * s_zmap_buf[_XIAFS_ZMAP_SLOTS]; /* 128 bytes */ - int s_imap_iznr[_XIAFS_IMAP_SLOTS]; /* 32 bytes */ - int s_zmap_zznr[_XIAFS_ZMAP_SLOTS]; /* 128 bytes */ - u_char s_imap_cached; /* flag for cached imap */ - u_char s_zmap_cached; /* flag for cached imap */ -}; - -#endif /* _XIA_FS_SB_H */ - - - diff -u --recursive --new-file v2.1.20/linux/include/net/ipv6.h linux/include/net/ipv6.h --- v2.1.20/linux/include/net/ipv6.h Fri Nov 15 23:49:10 1996 +++ linux/include/net/ipv6.h Tue Jan 14 13:45:30 1997 @@ -214,7 +214,8 @@ struct in6_addr * saddr, struct device *dev, struct ipv6_options *opt, - int proto, int noblock); + int proto, int hlimit, + int noblock); /* * rcv function (called from netdevice level) diff -u --recursive --new-file v2.1.20/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.20/linux/include/net/sock.h Thu Jan 2 15:55:25 1997 +++ linux/include/net/sock.h Tue Jan 14 13:42:14 1997 @@ -149,8 +149,11 @@ __u8 recvsrcrt:1, rxinfo:1, + rxhlim:1, + hopopts:1, + dstopts:1, mc_loop:1, - unused:4; + unused:2; /* device for outgoing mcast packets */ diff -u --recursive --new-file v2.1.20/linux/include/net/transp_v6.h linux/include/net/transp_v6.h --- v2.1.20/linux/include/net/transp_v6.h Sat Nov 30 12:03:12 1996 +++ linux/include/net/transp_v6.h Tue Jan 14 13:47:18 1997 @@ -28,7 +28,8 @@ extern int datagram_send_ctl(struct msghdr *msg, struct device **src_dev, struct in6_addr **src_addr, - struct ipv6_options *opt); + struct ipv6_options *opt, + int *hlimit); #define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) diff -u --recursive --new-file v2.1.20/linux/init/main.c linux/init/main.c --- v2.1.20/linux/init/main.c Thu Jan 2 15:55:25 1997 +++ linux/init/main.c Tue Jan 14 12:57:24 1997 @@ -6,6 +6,7 @@ * GK 2/5/95 - Changed to support mounting root fs via NFS * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96 * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96 + * Simplified starting of init: Michael A. Griffith */ #define __KERNEL_SYSCALLS__ @@ -53,8 +54,6 @@ extern char _stext, _etext; extern char *linux_banner; -static char printbuf[1024]; - extern int console_loglevel; static int init(void *); @@ -237,9 +236,6 @@ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; -static char * argv_rc[] = { "/bin/sh", NULL }; -static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL }; - char *get_options(char *str, int *ints) { char *cur = str; @@ -917,39 +913,6 @@ cpu_idle(NULL); } -static int printf(const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - write(1,printbuf,i=vsprintf(printbuf, fmt, args)); - va_end(args); - return i; -} - -static int do_rc(void * rc) -{ - close(0); - if (open(rc,O_RDONLY,0)) - return -1; - return execve("/bin/sh", argv_rc, envp_rc); -} - -static int do_shell(void * shell) -{ - char *argv[2]; - - close(0);close(1);close(2); - setsid(); - (void) open("/dev/tty1",O_RDWR,0); - (void) dup(0); - (void) dup(0); - argv[0] = shell; - argv[1] = NULL; - return execve(shell, argv, envp_rc); -} - #ifdef CONFIG_BLK_DEV_INITRD static int do_linuxrc(void * shell) { @@ -971,7 +934,6 @@ static int init(void * unused) { - int pid,i; #ifdef CONFIG_BLK_DEV_INITRD int real_root_mountflags; #endif @@ -1042,32 +1004,18 @@ (void) dup(0); (void) dup(0); + + /* + * We try each of these until one succeeds. + * + * The Bourne shell can be used instead of init if we are + * trying to recover a really broken machine. + */ - if (!execute_command) { - execve("/etc/init",argv_init,envp_init); - execve("/bin/init",argv_init,envp_init); - execve("/sbin/init",argv_init,envp_init); - /* if this fails, fall through to original stuff */ - - pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD); - if (pid>0) - while (pid != wait(&i)) - /* nothing */; - } - - while (1) { - pid = kernel_thread(do_shell, - execute_command ? execute_command : "/bin/sh", - SIGCHLD); - if (pid < 0) { - printf("Fork failed in init\n\r"); - continue; - } - while (1) - if (pid == wait(&i)) - break; - printf("\n\rchild %d died with code %04x\n\r",pid,i); - sync(); - } - return -1; + execve(execute_command,argv_init,envp_init); + execve("/etc/init",argv_init,envp_init); + execve("/bin/init",argv_init,envp_init); + execve("/sbin/init",argv_init,envp_init); + execve("/bin/sh",argv_init,envp_init); + panic("No init found. Try passing init= option to kernel."); } diff -u --recursive --new-file v2.1.20/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.20/linux/kernel/ksyms.c Mon Dec 30 15:39:16 1996 +++ linux/kernel/ksyms.c Fri Jan 3 11:33:26 1997 @@ -9,8 +9,8 @@ * by Bjorn Ekwall */ -#include #include +#include #include #include #include @@ -330,7 +330,6 @@ EXPORT_SYMBOL(___strtok); EXPORT_SYMBOL(init_fifo); EXPORT_SYMBOL(super_blocks); -EXPORT_SYMBOL(reuse_list); EXPORT_SYMBOL(fifo_inode_operations); EXPORT_SYMBOL(chrdev_inode_operations); EXPORT_SYMBOL(blkdev_inode_operations); diff -u --recursive --new-file v2.1.20/linux/kernel/module.c linux/kernel/module.c --- v2.1.20/linux/kernel/module.c Mon Dec 30 15:39:16 1996 +++ linux/kernel/module.c Tue Jan 14 09:02:10 1997 @@ -43,9 +43,7 @@ NULL, /* cleanup */ __start___ex_table, /* ex_table_start */ __stop___ex_table, /* ex_table_end */ -#ifdef __alpha__ - NULL, /* gp */ -#endif + /* Rest are NULL */ }; struct module *module_list = &kernel_module; @@ -186,11 +184,14 @@ goto err1; } - /* In the future we can check for various known sizes, but for - now there is only one. */ + /* Check for legal module header sizes. */ if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0) goto err1; - if (mod_user_size != sizeof(struct module)) { + switch (mod_user_size) { + case sizeof(struct module): + case &((struct module *)0L)->persist_start: + break; + default: printk(KERN_ERR "init_module: Invalid module header size.\n" KERN_ERR "A new version of the modutils is likely " "needed.\n"); @@ -378,8 +379,9 @@ next = mod->next; if (mod->refs == NULL && mod->usecount == 0 && - ((mod->flags & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED)) - == (MOD_AUTOCLEAN|MOD_RUNNING))) { + ((mod->flags + & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED|MOD_USED_ONCE)) + == (MOD_AUTOCLEAN|MOD_RUNNING|MOD_USED_ONCE))) { if (mod->flags & MOD_VISITED) mod->flags &= ~MOD_VISITED; else diff -u --recursive --new-file v2.1.20/linux/net/802/p8022.c linux/net/802/p8022.c --- v2.1.20/linux/net/802/p8022.c Thu Jan 2 15:55:26 1997 +++ linux/net/802/p8022.c Fri Jan 3 11:33:27 1997 @@ -16,6 +16,7 @@ * 4 entries at most). The current demux assumes this. */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/802/p8022tr.c linux/net/802/p8022tr.c --- v2.1.20/linux/net/802/p8022tr.c Thu Jan 2 15:55:26 1997 +++ linux/net/802/p8022tr.c Fri Jan 3 11:33:27 1997 @@ -8,6 +8,7 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/802/psnap.c linux/net/802/psnap.c --- v2.1.20/linux/net/802/psnap.c Mon Dec 30 15:39:16 1996 +++ linux/net/802/psnap.c Fri Jan 3 11:33:27 1997 @@ -10,6 +10,7 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/Makefile linux/net/Makefile --- v2.1.20/linux/net/Makefile Thu Jan 2 15:55:26 1997 +++ linux/net/Makefile Fri Jan 3 11:33:27 1997 @@ -89,13 +89,21 @@ endif endif -L_TARGET := network.a -L_OBJS := socket.o protocols.o sysctl_net.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) +# We must attach netsyms.o to socket.o, as otherwise there is nothing +# to pull the object file from the archive. + +SOCK := socket.o ifeq ($(CONFIG_NET),y) ifeq ($(CONFIG_MODULES),y) -LX_OBJS = netsyms.o +O_TARGET := sock_n_syms.o +O_OBJS := socket.o +OX_OBJS := netsyms.o +SOCK := $(O_TARGET) endif endif + +L_TARGET := network.a +L_OBJS := $(SOCK) protocols.o sysctl_net.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) M_OBJS := diff -u --recursive --new-file v2.1.20/linux/net/core/firewall.c linux/net/core/firewall.c --- v2.1.20/linux/net/core/firewall.c Thu Jan 2 15:55:26 1997 +++ linux/net/core/firewall.c Fri Jan 3 11:33:27 1997 @@ -6,6 +6,7 @@ * much hacked by: Alan Cox */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/ipv4/Makefile linux/net/ipv4/Makefile --- v2.1.20/linux/net/ipv4/Makefile Thu Dec 12 19:37:25 1996 +++ linux/net/ipv4/Makefile Fri Jan 3 11:33:27 1997 @@ -14,6 +14,7 @@ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o\ raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o ip_fw.o \ sysctl_net_ipv4.o fib.o ip_nat_dumb.o +IPV4X_OBJS := MOD_LIST_NAME := IPV4_MODULES M_OBJS := @@ -39,7 +40,7 @@ endif ifeq ($(CONFIG_IP_MASQUERADE),y) -IPV4_OBJS += ip_masq.o ip_masq_app.o +IPV4X_OBJS += ip_masq.o ip_masq_app.o M_OBJS += ip_masq_ftp.o ip_masq_irc.o ip_masq_raudio.o endif @@ -53,6 +54,7 @@ ifdef CONFIG_INET O_OBJS := $(IPV4_OBJS) +OX_OBJS := $(IPV4X_OBJS) endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.20/linux/net/ipv4/ip_masq_ftp.c linux/net/ipv4/ip_masq_ftp.c --- v2.1.20/linux/net/ipv4/ip_masq_ftp.c Mon Dec 30 15:39:17 1996 +++ linux/net/ipv4/ip_masq_ftp.c Fri Jan 3 11:33:27 1997 @@ -20,6 +20,7 @@ * */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/ipv4/ip_masq_irc.c linux/net/ipv4/ip_masq_irc.c --- v2.1.20/linux/net/ipv4/ip_masq_irc.c Mon Dec 30 15:39:17 1996 +++ linux/net/ipv4/ip_masq_irc.c Fri Jan 3 11:33:27 1997 @@ -20,6 +20,7 @@ * */ +#include #include #include diff -u --recursive --new-file v2.1.20/linux/net/ipv4/ip_masq_raudio.c linux/net/ipv4/ip_masq_raudio.c --- v2.1.20/linux/net/ipv4/ip_masq_raudio.c Mon Dec 30 15:39:17 1996 +++ linux/net/ipv4/ip_masq_raudio.c Fri Jan 3 11:33:27 1997 @@ -37,6 +37,7 @@ * */ +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/ipv6/datagram.c linux/net/ipv6/datagram.c --- v2.1.20/linux/net/ipv6/datagram.c Thu Dec 12 19:37:30 1996 +++ linux/net/ipv6/datagram.c Tue Jan 14 08:16:49 1997 @@ -65,6 +65,22 @@ cmsg = (struct cmsghdr *)((u8*) cmsg + cmsg->cmsg_len); } + if (np->rxhlim && (len >= sizeof(struct cmsghdr) + sizeof(int))) + { + int *hlim; + + cmsg->cmsg_len = (sizeof(struct cmsghdr) + sizeof(int)); + cmsg->cmsg_level = SOL_IPV6; + cmsg->cmsg_type = IPV6_HOPLIMIT; + + hlim = (int *) cmsg->cmsg_data; + *hlim = skb->nh.ipv6h->hop_limit; + + len -= cmsg->cmsg_len; + msg->msg_controllen += cmsg->cmsg_len; + cmsg = (struct cmsghdr *)((u8*) cmsg + cmsg->cmsg_len); + } + if (opt->srcrt) { int hdrlen = sizeof(struct rt0_hdr) + (opt->srcrt->hdrlen << 3); @@ -90,14 +106,15 @@ int datagram_send_ctl(struct msghdr *msg, struct device **src_dev, - struct in6_addr **src_addr, struct ipv6_options *opt) + struct in6_addr **src_addr, struct ipv6_options *opt, + int *hlimit) { struct inet6_dev *in6_dev = NULL; struct in6_pktinfo *src_info; struct cmsghdr *cmsg; struct ipv6_rt_hdr *rthdr; int len; - int err = -EINVAL; + int err = 0; for (cmsg = msg->msg_control; cmsg; cmsg = cmsg_nxthdr(msg, cmsg)) { @@ -113,6 +130,7 @@ if (cmsg->cmsg_len < (sizeof(struct cmsghdr) + sizeof(struct in6_pktinfo))) { + err = -EINVAL; goto exit_f; } @@ -123,6 +141,7 @@ in6_dev = ipv6_dev_by_index(src_info->ipi6_ifindex); if (in6_dev == NULL) { + err = -ENODEV; goto exit_f; } @@ -137,11 +156,11 @@ if ( ifp == NULL) { + err = -EINVAL; goto exit_f; } *src_addr = &src_info->ipi6_addr; - err = 0; } break; @@ -155,6 +174,7 @@ /* validate option length */ if (len < sizeof(struct ipv6_rt_hdr)) { + err = -EINVAL; goto exit_f; } @@ -165,28 +185,46 @@ */ if (rthdr->type) { + err = -EINVAL; goto exit_f; } if (((rthdr->hdrlen + 1) << 3) < len) - { + { + err = -EINVAL; goto exit_f; } /* segments left must also match */ if ((rthdr->hdrlen >> 1) != rthdr->segments_left) { + err = -EINVAL; goto exit_f; } opt->opt_nflen += ((rthdr->hdrlen + 1) << 3); opt->srcrt = rthdr; - err = 0; break; + + case IPV6_HOPLIMIT: + + len = cmsg->cmsg_len; + len -= sizeof(struct cmsghdr); + + if (len < sizeof(int)) + { + err = -EINVAL; + goto exit_f; + } + + *hlimit = *((int *) cmsg->cmsg_data); + break; + default: printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type); + err = -EINVAL; break; } } diff -u --recursive --new-file v2.1.20/linux/net/ipv6/icmp.c linux/net/ipv6/icmp.c --- v2.1.20/linux/net/ipv6/icmp.c Thu Dec 12 19:37:30 1996 +++ linux/net/ipv6/icmp.c Tue Jan 14 08:16:49 1997 @@ -267,7 +267,7 @@ ipv6_build_xmit(sk, icmpv6_getfrag, &msg, &hdr->saddr, len, - saddr, src_dev, NULL, IPPROTO_ICMPV6, 1); + saddr, src_dev, NULL, IPPROTO_ICMPV6, 0, 1); } static void icmpv6_echo_reply(struct sk_buff *skb) @@ -302,7 +302,7 @@ msg.daddr = &hdr->saddr; ipv6_build_xmit(sk, icmpv6_getfrag, &msg, &hdr->saddr, len, saddr, - skb->dev, NULL, IPPROTO_ICMPV6, 1); + skb->dev, NULL, IPPROTO_ICMPV6, 0, 1); } static __inline__ int ipv6_ext_hdr(u8 nexthdr) diff -u --recursive --new-file v2.1.20/linux/net/ipv6/ipv6_output.c linux/net/ipv6/ipv6_output.c --- v2.1.20/linux/net/ipv6/ipv6_output.c Thu Dec 12 19:37:30 1996 +++ linux/net/ipv6/ipv6_output.c Tue Jan 14 08:16:49 1997 @@ -397,11 +397,10 @@ int ipv6_build_xmit(struct sock *sk, inet_getfrag_t getfrag, const void *data, struct in6_addr *dest, unsigned short int length, struct in6_addr *saddr, struct device *dev, - struct ipv6_options *opt, int proto, + struct ipv6_options *opt, int proto, int hlimit, int noblock) { rt6_output_method_t output_method = default_output_method; - int hlimit; struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; struct dest_entry *dc = NULL; struct in6_addr *daddr = dest; @@ -420,17 +419,21 @@ } addr_type = ipv6_addr_type(daddr); - if (addr_type & IPV6_ADDR_MULTICAST) + + if (hlimit < 1) { - hlimit = np->mcast_hops; - if (dev == NULL) + if (addr_type & IPV6_ADDR_MULTICAST) { - dev = np->mc_if; + hlimit = np->mcast_hops; + if (dev == NULL) + { + dev = np->mc_if; + } } + else + hlimit = np->hop_limit; } - else - hlimit = np->hop_limit; - + if (addr_type & (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_SITELOCAL | IPV6_ADDR_MULTICAST)) { diff -u --recursive --new-file v2.1.20/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c --- v2.1.20/linux/net/ipv6/ipv6_sockglue.c Thu Dec 12 19:37:31 1996 +++ linux/net/ipv6/ipv6_sockglue.c Tue Jan 14 08:16:49 1997 @@ -133,6 +133,11 @@ retv = 0; break; + case IPV6_HOPLIMIT: + np->rxhlim = val; + retv = 0; + break; + case IPV6_UNICAST_HOPS: if (val > 255) { diff -u --recursive --new-file v2.1.20/linux/net/ipv6/raw.c linux/net/ipv6/raw.c --- v2.1.20/linux/net/ipv6/raw.c Thu Dec 12 19:37:31 1996 +++ linux/net/ipv6/raw.c Tue Jan 14 08:16:49 1997 @@ -149,7 +149,7 @@ *addr_len = sizeof(struct sockaddr_in6); } - if (msg->msg_control) + if (msg->msg_controllen) { int err; @@ -248,6 +248,7 @@ struct in6_addr *daddr; struct raw6_opt *raw_opt; u16 proto; + int hlimit = 0; int err; @@ -315,7 +316,7 @@ opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_options)); - err = datagram_send_ctl(msg, &dev, &saddr, opt); + err = datagram_send_ctl(msg, &dev, &saddr, opt, &hlimit); if (err < 0) { printk(KERN_DEBUG "invalid msg_control\n"); @@ -346,12 +347,13 @@ } err = ipv6_build_xmit(sk, rawv6_frag_cksum, &hdr, daddr, len, - saddr, dev, opt, proto, msg->msg_flags&MSG_DONTWAIT); + saddr, dev, opt, proto, hlimit, + msg->msg_flags&MSG_DONTWAIT); } else { err = ipv6_build_xmit(sk, rawv6_getfrag, msg->msg_iov, daddr, - len, saddr, dev, opt, proto, + len, saddr, dev, opt, proto, hlimit, msg->msg_flags&MSG_DONTWAIT); } diff -u --recursive --new-file v2.1.20/linux/net/ipv6/udp.c linux/net/ipv6/udp.c --- v2.1.20/linux/net/ipv6/udp.c Thu Dec 12 19:37:31 1996 +++ linux/net/ipv6/udp.c Tue Jan 14 08:16:49 1997 @@ -506,6 +506,7 @@ struct in6_addr *saddr = NULL; int len = ulen + sizeof(struct udphdr); int addr_type; + int hlimit = 0; int err; @@ -560,7 +561,7 @@ opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_options)); - err = datagram_send_ctl(msg, &dev, &saddr, opt); + err = datagram_send_ctl(msg, &dev, &saddr, opt, &hlimit); if (err < 0) { printk(KERN_DEBUG "invalid msg_control\n"); @@ -581,7 +582,8 @@ udh.pl_len = len; err = ipv6_build_xmit(sk, udpv6_getfrag, &udh, daddr, len, - saddr, dev, opt, IPPROTO_UDP, msg->msg_flags&MSG_DONTWAIT); + saddr, dev, opt, IPPROTO_UDP, hlimit, + msg->msg_flags&MSG_DONTWAIT); if (err < 0) return err; diff -u --recursive --new-file v2.1.20/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c --- v2.1.20/linux/net/ipx/af_ipx.c Thu Jan 2 15:55:28 1997 +++ linux/net/ipx/af_ipx.c Fri Jan 3 11:33:27 1997 @@ -62,9 +62,8 @@ * "AS-IS" and at no charge. */ -#include - #include +#include #include #include #include diff -u --recursive --new-file v2.1.20/linux/net/socket.c linux/net/socket.c --- v2.1.20/linux/net/socket.c Thu Jan 2 15:55:29 1997 +++ linux/net/socket.c Tue Jan 14 08:16:49 1997 @@ -1193,9 +1193,10 @@ struct iovec *iov=iovstack; struct msghdr msg_sys; void * krn_msg_ctl = NULL; + void * usr_msg_ctl = NULL; int err; int total_len; - int len; + int len = 0; /* kernel mode address */ char addr[MAX_SOCK_ADDR]; @@ -1233,6 +1234,12 @@ if (msg_sys.msg_controllen) { + /* + * FIXME: + * I'm assuming that the kernel may have to examine + * the acciliary control messages passed by the user. + * Find out what POSIX says about this... + */ krn_msg_ctl = kmalloc(msg_sys.msg_controllen, GFP_KERNEL); if (!krn_msg_ctl) @@ -1243,7 +1250,11 @@ err = copy_from_user(krn_msg_ctl, msg_sys.msg_control, msg_sys.msg_controllen); if (err) + { + err = -EFAULT; goto flush_it; + } + usr_msg_ctl = msg_sys.msg_control; msg_sys.msg_control = krn_msg_ctl; } @@ -1263,12 +1274,11 @@ { err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); - } - if (!err && msg_sys.msg_controllen) + if (err >= 0 && msg_sys.msg_controllen) { - err = copy_to_user(msg_sys.msg_control, krn_msg_ctl, + err = copy_to_user(usr_msg_ctl, krn_msg_ctl, msg_sys.msg_controllen); } @@ -1281,7 +1291,7 @@ kfree(krn_msg_ctl); } - if (err) + if (err < 0) return err; if (put_user(msg_sys.msg_flags, &msg->msg_flags)) diff -u --recursive --new-file v2.1.20/linux/scripts/Configure linux/scripts/Configure --- v2.1.20/linux/scripts/Configure Fri May 31 13:46:27 1996 +++ linux/scripts/Configure Fri Jan 3 11:33:27 1997 @@ -422,6 +422,7 @@ echo "/*" > $CONFIG_H echo " * Automatically generated C config: don't edit" >> $CONFIG_H echo " */" >> $CONFIG_H +echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H DEFAULT="" if [ "$1" = "-d" ] ; then diff -u --recursive --new-file v2.1.20/linux/scripts/Menuconfig linux/scripts/Menuconfig --- v2.1.20/linux/scripts/Menuconfig Tue Oct 29 19:58:51 1996 +++ linux/scripts/Menuconfig Fri Jan 3 11:33:27 1997 @@ -1020,6 +1020,7 @@ echo "/*" >$CONFIG_H echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H echo " */" >>$CONFIG_H + echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H MAKE=: #To prevent sound Makefile from running. diff -u --recursive --new-file v2.1.20/linux/scripts/mkdep.c linux/scripts/mkdep.c --- v2.1.20/linux/scripts/mkdep.c Sun Dec 22 16:38:16 1996 +++ linux/scripts/mkdep.c Fri Jan 3 11:33:27 1997 @@ -9,7 +9,7 @@ #include char *filename, *command, __depname[256] = "\n\t@touch "; -int needsconfig, hasconfig, hasdep; +int needsconfig, hasconfig, hasmodules, hasdep; #define depname (__depname+9) @@ -26,8 +26,11 @@ int plen; struct path_struct *path = path_array+type; - if (len == 14 && !memcmp(name, "linux/config.h", len)) - hasconfig = 1; + if (len == 14) + if (!memcmp(name, "linux/config.h", len)) + hasconfig = 1; + else if (!memcmp(name, "linux/module.h", len)) + hasmodules = 1; plen = path->len; memcpy(path->buffer+plen, name, len); @@ -287,9 +290,9 @@ command = ""; } } - needsconfig = hasconfig = hasdep = 0; + needsconfig = hasconfig = hasmodules = hasdep = 0; do_depend(); - if (hasconfig && !needsconfig) + if (hasconfig && !hasmodules && !needsconfig) fprintf(stderr, "%s doesn't need config\n", filename); } return 0; diff -u --recursive --new-file v2.1.20/linux/scripts/tkgen.c linux/scripts/tkgen.c --- v2.1.20/linux/scripts/tkgen.c Thu Jun 6 13:30:41 1996 +++ linux/scripts/tkgen.c Fri Jan 3 11:33:27 1997 @@ -978,6 +978,7 @@ printf("\tputs $autocfg \"/*\"\n"); printf("\tputs $autocfg \" * Automatically generated C config: don't edit\"\n"); printf("\tputs $autocfg \" */\"\n"); + printf("\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n"); for(cfg = scfg; cfg != NULL; cfg = cfg->next) { switch (cfg->tok)