Commit 38da6b16 authored by Linus Torvalds's avatar Linus Torvalds

[PATCH] Linux-0.96c (July 4, 1992)

Ext filesystem support! The VFS layer switchover was successful.
Ext support is a more FFS-like filesystem, although still quite heavily
influenced by my original Minix filesystem.  But it allows much bigger
filesystems (minixfs was limited to 64MB) and many more files (minixfs
had a 16-bit inode number).

Named pipes by Paul Hargrove (using the regular pipe code for actual IO).

[original announcement below]

0.96c is actually what I called patch3 earlier this week, but as the new
features were pretty big and the cdiff's are probably going to be bigger
than the normal patches, I decided I might as well make it a totally new
minor release and make a bootimage and complete source available.

0.96c contains:
 - bugfixes (tty, console driver, pty's, sockets)
 - fifo's (names pipes - Paul Hargrove & editing by me)
 - the alpha extended filesystem (Remy Card)
 - st_blocks implemented (ie du, ls give reasonable if not exact values
   for disk-space used)
 - Makefile cleanups and warnings at compile-time removed

Note that while the extended filesystem code is there, and this kernel
successfully mounts and uses the new filesystem (with long filenames and
>64MB partitions), it's still under testing: I haven't made the mkefs
program available, and the extended filesystem features shouldn't be
used for other than testing right now.

Some of the changes are just cleanups: most of the warnings when
compiling the new kernel should be gone (not counting the scsi code
which is still the old non-cleaned-up version), and the make'ing of the
kernel is more logical now.

The bugfixes include the corrected console.c driver, the socket
corrections (without which X sometimes locks up), some pty semantics
corrections (although I'm still not certain it's correct) and some
editing in the general tty driver (including fixing the bug introduced
in 0.96b.pl2 that caused a reboot with uninitialized tty devices).

While the extended filesystem support isn't "official" yet, I can
happily report that my limited testing hasn't found any problems with
long filenames etc.  It still needs a fsck program, but 1.0 looks like a
real possibility soon.

                Linus
parent fdfbbb35
......@@ -41,16 +41,11 @@ KEYBOARD = -DKBD_FINNISH -DKBDFLAGS=0
MATH_EMULATION = -DKERNEL_MATH_EMULATION
#
# uncomment this line if you are using gcc-1.40
#
#GCC_OPT = -fcombine-regs -fstrength-reduce
#
# standard CFLAGS
#
CFLAGS =-Wall -O6 -fomit-frame-pointer $(GCC_OPT)
CFLAGS =-Wall -O6 -fomit-frame-pointer
#
# if you want the ram-disk device, define this to be the
......@@ -64,33 +59,37 @@ LD86 =ld86 -0
AS =as
LD =ld
#LDFLAGS =-s -x -M
LDFLAGS = -M
CC =gcc $(RAMDISK)
MAKE =make CFLAGS="$(CFLAGS)"
CPP =cpp -nostdinc -Iinclude
HOSTCC =gcc -static
CC =gcc -nostdinc -I$(KERNELHDRS)
MAKE =make
CPP =$(CC) -E
AR =ar
ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o
FILESYSTEMS =fs/minix/minix.o
FILESYSTEMS =fs/minix/minix.o fs/ext/ext.o
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
kernel/blk_drv/scsi/scsi.a
MATH =kernel/math/math.a
LIBS =lib/lib.a
SUBDIRS =kernel mm fs net lib
KERNELHDRS =/usr/src/linux/include
.c.s:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -S -o $*.s $<
$(CC) $(CFLAGS) -S $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -c -o $*.o $<
$(CC) $(CFLAGS) -c -o $*.o $<
all: Version Image
subdirs: dummy
for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
Version:
@./makever.sh
@echo \#define UTS_RELEASE \"0.96b.pl2-`cat .version`\" > include/linux/config_rel.h
@echo \#define UTS_RELEASE \"0.96c-`cat .version`\" > include/linux/config_rel.h
@echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h
touch include/linux/config.h
......@@ -105,50 +104,19 @@ disk: Image
dd bs=8192 if=Image of=/dev/PS0
tools/build: tools/build.c
$(CC) -static $(CFLAGS) \
$(HOSTCC) $(CFLAGS) \
-o tools/build tools/build.c
boot/head.o: boot/head.s
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(FILESYSTEMS) $(DRIVERS) $(MATH) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(FILESYSTEMS) \
$(DRIVERS) \
$(MATH) \
$(LIBS) \
-o tools/system > System.map
kernel/math/math.a: dummy
(cd kernel/math; $(MAKE) MATH_EMULATION="$(MATH_EMULATION)")
kernel/blk_drv/blk_drv.a: dummy
(cd kernel/blk_drv; $(MAKE))
kernel/blk_drv/scsi/scsi.a: dummy
(cd kernel/blk_drv/scsi; $(MAKE))
kernel/chr_drv/chr_drv.a: dummy
(cd kernel/chr_drv; $(MAKE) KEYBOARD="$(KEYBOARD)")
kernel/kernel.o: dummy
(cd kernel; $(MAKE))
mm/mm.o: dummy
(cd mm; $(MAKE))
fs/fs.o: dummy
(cd fs; $(MAKE))
net/net.o: dummy
(cd net; $(MAKE))
fs/minix/minix.o: dummy
(cd fs/minix; $(MAKE))
lib/lib.a: dummy
(cd lib; $(MAKE))
tools/system: boot/head.o init/main.o subdirs
$(LD) $(LDFLAGS) -M boot/head.o init/main.o \
$(ARCHIVES) \
$(FILESYSTEMS) \
$(DRIVERS) \
$(MATH) \
$(LIBS) \
-o tools/system > System.map
boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
......@@ -168,33 +136,28 @@ clean:
rm -f Image System.map tmp_make core boot/bootsect boot/setup \
boot/bootsect.s boot/setup.s init/main.s
rm -f init/*.o tools/system tools/build boot/*.o
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
(cd net;make clean)
for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
backup: clean
(cd .. ; tar cf - linux | compress - > backup.Z)
cd .. ; tar cf - linux | compress - > backup.Z
sync
dep:
depend dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
(for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
(cd fs; make dep)
(cd kernel; make dep)
(cd mm; make dep)
(cd net;make dep)
(cd lib; make dep)
for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
dummy:
### Dependencies:
init/main.o : init/main.c include/stddef.h include/stdarg.h include/fcntl.h include/sys/types.h \
include/time.h include/asm/system.h include/asm/io.h include/linux/config.h \
include/linux/config_rel.h include/linux/config_ver.h include/linux/config.dist.h \
include/linux/sched.h include/linux/head.h include/linux/fs.h include/sys/dirent.h \
include/limits.h include/sys/vfs.h include/linux/mm.h include/linux/kernel.h \
include/signal.h include/sys/param.h include/sys/time.h include/sys/resource.h \
include/linux/tty.h include/termios.h include/linux/unistd.h
init/main.o : init/main.c /usr/src/linux/include/stddef.h /usr/src/linux/include/stdarg.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/asm/system.h \
/usr/src/linux/include/asm/io.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/config.h \
/usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
/usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
/usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
/usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
/usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
/usr/src/linux/include/sys/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
/usr/src/linux/include/termios.h /usr/src/linux/include/linux/unistd.h
This diff is collapsed.
......@@ -58,6 +58,14 @@ static void sync_buffers(int dev)
int sys_sync(void)
{
int i;
for (i=0 ; i<NR_SUPER ; i++)
if (super_block[i].s_dev
&& super_block[i].s_op
&& super_block[i].s_op->write_super
&& super_block[i].s_dirt)
super_block[i].s_op->write_super(&super_block[i]);
sync_inodes(); /* write out inodes into buffers */
sync_buffers(0);
return 0;
......@@ -65,6 +73,11 @@ int sys_sync(void)
int sync_dev(int dev)
{
struct super_block * sb;
if (sb = get_super (dev))
if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
sb->s_op->write_super (sb);
sync_buffers(dev);
sync_inodes();
sync_buffers(dev);
......
......@@ -19,12 +19,12 @@
#include <signal.h>
#include <errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <sys/ptrace.h>
#include <a.out.h>
#include <fcntl.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......@@ -275,7 +275,7 @@ static int count(char ** argv)
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
char *tmp, *pag;
char *tmp, *pag = NULL;
int len, offset = 0;
unsigned long old_fs, new_fs;
......
#
# 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...
.c.s:
$(CC) $(CFLAGS) -S $<
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(AS) -o $*.o $<
OBJS= bitmap.o freelists.o truncate.o namei.o inode.o \
file.o dir.o symlink.o blkdev.o chrdev.o fifo.o
ext.o: $(OBJS)
$(LD) -r -o ext.o $(OBJS)
clean:
rm -f core *.o *.a tmp_make
for i in *.c;do rm -f `basename $$i .c`.s;done
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
### Dependencies:
bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
/usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
/usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
blkdev.o : blkdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
/usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
/usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
chrdev.o : chrdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
/usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
/usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h
fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \
/usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
/usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
/usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
/usr/src/linux/include/linux/stat.h
freelists.o : freelists.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
/usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
/usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
/usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
/usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
/usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
/usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
/usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h
namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
/usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
/usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h
symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
/usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
/usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
/usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
/usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
/usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h
truncate.o : truncate.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
/usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
/usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
/*
* linux/fs/ext/bitmap.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/bitmap.c
*
* (C) 1991 Linus Torvalds
*/
/* bitmap.c contains the code that handles the inode and block bitmaps */
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#ifdef EXTFS_BITMAP
#define clear_block(addr) \
__asm__("cld\n\t" \
"rep\n\t" \
"stosl" \
::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
#define set_bit(nr,addr) ({\
char res; \
__asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
"=q" (res):"r" (nr),"m" (*(addr))); \
res;})
#define clear_bit(nr,addr) ({\
char res; \
__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
"=q" (res):"r" (nr),"m" (*(addr))); \
res;})
#define find_first_zero(addr) ({ \
int __res; \
__asm__("cld\n" \
"1:\tlodsl\n\t" \
"notl %%eax\n\t" \
"bsfl %%eax,%%edx\n\t" \
"jne 2f\n\t" \
"addl $32,%%ecx\n\t" \
"cmpl $8192,%%ecx\n\t" \
"jl 1b\n\t" \
"xorl %%edx,%%edx\n" \
"2:\taddl %%edx,%%ecx" \
:"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
__res;})
static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
unsigned numbits)
{
unsigned i, j, end, sum = 0;
struct buffer_head *bh;
for (i=0; (i<numblocks) && numbits; i++) {
if (!(bh=map[i]))
return(0);
if (numbits >= (8*BLOCK_SIZE)) {
end = BLOCK_SIZE;
numbits -= 8*BLOCK_SIZE;
} else {
int tmp;
end = numbits >> 3;
numbits &= 0x7;
tmp = bh->b_data[end] & ((1<<numbits)-1);
sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
numbits = 0;
}
for (j=0; j<end; j++)
sum += nibblemap[bh->b_data[j] & 0xf]
+ nibblemap[(bh->b_data[j]>>4)&0xf];
}
return(sum);
}
int ext_free_block(int dev, int block)
{
struct super_block * sb;
struct buffer_head * bh;
unsigned int bit,zone;
if (!(sb = get_super(dev)))
panic("trying to free block on nonexistent device");
if (block < sb->s_firstdatazone || block >= sb->s_nzones)
panic("trying to free block not in datazone");
bh = get_hash_table(dev,block);
if (bh) {
if (bh->b_count > 1) {
brelse(bh);
return 0;
}
bh->b_dirt=0;
bh->b_uptodate=0;
if (bh->b_count)
brelse(bh);
}
zone = block - sb->s_firstdatazone + 1;
bit = zone & 8191;
zone >>= 13;
bh = sb->s_zmap[zone];
if (clear_bit(bit,bh->b_data))
printk("free_block (%04x:%d): bit already cleared\n",dev,block);
bh->b_dirt = 1;
return 1;
}
int ext_new_block(int dev)
{
struct buffer_head * bh;
struct super_block * sb;
int i,j;
if (!(sb = get_super(dev)))
panic("trying to get new block from nonexistant device");
j = 8192;
for (i=0 ; i<8 ; i++)
if (bh=sb->s_zmap[i])
if ((j=find_first_zero(bh->b_data))<8192)
break;
if (i>=8 || !bh || j>=8192)
return 0;
if (set_bit(j,bh->b_data))
panic("new_block: bit already set");
bh->b_dirt = 1;
j += i*8192 + sb->s_firstdatazone-1;
if (j >= sb->s_nzones)
return 0;
if (!(bh=getblk(dev,j)))
panic("new_block: cannot get block");
if (bh->b_count != 1)
panic("new block: count is != 1");
clear_block(bh->b_data);
bh->b_uptodate = 1;
bh->b_dirt = 1;
brelse(bh);
#ifdef EXTFS_DEBUG
printk("ext_new_block: allocating block %d\n", j);
#endif
return j;
}
unsigned long ext_count_free_blocks(struct super_block *sb)
{
return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones))
<< sb->s_log_zone_size;
}
void ext_free_inode(struct inode * inode)
{
struct buffer_head * bh;
if (!inode)
return;
if (!inode->i_dev) {
memset(inode,0,sizeof(*inode));
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 nonexistent device\n");
return;
}
if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
return;
}
if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
printk("free_inode: nonexistent imap in superblock\n");
return;
}
if (clear_bit(inode->i_ino&8191,bh->b_data))
printk("free_inode: bit already cleared.\n\r");
bh->b_dirt = 1;
memset(inode,0,sizeof(*inode));
}
struct inode * ext_new_inode(int dev)
{
struct inode * inode;
struct buffer_head * bh;
int i,j;
if (!(inode=get_empty_inode()))
return NULL;
if (!(inode->i_sb = get_super(dev))) {
printk("new_inode: unknown device\n");
iput(inode);
return NULL;
}
j = 8192;
for (i=0 ; i<8 ; i++)
if (bh=inode->i_sb->s_imap[i])
if ((j=find_first_zero(bh->b_data))<8192)
break;
if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
iput(inode);
return NULL;
}
if (set_bit(j,bh->b_data)) { /* shouldn't happen */
printk("new_inode: bit already set");
iput(inode);
return NULL;
}
bh->b_dirt = 1;
inode->i_count = 1;
inode->i_nlink = 1;
inode->i_dev = dev;
inode->i_uid = current->euid;
inode->i_gid = current->egid;
inode->i_dirt = 1;
inode->i_ino = j + i*8192;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_op = NULL;
#ifdef EXTFS_DEBUG
printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
#endif
return inode;
}
unsigned long ext_count_free_inodes(struct super_block *sb)
{
return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes);
}
#endif
/*
* linux/fs/ext/blkdev.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/blkdev.c
*
* (C) 1991 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <errno.h>
/*
* Called every time an ext block special file is opened
*/
static int blkdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i < MAX_BLKDEV) {
filp->f_op = blkdev_fops[i];
if (filp->f_op && filp->f_op->open)
return filp->f_op->open(inode,filp);
}
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_blk_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
blkdev_open, /* open */
NULL, /* release */
};
struct inode_operations ext_blkdev_inode_operations = {
&def_blk_fops, /* 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 */
ext_bmap, /* bmap */
ext_truncate /* truncate */
};
/*
* linux/fs/ext/chrdev.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/chrdev.c
*
* (C) 1991 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <errno.h>
/*
* Called every time an ext character special file is opened
*/
static int chrdev_open(struct inode * inode, struct file * filp)
{
int i;
i = MAJOR(inode->i_rdev);
if (i < MAX_CHRDEV) {
filp->f_op = chrdev_fops[i];
if (filp->f_op && filp->f_op->open)
return filp->f_op->open(inode,filp);
}
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the special file...
*/
static struct file_operations def_chr_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
chrdev_open, /* open */
NULL, /* release */
};
struct inode_operations ext_chrdev_inode_operations = {
&def_chr_fops, /* 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 */
ext_bmap, /* bmap */
ext_truncate /* truncate */
};
/*
* linux/fs/ext/dir.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/dir.c
*
* (C) 1991 Linus Torvalds
*
* ext directory handling functions
*/
#include <errno.h>
#include <asm/segment.h>
#include <linux/fs.h>
#include <linux/ext_fs.h>
#include <linux/stat.h>
static int ext_readdir(struct inode *, struct file *, struct dirent *, int);
static struct file_operations ext_dir_operations = {
NULL, /* lseek - default */
NULL, /* read */
NULL, /* write - bad */
ext_readdir, /* readdir */
NULL, /* select - default */
NULL, /* ioctl - default */
NULL, /* no special open code */
NULL /* no special release code */
};
/*
* 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 */
ext_bmap, /* bmap */
ext_truncate /* truncate */
};
static int ext_readdir(struct inode * inode, struct file * filp,
struct dirent * dirent, int count)
{
unsigned int block,offset,i;
char c;
struct buffer_head * bh;
struct ext_dir_entry * de;
if (!inode || !S_ISDIR(inode->i_mode))
return -EBADF;
/* if (filp->f_pos & (sizeof (struct ext_dir_entry) - 1))
return -EBADF; */
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023;
block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
if (!block || !(bh = bread(inode->i_dev,block))) {
filp->f_pos += 1024-offset;
continue;
}
de = (struct ext_dir_entry *) (offset + bh->b_data);
while (offset < 1024 && filp->f_pos < inode->i_size) {
offset += de->rec_len;
filp->f_pos += de->rec_len;
if (de->inode) {
for (i = 0; i < de->name_len; i++)
if (c = de->name[i])
put_fs_byte(c,i+dirent->d_name);
else
break;
if (i) {
put_fs_long(de->inode,&dirent->d_ino);
put_fs_byte(0,i+dirent->d_name);
put_fs_word(i,&dirent->d_reclen);
brelse(bh);
return i;
}
}
/* de++; */
de = (struct ext_dir_entry *) ((char *) de + de->rec_len);
}
brelse(bh);
}
return 0;
}
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove.
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations ext_fifo_inode_operations = {
&def_fifo_fops, /* 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 */
NULL, /* bmap */
NULL /* truncate */
};
/*
* linux/fs/ext/file.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/file.c
*
* (C) 1991 Linus Torvalds
*
* ext regular file handling primitives
*/
#include <errno.h>
#include <sys/dirent.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#define NBUF 16
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#include <linux/fs.h>
#include <linux/ext_fs.h>
static int ext_file_read(struct inode *, struct file *, char *, int);
static int ext_file_write(struct inode *, struct file *, char *, int);
/*
* 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 */
NULL, /* no special open is needed */
NULL /* release */
};
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 */
ext_bmap, /* bmap */
ext_truncate /* truncate */
};
static inline void wait_on_buffer(struct buffer_head * bh)
{
cli();
while (bh->b_lock)
sleep_on(&bh->b_wait);
sti();
}
static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int read,left,chars,nr;
int block, blocks, offset;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * buflist[NBUF];
if (!inode) {
printk("ext_file_read: inode = NULL\n");
return -EINVAL;
}
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
printk("ext_file_read: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
if (filp->f_pos > inode->i_size)
left = 0;
else
left = inode->i_size - filp->f_pos;
if (left > count)
left = count;
if (left <= 0)
return 0;
read = 0;
block = filp->f_pos >> BLOCK_SIZE_BITS;
offset = filp->f_pos & (BLOCK_SIZE-1);
blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
bhb = bhe = buflist;
do {
if (blocks) {
--blocks;
if (nr = ext_bmap(inode,block++)) {
*bhb = getblk(inode->i_dev,nr);
if (!(*bhb)->b_uptodate)
ll_rw_block(READ,*bhb);
} else
*bhb = NULL;
if (++bhb == &buflist[NBUF])
bhb = buflist;
if (bhb != bhe)
continue;
}
if (*bhe) {
wait_on_buffer(*bhe);
if (!(*bhe)->b_uptodate) {
do {
brelse(*bhe);
if (++bhe == &buflist[NBUF])
bhe = buflist;
} while (bhe != bhb);
break;
}
}
if (left < BLOCK_SIZE - offset)
chars = left;
else
chars = BLOCK_SIZE - offset;
filp->f_pos += chars;
left -= chars;
read += chars;
if (*bhe) {
memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
brelse(*bhe);
buf += chars;
} else {
while (chars-->0)
put_fs_byte(0,buf++);
}
offset = 0;
if (++bhe == &buflist[NBUF])
bhe = buflist;
} while (left > 0);
if (!read)
return -EIO;
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
return read;
}
static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count)
{
off_t pos;
int written,block,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) {
if (!(block = ext_create_block(inode,pos/BLOCK_SIZE))) {
if (!written)
written = -ENOSPC;
break;
}
c = BLOCK_SIZE - (pos % BLOCK_SIZE);
if (c > count-written)
c = count-written;
if (c == BLOCK_SIZE)
bh = getblk(inode->i_dev, block);
else
bh = bread(inode->i_dev,block);
if (!bh) {
if (!written)
written = -EIO;
break;
}
p = (pos % BLOCK_SIZE) + bh->b_data;
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
written += c;
memcpy_fromfs(p,buf,c);
buf += c;
bh->b_uptodate = 1;
bh->b_dirt = 1;
brelse(bh);
}
inode->i_mtime = CURRENT_TIME;
inode->i_ctime = CURRENT_TIME;
filp->f_pos = pos;
inode->i_dirt = 1;
return written;
}
/*
* linux/fs/ext/freelists.c
*
* (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->s_zmap[0] and the block header is stored in s->s_zmap[1]. s_zmap[2]
contains the count of free blocks.
Currently, it is a hack to allow this kind of management with the super_block
structure.
Perhaps, in the future, we may have to change the super_block structure to
include dedicated fields.
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->s_imap[0] and the header
of the block containing the inode is stored in s->s_imap[1]. s_imap[2] contains
the count of free inodes.
*/
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#ifdef EXTFS_FREELIST
#define clear_block(addr) \
__asm__("cld\n\t" \
"rep\n\t" \
"stosl" \
::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
int ext_free_block(int dev, int block)
{
struct super_block * sb;
struct buffer_head * bh;
struct ext_free_block * efb;
if (!(sb = get_super(dev)))
panic("trying to free block on nonexistent device");
lock_super (sb);
if (block < sb->s_firstdatazone || block >= sb->s_nzones)
panic("trying to free block not in datazone");
bh = get_hash_table(dev,block);
if (bh) {
if (bh->b_count > 1) {
brelse(bh);
free_super (sb);
return 0;
}
bh->b_dirt=0;
bh->b_uptodate=0;
if (bh->b_count)
brelse(bh);
}
efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
if (efb->count == 254) {
#ifdef EXTFS_DEBUG
printk("ext_free_block: block full, skipping to %d\n", block);
#endif
brelse (sb->s_zmap[1]);
if (!(sb->s_zmap[1] = bread (dev, block)))
panic ("ext_free_block: unable to read block to free\n");
efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
efb->next = (unsigned long) sb->s_zmap[0];
efb->count = 0;
sb->s_zmap[0] = (struct buffer_head *) block;
} else {
efb->free[efb->count++] = block;
}
sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) + 1);
sb->s_dirt = 1;
sb->s_zmap[1]->b_dirt = 1;
free_super (sb);
return 1;
}
int ext_new_block(int dev)
{
struct buffer_head * bh;
struct super_block * sb;
struct ext_free_block * efb;
int /* i, */ j;
if (!(sb = get_super(dev)))
panic("trying to get new block from nonexistant device");
if (!sb->s_zmap[1])
return 0;
lock_super (sb);
efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
if (efb->count) {
j = efb->free[--efb->count];
sb->s_zmap[1]->b_dirt = 1;
} else {
#ifdef EXTFS_DEBUG
printk("ext_new_block: block empty, skipping to %d\n", efb->next);
#endif
j = (unsigned long) sb->s_zmap[0];
sb->s_zmap[0] = (struct buffer_head *) efb->next;
brelse (sb->s_zmap[1]);
if (!sb->s_zmap[0]) {
sb->s_zmap[1] = NULL;
} else {
if (!(sb->s_zmap[1] = bread (dev, (unsigned long) sb->s_zmap[0])))
panic ("ext_new_block: unable to read next free block\n");
}
}
if (j < sb->s_firstdatazone || j > sb->s_nzones) {
printk ("ext_new_block: blk = %d\n", j);
panic ("allocating block not in data zone\n");
}
sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) - 1);
sb->s_dirt = 1;
if (!(bh=getblk(dev,j)))
panic("new_block: cannot get block");
if (bh->b_count != 1)
panic("new block: count is != 1");
clear_block(bh->b_data);
bh->b_uptodate = 1;
bh->b_dirt = 1;
brelse(bh);
#ifdef EXTFS_DEBUG
printk("ext_new_block: allocating block %d\n", j);
#endif
free_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->s_zmap[1])
count = 0;
else {
efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
count = efb->count + 1;
block = efb->next;
while (block) {
if (!(bh = bread (sb->s_dev, block))) {
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",
(unsigned long) sb->s_zmap[2], count);
free_super (sb);
return count;
#else
return (unsigned long) sb->s_zmap[2];
#endif
}
void ext_free_inode(struct inode * inode)
{
struct buffer_head * bh;
struct ext_free_inode * efi;
unsigned long block;
if (!inode)
return;
if (!inode->i_dev) {
memset(inode,0,sizeof(*inode));
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 nonexistent device\n");
return;
}
lock_super (inode->i_sb);
if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
free_super (inode->i_sb);
return;
}
efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
(((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
if (efi->count == 14) {
#ifdef EXTFS_DEBUG
printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino);
#endif
brelse (inode->i_sb->s_imap[1]);
block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK;
if (!(bh = bread(inode->i_dev, block)))
panic("ext_free_inode: unable to read inode block\n");
efi = ((struct ext_free_inode *) bh->b_data) +
(inode->i_ino - 1) % EXT_INODES_PER_BLOCK;
efi->next = (unsigned long) inode->i_sb->s_imap[0];
efi->count = 0;
inode->i_sb->s_imap[0] = (struct buffer_head *) inode->i_ino;
inode->i_sb->s_imap[1] = bh;
} else {
efi->free[efi->count++] = inode->i_ino;
}
inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) + 1);
inode->i_sb->s_dirt = 1;
inode->i_sb->s_imap[1]->b_dirt = 1;
free_super (inode->i_sb);
memset(inode,0,sizeof(*inode));
}
struct inode * ext_new_inode(int dev)
{
struct inode * inode;
struct ext_free_inode * efi;
unsigned long block;
int /* i, */ j;
if (!(inode=get_empty_inode()))
return NULL;
if (!(inode->i_sb = get_super(dev))) {
printk("new_inode: unknown device\n");
iput(inode);
return NULL;
}
if (!inode->i_sb->s_imap[1])
return 0;
lock_super (inode->i_sb);
efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
(((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
if (efi->count) {
j = efi->free[--efi->count];
inode->i_sb->s_imap[1]->b_dirt = 1;
} else {
#ifdef EXTFS_DEBUG
printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
#endif
j = (unsigned long) inode->i_sb->s_imap[0];
if (efi->next < 1 || efi->next > inode->i_sb->s_ninodes) {
printk ("efi->next = %d\n", efi->next);
panic ("ext_new_inode: bad inode number in free list\n");
}
inode->i_sb->s_imap[0] = (struct buffer_head *) efi->next;
block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK;
brelse (inode->i_sb->s_imap[1]);
if (!inode->i_sb->s_imap[0]) {
inode->i_sb->s_imap[1] = NULL;
} else {
if (!(inode->i_sb->s_imap[1] = bread (dev, block)))
panic ("ext_new_inode: unable to read next free inode block\n");
}
}
inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) - 1);
inode->i_sb->s_dirt = 1;
inode->i_count = 1;
inode->i_nlink = 1;
inode->i_dev = dev;
inode->i_uid = current->euid;
inode->i_gid = current->egid;
inode->i_dirt = 1;
inode->i_ino = j;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_op = NULL;
#ifdef EXTFS_DEBUG
printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
#endif
free_super (inode->i_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->s_imap[1])
count = 0;
else {
efi = ((struct ext_free_inode *) sb->s_imap[1]->b_data) +
((((unsigned long) sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK);
count = efi->count + 1;
ino = efi->next;
while (ino) {
if (ino < 1 || ino > sb->s_ninodes) {
printk ("s_imap[0] = %d, ino = %d\n",
(int) sb->s_imap[0],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))) {
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",
(unsigned long) sb->s_imap[2], count);
free_super (sb);
return count;
#else
return (unsigned long) sb->s_imap[2];
#endif
}
#endif
/*
* linux/fs/ext/inode.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/inode.c
*
* (C) 1991 Linus Torvalds
*/
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/segment.h>
int sync_dev(int dev);
void ext_put_inode(struct inode *inode)
{
inode->i_size = 0;
ext_truncate(inode);
ext_free_inode(inode);
}
void ext_put_super(struct super_block *sb)
{
#ifdef EXTFS_BITMAP
int i;
#endif
lock_super(sb);
sb->s_dev = 0;
#ifdef EXTFS_BITMAP
for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++)
brelse(sb->s_imap[i]);
for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++)
brelse(sb->s_zmap[i]);
#endif
#ifdef EXTFS_FREELIST
if (sb->s_imap[1])
brelse (sb->s_imap[1]);
if (sb->s_zmap[1])
brelse (sb->s_zmap[1]);
#endif
free_super(sb);
return;
}
static struct super_operations ext_sops = {
ext_read_inode,
ext_write_inode,
ext_put_inode,
ext_put_super,
ext_write_super,
ext_statfs
};
struct super_block *ext_read_super(struct super_block *s,void *data)
{
struct buffer_head *bh;
struct ext_super_block *es;
int dev=s->s_dev,block;
#ifdef EXTFS_BITMAP
int i;
#endif
lock_super(s);
if (!(bh = bread(dev,1))) {
s->s_dev=0;
free_super(s);
printk("bread failed\n");
return NULL;
}
/* *((struct ext_super_block *) s) =
*((struct ext_super_block *) bh->b_data); */
es = (struct ext_super_block *) bh->b_data;
s->s_ninodes = es->s_ninodes;
s->s_nzones = es->s_nzones;
#ifdef EXTFS_BITMAP
s->s_imap_blocks = es->s_imap_blocks;
s->s_zmap_blocks = es->s_zmap_blocks;
#endif
s->s_firstdatazone = es->s_firstdatazone;
s->s_log_zone_size = es->s_log_zone_size;
s->s_max_size = es->s_max_size;
s->s_magic = es->s_magic;
#ifdef EXTFS_FREELIST
s->s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
s->s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
s->s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
s->s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
#endif
brelse(bh);
if (s->s_magic != EXT_SUPER_MAGIC) {
s->s_dev = 0;
free_super(s);
printk("magic match failed\n");
return NULL;
}
#ifdef EXTFS_BITMAP
for (i=0;i < EXT_I_MAP_SLOTS;i++)
s->s_imap[i] = NULL;
for (i=0;i < EXT_Z_MAP_SLOTS;i++)
s->s_zmap[i] = NULL;
block=2;
for (i=0 ; i < s->s_imap_blocks ; i++)
if (s->s_imap[i]=bread(dev,block))
block++;
else
break;
for (i=0 ; i < s->s_zmap_blocks ; i++)
if (s->s_zmap[i]=bread(dev,block))
block++;
else
break;
if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
for(i=0;i<EXT_I_MAP_SLOTS;i++)
brelse(s->s_imap[i]);
for(i=0;i<EXT_Z_MAP_SLOTS;i++)
brelse(s->s_zmap[i]);
s->s_dev=0;
free_super(s);
printk("block failed\n");
return NULL;
}
s->s_imap[0]->b_data[0] |= 1;
s->s_zmap[0]->b_data[0] |= 1;
#endif
#ifdef EXTFS_FREELIST
if (!s->s_zmap[0])
s->s_zmap[1] = NULL;
else
if (!(s->s_zmap[1] = bread (dev, (unsigned long) s->s_zmap[0]))) {
printk ("ext_read_super: unable to read first free block\n");
s->s_dev = 0;
free_super(s);
return NULL;
}
if (!s->s_imap[0])
s->s_imap[1] = NULL;
else {
block = 2 + (((unsigned long) s->s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
if (!(s->s_imap[1] = bread (dev, block))) {
printk ("ext_read_super: unable to read first free inode block\n");
brelse(s->s_zmap[1]);
s->s_dev = 0;
free_super (s);
return NULL;
}
}
#endif
free_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(dev,EXT_ROOT_INO))) {
s->s_dev=0;
printk("get root inode failed\n");
return NULL;
}
return s;
}
void ext_write_super (struct super_block *sb)
{
#ifdef EXTFS_FREELIST
struct buffer_head * bh;
struct ext_super_block * es;
#ifdef EXTFS_DEBUG
printk ("ext_write_super called\n");
#endif
if (!(bh = bread (sb->s_dev, 1))) {
printk ("ext_write_super: bread failed\n");
return;
}
es = (struct ext_super_block *) bh->b_data;
es->s_firstfreeblock = (unsigned long) sb->s_zmap[0];
es->s_freeblockscount = (unsigned long) sb->s_zmap[2];
es->s_firstfreeinode = (unsigned long) sb->s_imap[0];
es->s_freeinodescount = (unsigned long) sb->s_imap[2];
bh->b_dirt = 1;
brelse (bh);
sb->s_dirt = 0;
#endif
}
void ext_statfs (struct super_block *sb, struct statfs *buf)
{
long tmp;
put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
put_fs_long(1024, &buf->f_bsize);
put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks);
tmp = ext_count_free_blocks(sb);
put_fs_long(tmp, &buf->f_bfree);
put_fs_long(tmp, &buf->f_bavail);
put_fs_long(sb->s_ninodes, &buf->f_files);
put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
/* Don't know what value to put in buf->f_fsid */
}
static int _ext_bmap(struct inode * inode,int block,int create)
{
struct buffer_head * bh;
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) {
if (create && !inode->i_data[block])
if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
inode->i_ctime=CURRENT_TIME;
inode->i_dirt=1;
}
return inode->i_data[block];
}
block -= 9;
if (block<256) {
if (create && !inode->i_data[9])
if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
if (!inode->i_data[9])
return 0;
if (!(bh = bread(inode->i_dev,inode->i_data[9])))
return 0;
i = ((unsigned long *) (bh->b_data))[block];
if (create && !i)
if (i=ext_new_block(inode->i_dev)) {
((unsigned long *) (bh->b_data))[block]=i;
bh->b_dirt=1;
}
brelse(bh);
return i;
}
block -= 256;
if (block<256*256) {
if (create && !inode->i_data[10])
if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
if (!inode->i_data[10])
return 0;
if (!(bh=bread(inode->i_dev,inode->i_data[10])))
return 0;
i = ((unsigned long *)bh->b_data)[block>>8];
if (create && !i)
if (i=ext_new_block(inode->i_dev)) {
((unsigned long *) (bh->b_data))[block>>8]=i;
bh->b_dirt=1;
}
brelse(bh);
if (!i)
return 0;
if (!(bh=bread(inode->i_dev,i)))
return 0;
i = ((unsigned long *)bh->b_data)[block&255];
if (create && !i)
if (i=ext_new_block(inode->i_dev)) {
((unsigned long *) (bh->b_data))[block&255]=i;
bh->b_dirt=1;
}
brelse(bh);
return i;
}
printk("ext_bmap: triple indirection not yet implemented\n");
return 0;
}
int ext_bmap(struct inode * inode,int block)
{
return _ext_bmap(inode,block,0);
}
int ext_create_block(struct inode * inode, int block)
{
return _ext_bmap(inode,block,1);
}
void ext_read_inode(struct inode * inode)
{
struct buffer_head * bh;
struct ext_inode * raw_inode;
int block;
#ifdef EXTFS_BITMAP
block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
#ifdef EXTFS_FREELIST
block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
if (!(bh=bread(inode->i_dev,block)))
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;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = raw_inode->i_zone[0];
else for (block = 0; block < 12; block++)
inode->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 = &ext_chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &ext_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &ext_fifo_inode_operations;
inode->i_size = 0;
inode->i_pipe = 1;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
}
void ext_write_inode(struct inode * inode)
{
struct buffer_head * bh;
struct ext_inode * raw_inode;
int block;
#ifdef EXTFS_BITMAP
block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
#ifdef EXTFS_FREELIST
block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
if (!(bh=bread(inode->i_dev,block)))
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] = inode->i_rdev;
else for (block = 0; block < 12; block++)
raw_inode->i_zone[block] = inode->i_data[block];
bh->b_dirt=1;
inode->i_dirt=0;
brelse(bh);
}
This diff is collapsed.
/*
* linux/fs/ext/symlink.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/symlink.c
*
* (C) 1991 Linus Torvalds
*
* ext symlink handling code
*/
#include <errno.h>
#include <asm/segment.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/ext_fs.h>
#include <linux/stat.h>
static int ext_readlink(struct inode *, char *, int);
static struct inode * ext_follow_link(struct inode *, 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, /* bmap */
NULL /* truncate */
};
static struct inode * ext_follow_link(struct inode * dir, struct inode * inode)
{
unsigned short fs;
struct buffer_head * bh;
if (!dir) {
dir = current->root;
dir->i_count++;
}
if (!inode) {
iput(dir);
return NULL;
}
if (!S_ISLNK(inode->i_mode)) {
iput(dir);
return inode;
}
__asm__("mov %%fs,%0":"=r" (fs));
if ((current->link_count > 5) || !inode->i_data[0] ||
!(bh = bread(inode->i_dev, inode->i_data[0]))) {
iput(dir);
iput(inode);
return NULL;
}
iput(inode);
__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
current->link_count++;
inode = _namei(bh->b_data,dir,1);
current->link_count--;
__asm__("mov %0,%%fs"::"r" (fs));
brelse(bh);
return inode;
}
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;
if (inode->i_data[0])
bh = bread(inode->i_dev, inode->i_data[0]);
else
bh = NULL;
iput(inode);
if (!bh)
return 0;
i = 0;
while (i<buflen && (c = bh->b_data[i])) {
i++;
put_fs_byte(c,buffer++);
}
brelse(bh);
return i;
}
/*
* linux/fs/ext/truncate.c
*
* (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/truncate.c
*
* (C) 1991 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <errno.h>
/*
* 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;
int result = 0;
#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
repeat:
for (i = DIRECT_BLOCK ; i < 9 ; i++) {
if (i < DIRECT_BLOCK)
goto repeat;
if (!inode->i_data[i])
continue;
result = 1;
if (ext_free_block(inode->i_dev,inode->i_data[i]))
inode->i_data[i] = 0;
}
return result;
}
static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
{
int i;
struct buffer_head * bh = NULL;
unsigned long * ind;
int result = 0;
#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
if (*p)
bh = bread(inode->i_dev,*p);
if (!bh)
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 *) bh->b_data;
if (!*ind)
continue;
result = 1;
if (ext_free_block(inode->i_dev,*ind))
*ind = 0;
}
ind = (unsigned long *) bh->b_data;
for (i = 0; i < 256; i++)
if (*(ind++))
break;
brelse(bh);
if (i >= 256) {
result = 1;
if (ext_free_block(inode->i_dev,*p))
*p = 0;
}
return result;
}
static int trunc_dindirect(struct inode * inode)
{
int i;
struct buffer_head * bh = NULL;
unsigned long * dind;
int result = 0;
#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(256+9))>>8)
if (inode->i_data[10])
bh = bread(inode->i_dev,inode->i_data[10]);
if (!bh)
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 *) bh->b_data;
if (!*dind)
continue;
result |= trunc_indirect(inode,9+256+(i<<8),dind);
}
dind = (unsigned long *) bh->b_data;
for (i = 0; i < 256; i++)
if (*(dind++))
break;
brelse(bh);
if (i >= 256) {
result = 1;
if (ext_free_block(inode->i_dev,inode->i_data[10]))
inode->i_data[10] = 0;
}
return result;
}
void ext_truncate(struct inode * inode)
{
int flag;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
/* if (inode->i_data[7] & 0xffff0000)
printk("BAD! ext inode has 16 high bits set\n"); */
while (1) {
flag = trunc_direct(inode);
flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
flag |= trunc_dindirect(inode);
if (!flag)
break;
current->counter = 0;
schedule();
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
}
/*
* Called when a 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");
}
......@@ -5,12 +5,11 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <linux/stat.h>
#include <asm/segment.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove
*/
#include <errno.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/kernel.h>
extern struct file_operations read_pipe_fops;
extern struct file_operations write_pipe_fops;
extern struct file_operations rdwr_pipe_fops;
static int fifo_open(struct inode * inode,struct file * filp)
{
int retval = 0;
unsigned long page;
switch( filp->f_mode ) {
case 1:
/*
* O_RDONLY
* POSIX.1 says that O_NONBLOCK means return with the FIFO
* opened, even when there is no process writing the FIFO.
*/
filp->f_op = &read_pipe_fops;
PIPE_READERS(*inode)++;
if (!(filp->f_flags & O_NONBLOCK))
while (!PIPE_WRITERS(*inode)) {
if (PIPE_HEAD(*inode) != PIPE_TAIL(*inode))
break;
if (current->signal & ~current->blocked) {
retval = -ERESTARTSYS;
break;
}
interruptible_sleep_on(&PIPE_READ_WAIT(*inode));
}
if (retval)
PIPE_READERS(*inode)--;
break;
case 2:
/*
* O_WRONLY
* POSIX.1 says that O_NONBLOCK means return -1 with
* errno=ENXIO when there is no process reading the FIFO.
*/
if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
retval = -ENXIO;
break;
}
filp->f_op = &write_pipe_fops;
PIPE_WRITERS(*inode)++;
while (!PIPE_READERS(*inode)) {
if (current->signal & ~current->blocked) {
retval = -ERESTARTSYS;
break;
}
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
}
if (retval)
PIPE_WRITERS(*inode)--;
break;
case 3:
/*
* O_RDWR
* POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
* This implementation will NEVER block on a O_RDWR open, since
* the process can at least talk to itself.
*/
filp->f_op = &rdwr_pipe_fops;
PIPE_WRITERS(*inode) += 1;
PIPE_READERS(*inode) += 1;
break;
default:
retval = -EINVAL;
}
if (PIPE_WRITERS(*inode))
wake_up(&PIPE_READ_WAIT(*inode));
if (PIPE_READERS(*inode))
wake_up(&PIPE_WRITE_WAIT(*inode));
if (retval || inode->i_size)
return retval;
page = get_free_page();
if (inode->i_size) {
free_page(page);
return 0;
}
if (!page)
return -ENOMEM;
inode->i_size = page;
return 0;
}
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
* depending on the access mode of the file...
*/
struct file_operations def_fifo_fops = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
fifo_open, /* will set read or write pipe_fops */
NULL
};
......@@ -6,10 +6,10 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
struct inode inode_table[NR_INODE]={{0,},};
......@@ -100,7 +100,7 @@ void sync_inodes(void)
inode = 0+inode_table;
for(i=0 ; i<NR_INODE ; i++,inode++) {
wait_on_inode(inode);
if (inode->i_dirt && !inode->i_pipe)
if (inode->i_dirt)
write_inode(inode);
}
}
......@@ -119,27 +119,25 @@ void iput(struct inode * inode)
if (inode->i_pipe) {
wake_up(&inode->i_wait);
wake_up(&inode->i_wait2);
if (--inode->i_count)
return;
free_page(inode->i_size);
inode->i_count=0;
inode->i_dirt=0;
inode->i_pipe=0;
return;
}
if (!inode->i_dev) {
repeat:
if (inode->i_count>1) {
inode->i_count--;
return;
}
repeat:
if (inode->i_count>1) {
if (inode->i_pipe) {
free_page(inode->i_size);
inode->i_size = 0;
}
if (!inode->i_dev) {
inode->i_count--;
return;
}
if (!inode->i_nlink) {
if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode)
if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
inode->i_sb->s_op->put_inode(inode);
return;
return;
}
}
if (inode->i_dirt) {
write_inode(inode); /* we can sleep - so do again */
......@@ -190,12 +188,13 @@ struct inode * get_pipe_inode(void)
if (!(inode = get_empty_inode()))
return NULL;
if (!(inode->i_size=get_free_page())) {
if (!(inode->i_size = get_free_page())) {
inode->i_count = 0;
return NULL;
}
inode->i_count = 2; /* sum of readers/writers */
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
inode->i_pipe = 1;
return inode;
}
......
......@@ -4,9 +4,9 @@
* (C) 1991 Linus Torvalds
*/
#include <linux/string.h>
#include <errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/sched.h>
......
This diff is collapsed.
......@@ -5,8 +5,8 @@
*/
/* bitmap.c contains the code that handles the inode and block bitmaps */
#include <linux/string.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
......
......@@ -4,13 +4,13 @@
* (C) 1991 Linus Torvalds
*/
#include <errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fcntl.h>
/*
* Called every time a minix block special file is opened
......
......@@ -4,13 +4,13 @@
* (C) 1991 Linus Torvalds
*/
#include <errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fcntl.h>
/*
* Called every time a minix character special file is opened
......
/*
* linux/fs/fifo.c
*
* written by Paul H. Hargrove
*/
#include <linux/sched.h>
#include <linux/minix_fs.h>
extern struct file_operations def_fifo_fops;
struct inode_operations minix_fifo_inode_operations = {
&def_fifo_fops, /* 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 */
NULL, /* bmap */
NULL /* truncate */
};
......@@ -7,13 +7,13 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <sys/dirent.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
......
......@@ -41,6 +41,7 @@ static struct super_operations minix_sops = {
minix_write_inode,
minix_put_inode,
minix_put_super,
NULL,
minix_statfs
};
......@@ -243,6 +244,13 @@ void minix_read_inode(struct inode * inode)
inode->i_op = &minix_chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &minix_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
inode->i_size = 0;
inode->i_pipe = 1;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
}
void minix_write_inode(struct inode * inode)
......
......@@ -9,9 +9,9 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <asm/segment.h>
#include <fcntl.h>
#include <errno.h>
#include <const.h>
......@@ -266,6 +266,13 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
inode->i_op = &minix_chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &minix_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
inode->i_size = 0;
inode->i_pipe = 1;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
if (S_ISBLK(mode) || S_ISCHR(mode))
inode->i_rdev = rdev;
inode->i_mtime = inode->i_atime = CURRENT_TIME;
......
......@@ -4,13 +4,13 @@
* (C) 1991 Linus Torvalds
*/
#include <errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
#include <linux/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/fcntl.h>
/*
* Truncate has the most races in the whole filesystem: coding it is
......
......@@ -8,14 +8,15 @@
* Some corrections by tytso.
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <errno.h>
#include <const.h>
#include <asm/segment.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <fcntl.h>
#include <errno.h>
#include <const.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
struct inode * _namei(const char * filename, struct inode * base,
......@@ -277,7 +278,7 @@ int do_mknod(const char * filename, int mode, int dev)
int sys_mknod(const char * filename, int mode, int dev)
{
if (suser())
if (S_ISFIFO(mode) || suser())
return do_mknod(filename,mode,dev);
return -EPERM;
}
......
......@@ -5,12 +5,12 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
#include <sys/vfs.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
......@@ -101,6 +101,10 @@ int sys_ftruncate(unsigned int fd, unsigned int length)
return 0;
}
/* If times==NULL, set access and modification to current time,
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
int sys_utime(char * filename, struct utimbuf * times)
{
struct inode * inode;
......@@ -109,15 +113,20 @@ int sys_utime(char * filename, struct utimbuf * times)
if (!(inode=namei(filename)))
return -ENOENT;
if (times) {
if (current->euid != inode->i_uid &&
!permission(inode,MAY_WRITE)) {
if ((current->euid != inode->i_uid) && !suser()) {
iput(inode);
return -EACCES;
return -EPERM;
}
actime = get_fs_long((unsigned long *) &times->actime);
modtime = get_fs_long((unsigned long *) &times->modtime);
} else
} else {
if ((current->euid != inode->i_uid) &&
!permission(inode,MAY_WRITE)) {
iput(inode);
return -EACCES;
}
actime = modtime = CURRENT_TIME;
}
inode->i_atime = actime;
inode->i_mtime = modtime;
inode->i_dirt = 1;
......
......@@ -7,10 +7,10 @@
#include <signal.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>
#include <asm/segment.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......@@ -21,7 +21,7 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
if (!(filp->f_flags & O_NONBLOCK))
while (!PIPE_SIZE(*inode)) {
wake_up(& PIPE_WRITE_WAIT(*inode));
if (inode->i_count != 2) /* are there any writers? */
if (!PIPE_WRITERS(*inode)) /* are there any writers? */
return 0;
if (current->signal & ~current->blocked)
return -ERESTARTSYS;
......@@ -33,13 +33,12 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
chars = count;
if (chars > size)
chars = size;
count -= chars;
memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
read += chars;
size = PIPE_TAIL(*inode);
PIPE_TAIL(*inode) += chars;
PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
while (chars-->0)
put_fs_byte(((char *)inode->i_size)[size++],buf++);
count -= chars;
buf += chars;
}
wake_up(& PIPE_WRITE_WAIT(*inode));
return read?read:-EAGAIN;
......@@ -49,35 +48,44 @@ static int pipe_write(struct inode * inode, struct file * filp, char * buf, int
{
int chars, size, written = 0;
if (inode->i_count != 2) { /* no readers */
if (!PIPE_READERS(*inode)) { /* no readers */
send_sig(SIGPIPE,current,0);
return -EINTR;
return -EPIPE;
}
/* if count < PAGE_SIZE, we have to make it atomic */
if (count < PAGE_SIZE)
size = PAGE_SIZE-count;
else
size = PAGE_SIZE-1;
while (count>0) {
while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
wake_up(& PIPE_READ_WAIT(*inode));
if (inode->i_count != 2) { /* no readers */
while (PIPE_SIZE(*inode) >= size) {
if (!PIPE_READERS(*inode)) { /* no readers */
send_sig(SIGPIPE,current,0);
return written?written:-EINTR;
return written?written:-EPIPE;
}
if (current->signal & ~current->blocked)
return written?written:-EINTR;
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
return written?written:-ERESTARTSYS;
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
else
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
}
chars = PAGE_SIZE-PIPE_HEAD(*inode);
if (chars > count)
chars = count;
if (chars > size)
chars = size;
count -= chars;
written += chars;
size = PIPE_HEAD(*inode);
PIPE_HEAD(*inode) += chars;
PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
while (chars-->0)
((char *)inode->i_size)[size++]=get_fs_byte(buf++);
while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
chars = PAGE_SIZE-PIPE_HEAD(*inode);
if (chars > count)
chars = count;
if (chars > size)
chars = size;
memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
written += chars;
PIPE_HEAD(*inode) += chars;
PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
count -= chars;
buf += chars;
}
wake_up(& PIPE_READ_WAIT(*inode));
size = PAGE_SIZE-1;
}
wake_up(& PIPE_READ_WAIT(*inode));
return written;
}
......@@ -110,18 +118,34 @@ static int pipe_ioctl(struct inode *pino, struct file * filp,
}
/*
* Ok, these two routines should keep track of readers/writers,
* but it's currently done with the inode->i_count checking.
* Ok, these three routines NOW keep track of readers/writers,
* Linus previously did it with inode->i_count checking.
*/
static void pipe_read_release(struct inode * inode, struct file * filp)
{
PIPE_READERS(*inode)--;
wake_up(&PIPE_WRITE_WAIT(*inode));
}
static void pipe_write_release(struct inode * inode, struct file * filp)
{
PIPE_WRITERS(*inode)--;
wake_up(&PIPE_READ_WAIT(*inode));
}
static void pipe_rdwr_release(struct inode * inode, struct file * filp)
{
PIPE_READERS(*inode)--;
PIPE_WRITERS(*inode)--;
wake_up(&PIPE_READ_WAIT(*inode));
wake_up(&PIPE_WRITE_WAIT(*inode));
}
static struct file_operations read_pipe_fops = {
/*
* The three file_operations structs are not static because they
* are also used in linux/fs/fifo.c to do operations on fifo's.
*/
struct file_operations read_pipe_fops = {
pipe_lseek,
pipe_read,
bad_pipe_rw,
......@@ -132,7 +156,7 @@ static struct file_operations read_pipe_fops = {
pipe_read_release
};
static struct file_operations write_pipe_fops = {
struct file_operations write_pipe_fops = {
pipe_lseek,
bad_pipe_rw,
pipe_write,
......@@ -143,6 +167,17 @@ static struct file_operations write_pipe_fops = {
pipe_write_release
};
struct file_operations rdwr_pipe_fops = {
pipe_lseek,
pipe_read,
pipe_write,
pipe_readdir,
NULL, /* pipe_select */
pipe_ioctl,
NULL, /* no special open code */
pipe_rdwr_release
};
int sys_pipe(unsigned long * fildes)
{
struct inode * inode;
......
......@@ -36,7 +36,7 @@ int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
struct file * file;
int tmp;
int tmp = -1;
if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode))
return -EBADF;
......@@ -80,7 +80,6 @@ int sys_read(unsigned int fd,char * buf,unsigned int count)
verify_area(buf,count);
if (file->f_op && file->f_op->read)
return file->f_op->read(inode,file,buf,count);
printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}
......@@ -97,6 +96,5 @@ int sys_write(unsigned int fd,char * buf,unsigned int count)
return 0;
if (file->f_op && file->f_op->write)
return file->f_op->write(inode,file,buf,count);
printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode);
return -EINVAL;
}
......@@ -125,7 +125,7 @@ static int check_in(select_table * wait, struct inode * inode)
else
add_wait(&tty->secondary->proc_list, wait);
else if (inode->i_pipe)
if (!PIPE_EMPTY(*inode) || inode->i_count < 2)
if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
return 1;
else
add_wait(&inode->i_wait, wait);
......@@ -169,7 +169,7 @@ static int check_ex(select_table * wait, struct inode * inode)
else
return 0;
else if (inode->i_pipe)
if (inode->i_count < 2)
if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
return 1;
else
add_wait(&inode->i_wait,wait);
......
......@@ -26,7 +26,10 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
tmp.st_size = inode->i_size;
if( S_ISFIFO(inode->i_mode) )
tmp.st_size = 0;
else
tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
......@@ -36,6 +39,7 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
{
struct new_stat tmp = {0, };
unsigned int blocks, indirect;
verify_area(statbuf,sizeof (*statbuf));
tmp.st_dev = inode->i_dev;
......@@ -45,10 +49,34 @@ static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
tmp.st_size = inode->i_size;
if( S_ISFIFO(inode->i_mode) )
tmp.st_size = 0;
else
tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
/*
* Right now we fake the st_blocks numbers: we'll eventually have to
* add st_blocks to the inode, and let the vfs routines keep track of
* it all. This algorithm doesn't guarantee correct block numbers, but
* at least it tries to come up with a plausible answer...
*
* In fact, the minix fs doesn't use these numbers (it uses 7 and 512
* instead of 10 and 256), but who cares... It's not that exact anyway.
*/
blocks = (tmp.st_size + 1023) / 1024;
if (blocks > 10) {
indirect = (blocks - 11)/256+1;
if (blocks > 10+256) {
indirect += (blocks - 267)/(256*256)+1;
if (blocks > 10+256+256*256)
indirect++;
}
blocks += indirect;
}
tmp.st_blksize = 1024;
tmp.st_blocks = blocks;
memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
......
......@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <asm/system.h>
......@@ -34,6 +35,7 @@ int ROOT_DEV = 0;
static struct file_system_type file_systems[] = {
{minix_read_super,"minix"},
{ext_read_super,"ext"},
{NULL,NULL}
};
......@@ -174,6 +176,8 @@ int sys_umount(char * dev_name)
sb->s_covered = NULL;
iput(sb->s_mounted);
sb->s_mounted = NULL;
if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
sb->s_op->write_super (sb);
put_super(dev);
sync_dev(dev);
return 0;
......
#define UTS_RELEASE "0.96a-37"
#define UTS_RELEASE "0.96b-63"
#define UTS_VERSION "06/20/92"
#define UTS_VERSION "07/04/92"
/*
* The ext filesystem constants/structures
*/
#ifndef _EXT_FS_H
#define _EXT_FS_H
#include <sys/types.h>
/*
* Free blocks/inodes management style
*
* One of these two constants must be defined
*
*/
/* #define EXTFS_BITMAP */ /* use a bitmap */
#define EXTFS_FREELIST /* use a linked list */
#define EXT_NAME_LEN 255
#define EXT_ROOT_INO 1
#define EXT_I_MAP_SLOTS 8
#define EXT_Z_MAP_SLOTS 8
#define EXT_SUPER_MAGIC 0x137D
#define EXT_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_inode)))
/* #define EXT_DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_dir_entry))) */
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;
#ifdef EXTFS_BITMAP
unsigned long s_imap_blocks;
unsigned long s_zmap_blocks;
#endif
#ifdef EXTFS_FREELIST
unsigned long s_firstfreeblock;
unsigned long s_freeblockscount;
unsigned long s_firstfreeinode;
unsigned long s_freeinodescount;
#endif
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];
};
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);
extern struct inode * ext_new_inode(int dev);
extern void ext_free_inode(struct inode * inode);
extern unsigned long ext_count_free_inodes(struct super_block *sb);
extern int ext_new_block(int dev);
extern int ext_free_block(int dev, int block);
extern unsigned long ext_count_free_blocks(struct super_block *sb);
extern int ext_create_block(struct inode *, int);
extern int ext_bmap(struct inode *,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 *);
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 *);
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;
extern struct inode_operations ext_chrdev_inode_operations;
extern struct inode_operations ext_blkdev_inode_operations;
extern struct inode_operations ext_fifo_inode_operations;
extern struct file_operations ext_file_operations;
extern struct file_operations ext_dir_operations;
#endif
......@@ -48,16 +48,4 @@ struct flock {
pid_t l_pid;
};
#ifdef __cplusplus
extern "C" {
#endif
extern int creat(const char * filename,mode_t mode);
extern int fcntl(int fildes,int cmd, ...);
extern int open(const char * filename, int flags, ...);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _FD_H_
#ifndef _FD_H
#define _FD_H
#define FDCLRPRM 0 /* clear user-defined parameters */
......
......@@ -60,6 +60,8 @@ void buffer_init(long buffer_end);
#define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)
#define PIPE_HEAD(inode) ((inode).i_data[0])
#define PIPE_TAIL(inode) ((inode).i_data[1])
#define PIPE_READERS(inode) ((inode).i_data[2])
#define PIPE_WRITERS(inode) ((inode).i_data[3])
#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))
#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
......@@ -192,6 +194,7 @@ struct super_operations {
void (*write_inode) (struct inode *inode);
void (*put_inode) (struct inode *inode);
void (*put_super)(struct super_block *sb);
void (*write_super) (struct super_block *sb);
void (*statfs) (struct super_block *sb, struct statfs *buf);
};
......@@ -212,6 +215,7 @@ extern struct buffer_head * start_buffer;
extern int nr_buffers;
extern void check_disk_change(int dev);
extern void invalidate_inodes(int dev);
extern int floppy_change(struct buffer_head * first_block);
extern int ticks_to_floppy_on(unsigned int dev);
extern void floppy_on(unsigned int dev);
......@@ -242,6 +246,7 @@ extern void bread_page(unsigned long addr,int dev,int b[4]);
extern struct buffer_head * breada(int dev,int block,...);
extern int sync_dev(int dev);
extern struct super_block * get_super(int dev);
extern void put_super(int dev);
extern int ROOT_DEV;
extern void mount_root(void);
......
......@@ -86,6 +86,7 @@ extern struct inode_operations minix_dir_inode_operations;
extern struct inode_operations minix_symlink_inode_operations;
extern struct inode_operations minix_chrdev_inode_operations;
extern struct inode_operations minix_blkdev_inode_operations;
extern struct inode_operations minix_fifo_inode_operations;
extern struct file_operations minix_file_operations;
extern struct file_operations minix_dir_operations;
......
......@@ -17,11 +17,29 @@ extern void rw_swap_page(int rw, unsigned int nr, char * buf);
#define write_swap_page(nr,buf) \
rw_swap_page(WRITE,(nr),(buf))
/* memory.c */
extern unsigned long get_free_page(void);
extern unsigned long put_dirty_page(unsigned long page,unsigned long address);
extern void free_page(unsigned long addr);
void swap_free(int page_nr);
void swap_in(unsigned long *table_ptr);
extern int free_page_tables(unsigned long from,unsigned long size);
extern int copy_page_tables(unsigned long from,unsigned long to,long size);
extern int unmap_page_range(unsigned long from, unsigned long size);
extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
int permiss);
extern void un_wp_page(unsigned long * table_entry);
extern void do_wp_page(unsigned long error_code,unsigned long address);
extern void write_verify(unsigned long address);
extern void do_no_page(unsigned long error_code, unsigned long address,
struct task_struct *tsk, unsigned long user_esp);
extern void mem_init(long start_mem, long end_mem);
extern void show_mem(void);
extern void do_page_fault(unsigned long *esp, unsigned long error_code);
/* swap.c */
extern void swap_free(int page_nr);
extern void swap_in(unsigned long *table_ptr);
extern inline volatile void oom(void)
{
......
......@@ -60,10 +60,8 @@
#define MAX_SHARED_LIBS 6
extern int copy_page_tables(unsigned long from, unsigned long to, long size);
extern int free_page_tables(unsigned long from, unsigned long size);
extern void sched_init(void);
extern void show_state(void);
extern void schedule(void);
extern void trap_init(void);
extern void panic(const char * str);
......
#ifndef _STRING_H_
#define _STRING_H_
#include <sys/types.h>
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
extern char * strerror(int errno);
/*
......
......@@ -66,34 +66,11 @@ struct serial_struct {
#define FULL(a) (!LEFT(a))
#define CHARS(a) (((a)->head-(a)->tail)&(TTY_BUF_SIZE-1))
static inline void PUTCH(char c, struct tty_queue * queue)
{
int head;
unsigned long flags;
__asm__("pushfl ; popl %0 ; cli":"=r" (flags));
head = (queue->head + 1) & (TTY_BUF_SIZE-1);
if (head != queue->tail) {
queue->buf[queue->head] = c;
queue->head = head;
}
__asm__("pushl %0 ; popfl"::"r" (flags));
}
static inline int GETCH(struct tty_queue * queue)
{
int result = -1;
unsigned long flags;
__asm__("pushfl ; popl %0 ; cli":"=r" (flags));
if (queue->tail != queue->head) {
result = 0xff & queue->buf[queue->tail];
queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
}
__asm__("pushl %0 ; popfl"::"r" (flags));
return result;
}
extern void put_tty_queue(char c, struct tty_queue * queue);
extern int get_tty_queue(struct tty_queue * queue);
#define PUTCH(c,queue) put_tty_queue((c),(queue))
#define GETCH(queue) get_tty_queue(queue)
#define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])
#define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT])
#define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])
......@@ -138,7 +115,7 @@ struct tty_struct {
int pgrp;
int session;
int stopped;
int busy;
int flags;
int count;
struct winsize winsize;
void (*write)(struct tty_struct * tty);
......@@ -151,36 +128,17 @@ struct tty_struct {
/*
* so that interrupts won't be able to mess up the
* queues, copy_to_cooked must be atomic with repect
* to itself, as must tty->write.
* to itself, as must tty->write. These are the flag bits.
*/
#define TTY_WRITE_BUSY 1
#define TTY_READ_BUSY 2
#define TTY_CR_PENDING 4
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
#define TTY_READ_FLUSH(tty) tty_read_flush((tty))
#define TTY_WRITE_FLUSH(tty) \
do { \
cli(); \
if (!EMPTY((tty)->write_q) && !(TTY_WRITE_BUSY & (tty)->busy)) { \
(tty)->busy |= TTY_WRITE_BUSY; \
sti(); \
(tty)->write((tty)); \
cli(); \
(tty)->busy &= ~TTY_WRITE_BUSY; \
} \
sti(); \
} while (0)
#define TTY_READ_FLUSH(tty) \
do { \
cli(); \
if (!EMPTY((tty)->read_q) && !(TTY_READ_BUSY & (tty)->busy)) { \
(tty)->busy |= TTY_READ_BUSY; \
sti(); \
copy_to_cooked((tty)); \
cli(); \
(tty)->busy &= ~TTY_READ_BUSY; \
} \
sti(); \
} while (0)
extern void tty_write_flush(struct tty_struct *);
extern void tty_read_flush(struct tty_struct *);
extern struct tty_struct tty_table[];
extern struct serial_struct serial_table[];
......
......@@ -8,7 +8,7 @@ typedef long ptrdiff_t;
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned long size_t;
typedef unsigned int size_t;
#endif
#undef NULL
......
......@@ -2,6 +2,7 @@
#define _SYS_DIRENT_H
#include <limits.h>
#include <sys/types.h>
struct dirent {
long d_ino;
......
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#include <stddef.h>
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
#ifndef _SSIZE_T
#define _SSIZE_T
typedef int ssize_t;
#endif
#ifndef _TIME_T
#define _TIME_T
typedef long time_t;
#endif
#ifndef _CLOCK_T
#define _CLOCK_T
typedef long clock_t;
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef long ptrdiff_t;
......@@ -24,16 +36,29 @@ typedef int pid_t;
typedef unsigned short uid_t;
typedef unsigned short gid_t;
typedef unsigned short dev_t;
#ifdef OLD_LINUX
typedef unsigned short ino_t;
#else
typedef unsigned long ino_t;
#endif
typedef unsigned short mode_t;
typedef unsigned short umode_t;
typedef unsigned short nlink_t;
typedef int daddr_t;
typedef long off_t;
/* bsd */
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
/* sysv */
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef char *caddr_t;
typedef unsigned char cc_t;
......
......@@ -17,7 +17,10 @@ typedef unsigned int size_t;
#define CLOCKS_PER_SEC 100
#ifndef _CLOCK_T
#define _CLOCK_T
typedef long clock_t;
#endif
struct tm {
int tm_sec;
......
......@@ -6,7 +6,6 @@
#include <stddef.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
......@@ -14,6 +13,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <linux/fcntl.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/tty.h>
......@@ -40,6 +40,7 @@ static inline _syscall0(pid_t,setsid)
static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
static inline _syscall1(int,dup,int,fd)
static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
static inline _syscall1(int,close,int,fd)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
......@@ -52,8 +53,8 @@ static char printbuf[1024];
extern int vsprintf();
extern void init(void);
extern void blk_dev_init(void);
extern long chr_dev_init(long);
extern long blk_dev_init(long,long);
extern long chr_dev_init(long,long);
extern void hd_init(void);
extern void floppy_init(void);
extern void sock_init(void);
......@@ -162,13 +163,10 @@ void start_kernel(void)
else
buffer_memory_end = 1*1024*1024;
main_memory_start = buffer_memory_end;
#ifdef RAMDISK
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
#endif
trap_init();
sched_init();
main_memory_start = chr_dev_init(main_memory_start);
blk_dev_init();
main_memory_start = chr_dev_init(main_memory_start,memory_end);
main_memory_start = blk_dev_init(main_memory_start,memory_end);
mem_init(main_memory_start,memory_end);
time_init();
printk("Linux version " UTS_RELEASE " " __DATE__ " " __TIME__ "\n");
......
This diff is collapsed.
......@@ -9,69 +9,72 @@
# parent makefile.
#
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
CC =gcc -nostdinc -I../../include
CPP =cpp -nostdinc -I../../include
.c.s:
$(CC) $(CFLAGS) \
-S -o $*.s $<
$(CC) $(CFLAGS) $(RAMDISK) -S $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) \
-c -o $*.o $<
$(CC) $(CFLAGS) $(RAMDISK) -c $<
SUBDIRS = scsi
OBJS = hd.o ll_rw_blk.o floppy.o ramdisk.o
all: blk_drv.a
all: blk_drv.a subdirs
blk_drv.a: $(OBJS)
rm -f blk_drv.a
$(AR) rcs blk_drv.a $(OBJS)
sync
subdirs: dummy
for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
clean:
rm -f core *.o *.a tmp_make
for i in *.c;do rm -f `basename $$i .c`.s;done
(cd scsi; make clean)
cd scsi; $(MAKE) clean
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
$(CPP) -M $$i;done) >> tmp_make
for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
dummy:
### Dependencies:
floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/fdreg.h \
../../include/linux/fd.h ../../include/asm/system.h ../../include/asm/io.h ../../include/asm/segment.h \
../../include/errno.h blk.h
hd.s hd.o : hd.c ../../include/errno.h ../../include/linux/config.h ../../include/linux/config_rel.h \
../../include/linux/config_ver.h ../../include/linux/config.dist.h ../../include/linux/sched.h \
../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/timer.h \
../../include/linux/hdreg.h ../../include/asm/system.h ../../include/asm/io.h \
../../include/asm/segment.h blk.h
ll_rw_blk.s ll_rw_blk.o : ll_rw_blk.c ../../include/errno.h ../../include/linux/sched.h \
../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \
../../include/sys/dirent.h ../../include/limits.h ../../include/sys/vfs.h ../../include/linux/mm.h \
../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \
../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/asm/system.h \
floppy.o : floppy.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
/usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/fdreg.h \
/usr/src/linux/include/linux/fd.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
/usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h blk.h
hd.o : hd.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/config.h \
/usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
/usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
/usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
/usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
/usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \
/usr/src/linux/include/linux/hdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
/usr/src/linux/include/asm/segment.h blk.h
ll_rw_blk.o : ll_rw_blk.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
/usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
/usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
/usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
/usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
blk.h
ramdisk.o : ramdisk.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
/usr/src/linux/include/stddef.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
/usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
/usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
/usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
/usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
/usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
/usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/memory.h \
blk.h
ramdisk.s ramdisk.o : ramdisk.c ../../include/linux/string.h ../../include/linux/config.h \
../../include/linux/config_rel.h ../../include/linux/config_ver.h ../../include/linux/config.dist.h \
../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \
../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \
../../include/sys/vfs.h ../../include/linux/mm.h ../../include/linux/kernel.h \
../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \
../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h \
../../include/asm/segment.h ../../include/asm/memory.h blk.h
......@@ -785,7 +785,7 @@ static void redo_fd_request(void)
if (current_drive != (format_req.device & 3))
current_track = NO_TRACK;
current_drive = format_req.device & 3;
if (format_req.track < 0 || format_req.track >= floppy->track ||
if (((unsigned) format_req.track) >= floppy->track ||
(format_req.head & 0xfffe) || probing) {
request_done(0);
goto repeat;
......
......@@ -14,6 +14,8 @@
#include "blk.h"
extern long rd_init(long mem_start, int length);
/*
* The request-struct contains all necessary data
* to load a nr of sectors into memory
......@@ -241,7 +243,7 @@ void ll_rw_block(int rw, struct buffer_head * bh)
make_request(major,rw,bh);
}
void blk_dev_init(void)
long blk_dev_init(long mem_start, long mem_end)
{
int i;
......@@ -249,6 +251,10 @@ void blk_dev_init(void)
request[i].dev = -1;
request[i].next = NULL;
}
#ifdef RAMDISK
mem_start += rd_init(mem_start, RAMDISK*1024);
#endif
return mem_start;
}
void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
......
......@@ -8,22 +8,12 @@
#DEBUG = -DDEBUG=0xffffffff -DDEBUG_NO_CMD
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
CC =cc
CPP =cc -E -nostdinc -I../../../include
.c.s:
$(CC) -nostdinc $(CFLAGS) $(DEBUG) \
-S -o $*.s $<
$(CC) $(CFLAGS) $(DEBUG) -S $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) -nostdinc -I../../../include $(CFLAGS) $(DEBUG) \
-c -o $*.o $<
$(CC) $(CFLAGS) $(DEBUG) -c $<
LOWLEVELCSRC = aha1542.c seagate.c ultrastor.c
LOWLEVELHSRC = aha1542.c seagate.h ultrastor.h
......@@ -36,14 +26,14 @@ OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \
all: scsi.a
config.out : config.in ../../../include/linux/config.h
config.out : config.in $(KERNELHDRS)/linux/config.h
rm -f foo.c
ln -s config.in foo.c
$(CPP) foo.c | grep '\.o' > config.out
rm foo.c
figure : hosts.h ../../../include/linux/config.h hosts.c config.out
$(CC) -I../../../include -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c config.out
$(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
max_hosts.h : figure
(echo "#ifndef _MAX_HOSTS_H"; \
......@@ -70,12 +60,11 @@ seagate.s seagate.o : seagate.c ../../../include/linux/config.h \
../../../include/sys/param.h ../../../include/sys/time.h \
../../../include/time.h ../../../include/sys/resource.h \
../../../include/linux/string.h seagate.h scsi.h hosts.h max_hosts.h
cc -nostdinc -I../../../include -Wall -c seagate.c $(DEBUG)
$(CC) -Wall -c seagate.c $(DEBUG)
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
(for i in *.c ;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
$(CPP) -M $$i;done) >> tmp_make
for i in *.c ;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
### Dependencies:
......
......@@ -10,6 +10,7 @@
#include <linux/string.h>
#include <asm/system.h>
#include <asm/io.h>
#include <sys/types.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -16,8 +16,6 @@
*
*/
typedef unsigned char unchar;
/* I/O Port interface 4.2 */
/* READ */
#define STATUS base
......
......@@ -30,6 +30,7 @@
#include "hosts.h"
#ifdef CONFIG_SCSI_AHA1542
#include <sys/types.h>
#include "aha1542.h"
#endif
......
This diff is collapsed.
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include <linux/sched.h>
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/system.h>
......@@ -40,7 +41,6 @@ unsigned char lfnlmode = 0;
extern void do_keyboard_interrupt(void);
extern void ctrl_alt_del(void);
extern void show_mem(void), show_state(void);
extern void change_console(unsigned int new_console);
extern struct tty_queue *table_list[];
......@@ -679,7 +679,7 @@ static unsigned char alt_map[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, '|', 0,
0, 0, 0, 0, 0, 0, '\\', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
......@@ -874,7 +874,7 @@ unsigned int handle_diacr(unsigned int ch)
}
#if defined KBD_FR
#if defined KBD_FR || defined KBD_US
static unsigned char num_table[] = "789-456+1230.";
#else
static unsigned char num_table[] = "789-456+1230,";
......
......@@ -241,10 +241,10 @@ static struct file_operations mem_fops = {
NULL /* no special release code */
};
long chr_dev_init(long kmem_start)
long chr_dev_init(long mem_start, long mem_end)
{
chrdev_fops[1] = &mem_fops;
kmem_start = tty_init(kmem_start);
kmem_start = lp_init(kmem_start);
return kmem_start;
mem_start = tty_init(mem_start);
mem_start = lp_init(mem_start);
return mem_start;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -15,11 +15,10 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/segment.h>
#include <asm/system.h>
extern void write_verify(unsigned long address);
long last_pid=0;
void verify_area(void * addr,int size)
......
......@@ -7,6 +7,7 @@
/* These are all the functions necessary to implement itimers */
#include <linux/sched.h>
#include <linux/string.h>
#include <asm/segment.h>
#include <signal.h>
......
This diff is collapsed.
......@@ -28,7 +28,7 @@ int need_resched = 0;
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
void show_task(int nr,struct task_struct * p)
static void show_task(int nr,struct task_struct * p)
{
int i,j = 4096-sizeof(struct task_struct);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment